如何将嵌套结构的成员复制到 CUDA 设备的内存空间?
Posted
技术标签:
【中文标题】如何将嵌套结构的成员复制到 CUDA 设备的内存空间?【英文标题】:How can I copy the members of nested structs to a CUDA device's memory space? 【发布时间】:2011-10-10 07:12:56 【问题描述】:我正在尝试将一些嵌套结构复制到设备内存中,以便在 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】:像gpuXInputs
这样的字段需要指向已分配有cudaMalloc
的内存,以便它们是指向设备内存的有效指针。
通常,您需要数据结构的主机版本,您的分配使用malloc
等,然后是设备上这些数据结构的镜像,这些数据结构已通过cudaMalloc
分配。这些数据结构中的任何指针都需要指向正确的内存类型——你不能“混合和匹配”。
【讨论】:
这就是我正在尝试的;我 cudaMalloc 为 rdLearningSet 结构分配了足够的设备内存,并将指向该结构的指针存储在 rdLEarn 中。然后我 cudaMalloc 有足够的设备内存来保存这么多组输入坐标,并将指向该坐标的指针存储在设备内存位置 rdLrean->gpuXInputs 中。这似乎工作正常。但是,当我尝试将该坐标集块复制到存储为 rdLearn->gpuXInputs 的指针的目的地时,不行! rdlSource 是我构建复制结构的地方。我看不出我在哪里混合了结构中的指针类型,你能指出来吗? 仅从这些代码片段进行调试并不容易 - 我建议您采取“分而治之”的方法,直到遇到更小的问题 我注意到 CUDA C PDF 中提供的示例使用 cudaMalloc ((void**)&varname, ... 但是 cudaMemcpy(varname, ... 在复制时使用。删除地址运算符在上面代码的问题行中,让我复制值的数组。奇怪的是,奇异值仍然可以通过 & 来验证地来回复制。以上是关于如何将嵌套结构的成员复制到 CUDA 设备的内存空间?的主要内容,如果未能解决你的问题,请参考以下文章