使用GPU设备执行OpenCL程序失败

使用GPU设备执行OpenCL程序失败,opencl,Opencl,我是OpenCL的初学者。为了学习库的基本知识,我尝试在以下URL执行第一个程序: https://www.olcf.ornl.gov/tutorials/opencl-vector-addition/ 我以前把Novidia英伟达计算软件SDK中的OpenCL包含和库连接起来,当然程序的编译也可以。但是,如果我运行它,clCreateContext函数中的执行就会失败 // Bind to platform err = clGetPlatformIDs(1, &cpPlatform,

我是OpenCL的初学者。为了学习库的基本知识,我尝试在以下URL执行第一个程序:

https://www.olcf.ornl.gov/tutorials/opencl-vector-addition/
<>我以前把Novidia英伟达计算软件SDK中的OpenCL包含和库连接起来,当然程序的编译也可以。但是,如果我运行它,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);
问题来自之前的方法CLGetDeviceID,如果函数CLGetDeviceID中的替换使用CL_device_TYPE_CPU替换标志CL_device_TYPE_GPU,则该方法似乎感觉不到设备id变量。程序工作正常。不过,我的图形卡驱动程序已经更新。根据执行情况,我的计算机上似乎没有任何GPU设备。这很奇怪。您是否认为我的驱动程序不正确,并且缺少依赖项?我真的迷路了。有人能帮我吗


非常感谢您的帮助。

如果如您所说,CL\U设备\U类型\U CPU选项适合您,则您所使用的平台没有GPU设备

您应该尝试其他平台,因为Intel和nVIDIA设备位于不同的平台中

您可以尝试使用err=clGetPlatformIDs2,&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);

如果如你所说,CL_设备\u类型\u CPU选项适合你,那么你得到的平台没有GPU设备

您应该尝试其他平台,因为Intel和nVIDIA设备位于不同的平台中

您可以尝试使用err=clGetPlatformIDs2,&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);

您是否检查以确保只定义了一个平台

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);
}

注意平台ID的NULL参数。在这种情况下,行为是由实现定义的,因此您可以查看支持哪个设备。我怀疑您将取回一个CPU设备,但它值得检查。

您是否检查以确保只定义了一个平台

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);
}

注意平台ID的NULL参数。在这种情况下,行为是由实现定义的,因此您可以查看支持哪个设备。我怀疑您将取回一台CPU设备,但值得检查。

是的,我有两台设备:一台intel CPU设备和一台NVIDIA GPU设备。没有平台阵列,默认情况下我只能访问CPU设备。现在,一切都好了,我可以加载GPU设备了。非常感谢你的帮助。再见。是的,我有两个设备:英特尔CPU设备和英伟达GPU设备。没有平台阵列,默认情况下我只能访问CPU设备。现在,一切都好了,我可以加载GPU设备了。非常感谢你的帮助。再见