Как передать данные (динамически распределяемые с помощью malloc) с устройства на хост в cuda? - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть реализация ниже связанного списка, где я вызываю malloc внутри ядра. Теперь мне нужно увидеть результат на хост-машине. По сути, мне нужно передать все, что я создал на устройстве, для передачи на хост.

Я рассмотрел несколько реализаций, но не получил ясного представления.

struct SlabList{
        int val[SLAB_SIZE];
        int key[SLAB_SIZE];
        struct SlabList* next;
};
__global__ void insertKernel(struct SlabList* head_ref, int* new_key, int* new_val, int size){
        int id = blockIdx.x*blockDim.x + threadIdx.x;
        if(id==0){
        head_ref=NULL;
        for(int i=0;i<size/4;i++){
                struct SlabList* new_node = (struct SlabList*) malloc(sizeof(struct SlabList));
                for(int j=0;j<SLAB_SIZE;j++){
                        new_node->key[j] = new_key[i*SLAB_SIZE+j];
                        new_node->val[j]= new_val[i*SLAB_SIZE+j];
                        printf("key--->%d\tVal---->%d\n",new_node->key[j],new_node->val[j]);
                }
                new_node->next = head_ref;
                head_ref    = new_node;
        }
}

int main(void){
int *val_array = (int *)malloc(N * sizeof(int));
        int *key_array = (int *)malloc(N * sizeof(int));
        int *d_val_array = NULL;
        int *d_key_array = NULL;
        int *device_array;
        struct SlabList *start=(struct SlabList*)malloc(sizeof(struct SlabList));
        struct SlabList *d_start=(struct SlabList*)malloc(sizeof(struct SlabList));
        cudaMalloc(&d_val_array, N * sizeof(int));
        cudaMalloc(&d_key_array, N * sizeof(int));
        struct Slab* new_node = (struct Slab*) malloc(sizeof(struct Slab));
        for (int i = 0; i < N; i++){
                val_array[i] =i;
                key_array[i] =i+10;
        }
        cudaMemcpy(d_val_array, val_array, N * sizeof(int), cudaMemcpyHostToDevice);
        cudaDeviceSetLimit(cudaLimitMallocHeapSize, sizeof(struct SlabList)*N);
        cudaMemcpy(d_key_array, key_array, N * sizeof(int), cudaMemcpyHostToDevice);
        const clock_t begin_time1 = clock();
        insertKernel<<<1, 1>>>(d_start, d_val_array,d_key_array, N);
//      insertKernel<<<32, 32>>>();
        cudaDeviceSynchronize();
        struct SlabList* head1 = NULL;
        cudaMemcpy(head1, d_start, N * sizeof(int), cudaMemcpyDeviceToHost);

1 Ответ

2 голосов
/ 05 апреля 2019

Невозможно передать данные из области, выделенной в ядре malloc, непосредственно в память хоста.Причина этого - , упомянутая в руководстве по программированию .Области данных, выделенные в ядре malloc или в ядре new или в ядре cudaMalloc, выделяются из специальной области, называемой кучей устройств.

Адреса в куче устройств не могут участвовать влюбой основанный на хосте cudaMemcpy -типа API.Только адреса в памяти хоста или адреса, полученные из распределителя устройств на основе хоста, такого как cudaMalloc, cudaHostAlloc или cudaMallocManaged, могут участвовать в API типа хоста cudaMemcpy.

Поэтому единственное решениеis:

  1. Обеспечение выделения с использованием API на основе хоста (например, cudaMalloc, cudaHostAlloc, cudaMallocManaged)
  2. В коде устройства скопируйте данные из регионавыделенный в ядре malloc для области, выделенной на шаге 1 выше.
  3. При необходимости используйте обычный API копирования на основе хоста (например, cudaMemcpy, но явно не требуется, если область на шаге 1выделенный с помощью cudaHostAlloc или cudaMallocManaged), чтобы скопировать данные из области, выделенной на шаге 1, на хост.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...