0

レイトレーシングに似た CUDA を使用して、3D オブジェクトで光散乱シミュレーションを実行したいと考えています。だから私はベクトルクラスが必要です。

私のフォトンを表すクラスをデバイスに持ち込もうとしました。このクラスには、動的に割り当てられたベクトル クラス (自己記述) が含まれています。動的である必要はありませんが、別のケースでも同じ問題が発生します。

問題は、カーネル内のベクトルを変更しようとすると、不特定の起動エラーが発生することです。

コピーコンストラクターなどの問題でもあると思います。しばらくの間、C++/CUDA をプログラミングしていませんでした。

Compute 機能 2.0 および CUDA 5.0 を搭載した GTX 480 を使用しています。

これが私のメインです:

#include "photon.cuh"
#include "Container/vector3f.cu"

// Device code (Kernel, GPU)
__global__ void Sim(photon * l_x){
    l_x->vec->m_x = l_x->vec->m_x +1;
    l_x->vec->m_y = l_x->vec->m_y +1;
    l_x->vec->m_z = l_x->vec->m_z +1;
}

// Host Code (CPU)
int main(int argc, char** argv)
{
    photon *h_x,*d_x,*h_x2;

    h_x = new photon();
    //h_x->vec = new vector3f();
    h_x->vec->m_x = 1;
    h_x->vec->m_y = 2;
    h_x->vec->m_z = 3;

    std::cout << "Malloc" << std::endl;
    h_x2 = (photon*)malloc(sizeof(photon));
    cudaMalloc((void**)&d_x,sizeof(photon));

    std::cout << "Cpy h-d" << std::endl;
    cudaMemcpy(d_x,h_x,sizeof(photon),cudaMemcpyHostToDevice);
    cudaError_t Err = cudaGetLastError();
    if ( cudaSuccess != Err )
        std::cout << cudaGetErrorString (Err) << std::endl;

    std::cout << "Sim" << std::endl;
    Sim<<<1, 1>>>(d_x);
    cudaThreadSynchronize();

    Err = cudaGetLastError();
    if ( cudaSuccess != Err )
        std::cout << cudaGetErrorString (Err) << std::endl;

    std::cout << "CPY back" << std::endl;
    cudaMemcpy(h_x2, d_x, sizeof(photon), cudaMemcpyDeviceToHost);

    std::cout << h_x2->vec->m_x << std::endl;
    std::cout << h_x2->vec->m_y << std::endl;
    std::cout << h_x2->vec->m_z << std::endl;

    cudaFree(d_x);
    return 0;
}

Photon クラス:(.cuh)

class photon {
public:
    vector3f *vec;
    __host__ __device__ photon();
    __host__ __device__ virtual ~photon();
    __host__ __device__ photon(const photon &other);
};

(.cu)

#include "photon.cuh"
#include "Container/vector3f.cu"

__host__ __device__ photon::photon(){
    this->vec = new vector3f();}

__host__ __device__ photon::~photon(){
    delete this->vec;}

__host__ __device__ photon::photon(const photon &rhs){
    this->vec = new vector3f(*rhs.vec);}

最後に、ベクトル クラス:

class vector3f {
public:
    float m_x;
    float m_y;
    float m_z;

__host__ __device__ vector3f(float l_x, float l_y, float l_z){
        this->m_x = l_x;
        this->m_y = l_y;
        this->m_z = l_z;}
__host__ __device__ vector3f(const vector3f& l_vector){
        this->m_x = l_vector.m_x;
        this->m_y = l_vector.m_y;
        this->m_z = l_vector.m_z;}
__host__ __device__ vector3f(){
        this->m_x = 0;
        this->m_y = 0;
        this->m_z = 0;}};
4

1 に答える 1

2

根本的な問題は、photonクラスをインスタンス化するのはホスト上だけであり、そのホスト インスタンスをデバイスに直接コピーしていることです。これは、デバイス コードが GPU 上のホスト ポインターを逆参照しようとしていることを意味します。これは違法であり、表示されているランタイム エラーを生成します。CUDA API は魔法のようなディープ コピーを行うわけではないため、何らかの方法でこれを自分で管理する必要があります。

明らかな解決策は、参照ではなく値によって格納されるphotonようにクラスを再設計することです。vecその後、問題全体が解消されます (また、メモリ アクセス中のポインターの間接化のレベルを削除するため、GPU でのパフォーマンスが大幅に向上します)。

へのポインターを持つことに固執している場合はvec、コンストラクターを再設計して、メモリ プールからポインターを取得し、構築用のデバイス プールを割り当てます。デバイス ポインターをコンストラクターに渡すと、結果のインスタンスには有効なデバイス メモリへのポインターが含まれます。

于 2013-08-30T10:51:18.857 に答える