• Nem Talált Eredményt

2. Az OpenCL API eszközei

7.6. példa - platform.c

#include <stdio.h>

#include <error.h>

#include <CL/opencl.h>

#define MAX_PLATFORMS 10

#define MAX_DEVICES 10

#define MAX_STRING_SIZE 1000 int main(int argc, char** argv) {

cl_int err;

cl_uint numPlatforms;

cl_platform_id platforms[MAX_PLATFORMS];

char pString[MAX_STRING_SIZE];

int size;

int i;

err= clGetPlatformIDs(MAX_PLATFORMS, platforms, &numPlatforms);

ERROR(err, "clGetPlatformIDs");

printf("Number of platforms: %d\n", numPlatforms);

for ( i= 0; i < numPlatforms; ++i ) {

err= clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, MAX_STRING_SIZE, pString,

&size);

ERROR(err, "clGetPlatformInfo");

printf("Platform name: %s\n", pString);

err= clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, MAX_STRING_SIZE, pString,

&size);

ERROR(err, "clGetPlatformInfo");

printf("Platform vendor: %s\n", pString);

err= clGetPlatformInfo(platforms[i], CL_PLATFORM_VERSION, MAX_STRING_SIZE, pString,

&size);

ERROR(err, "clGetPlatformInfo");

printf("Platform version: %s\n", pString);

err= clGetPlatformInfo(platforms[i], CL_PLATFORM_PROFILE, MAX_STRING_SIZE, pString,

&size);

ERROR(err, "clGetPlatformInfo");

printf("Platform profile: %s\n", pString);

err= clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, MAX_STRING_SIZE, pString, &size);

ERROR(err, "clGetPlatformInfo");

printf("Platform extensions: %s\n", pString);

}

return 0;

}

A példaprogram fordítását a cmake eszközökön alapuló konfigurálás előzi meg, ezért itt kerítünk alkalmat az előző szakaszban bemutatott cmake kereső modul használatának bemutatására. A példaprogram fordításához az alábbi konfigurációs állományt használjuk.

7.7. példa - CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(platform)

AUX_SOURCE_DIRECTORY(. SRC)

ADD_EXECUTABLE(${PROJECT_NAME} ${SRC})

SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/.") FIND_PACKAGE(OpenCL REQUIRED)

MESSAGE(STATUS "OpenCL_Found: ${OPENCL_FOUND}")

TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OPENCL_LIBRARY}) INCLUDE_DIRECTORIES(${OPENCL_INCLUDE_DIR})

SET(CMAKE_VERBOSE_MAKEFILE ON)

A konfigurálás során a következőhöz hasonló kimenetet kapunk:

user@home> cmake .

-- The C compiler identification is GNU 4.7.3 -- The CXX compiler identification is GNU 4.7.3 -- Detecting C compiler ABI info

-- Detecting C compiler ABI info - done -- Detecting CXX compiler ABI info

-- Detecting CXX compiler ABI info - done -- Found OpenCL: /usr/lib/libOpenCL.so -- OpenCL 1.1 CUDA 4.2.1

-- OpenCL_Found: TRUE -- Configuring done -- Generating done

-- Build files have been written to: /home/user/opencl-platform

A kimenetből egyrészt láthatjuk, hogy a konfiguráció sikeres volt, másrészt az OpenCL_Found változó TRUE értékéből arra is következtethetünk, hogy a kereső modulnak sikerült azonosítania szoftverkörnyezetünkben az OpenCL header-fájlokat és az implementációt. Az OpenCL 1.1 CUDA 4.2.1 sztring a konfiguráció során tesztként lefordított (a kereső modulban definiált) egyszerű program sztenderd kimenete.

A konfigurációt követően természetesen fel kell dolgozni az előálló Makefile-t (make), majd alkalmazásunkat futtatva az alábbi kimenetet kapjuk:

user@home> ./platform Number of platforms: 1 Platform name: NVIDIA CUDA

Platform vendor: NVIDIA Corporation Platform version: OpenCL 1.1 CUDA 4.2.1 Platform profile: FULL_PROFILE

Platform extensions: cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll

A program kimenetéből azt olvashatjuk ki, hogy a számítógépen egyedül az NVidia gyártó OpenCL 1.1-es verzióját támogató CUDA platform érhető el. A FULL_PROFILE tulajdonság arra utal, hogy a platform a teljes 1.1-es specifikációt támogatja. A tulajdonság értékeként megjelenhet még az EMBEDDED_PROFILE sztring, ekkor az OpenCL specifikációnak csak egy részét használhatjuk. A fejezetben bemutatásra kerülő OpenCL függvényeket minden OpenCL-t támogató eszköznek implementálnia kell, így ha a FULL_PROFILE sztringet kapjuk, bátran használhatjuk az itt tanultakat. Vannak azonban olyan opcionális lehetőségek, amelyek csak kényelmi funkciókat szolgáltatnak, vagy túl specifikusak, egyes hardverek működésére esetleg ortogonálisak.

Ezeket un. kiterjesztésként valósíthatják meg a gyártók. Az elérhető kiterjesztések mindig lekérdezhetők, esetünkben a példaprogram kimenetének utolsó bejegyzéseként láthatók. Mivel a különböző hardvereszközök és driverek az OpenCL szabvány különböző verzióit támogatják, a platform tulajdonságainak lekérdezése alapján tudjuk eldönteni, hogy alkalmas-e a platform az OpenCL bizonyos verziója alapján megírt szoftverünk futtatására.

Eszközök. Az egyes platformok több különböző OpenCL eszközt tartalmazhatnak, például ma már nem ritka, hogy egy asztali számítógépben két grafikus kártya is van, így egy platform nem azonosít OpenCL eszközt, csak eszközök egy csoportját. Egy adott platformhoz tartozó eszközök azonosítóit a clGetDeviceIDs függvény segítségével kérdezhetjük le.

Specifikáció:

cl_int clGetDeviceIDs( cl_platform_id platform,

cl_device_type device_type,

cl_uint num_entries, cl_device_id*

devices,

cl_uint*

num_devices);

Paraméterek: platform - Egy platform azonosítója.

device_type - A lekérdezendő eszközök típusa. A lehetséges értékeit specifikáló konstansokat a 7.2.

táblázatban foglaljuk össze.

num_entries - A devices címre kerülő azonosítók maximális száma.

devices - Egy num_entries méretű, cl_device típusú tömb, amelybe a lekérdezett azonosítók kerülnek.

num_devices - Ezen címre kerül be a ténylegesen visszaadott, azaz a devices tömbbe írt azonosítók száma.

Visszatérési érték: Sikeres végrehajtás esetén CL_SUCCESS, ellenkező esetben hibakód.

7.2. táblázat - A

clGetDeviceIDs

függvénnyel lekérdezhető eszközök típusai és a hozzájuk tartozó nevesített konstansok.

Nevesített konstans A lekérdezhető eszközök típusa

CL_DEVICE_TYPE_CPU Processzorok (CPU).

CL_DEVICE_TYPE_GPU Grafikus processzorok (GPU).

CL_DEVICE_TYPE_ACCELERATOR OpenCL-t támogató hardveres gyorsítók.

CL_DEVICE_TYPE_CUSTOM Az OpenCL C-t nem támogató hardveres gyorsító eszközök.

CL_DEVICE_TYPE_DEFAULT Az alapértelmezett OpenCL eszköz.

CL_DEVICE_TYPE_ALL Az összes elérhető OpenCL eszköz.

A lekérdezhető eszközök típusait áttekintve ismét felmerül a hardveres gyorsító eszköz fogalma, amely szintén támogathatja az OpenCL technológiát. Mit is értünk hardveres gyorsító alatt? Olyan eszközökre kell gondolni, amelyeket a számítógéphez csatlakoztatva bizonyos célfeladatok elvégzése nagyban felgyorsítható. Egyrészt, maga a grafikus kártya is tekinthető egy hardveres gyorsítónak, sőt, az ezredforduló környékén a 3D megjelenítést aktívan használó szoftverek igényelték is, hogy a grafikus kártya mellett egy grafikus gyorsító kártya5 is jelen legyen a számítógépben. Napjainkra természetesen ezek egybeolvadtak. Jelenleg az egyik legelterjedtebb megközelítést a Field Programmable Gate Array (FPGA) csipeken alapuló hardveres gyorsító eszközök használata jelenti. Mára megjelentek az első OpenCL-t támogató FPGA-kártyák, amelyek meghatározó szerepe valószínűsíthető a jövőre nézve. Az FPGA eszközökről, azok felépítéséről, céljairól az utolsó fejezetben írunk bővebben.

5Az 1990-es évek második felében a 3Dfx cég úttörő munkát végzett a grafikus gyorsító kártyák fejlesztése terén. Legnépszerűbb szériáját a Voodoo kártyák alkották, népszerűségüket és piaci helyzetüket jól jellemezte, hogy kevésbé hozzáértő érdeklődők akkoriban minden grafikus gyorsító kártyát 3Dfx-kártyának hívtak, akkor is, ha azt nem a 3Dfx gyártotta.

Hasonlóan a platformokhoz, az egyes OpenCL eszközök is rendelkeznek tulajdonságokkal, amelyeket a clGetDeviceInfo függvénnyel kérdezhetünk le. A lekérdezhető tulajdonságok száma verzióról verzióra növekszik. A legfontosabb tulajdonságokat specifikáló konstansokat és a tulajdonságok típusait a 7.3.

táblázatban foglaljuk össze.

Paraméterek: device - Egy platform azonosítója.

param_name - A fontosabb lekérdezhető paraméterek nevét, típusát és jelentését a 7.3. táblázatban foglaljuk össze.

param_value_size - A függvény által a

param_value címre írható bájtok maximális száma.

param_value - Egy param_value_size bájt méretű lefoglalt memóriaterület címe.

param_value_size_ret - Ezen címre kerül be a ténylegesen visszaadott, azaz param_value címre másolt bájtok száma.

Visszatérési érték: Sikeres végrehajtás esetén CL_SUCCESS, ellenkező esetben hibakód.

7.3. táblázat - Az OpenCL eszközök

clGetDeviceInfo

függvénnyel lekérdezhető fontosabb tulajdonságaihoz tartozó konstansok és tulajdonságok típusa. Megjegyezzük, hogy ezektől jóval több és specifikusabb tulajdonság kérdezhető le, ezek leírását az aktuális OpenCL specifikációban találja az olvasó.

cl_device_info értéke Típus Leírás

CL_DEVICE_MAX_COMPUTE_UNITS cl_uint A számítási egységek száma az eszközön. A munkacsoportok a számítási egységen kerülnek párhuzamos végrehajtásra.

CL_DEVICE_MAX_WORK_GROUP_SIZ E

size_t A munkacsoportok maximális

mérete.

CL_DEVICE_MAX_WORK_ITEM_DIME NSIONS

cl_uint A munkaelemek indexeit definiáló indextartomány dimenzióinak maximális száma. Minimális értéke 3.

CL_DEVICE_MAX_WORK_ITEM_SIZE S

size_t[] Az egyes dimenziókban

maximálisan definiálható munkaelemek száma.

CL_DEVICE_MAX_GLOBAL_MEM_SIZ E

cl_ulong Az eszköz globális memóriájának mérete bájtokban. A globális memóriában maximum ennek negyede foglalható le dinamikusan.

CL_DEVICE_MAX_GLOBAL_MEM_CAC HE_SIZE

cl_ulong A globális memória gyorsítótár mérete bájtokban.

CL_DEVICE_MAX_CONSTANT_BUFFE R_SIZE

cl_ulong A konstans memória mérete

bájtokban.

cl_device_info értéke Típus Leírás

CL_DEVICE_MAX_LOCAL_MEM_SIZE cl_ulong A lokális memória mérete bájtokban.

CL_DEVICE_MAX_CLOCK_FREQUENC Y

cl_uint Az eszköz maximális órajele MHz-ben.

CL_DEVICE_PRINTF_BUFFER_SIZE size_t A grafikus kártyán használhatjuk a printf függvényt, amelynek kimenete egy puffer-be kerül. Ezen puffer méretét kaphatjuk vissza a tulajdonság lekérdezésekor.

CL_DEVICE_PROFILE char[] Az eszköz által támogatott profil, a korábbiakhoz hasonlóan értéke

FULL_PROFILE vagy

EMBEDDED_PROFILE.

CL_DEVICE_TYPE cl_device_type Az eszköz típusa, lehetséges értékei megegyeznek 7.2. táblázatban foglalt konstansok kombinációival.

CL_DEVICE_AVAILABLE cl_bool A paraméter értéke CL_TRUE, ha az eszköz elérhető, ellenkező esetben CL_FALSE.

CL_DEVICE_COMPILER_AVAILABLE cl_bool A paraméter értéke CL_TRUE, ha az eszközhöz megfelelő fordító elérhető, ellenkező esetben CL_FALSE.

CL_DEVICE_LINKER_AVAILABLE cl_bool A paraméter értéke CL_TRUE, ha az eszközhöz megfelelő linker elérhető, ellenkező esetben CL_FALSE.

CL_DEVICE_NAME char[] Az eszköz neve karaktertömbként.

CL_DEVICE_VENDOR char[] Az eszköz gyártójának neve

karaktertömbként.

CL_DRIVER_VERSION char[] Az eszköz driver verziószáma

karaktertömbként.

CL_DEVICE_VERSION char[] Az eszköz által támogatott OpenCL specifikáció verziószáma.

CL_DEVICE_OPENCL_C_VERSION char[] Az eszköz által támogatott OpenCL C nyelv verziószáma.

A függvény használata során le kell foglalnunk a lekérdezendő tulajdonságnak megfelelő méretű memóriaterületet, s a függvény ezen területre írja a tulajdonság értékét. A függvény használatát az alábbi példaprogramon keresztül szemléltetjük.