我想在使用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;
}
光子类:(。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;}};
答案 0 :(得分:2)
潜在的问题是,您在photon
类实例化任何地方的唯一时间是在主机上,并且您正在将该主机实例直接复制到设备。这意味着设备代码试图取消引用GPU上的主机指针,这是非法的并且会产生您看到的运行时错误。 CUDA API不进行任何神奇的深度复制,因此您必须以某种方式自行管理。
显而易见的解决方案是重新设计photon
类,以便vec
按值而不是引用存储。然后整个问题就消失了(因为你在内存访问期间删除了一个指针间接层,因此在GPU上性能会好很多)。
如果您注意使用指向vec
的指针,请重新设计构造函数,使其从内存池中获取指针,并为构造分配设备池。如果将设备指针传递给构造函数,则生成的实例将具有指向有效设备内存的指针。