【发布时间】:2015-08-12 18:38:31
【问题描述】:
我编写了一个简单的 cuda 代码来测试是否可以将指针向量复制到 GPU 的类。
这就是我所拥有的:
test.hpp:
class Class {
public:
Class() {};
virtual ~Class() {};
__host__ __device__ int print() { return 42; };
__host__ __device__ virtual int getClass() const = 0;
};
class AlphaClass : public Class
{
public:
AlphaClass() {
className = "Alpha";
classAvgGrade = 90;
classSize = 100;
for(int i = 0; i < classSize; i++){
classScores.push_back((90+i)%100);
}
};
~AlphaClass() { };
std::string className;
int classAvgGrade;
int classSize;
std::vector<int> classScores;
__host__ __device__ void incClassSize(){
classSize++;
};
__host__ __device__ virtual int getClass() const{
return 0;
};
};
class BetaClass : public Class
{
public:
BetaClass() {
className = "Beta";
classAvgGrade = 80;
classSize = 120;
for(int i = 0; i < classSize; i++){
classScores.push_back((80+i)%100);
}
}
~BetaClass() { };
std::string className;
int classAvgGrade;
int classSize;
std::vector<int> classScores;
__host__ __device__ void incClassSize(){
classSize++;
}
__host__ __device__ virtual int getClass() const{
return 1;
};
};
class CudaClass : public Class
{
public:
CudaClass() {
className = "Cuda";
classAvgGrade = 70;
classSize = 110;
for(int i = 0; i < classSize; i++){
classScores.push_back(70);
}
};
~CudaClass() {
//do nothing
};
std::string className;
int classAvgGrade;
int classSize;
std::vector<int> classScores;
__host__ __device__ void incClassSize(){
classSize++;
};
};
test.cpp:
struct GlobalConstants {
Class** classList;
};
__constant__ GlobalConstants cuConstRaytracerParams;
__global__ void useClass()
{
Class** deviceClassList = cuConstRaytracerParams.classList;
AlphaClass* alpha = (AlphaClass*) deviceClassList[0];
BetaClass* beta = (BetaClass*) deviceClassList[1];
CudaClass* cuda = (CudaClass*) deviceClassList[2];
printf("%s\n", alpha->className);
printf("%s\n", beta->className);
printf("%s\n", cuda->ClassName);
printf("alpha avg = %d\n", alpha->classAvgGrade);
printf("beta avg = %d\n", beta->classAvgGrade);
printf("cuda avg = %d\n", cuda->classAvgGrade);
};
...
AlphaClass *alpha;
alpha = new AlphaClass();
BetaClass *beta;
beta = new BetaClass();
CudaClass *cuda;
cuda = new CudaClass();
std::vector<Class*> classes;
classes.push_back(alpha);
classes.push_back(beta);
classes.push_back(cuda);
AlphaClass* alpha_ptr;
BetaClass* beta_ptr;
CudaClass* cuda_ptr;
// copy classes to cuda
thrust::device_vector<Class*> deviceClassList;
for(int i = 0; i < classes.size(); i++){
if(classes[i]->getClass() == 0){
cudaMalloc(&alpha_ptr, sizeof(AlphaClass));
cudaMemcpy(alpha_ptr, &classes[i],sizeof(AlphaClass), cudaMemcpyHostToDevice);
deviceClassList.push_back(alpha_ptr);
}else if(classes[i]->getClass() == 1){
cudaMalloc(&beta_ptr, sizeof(BetaClass));
cudaMemcpy(beta_ptr, &classes[i],sizeof(BetaClass), cudaMemcpyHostToDevice);
deviceClassList.push_back(beta_ptr);
}else if(classes[i]->getClass() == 2){
cudaMalloc(&cuda_ptr, sizeof(CudaClass));
cudaMemcpy(cuda_ptr, &classes[i],sizeof(CudaClass), cudaMemcpyHostToDevice);
deviceClassList.push_back(cuda_ptr);
}else{
//do nothing
}
}
Class** class_ptr = thrust::raw_pointer_cast(&deviceClassList[0]);
//ADD IT TO CUDA PARAM STRUCT
GlobalConstants params;
params.classList = class_ptr;
cudaMemcpyToSymbol(cuConstRaytracerParams, ¶ms, sizeof(GlobalConstants));
useClass<<<1,1>>>();
cudaDeviceSynchronize();
...cleanup code
当我运行它时,我没有得到正确的值并得到以下结果:
阿尔法平均值 = 39696816
测试平均 = 70
cuda 平均 = 0
我没有得到任何字符串结果。
【问题讨论】:
-
将指针指向 Class* ?
-
@Ashalynd 肯定会消除编译器错误,但我想将它用作 AlphaClass,因为 AlphaClass 有数据
-
该错误与cuda无关:您尝试将
Class的指针分配给AlphaClass的指针。要解决此错误,您应该强制转换:AlphaClass* alpha = (AlphaClass*)deviceClassList[0];但是,我认为您尝试执行的操作不受支持。 minimal reproducible example 将有助于阐明您想要做什么。 -
代码中还有其他问题可能需要先解决。例如,您不能在设备代码中使用 std::string 和 std::vector。也许这会改变你的设计决策。
-
是的,当然......但我会说它还不够简化。您的代码中有很多不需要演示行为的东西。因此,一目了然并不容易。此外,您发布的错误与主要问题无关。这就是为什么我要求minimal reproducible example。