我想以不同的方式将结构数组从主机复制到设备。我可以通过电缆将整个结构从主机复制到设备,但是无法将结构的单个元素从主机复制到设备,而其中一个元素是指针变量。我在执行此操作时遇到段错误。指针变量而不是普通变量会出现问题。
我调试并确定错误位于下面的行中。
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)
预先感谢
答案 0 :(得分:2)
关于这一行:
cudaMemcpy(d_s[i].data,h_s[i].data,sizeof(float *),cudaMemcpyHostToDevice);
您要求cudaMemcpy
做的是:
h_s[i].data
检索源指针float *
数量d_s[i].data
检索目标指针这有很多问题,但是最基本的问题不是您真正想做的事。
您要复制的内容是(源位置)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。