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

时间:2011-08-03 16:10:04

标签: c++ cuda gpgpu

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

1 个答案:

答案 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设备指针,您仍然需要逐个复制!

如果只有一个可以一次移动的自包含类可能会更容易,但这可能不实用,或者出于内存局部性的原因而不合适。你必须小心谨慎。如果该成员只是一对,为什么不直接将这两个项目放在主类中?