[英]How to copy variables from a custom class array on host into a float array on device in CUDA
我正在使用CUDA。 我在主机上有以下课程:
class Particle{
public:
float x;
float v;
// several other variables
}
然后我有一个粒子向量
vector <Particle> p_all(512);
在GPU上,我想对所有x的数组(从所有粒子中获取)进行操作,并希望将数据从“粒子”数组复制到设备上的float数组中。 我有一种可以使用cudaMemcpy的预感,我尝试了以下代码,但它给出了无效的音调错误。
cudaMalloc( (void**) &pos_dev, sizeof(float)*512);
cudaMemcpy2D( (void*) &pos_dev, sizeof(float), (void*)&p_all[0].x, sizeof(Particle), sizeof(Particle), 512*sizeof(float), cudaMemcpyHostToDevice);
有可能这样做吗? 当然,备份解决方案是使用for循环创建x的数组,然后将其复制到设备中。 但我正在寻找一种更有效的解决方案。
谢谢。
完整代码如下。
#include <cuda_runtime.h>
#include <iostream>
#include <vector>
using namespace std;
// This will output the proper error string when calling cudaGetLastError
void getLastCudaError(string s=""){
string errMessage = s;
cudaError_t err = cudaGetLastError();
if( err != cudaSuccess){
cerr << __FILE__ << "(" << __LINE__ << ") : Last Cuda Error - " << errMessage
<< " (" << int(err) << "): " << cudaGetErrorString(err) << ".\n";
exit(-1);
}
}
class Particle{
public:
float x;
float v;
int a;
char c;
short b;
Particle(){
a=1988; c='a'; v=5.56; x=1810; b=1.66;
}
};
template <class T>
void printVec(vector <T> &v, string name = "v"){
cout << name << " = ";
for (int i=0; i<v.size(); ++i) cout << v[i] << " " ;
cout << '\n';
}
int main(){
const int N = 512;
vector <float> pos(N,5);
vector <Particle> p_all(N);
float * pos_dev;
float * vel_dev;
cudaMalloc( (void**) &pos_dev, sizeof(float)*N);
printVec(pos, "pos");
cudaMemcpy2D( (void*) &pos_dev, sizeof(float), (void*)&(p_all[0].x), sizeof(Particle), sizeof(float), N, cudaMemcpyHostToDevice);
getLastCudaError("HtoD");
cudaMemcpy( (void*) &pos[0], (void*)&pos_dev, N*sizeof(float), cudaMemcpyDeviceToHost);
getLastCudaError("DtoH");
printVec(pos, "pos_new");
return 0;
}
您将数据分配为“结构数组”,例如
class Particle{
public:
float x;
float v;
}
Particle foo[N];
由于数据交织,这将导致合并问题,因此,您正在尝试使用cudaMemcpy2D
。 就带宽利用而言,一种更方便的解决方案是将数据分配为“数组结构”,如下所示:
class Particle{
public:
float x[N];
float v[N];
}
Particle foo;
这样,您将可以避免使用cudaMemcpy2D
并通过简单的cudaMemcpy
将数据从主机复制到设备。
您的cudaMemcpy2D
呼叫设置不正确。 检查文档 。
试试这个代替:
cudaMemcpy2D( (void*) pos_dev, sizeof(float), (void*)&(p_all[0].x), sizeof(Particle), sizeof(float), 512, cudaMemcpyHostToDevice);
有多个参数需要修改,但是无效音调错误出现,因为请求的传输宽度(以字节为单位)(您具有sizeof(Particle)
)宽于目标音调( sizeof(float)
,这是正确的)
编辑:另外,尽管您没有询问,但是现在发布的代码中的最终cudaMemcpy
操作也不正确。 以下更改应有所帮助:
cudaMemcpy( (void*) &(pos[0]), (void*)pos_dev, N*sizeof(float), cudaMemcpyDeviceToHost);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.