我开发了一个使用thrust
的算法。我的办公室电脑有一张带有体系结构的数据自动化系统卡:
-关于设备0的一般信息: Quadro 2000计算能力: 2.1时钟速率: 1251000 kHz设备重叠:启用内核执行超时:禁用
在这台机器上,我的算法运行时没有错误。但是,实验室机器上的一个干净的构建在试图生成一个thrust::system::system_error
时抛出一个讨厌的device_vector
。这两台机器都在运行RedHat 6,配置方式相同,只有多个显卡除外。这台实验室机器包含三张启用了CUDA的卡片,其结构如下:
-关于设备0名称的一般信息: Tesla C2050计算功能: 2.0时钟速率: 1147000 kHz设备重叠:启用内核执行超时:禁用 -关于设备1名称的一般信息: Quadro 2000计算能力: 2.1时钟速率: 1251000 kHz设备重叠:启用内核执行超时:禁用 -关于设备2名称的一般信息: Quadro 2000计算能力: 2.1时钟速率: 1251000 kHz设备重叠:启用内核执行超时: Enabled`
我知道,为了工作,需要针对目标体系结构编译thrust
。因此,我将CUDA设备设置为1
。但是,错误仍然存在。
作为调试措施,我在cudaGetDevice()
分配之前放置了一个device_vector
调用。该设备正确地声明为1
。
int device;
CUDA_CHECK_RETURN(cudaGetDevice(&device), __FILE__, __LINE__);
std::cout << "Operating on device " << device << std::endl; // <-- device 1
// copy the turns to the runtime
thrust::device_vector<MalfunctionTurn> d_turns = turns; // <-- error here
我想调试一下这件事就快疯了。以前有人见过这样的错误吗?更值得注意的是,cudaSetDevice()
中是否存在我不知道的限制?我担心是因为两张相同的卡片在不同的机器上不能运行相同的代码。
提前谢谢。
编辑
编译命令行:nvcc -rdc=true -arch=sm_21 -O3 file
下面是一个复制错误的最小示例:
#define DEVICE __device__
#define HOST __host__
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
template <typename T, std::size_t N>
class Container {
public:
DEVICE HOST
Container() {
}
private:
T data[N];
};
typedef Container<double, 7> double7;
template <std::size_t N = 10 >
class History {
public:
DEVICE HOST
History() {
}
DEVICE HOST
virtual ~History() {
}
private:
double7 history[N];
};
int main() {
try {
thrust::host_vector<History<> > histories(1);
thrust::device_vector<History<> > d_histories = histories;
} catch (const thrust::system_error &) {
std::cerr << "boo boo" << std::endl;
}
return 0;
}
发布于 2014-09-24 13:57:37
据我所知,您的代码(在幕后)违反了对使用虚拟函数的类的数据自动化系统限制:
不允许将具有虚拟函数的类的对象作为参数传递给
__global__
函数。
如果我取下你的代码并删除:
#include <JARSS.h>
并将其替换为:
#define HOST __host__
#define DEVICE __device__
我可以编出来。然而,在引擎盖下,推力执行这一行:
thrust::device_vector<History<> > d_histories = histories;
通过启动一个以要复制到设备的主机上的对象作为参数的内核。(例如,您可以使用nvprof
验证内核的启动。)这是推力的常见行为。问题在于那些具有虚拟析构函数的对象不能以这种方式复制。
与您的问题所述相反,此代码不应在任何CUDA机器上正确运行。
您可以通过注释掉虚拟析构函数来“修复”您的代码。如果您需要多态行为,那么对实际代码的修复可能会比这更复杂。仍然可以使用带有推力的多态对象行为,请参阅这个答案中的工作示例。
https://stackoverflow.com/questions/26025281
复制相似问题