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

发布于 2024-11-27 14:58:05 字数 1520 浏览 3 评论 0原文

我有一个 CUDA 应用程序,正在处理一组对象;每个对象都有一个指向 std::pair 数组的指针。我正在尝试 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;
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泼猴你往哪里跑 2024-12-04 14:58:05

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

cudaMalloc is a host function that Wants write the point into host em>记忆。但是,您正在向其传递设备内存中的指针!

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

示意一下:

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

拥有一个可以一次性移动的独立类可能会更容易,但由于内存局部性的原因,这可能不实用或不理想。你必须仔细考虑这一点。如果成员只是一对,为什么不直接将这两个项目放在主类中呢?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文