OpenCL Platform Information Using C++ and CMake
Each OpenCL platform is an implementation of OpenCL on a company hardware. Because OpenCL is an application programming interface (API) each brand chooses how to implement it on their hardware. This implementation can be done over GPUs, CPUs, FPGAs, and other kind of accelerators.
Is the responsibility of each brand to maintain and fix the implementation on their hardware. Those brands like AMD, Nvidia and Intel most commonly, have to offer drivers and runtimes to be able to execute and compile OpenCL programs on their hardware. Not all the functions must be supported on all the hardware that implement OpenCL, for this reason you can request each device of that platform what operations do they support and is the responsibility of the programmer to handle multiple vendors different capabilities.
A platform is used to discover the available hardware and retrieve all the devices. This will be used to discover their capabilities and harvest all their computational power.
Platform C Construct
Programming OpenCL in C++ is a wrapper to the C functions, the C function to initialize the platform structures is the following:
// Provided by CL_VERSION_1_0
cl_int clGetPlatformIDs(
cl_uint num_entries,
cl_platform_id* platforms,
cl_uint* num_platforms);
The parameters of the function are the following
num_entries
is the number of cl_platform_id entries that can be added to platforms. If platforms is not NULL, num_entries must be greater than zero.platforms
returns a list of OpenCL platforms found. The cl_platform_id values returned in platforms can be used to identify a specific OpenCL platform. If platforms is NULL, this argument is ignored. The number of OpenCL platforms returned is the minimum of the value specified by num_entries or the number of OpenCL platforms available.num_platforms
returns the number of OpenCL platforms available. If num_platforms is NULL, this argument is ignored.
In C, the function has to be called twice. First to get the number of platforms and second to initialize the structures once allocated.
cl_platform_id *platforms;
cl_uint num_platforms;
clGetPlatformIDs(10, NULL, &num_platforms);
platforms = (cl_platform_id*)
malloc(sizeof(cl_platform_id) * num_platforms);
clGetPlatformIDs(num_platforms, platforms, NULL);
Note:
Note that num_entries
is the maximum number of platforms you are interested in finding while num_platforms
are the number of platforms found on the system
The C++ Wrapper uses vector to dynamically retrieve the platform classes using the static method get()
public: static cl_int Platform::get(std::vector<Platform> *platforms)
The code to retrieve all the platforms can be with the following two lines:
std::vector<cl::Platform> platforms{};
cl::Platform::get(&platforms);
main.cpp
The following code section uses cl::Platform::get(&platforms);
to collect all the platforms into a std::vector<cl::Platform>
#include <iostream>
#include <CL/opencl.hpp>
int main() {
// initialize a vector to store the platforms
std::vector<cl::Platform> platforms{};
// collect the platforms available
cl::Platform::get(&platforms);
// make sure at least we have a platform
if (platforms.empty()){
std::cerr << "No platforms found!" << std::endl;
exit(1);
}
std::cout << "Number of platforms found: " << platforms.size() << std::endl;
// iterate over each platform
for (const cl::Platform& platform : platforms) {
std::cout << "\tPlatform name: " << platform.getInfo<CL_PLATFORM_NAME>() << std::endl;
std::cout << "\tPlatform vendor: " << platform.getInfo<CL_PLATFORM_VENDOR>() << std::endl;
std::cout << "\tPlatform version: " << platform.getInfo<CL_PLATFORM_VERSION>() << std::endl;
std::cout << "\tPlatform profile: " << platform.getInfo<CL_PLATFORM_PROFILE>() << std::endl;
std::cout << "\tPlatform extensions: " << platform.getInfo<CL_PLATFORM_EXTENSIONS>() << std::endl;
// collect the devices
std::vector<cl::Device> devices;
platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
std::cout << "\tPlatform devices: " << devices.size() << std::endl;
std::cout << "\n----------\n" << std::endl;
}
std::cout << "Done!" << std::endl;
return 0;
}
CMakeLists.txt Code
cmake_minimum_required(VERSION 3.28)
project(OpenCL_PlatformInformation LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
add_executable(${PROJECT_NAME} main.cpp)
find_package(OpenCL REQUIRED)
target_link_libraries(${PROJECT_NAME} OpenCL::OpenCL)
target_compile_definitions(${PROJECT_NAME} PRIVATE CL_HPP_TARGET_OPENCL_VERSION=300)
Program Output
This is the output of my current system:
Number of platforms found: 2
Platform name: Clover
Platform vendor: Mesa
Platform version: OpenCL 1.1 Mesa 22.3.6
Platform profile: FULL_PROFILE
Platform extensions: cl_khr_icd
Platform devices: 1
----------
Platform name: rusticl
Platform vendor: Mesa/X.org
Platform version: OpenCL 3.0
Platform profile: FULL_PROFILE
Platform extensions: cl_khr_icd
Platform devices: 0
----------
Done!
Process finished with exit code 0
If you spot any typos, have questions, or need assistance with the build, feel free to contact me at: antonimercer@lthjournal.com
This guide contains no affiliate links or ads. If you'd like to support this or future projects, you can do so here:
By supporting monthly you will help me create awesome guides and improve current ones.
Technologies used
Debian 12, Linux, OpenCL, C++, AMD, Nvidia, Intel, GPU