Как скопировать память, выделенную в функции устройства, обратно в основную память

У меня есть программа CUDA, содержащая функцию хоста и функцию устройстваВыполнить (), В функции хоста я выделяю глобальную памятьвыход который затем будет передан в функцию устройства и использован для хранения адреса глобальной памяти, выделенной в функции устройства. Я хочу получить доступ к выделенной памяти в ядре в функции хоста. Ниже приведен код:

#include <stdio.h>
typedef struct                      
{
  int             * p;            
  int              num;            
} Structure_A;

__global__ void Execute(Structure_A *output);

int main(){

    Structure_A *output;
    cudaMalloc((void***)&output,sizeof(Structure_A)*1);
    dim3 dimBlockExecute(1,1);
    dim3 dimGridExecute(1,1);
    Execute<<<dimGridExecute,dimBlockExecute>>>(output);
    Structure_A * output_cpu;
    int * p_cpu;
    cudaError_t err;

    output_cpu= (Structure_A*)malloc(sizeof(Structure_A));
    err=cudaMemcpy(output_cpu,output,sizeof(Structure_A),cudaMemcpyDeviceToHost);    
    if( err != cudaSuccess)
    {
        printf("CUDA error a: %s\n", cudaGetErrorString(err));
        exit(-1);
    }
    p_cpu=(int *)malloc(sizeof(int));
    err=cudaMemcpy(p_cpu,output_cpu[0].p,sizeof(int),cudaMemcpyDeviceToHost);    
    if( err != cudaSuccess)
    {
        printf("CUDA error b: %s\n", cudaGetErrorString(err));
        exit(-1);
    }   
    printf("output=(%d,%d)\n",output_cpu[0].num,p_cpu[0]);
    return 0;
}

__global__ void Execute(Structure_A *output){

    int thid=threadIdx.x;

    output[thid].p= (int*)malloc(thid+1);

    output[thid].num=(thid+1);

    output[thid].p[0]=5;
} 

Я могу скомпилировать программу. Но когда я его запустил, я получил ошибку, показывающую, что в следующей функции копирования памяти есть недопустимый аргумент:

err=cudaMemcpy(p_cpu,output_cpu[0].p,sizeof(int),cudaMemcpyDeviceToHost); 

Версия CUDA - 4.2. Карта CUDA: Tesla C2075 ОС: x86_64 GNU / Linux

Редактировать: изменил код и выделил правильный размер памяти для output_cpu и p_cpu.

Ответы на вопрос(1)

Решение Вопроса

вы выделяете только 1 байт в обеих этих двух строках, что недостаточно для хранения одного экземпляраStructure_A.

output_cpu= (Structure_A*)malloc(1);
p_cpu=(int *)malloc(1);

Но непосредственной причиной вашей ошибки является то, что вы выполняете memcpy из указателя, выделенного для динамической памяти устройства (т.е.malloc или жеnew внутри кода вашего устройства) на указатель хоста.

err=cudaMemcpy(p_cpu,output_cpu[0].p,sizeof(int),cudaMemcpyDeviceToHost);   

К сожалению, API времени выполнения хоста для cudaMalloc, cudaFree и cudaMemcpy в настоящее время не совместим с памятью, выделенной в куче времени выполнения устройства.

 talonmies24 окт. 2012 г., 08:11
Ваш последний указатель неверен.output_cpu[0].p является указателем устройства, но он размещен в динамической памяти, поэтому передача данных с устройства на хост API не поддерживается.
 talonmies24 окт. 2012 г., 08:43
или альтернативно предварительные декларации должны быть вне закона .....
 harrism24 окт. 2012 г., 08:42
D'о! Люди не должны размещать так много кода. :)
 harrism24 окт. 2012 г., 08:29
Спасибо, для меня не было очевидно, что OP вызывал malloc / new на устройстве, так как OP не содержал никакого кода ядра. Надо было читать более внимательно. Я отредактировал код ОП, чтобы прояснить это.
 talonmies24 окт. 2012 г., 08:32
Есть код ядра. Прокрутить вниз :)

Ваш ответ на вопрос