如何在CUDA中将结构数组的指针变量从主机复制到设备

时间:2019-10-15 10:02:02

标签: cuda

我想以不同的方式将结构数组从主机复制到设备。我可以通过电缆将整个结构从主机复制到设备,但是无法将结构的单个元素从主机复制到设备,而其中一个元素是指针变量。我在执行此操作时遇到段错误。指针变量而不是普通变量会出现问题。

我调试并确定错误位于下面的行中。

cudaMemcpy(d_s[i].data,h_s[i].data,sizeof(float*),cudaMemcpyHostToDevice);

我无法解决此问题。

#include<iostream>

using namespace std;

struct structure
{
   int count;
   float *data;
};


structure * fillStructure(int n,  float *tdata )
{

   structure *h_s;
   h_s = (structure *) malloc( n * sizeof(structure));

   for(int i =0; i< n; i++)
   {
           h_s[i].count =i;
           h_s[i].data = &tdata[i];
   }
   cout<<"Input:\n";
   for(int i=0; i<n ;i++)
   {
       cout<<h_s[i].count<<"\t";
   }
   cout<<endl;
   for(int i=0; i<n ;i++)
   {
       cout<<*(h_s[i].data)<<"\t";
   }
   cout<<endl;
   structure *d_s;

   cudaMalloc((void**)&d_s, n * sizeof(structure));
   for(int i=0; i<n ;i++)
   {
       cudaMemcpy(&d_s[i].count,&h_s[i].count, sizeof(int), cudaMemcpyHostToDevice);
       cudaMemcpy(d_s[i].data,h_s[i].data,sizeof(float *),cudaMemcpyHostToDevice);
   }
                                                                                                                             1,1           Top
 return d_s;

}

int main()
{
   int N =5;
   float *ldata;
   ldata = (float*) malloc(N * sizeof(float));
   for(int i=0 ; i< N ; i++)
   {
    ldata[i] =i*i;
   }
        structure *ps = fillStructure(N, ldata);

        structure *ls;
        ls =(structure *) malloc( N  * sizeof(structure));
        cudaMemcpy(ls,ps,N * sizeof(structure),cudaMemcpyDeviceToHost);

   cout<<"Result:\n";
   for(int i=0; i< N;i++)
   {
       cout<<ls[i].count<<"\t";
   }
   cout<<endl;
   for(int i =0 ; i< N; i++)
   {
     cout<<*(ls[i].data)<<"\t";
   }
   cout<<endl;

}

预期输出为

Input:
0   1   2   3   4   
0   1   4   9   16  
Result:
Input:
0   1   2   3   4   
0   1   4   9   16  

但是实际输出是

Input:
0   1   2   3   4   
0   1   4   9   16  
Segmentation fault (core dumped)

预先感谢

1 个答案:

答案 0 :(得分:2)

关于这一行:

cudaMemcpy(d_s[i].data,h_s[i].data,sizeof(float *),cudaMemcpyHostToDevice);

您要求cudaMemcpy做的是:

  1. h_s[i].data检索源指针
  2. 使用该指针,从该指针所指向的位置检索一个float *数量
  3. d_s[i].data检索目标指针
  4. 使用该指针,将在第2步中检索到的数量存储到第3步中指针指向的任何位置。

这有很多问题,但是最基本的问题不是您真正想做的事。

您要复制的内容是(源位置)h_s[i].data中包含的指针值,并且您想将其存储在(目的地)d_s[i].data中。为了使该工作有效,您必须将指针传递到这些位置(源和目标)。

您可以通过在两个项目中都添加与号来解决此问题:

cudaMemcpy(&(d_s[i].data),&(h_s[i].data),sizeof(float *),cudaMemcpyHostToDevice);

那应该解决段错误。它将正确地将h_s[i].data中包含的指针的数值复制到d_s[i].data

但是,正如我之前对您所说的,您在此处从源位置复制的指针设置如下:

       h_s[i].data = &tdata[i];

,这是指向主机内存中某个位置的指针。这样的指针不能在CUDA设备代码中安全使用,因此,努力将指针正确复制到设备上并没有多大意义。设备代码中将没有用。

您仍然没有掌握CUDA深拷贝的必要性以使该方案有效。如前所述,这一步一步地介绍了here

相关问题