OpenCL (Open Computing Language) besteht aus zwei Teilen: einer Host-API in C, mit der das Programm Geräte auswählt und Kernel startet, und der Kernel-Sprache OpenCL C, in der die auf der GPU laufenden Funktionen geschrieben werden. Dieser Artikel listet die wichtigsten Funktionen beider Seiten.
Plattform und Gerät wählen
clGetPlatformIDs(1, &platform, &n) // OpenCL-Plattform finden
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL)
Kontext, Queue und Kernel bauen
clCreateContext(NULL, 1, &device, NULL, NULL, &err)
clCreateCommandQueueWithProperties(ctx, device, NULL, &err) // seit OpenCL 2.0; ersetzt clCreateCommandQueue
clCreateProgramWithSource(ctx, 1, &src, NULL, &err)
clBuildProgram(prog, 1, &device, NULL, NULL, NULL)
clCreateKernel(prog, "vec_add", &err)
Die ältere Funktion clCreateCommandQueue gilt seit OpenCL 2.0 als veraltet; neuere Programme nutzen die WithProperties-Variante.
Speicher und Kernel-Start
clCreateBuffer(ctx, CL_MEM_READ_WRITE, n * sizeof(float), NULL, &err)
clEnqueueWriteBuffer(queue, buf, CL_TRUE, 0, bytes, host_ptr, 0, NULL, NULL)
clSetKernelArg(kernel, 0, sizeof(cl_mem), &buf)
clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, &local, 0, NULL, NULL)
clEnqueueReadBuffer(queue, buf, CL_TRUE, 0, bytes, host_ptr, 0, NULL, NULL)
Kernel in OpenCL C
__kernel void vec_add(__global const float *a,
__global const float *b,
__global float *c) {
int i = get_global_id(0);
c[i] = a[i] + b[i];
}
Jeder Work-Item bekommt eine eindeutige ID: get_global_id(0) liefert sie, get_local_id(0) die Position innerhalb der Work-Group. Speicher-Adressräume heißen __global, __local, __constant und __private; innerhalb einer Work-Group synchronisiert barrier(CLK_LOCAL_MEM_FENCE).
Verwandte Grundlagen: OpenMP-Befehle, MPI-Befehle, CUDA, DSP, FPGA.