3

デバイスに割り当てられるクラスを作成しようとしています。ホストオブジェクトを作成して手動でデバイスにコピーするのではなく、内部のフィールドを含むオブジェクト全体がデバイスに自動的に割り当てられるように、コンストラクターをデバイスで実行したいと考えています。

スラストdevice_newを使用しています

これが私のコードです:

using namespace thrust;

class Particle
{
    public:
    int* data;

    __device__  Particle()
    {
        data = new int[10];
        for (int i=0; i<10; i++)
        {
            data[i] = i*2;
        }
    }
};


__global__ void test(Particle* p)
{
    for (int i=0; i<10; i++)
        printf("%d\n", p->data[i]);
}

int main() {

    device_ptr<Particle> p = device_new<Particle>();

    test<<<1,1>>>(thrust::raw_pointer_cast(p));


    cudaDeviceSynchronize();

    printf("Done!\n");

}

コンストラクターに注釈を付けて__device__device_new (thrust) を使用しましたが、これは機能しません。誰かが理由を説明してもらえますか?

助けを求める乾杯

4

2 に答える 2

4

その答えは、ここに記載されている説明にあると思います。ボンネットの下の推力を知っている誰かがおそらくやって来て、これが真実かどうかを示すでしょう.

推力は 2009 年から大きく変化しましたdevice_newが、オブジェクトが実際にホスト上で一時的にインスタンス化されてからデバイスにコピーされる何らかの形式の操作をまだ使用している可能性があります。ただし、上記の参考文献に記載されているサイズ制限は適用されなくなったと思います。

これを機能させることができました:

#include <stdio.h>
#include <thrust/device_ptr.h>
#include <thrust/device_new.h>

#define N 512

using namespace thrust;

class Particle
{
    public:
    int data[N];

    __device__ __host__  Particle()
    {
//        data = new int[10];
        for (int i=0; i<N; i++)
        {
            data[i] = i*2;
        }
    }
};


__global__ void test(Particle* p)
{
    for (int i=0; i<N; i++)
        printf("%d\n", p->data[i]);
}

int main() {

    device_ptr<Particle> p = device_new<Particle>();

    test<<<1,1>>>(thrust::raw_pointer_cast(p));


    cudaDeviceSynchronize();

    printf("Done!\n");

}

興味深いことに、__host__コンストラクターのデコレーターを省略すると、偽の結果が返されます。これは、一時オブジェクトのコピー メカニズムがまだ有効であることを示唆しています。また、静的ではなく動的割り当てを使用するように切り替えると、偽の結果が返されます (および cuda-memcheck は範囲外アクセス エラーを報告します)。これは、ホスト上で一時的なオブジェクトの作成とそれに続くコピーを使用しdataていることも示唆しています。device_newデバイスに。

于 2013-04-18T14:27:21.627 に答える