OpenCL tutorial – część 2 – listowanie dostępnych urządzeń

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.

Ten wpis został opublikowany w kategorii C++, OpenCL, Windows. Dodaj zakładkę do bezpośredniego odnośnika.