我有一个CUDA应用程序,我正在使用一组对象;每个对象都有一个指向std::pair<int, double>
数组的指针。我正在尝试cudaMemcpy对象数组,然后cudaMemcpy对每个对象的数组,但这给了我各种悲伤。它崩溃试图复制到内部数组;我不明白如何将其移动......
#include <cuda.h> #include <cuda_runtime.h> #include <iostream> using namespace std; class Object { public: int id; float something; std::pair<int, float> *somePairs; }; Object *objects; void initObjects() { objects = new Object[10]; for( int idx = 0; idx < 10; idx++ ) { objects[idx].id = idx; objects[idx].something = (float) idx; objects[idx].somePairs = new std::pair<int, float>[10]; for ( int jdx = 10; jdx < 10; jdx++ ) { objects[idx].somePairs[jdx] = std::pair<int, float>( jdx, (float) jdx ); } } } void cudaMemcpyObjects() { Object *devObjects; cudaMalloc( &devObjects, sizeof(Object) * 10 ); cudaMemcpy( devObjects, objects, sizeof(Object) * 10, cudaMemcpyHostToDevice ); for ( int idx = 0; idx < 10; idx++ ) { size_t pairSetSize = sizeof(std::pair<int, float>) * 10; // CRASH HERE ... v cudaMalloc( &(devObjects[idx].somePairs), pairSetSize ); cudaMemcpy( devObjects[idx].somePairs, objects[idx].somePairs, sizeof( std::pair<int, float> ) * 10, cudaMemcpyHostToDevice ); } } int main() { initObjects(); cudaMemcpyObjects(); return 0; }
答案 0 :(得分:6)
我的CUDA体验仅处于起步阶段,但我相信错误是这样的:
cudaMalloc
是一个主机函数,它希望将指针写入 host 内存。但是,您在 device 内存中传递了一个指针!
要解决此问题,您应首先创建设备指针并将其填充到主机对象结构中,然后将整个内容复制到设备上,并将各个对复制到设备上。
示意性地:
struct Bar;
struct Foo
{
int tag;
Bar * bp;
};
void setup()
{
Foo * hFoo = new Foo[10];
Foo * dFoo;
cudaMalloc(dFoo, sizeof(Foo) * 10);
for (size_t i = 0; i != 10; ++i)
{
Bar * dBar;
cudaMalloc(&dbar, sizeof(Bar));
Bar b; // automatic temporary -- we never keep a host copy of this
cudaMemcpy(dBar, &b, sizeof(Bar));
hFoo[i].bp = dBar; // this is already a device pointer!
}
cudaMemcpy(dFoo, hFoo, sizeof(Foo) * 10);
}
在返回时,不要忘记Foo::bp
是设备指针,您仍然需要逐个复制!
如果只有一个可以一次移动的自包含类可能会更容易,但这可能不实用,或者出于内存局部性的原因而不合适。你必须小心谨慎。如果该成员只是一对,为什么不直接将这两个项目放在主类中?