CUDA -复制到数组内的数组对象

CUDA - copy to array within array of Objects

本文关键字:数组 对象 复制 CUDA      更新时间:2023-10-16

我有一个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;
}

我的CUDA经验仅处于起步阶段,但我相信错误是这样的:

cudaMalloc是一个host函数,它想把指针写入host内存。然而,你传递给它一个指针在设备内存!

要解决这个问题,您应该首先创建设备指针并将它们填充到宿主对象结构中,然后将整个指针复制到设备中,并将单个指针对复制到设备中。

示意图:

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设备指针,您仍然需要逐一复制回来!

只拥有一个可以一次移动的自包含类可能会更容易,但这可能不实际,或者出于内存局部性的原因,这是不可取的。你必须仔细考虑这件事。如果成员只是一对,为什么不把这两个项直接放在main类中呢?