CUDA C считывает изображение с хоста и копирует на устройство

#c #cuda

#c #cuda

Вопрос:

Мне нужно прочитать изображение и сохранить его в массив символов без знака и использовать массив для создания класса. Конструкция класса — это функция устройства. поэтому мне нужно прочитать изображение и скопировать на устройство. Код похож на приведенный ниже.

     __global__ void print_copy_result(unsigned char **tdt)
{
    if (threadIdx.x == 0 amp;amp; blockIdx.x == 0) 
    {
        printf("%ct%ct%ct", (*tdt)[0], (*tdt)[1], (*tdt)[2]);
    }
}

int main()
{
    int inx, iny, inn;
    unsigned char* texture_data = stbi_load("60847663_p0.jpg", amp;inx, amp;iny, amp;inn, 0);
    printf("%hhc, %hhc, %hhcn", texture_data[0], texture_data[1], texture_data[2]);

    unsigned char* d_texture_data;

    checkCudaErrors(cudaMallocManaged(amp;d_texture_data, inx * iny * inn * sizeof(unsigned char)));
    checkCudaErrors(cudaMemcpy(d_texture_data, texture_data, inx * iny * inn * sizeof(unsigned char), cudaMemcpyDefault));
    print_copy_result<<<1, 1>>>(amp;d_texture_data);
    checkCudaErrors(cudaGetLastError());
    checkCudaErrors(cudaDeviceSynchronize());
    return 0;
}
  

но я получаю ошибку CUDA = 700, на checkCudaErrors(cudaDeviceSynchronize()); каком шаге я ошибся?

Комментарии:

1. amp;d_texture_data находится в памяти хоста, вот в чем вы ошиблись

Ответ №1:

Как указано в комментариях, amp;d_texture_data это указатель на память хоста (не управляемую память, а память хоста). Такой указатель на память хоста по существу непригоден для использования кодом устройства CUDA (код ядра CUDA не может разыменовывать такие указатели на память хоста, за исключением некоторых случаев на платформах Power9).

В любом случае вам не нужен такой уровень косвенности. Наиболее прямым подходом было бы использовать методологию, аналогичную показанной здесь, и просто передать «обычный» управляемый указатель вашему ядру. Поскольку мы избавляемся от подхода с двумя указателями, в ядре также необходимы изменения:

 $ cat t54.cu
#include <cstdio>
#include <helper_cuda.h>

    __global__ void print_copy_result(unsigned char *tdt)
{
    if (threadIdx.x == 0 amp;amp; blockIdx.x == 0)
    {
        printf("%ct%ct%ct", tdt[0], tdt[1], tdt[2]);
    }
}

int main()
{
    int inx, iny, inn;
    const unsigned char texture_data[] = {'a', 'b', 'c'};
    printf("%hhc, %hhc, %hhcn", texture_data[0], texture_data[1], texture_data[2]);
    inx = sizeof(texture_data)/sizeof(texture_data[0]);
    iny = 1;
    inn = 1;
    unsigned char* d_texture_data;

    checkCudaErrors(cudaMallocManaged(amp;d_texture_data, inx * iny * inn * sizeof(unsigned char)));
    checkCudaErrors(cudaMemcpy(d_texture_data, texture_data, inx * iny * inn * sizeof(unsigned char), cudaMemcpyDefault));
    print_copy_result<<<1, 1>>>(d_texture_data);
    checkCudaErrors(cudaGetLastError());
    checkCudaErrors(cudaDeviceSynchronize());
    printf("n");
    return 0;
}
$ nvcc -o t54 t54.cu -arch=sm_35 -I/usr/local/cuda/samples/common/inc  -Wno-deprecated-gpu-targets
$ cuda-memcheck ./t54
========= CUDA-MEMCHECK
a, b, c
a       b       c
========= ERROR SUMMARY: 0 errors
$