0
votes

Just started to learn OpenCL and setup a Visual Studio project using VS2015. Somehow, the code can find only 1 platform (I guess it should be the CPU), and cannot find the GPU device. Can someone please help? The detailed information is as follows:

  1. GPU: Nvidia Quadro K4000
  2. CUDA Installation

    CUDA is at: “C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5

    OpenCL related files are located at "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include\CL" and "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\Win32" (assuming 32bit system)

    The installer created two environment variables “CUDA_PATH” and “CUDA_PATH_V7_5”. They both point to the above location.

  3. In Visual Studio, the project is set up as

    "Project Properties" -> "C/C++" -> "Additional Include Directories" -> "$(CUDA_PATH)\include"

    "Project Properties" -> "Linker" -> "Additional Library Directories" -> "$(CUDA_PATH)\lib\Win32"

    "Project Properties" -> "Linker" -> "Input" -> "Additional Dependencies" -> "OpenCL.lib"

The code is very simple:

#include "stdafx.h"
#include <iostream>
#include <CL/cl.h>
using namespace std;

int main()
{
    cl_int err;
    cl_uint numPlatforms;

    err = clGetPlatformIDs(0, NULL, &numPlatforms);

    if (CL_SUCCESS == err)
        cout << "Detected OpenCL platforms: " << numPlatforms  << endl;
    else
        cout << "Error calling clGetPlatformIDs. Error code:" << err << endl;


    cl_device_id device = NULL;
    err = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
    if (err == CL_SUCCESS)
        cout << device << endl;

    return 0;
}

The code compiles and runs, but it cannot the GPU device. Specifically, the returned value of variable device is device = 0x00000000 <NULL>. What would be the problem? Thanks for the help.

1

1 Answers

3
votes

This is not the way you use the OpenCL API.

You need to obtain a valid cl_platform_id object which it needs to be used to retrieve a cl_device_id. You are always passing NULL, this can't work.

The first time you invoke the clGetPlatformIds, you do it in order to obtain the number of platforms in the system. After than you need to invoke the method again in order to retrieve the actual cl_platform_ids:

size_t numPlatforms;
err = clGetPlatformIDs(0, NULL, &numPlatforms);
assert(numPlatforms > 0);
cl_platform_id platform_ids[numPlatforms];
err = clGetPlatformIDs(numPlatforms, platform_ids, NULL);

However, if you already know there is going to be only one platform in the system, then you can do speedup things as follows, but make sure to check for errors:

cl_platform_id platform_id;
err = clGetPlatformIDs(1, &platform_id, NULL);
assert(err == CL_SUCCESS);

After you have obtained a platform you need to follow the same procedure to first obtain the number of devices and then retrieve the list of OpenCL devices (which you then will need to build a cl_context, queues...):

// Note: this has to be done for each `cl_platform_id`
// until you find the device you were looking for
size_t numDevices;
err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
assert(numDevices > 0);
cl_device_id devices[numDevices];
err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);

I guess you understand the procedure now. If like above, you already know that there is only 1 GPU device in the system, you can directly get its cl_device_id as follows:

cl_device_id device;
err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
assert(err == CL_SUCCESS);