Reputation: 18148
I have this code:
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetPlatformIDs.html
cl_uint platformIdCount = 0;
clGetPlatformIDs(0, nullptr, &platformIdCount);
if (platformIdCount == 0) {
std::cerr << "No OpenCL platform found" << std::endl;
return 1;
}
else {
std::cout << "Found " << platformIdCount << " platform(s)" << std::endl;
}
std::vector<cl_platform_id> platformIds(platformIdCount);
clGetPlatformIDs(platformIdCount, platformIds.data(), nullptr);
for (cl_uint i = 0; i < platformIdCount; ++i) {
std::cout << "\t (" << (i + 1) << ") : " << GetPlatformName(platformIds[i]) << std::endl;
}
// http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceIDs.html
cl_uint deviceIdCount = 0;
clGetDeviceIDs(platformIds[1], CL_DEVICE_TYPE_ALL, 0, nullptr,
&deviceIdCount);
if (deviceIdCount == 0) {
std::cerr << "No OpenCL devices found" << std::endl;
return 1;
}
else {
std::cout << "Found " << deviceIdCount << " device(s)" << std::endl;
}
std::vector<cl_device_id> deviceIds(deviceIdCount);
clGetDeviceIDs(platformIds[1], CL_DEVICE_TYPE_ALL, deviceIdCount,
deviceIds.data(), nullptr);
for (cl_uint i = 0; i < deviceIdCount; ++i) {
std::cout << "\t (" << (i + 1) << ") : " << GetDeviceName(deviceIds[i]) << std::endl;
}
and I am running it on a laptop that has 2 gpu, one HD4400 and GForce 750.
When I run it, I am getting two platform and each platform has the device for that specific manufacturer, for example on platform 0, I am getting i7 and HD4400 and on platform 1, I am getting GeForce 750.
I thought that I can get all devices from one platform?
Am I correct to believe to find a suitable device, I need to go over all platforms and find devices which are for GPU and then I have the list of all devices?
What is the correct way to find suitable device for a task?
Say I want to find GPU with maximum memory or maximum worker?
Is there any library that can help me on this?
Upvotes: 4
Views: 14446
Reputation: 5736
The OpenCL platform basically denotes the manufacturer. If you would have two (can be different models) Nvidia GPUs, they would be on the same platform. But Intel and Nvidia are different platforms.
Yes, you need to specifically select one device for your OpenCL computations. Therefore you iterate over all platforms and for every platform over all of its devices in order to get a list of all available OpenCL devices. Then from this list you can select the best/fastest one (in your case the GForce 750 as it is both faster than the HD4400 and has more video memory).
Here is some code that will give you a list of all available devices in the devices
vector. Select the GeForce 750 with devices[1]
.
std::vector<Device> devices;
int find_devices() {
std::vector<Platform> platforms; // get all platforms
std::vector<Device> devices_available;
int n = 0; // number of available devices
Platform::get(&platforms);
for(int i=0; i<(int)platforms.size(); i++) {
devices_available.clear();
platforms[i].getDevices(CL_DEVICE_TYPE_ALL, &devices_available);
if(devices_available.size()==0) continue; // no device found in plattform i
for(int j=0; j<(int)devices_available.size(); j++) {
n++;
devices.push_back(devices_available[j]);
}
}
if(platforms.size()==0||devices.size()==0) {
std::cout << "Error: There are no OpenCL devices available!" << std::endl;
return -1;
}
for(int i=0; i<n; i++) std::cout << "ID: " << i << ", Device: " << devices[i].getInfo<CL_DEVICE_NAME>() << std::endl;
return n; // return number of available devices
}
For an easy start with OpenCL, I created a lightweight wrapper that vastly simplifies the OpenCL C++ bindings and eliminates the entire code overhead that comes with it. You can get the list of all available devices with get_devices()
and automatically find the fastest device with select_device_with_most_flops()
: https://github.com/ProjectPhysX/OpenCL-Wrapper
Upvotes: 5
Reputation: 279
clinfo[1] utility and clinfo[2] utility show available platforms and devices information. They are good for local use. khronos clGetPlatformIDs and clGetDeviceIDs are good for runtime detection when distributing software.
1: https://github.com/Oblomov/clinfo 1: https://sf.net/p/clinfo
Upvotes: 1
Reputation: 6333
You cannot get all devices in one platform.
At most, you'll just see devices from the same vendor grouped together (e.g., AMD CPU and AMD GPU, or Intel CPU and GPU). On Windows (and I presume Linux) you might see multiple platforms. On Mac OS X, I've only ever seen one (with the CPU and all GPUs).
You are correct that you need to iterate all platforms and all devices to find them all. You can filter to what you'll support, and sort based on capabilities.
Upvotes: 1