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();
cudaMemcpyObjects();
return 0;
}
My CUDA experience is only in its infancy, but I believe the error is like this:
cudaMallocis 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:
On the return, don’t forget that the
Foo::bpare 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?