Как я могу скопировать элементы вложенных структур в область памяти устройства CUDA? - PullRequest
1 голос
/ 10 октября 2011

Я пытаюсь скопировать некоторые вложенные структуры в память устройства для использования ядром в симуляторе нейронной сети с ускорением CUDA. Этот код связывает и запускает, но выдает некоторые исключения и ошибки CUDA:

typedef struct rdLayer
{
    long NeuronQty ;
    long DendriteQty ;

    cuDoubleComplex *gpuWeights ;
    cuDoubleComplex *gpuZOutputs ;
    cuDoubleComplex *gpuDeltas ;
    cuDoubleComplex *gpuUnWeights ;
} rdLayer;

typedef struct rdNetwork
{
    long SectorQty;
    double K_DIV_TWO_PI;
    double two_pi_div_sect_qty;
    cuDoubleComplex *gpuSectorBdry;
    long LayerQty;
    rdLayer *rLayer;
} rdNetwork;

struct rdLearningSet 
{
    long EvalMode ;
    long SampleQty ;
    long InputQty ;
    long OutputQty ;
    long ContOutputs ;
    long SampleIdxReq ;

    cuDoubleComplex *gpuXInputs ;
    cuDoubleComplex *gpuDOutputs ;
    cuDoubleComplex *gpuYOutputs ;
    double *gpudSE1024 ;
    cuDoubleComplex *gpuOutScalar ;
};

[...]
    struct rdLearningSet * rdLearn;
    struct rdNetwork * rdNet;
[...]
    cudaMalloc(&rdNet, sizeof(rdNetwork));
    cudaMalloc(&rdLearn, sizeof(rdLearningSet));
[...]
    cuDoubleComplex * dummy;
    struct rdLayer rdlSource, * rdldummy;
[...]
    //rdLayer *rLayer;
    cudaMalloc(&rdldummy, sizeof(rdLayer)*rSes.rNet->LayerQty);
    cudaMemcpy( &rdNet->rLayer, &rdldummy, sizeof(rdLayer*), cudaMemcpyHostToDevice);
    for (int L=1; L<rSes.rNet->LayerQty; L++){
            // construct layer to be copied
            rdlSource.NeuronQty=rSes.rNet->rLayer[L].iNeuronQty 
            rdlSource.DendriteQty=rSes.rNet->rLayer[L].iDendriteQty 
            cudaMalloc( &rdlSource.gpuWeights, sizeof(cuDoubleComplex) * (rSes.rNet->rLayer[L].DendriteQty+1) * (rSes.rNet->rLayer[L].NeuronQty+1) ) 
                    mCheckCudaWorked
            cudaMalloc( &rdlSource.gpuZOutputs, sizeof(cuDoubleComplex) * (rSes.rNet->rLayer[L].DendriteQty+1) * (rSes.rNet->rLayer[L].NeuronQty+1) ) 
                    mCheckCudaWorked
            cudaMalloc( &rdlSource.gpuDeltas, sizeof(cuDoubleComplex) * (rSes.rNet->rLayer[L].iDendriteQty+1) * (rSes.rNet->rLayer[L].iNeuronQty+1) ) 
                    mCheckCudaWorked
            cudaMalloc( &rdlSource.gpuUnWeights, sizeof(cuDoubleComplex) * (rSes.rNet->rLayer[L].iDendriteQty+1) * (rSes.rNet->rLayer[L].iNeuronQty+1) ) 
                    mCheckCudaWorked
            //copy layer sructure to Device mem
            cudaMemcpyToSymbol( "rdNet->rLayer", &rdlSource, sizeof(rdLayer), sizeof(rdLayer) * L, cudaMemcpyHostToDevice );/*! 2D neuron cx weight matrix on GPU */
                    mCheckCudaWorked
    }
[...]   
    cudaMalloc(&dummy, sizeof(cuDoubleComplex) * (rSes.rLearn->SampleQty) * (rSes.rLearn->InputQty+1) ); /*! 2D complex input tuples in GPU. */
            cudaMemcpy( &rdLearn->gpuXInputs, &dummy, sizeof(cuDoubleComplex*), cudaMemcpyHostToDevice );
                    cudaMemcpy( &dummy, &rSes.rLearn->gpuXInputs, sizeof(cuDoubleComplex) * (rSes.rLearn->SampleQty) * (rSes.rLearn->InputQty+1), cudaMemcpyHostToDevice); 
                    mCheckCudaWorked        
    cudaMalloc(&dummy, sizeof(cuDoubleComplex) * (rSes.rLearn->SampleQty) * (rSes.rLearn->OutputQty+1) ); /*! 2D desired complex outputs in GPU. */
            cudaMemcpy( &rdLearn->gpuDOutputs, &dummy, sizeof(cuDoubleComplex*), cudaMemcpyHostToDevice );
                    cudaMemcpy( &dummy, &rSes.rLearn->gpuDOutputs, sizeof(cuDoubleComplex) * (rSes.rLearn->SampleQty) * (rSes.rLearn->OutputQty+1), cudaMemcpyHostToDevice); 
                    mCheckCudaWorked
[...]

К сожалению, вызов cudaMemcpyToSymbol возвращает ошибку, которую макрос mCheckCudaWorked сообщает как «недопустимый символ устройства», тогда как последний (cudaMemcpy (& dummy, & rSes.rLearn-> gpuDOutputs ...) и третий от последнего (cudaMemcpy) & dummy, & rSes.rLearn-> gpuXInputs ...) вызовы cudaMemcpy возвращают «неверный аргумент».

Я в недоумении относительно того, как приступить к копированию этих элементов в память устройства и адресуемости из кода ядра. & dummy и & rdldummy положительно возвращаются в качестве указателей на адреса памяти устройства, где ожидает выделенная память, и я могу записать эти указатели в память устройства, но я не могу уговорить большую часть значений членов скопировать их в указанный распределение. Помогите?

1 Ответ

0 голосов
/ 10 октября 2011

Поля наподобие gpuXInputs должны указывать на память, которая была выделена с помощью cudaMalloc, чтобы они были действительными указателями на память устройства .

Как правило, вам нужна версия хоста ваших структур данных, где ваши выделения используют malloc и т. Д., А затем зеркало этих структур данных на устройстве, которые были выделены через cudaMalloc. Любые указатели в этих структурах данных должны указывать на правильный тип памяти - вы не можете «смешивать и сопоставлять».

...