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

标签 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)

提前致谢

最佳答案

关于这一行:

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 .

关于cuda - 如何在 CUDA 中将结构体数组的指针变量从主机复制到设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58392069/

相关文章:

cuda - NPP 函数可以作为设备函数调用吗?

CUDA 共享内存广播和 __syncthreads 行为

cuda - 如何防止两个CUDA程序互相干扰

cuda - 如何选择带有 CUDA 的 GPU?

arrays - CUDA中的一维最小卷积

image - 学习英伟达 CUDA

c++ - cudaDeviceSynchronize() 错误代码 77 : cudaErrorIllegalAddress

c++ - CUDA 编译器 (nvcc) 宏

c - 使用 OpenGL 从使用 CUDA 生成的顶点缓冲区对象绘制图像

c++ - 让应用程序拥有 CPU 和 GPU 计算后端的最佳方式是什么