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.