Przed nami druga część wprowadzenia do OpenCL. W tej części pokażę jak sprawdzić czy nasz sprzęt obsługuje OpenCL.
Naszym zadaniem jest wypisanie wszystkich urządzeń zainstalowanych w naszym komputerze, które wspierają OpenCL.
Na początek pobierzemy liczbę platform:
cl_int error = CL_SUCCESS; // Get platform number. cl_uint platformNumber = 0; error = clGetPlatformIDs(0, NULL, &platformNumber);
Zmienna platformNumber powinna przechowywać liczbę dostępnych platform, które obsługują OpenCL. Zmienna error zawiera 0 (CL_SUCCESS), jeżeli operacja wykonała się poprawnie lub liczbę różną od zera, jeżeli wystąpił błąd.
Funkcja clGetPlatformIDs ma dwa zastosowania. Pierwsze już znamy, czyli pobieranie liczby dostępnych platform, a drugie to pobieranie listy identyfikatorów dostępnych platform.
Najpierw alokujemy pamięć, a następnie pobieramy identyfikatory:
// Get platform identifiers. cl_platform_id* platformIds = new cl_platform_id[platformNumber]; error = clGetPlatformIDs(platformNumber, platformIds, NULL);
Skoro znamy już identyfikatory platform, to wykorzystajmy je do pobrania bardziej szczegółowych informacji na temat platform. Dzięki funkcji clGetPlatformInfo możemy poznać takie dane jak nazwa czy producent platformy:
// Get platform info.
for (cl_uint i = 0; i < platformNumber; ++i)
{
char name[1024] = { '\0' };
std::cout << "Platform:\t" << i << std::endl;
error = clGetPlatformInfo(platformIds[i], CL_PLATFORM_NAME, 1024, &name, NULL);
std::cout << "Name:\t\t" << name << std::endl;
error = clGetPlatformInfo(platformIds[i], CL_PLATFORM_VENDOR, 1024, &name, NULL);
std::cout << "Vendor:\t\t" << name << std::endl;
std::cout << std::endl;
}
Wiemy już na jakich platformach możemy operować, czas na pobranie informacji o konkretnych urządzeniach, które wspierają OpenCL.
Pobieranie informacji na temat urządzeń jest bardzo podobne do pobierania informacji na temat platform. Najpierw pobieramy liczbę urządzeń, następnie alokujemy pamięć na ich identyfikatory, a na końcu pobieramy szczegółowe informacje na temat urządzenia takie jak nazwa czy wersja.
Poniższy kod umieszczamy w pętli, dzięki czemu pobierzemy informacje na temat wszystkich urządzeń we wszystkich platformach:
// Get device count.
cl_uint deviceNumber;
error = clGetDeviceIDs(platformIds[i], CL_DEVICE_TYPE_GPU, 0, NULL, &deviceNumber);
if (0 == deviceNumber)
{
std::cout << "No OpenCL devices found on platform " << i << "." << std::endl;
}
// Get device identifiers.
cl_device_id* deviceIds = new cl_device_id[deviceNumber];
error = clGetDeviceIDs(platformIds[i], CL_DEVICE_TYPE_GPU, deviceNumber, deviceIds, &deviceNumber);
// Get device info.
for (cl_uint i = 0; i < deviceNumber; ++i)
{
char name[1024] = { '\0' };
std::cout << "Device:\t\t" << i << std::endl;
error = clGetDeviceInfo(deviceIds[i], CL_DEVICE_NAME, 1024, &name, NULL);
std::cout << "Name:\t\t" << name << std::endl;
error = clGetDeviceInfo(deviceIds[i], CL_DEVICE_VENDOR, 1024, &name, NULL);
std::cout << "Vendor:\t\t" << name << std::endl;
error = clGetDeviceInfo(deviceIds[i], CL_DEVICE_VERSION, 1024, &name, NULL);
std::cout << "Version:\t" << name << std::endl;
}
std::cout << std::endl;
// Free memory.
delete[] deviceIds;
Kompilujemy i uruchamiamy nasz program.
Kod programu
Cały kod powinien wyglądać tak:
#include
#include
#include <CL/cl.h>
int main()
{
cl_int error = 0;
// Get platform number.
cl_uint platformNumber = 0;
error = clGetPlatformIDs(0, NULL, &platformNumber);
if (0 == platformNumber)
{
std::cout << "No OpenCL platforms found." << std::endl;
return 0;
}
// Get platform identifiers.
cl_platform_id* platformIds = new cl_platform_id[platformNumber];
error = clGetPlatformIDs(platformNumber, platformIds, NULL);
// Get platform info.
for (cl_uint i = 0; i < platformNumber; ++i)
{
char name[1024] = { '\0' };
std::cout << "Platform:\t" << i << std::endl;
error = clGetPlatformInfo(platformIds[i], CL_PLATFORM_NAME, 1024, &name, NULL);
std::cout << "Name:\t\t" << name << std::endl;
error = clGetPlatformInfo(platformIds[i], CL_PLATFORM_VENDOR, 1024, &name, NULL);
std::cout << "Vendor:\t\t" << name << std::endl;
std::cout << std::endl;
// Get device count.
cl_uint deviceNumber;
error = clGetDeviceIDs(platformIds[i], CL_DEVICE_TYPE_GPU, 0, NULL, &deviceNumber);
if (0 == deviceNumber)
{
std::cout << "No OpenCL devices found on platform " << i << "." << std::endl;
}
// Get device identifiers.
cl_device_id* deviceIds = new cl_device_id[deviceNumber];
error = clGetDeviceIDs(platformIds[i], CL_DEVICE_TYPE_GPU, deviceNumber, deviceIds, &deviceNumber);
// Get device info.
for (cl_uint i = 0; i < deviceNumber; ++i)
{
char name[1024] = { '\0' };
std::cout << "Device:\t\t" << i << std::endl;
error = clGetDeviceInfo(deviceIds[i], CL_DEVICE_NAME, 1024, &name, NULL);
std::cout << "Name:\t\t" << name << std::endl;
error = clGetDeviceInfo(deviceIds[i], CL_DEVICE_VENDOR, 1024, &name, NULL);
std::cout << "Vendor:\t\t" << name << std::endl;
error = clGetDeviceInfo(deviceIds[i], CL_DEVICE_VERSION, 1024, &name, NULL);
std::cout << "Version:\t" << name << std::endl;
}
std::cout << std::endl;
// Free memory.
delete[] deviceIds;
}
// Free memory.
delete[] platformIds;
// Press Enter, to quit application.
std::cin.get();
return 0;
}
Wyniki
Program po uruchomieniu powinien dać wynik podobny do poniższego:
Platform: 0 Name: Intel(R) OpenCL Vendor: Intel(R) Corporation Device: 0 Name: Intel(R) HD Graphics 4000 Vendor: Intel(R) Corporation Version: OpenCL 1.1 Platform: 1 Name: NVIDIA CUDA Vendor: NVIDIA Corporation Device: 0 Name: GeForce GT 650M Vendor: NVIDIA Corporation Version: OpenCL 1.1 CUDA
Widzimy wszystkie platformy oraz urządzenia, które obsługują OpenCL. W moim przypadku jest to zintegrowana karta graficzna Intel HD Graphics 4000 oraz GeForce GT 650M.
Źródła w serwisie GitLab.
W następnej części kursu wykonamy i uruchomimy pierwszy program OpenCL.