Значения массива после cudaMemcpy - PullRequest
2 голосов
/ 29 марта 2012

Я хотел бы знать, если при вызове cudaMemcpy (...) для получения памяти на графическом процессоре копируются также значения внутри массива или нет.Я объясню лучше: я копирую значения из одного массива в другой, а затем вызываю cudaMalloc и cudaMemcpy.

// Copying values of the arrays
for(int i = 0; i<16; i++){
    array_device_1[i] = array_host_1[i];
    array_device_2[i] = array_host_2[i];
}

// Memory allocation of array_device_1 and array_device_2
cudaMalloc((void**) &array_device_1, SIZE_INT*size);
cudaMalloc((void**) &array_device_2, SIZE_INT*size);

// Transfer array_device_1 and array_device_2
cudaMemcpy(array_device_1, array_host_1, SIZE_INT*size, cudaMemcpyHostToDevice);
cudaMemcpy(array_device_2, array_host_2, SIZE_INT*size, cudaMemcpyHostToDevice);

kernel<<<N, N>>>(array_device_1, array_device_2);

cudaMemcpy(array_host_1, array_device_1, SIZE_INT*size, cudaMemcpyDeviceToHost);
cudaMemcpy(array_host_2, array_device_2, SIZE_INT*size, cudaMemcpyDeviceToHost);

cudaFree(array_device_1);
cudaFree(array_device_2);

Итак, когда я выполняю все эти инструкции и использую все массивы в ядре, значения внутри array_device_1 и array_device_2 или нет?Я попытался распечатать после ядра, и я заметил, что все массивы пусты!На самом деле я не могу понять, как я могу сохранить значения внутри них и затем изменить их значения с помощью функции ядра.

Ответы [ 4 ]

4 голосов
/ 29 марта 2012

Да, у них есть свои ценности внутри. Но вы не можете распечатать их на хосте. Для этого вам нужно будет скопировать ваши данные обратно, используя

cudaMemcpy((void *) array_host_2, (void *) array_device_2, SIZE_INT*size, cudaMemcpyDeviceToHost);

И тогда вы можете распечатать значения array_host_2.

Немного более подробного объяснения: ваш array_device_* живет на графическом процессоре, а с вашего процессора (который печатает ваш вывод) у вас нет прямого доступа к этим данным. Поэтому вам необходимо сначала скопировать его обратно в память вашего ЦП, прежде чем распечатать.

1 голос
/ 02 апреля 2012

Пример копирования массива с данными на устройство, изменения значений в ядре, копирования обратно на хост и печати новых значений:

// Function to run on device by many threads
__global__ void myKernel(int *d_arr) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    d_arr[idx] = d_arr[idx]*2;
}

int main(void) {
    int *h_arr, *d_arr;
    h_arr = (int *)malloc(10*sizeof(int));
    for (int i=0; i<10; ++i)
        h_arr[i] = i; // Or other values

    // Sends data to device
    cudaMalloc((void**) &d_arr, 10*sizeof(int));
    cudaMemcpy(d_arr, h_arr, 10*sizeof(int), cudaMemcpyHostToDevice);

    // Runs kernel on device
    myKernel<<< 2, 5 >>>(d_arr);

    // Retrieves data from device 
    cudaMemcpy(h_arr, d_arr, 10*sizeof(int), cudaMemcpyDeviceToHost);

    for (int i = 0; i<10; ++i)
        printf("Post kernel value in h_arr[%d] is: %d\n", i,h_arr[i]);

    cudaFree(d_arr);
    free(h_arr);
    return 0;
}
1 голос
/ 29 марта 2012

Представленный вами фрагмент кода выглядит правильно, за исключением первых нескольких строк, как указано выше.Вы уверены, что ядро ​​правильно?Возможно, вы не записываете измененные значения обратно в глобальную память.Если вы создадите другой набор хост-массивов и скопируете массивы GPU обратно перед запуском ядра, они будут правильными?Исходя из того, что у вас есть, значения внутри array_host_ * должны были быть правильно скопированы в array_device_ *.

0 голосов
/ 20 мая 2019

Вы можете использовать функцию ядра для прямой печати значений в памяти графического процессора.Использование может использовать что-то вроде:

__global__ void printFunc(int *devArray){
      printf("%d", devArray[0]);
} 

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...