cudaMemcpy2D устанавливает значения в 0

Я пытаюсь скопировать двумерный массив с хоста на устройство с помощью cudaMallocPitch и cudaMemcpy2D, но у меня возникла проблема, когда кажется, что оно устанавливает мое значение равным 0.

Я напишу основы своего кода в браузере. Я знаю, что значение, которое я печатаю из ядра, не равно 0. Есть идеи?

__global__ void kernel(float **d_array) {
    printf("%f", d_array[0][0]);
}

void kernelWrapper(int rows, int cols, float **array) {
    float **d_array;
    size_t pitch;
    cudaMallocPitch((void**) &d_array, &pitch, rows*sizeof(float), cols);
    cudaMemcpy2D(d_array, pitch, array, rows*sizeof(float), rows*sizeof(float), cols, cudaMemcpyHostToDevice);
    kernel<<<1,1>>>(d_array);
}

По какой-то причине ядро ​​продолжает печатать 0,0000. Я знаю, что первый элемент не равен 0, так как я тестировал печать первого элемента массива хоста. Что происходит?

РЕДАКТИРОВАТЬ: Я также пытался этот код, но получил недопустимые ошибки указателя.

cudaMalloc(d_array, rows*sizeof(float*));
for (int i = 0; i < rows; i++) {
    cudaMalloc((void**) &d_array[i], cols*sizeof(float));
}
cudaMemcpy(d_array, array, rows*sizeof(float*), cudaMemcpyHostToDevice);

1 ответ

Несмотря на свое название, cudaMemcpy2D не копирует дважды подписанный массив хоста C (**) для дважды подписавшегося (**) массив устройств. Вы заметите, что он ожидает одиночные указатели (*), чтобы быть переданным к нему, а не двойные указатели (**). cudaMemcpy2D используется для копирования плоского пошагового массива, а не двумерного массива. Есть два аспекта, присущих концепции постепенного доступа, отсюда и название.

В общем, попытка скопировать 2D-массив с хоста на устройство сложнее, чем просто один вызов API. Рекомендуется сгладить массив, чтобы вы могли ссылаться на него одним указателем (*), тогда вызовы API будут работать. Существует множество примеров правильного использования cudaMemcpy2D на SO, просто поищите их.

Кроме того, вы должны выполнять проверку ошибок cuda во всех вызовах API cuda и вызовах ядра, всякий раз, когда у вас возникают трудности с кодом CUDA.

Если вы действительно хотите скопировать 2D-массив напрямую, взгляните на этот вопрос / ответ для проработанного примера. Это не тривиально.

Другие вопросы по тегам