我是OpenCL的初学者。为了学习库的基础知识,我尝试在以下URL执行第一个程序:
https://www.olcf.ornl.gov/tutorials/opencl-vector-addition/
我以前链接了来自 NVIDIA GPU计算SDK 的openCL include和库,当然编译程序还可以。但是,如果我运行它,则clCreateContext
函数内的执行失败。
// Bind to platform
err = clGetPlatformIDs(1, &cpPlatform, NULL);
// Get ID for the device
err = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
// Create a context
context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);
问题来自上一个方法clGetDeviceIDs
,它似乎感觉不到device_id
变量(如果clGetDeviceIDs
中的CL_DEVICE_TYPE_GPU
标记为CL_DEVICE_TYPE_CPU
的替换{{1}}该程序完美无缺)。不过,我的显卡驱动程序已更新。根据执行情况,我的计算机上似乎没有任何GPU设备。这很奇怪。你认为我的驱动程序不正确并且缺少依赖关系吗?我真的迷路了。有人能帮帮我吗?
非常感谢您的帮助。
答案 0 :(得分:3)
您是否检查过以确保只定义了1个平台?
cl_uint nPlatforms;
cl_uint err = CL_SUCCESS;
err = clGetPlatformIDs(1, NULL, &nPlatforms);
如果有多个平台,您可以这样做:
cl_platform_id* platformID_Array;
platformID_Array = (cl_platform_id *)malloc(sizeof(cl_platform_id)*nPlatforms);
err = CL_SUCCESS;
err = clGetPlatformIDs(nPlatforms, platformID_Array, NULL);
然后检查姓名:
for (cl_uint i = 0; i < nPlatforms; i++) {
size_t vendorSize;
char* vendorCstring;
err = clGetPlatformInfo(platformID_Array[i], CL_PLATFORM_VENDOR, 0, NULL, &vendorSize);
vendorCstring = (char*)malloc(sizeof(char)*vendorSize);
err = clGetPlatformInfo(platformID_Array[i], CL_PLATFORM_VENDOR, vendorSize, vendorCstring, NULL);
printf("Platform name = %s\n",vendorCstring);
}
您也可以尝试:
err = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
注意平台ID的NULL参数。在这种情况下,行为是实现定义的,因此您可以看到支持哪个设备。我怀疑你会得到一个CPU设备,但值得检查。
答案 1 :(得分:2)
如果您说,选项CL_DEVICE_TYPE_CPU
适合您,则您获得的平台没有GPU设备。
您应该尝试其他平台,因为英特尔和nVIDIA设备位于不同的平台上。
您可以尝试err = clGetPlatformIDs(2, &cpPlatform, NULL);
并获得两个平台而不是1,或者使用另一个更聪明的算法来查找所有可用平台上的有效GPU。
当然,这不是链接或编译问题,因为方法可以正常工作。
我会这样做:
// Num of platforms
int numplat;
err = clGetPlatformIDs(0, NULL, &numplat);
// Num of platforms
int cpPlat[numplat];
err = clGetPlatformIDs(numplat, &cpPlat, NULL);
// Get ID for the device
for(int i=0; i<numplat; i++){
err = clGetDeviceIDs(cpPlatform[i], CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
if (err == CL_SUCCESS )
break;
}
// Create a context
context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);