开发者

CUDA - copy to array within array of Objects

I have a CUDA application I'm working on with an array of Objects; each object has a pointer to an array of std::pair<int, double>. I'm trying to cudaMemcpy the array of objects over, then cudaMemcpy the array of pairs to each of the objects, however this is giving me all kinds of grief. It crashes attempting to copy to the inner array; I don't understand how to move this over...

#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();
    cu开发者_运维问答daMemcpyObjects();
    return 0;
}


My CUDA experience is only in its infancy, but I believe the error is like this:

cudaMalloc is a host function that wants to write the pointer into host memory. However, you are passing to it a pointer in device memory!

To fix this, you should first create the device pointers and fill them into your host object structure, and only then copy the whole thing over to the device, and also copy the individual pairs over to the device as well.

Schematically:

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);
}

On the return, don't forget that the Foo::bp are device pointers that you still need to copy back one by one!

It would probably be easier to just have one self-contained class that you can move in one go, but that may not be practical, or desirable for reasons of memory locality. You have to thing carefully about this. If the member is just a pair, why not put the two items in the main class directly?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜