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-массив напрямую, взгляните на этот вопрос / ответ для проработанного примера. Это не тривиально.