Examples from the OpenCL cookbook written by Dhruba Bandopadhyay.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

210 lines
3.8 KiB

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
#define KERNEL "part4.cl"
size_t
clPutProgramBinaryToFile(
const char * const filename,
const cl_program * const program)
{
cl_int cl_status;
cl_uint num_devices;
cl_status = clGetProgramInfo(
*program,
CL_PROGRAM_NUM_DEVICES,
sizeof(cl_uint),
&num_devices,
NULL);
if (cl_status != CL_SUCCESS) {
return 0;
}
cl_device_id devices[num_devices];
cl_status =
clGetProgramInfo(
*program,
CL_PROGRAM_DEVICES,
sizeof(cl_device_id) * num_devices,
devices,
NULL);
if (cl_status != CL_SUCCESS) {
return 0;
}
size_t binary_size[num_devices];
cl_status =
clGetProgramInfo(
*program,
CL_PROGRAM_BINARY_SIZES,
sizeof(size_t) * num_devices,
binary_size,
NULL);
if (cl_status != CL_SUCCESS) {
return 0;
}
unsigned char * binaries[num_devices];
for (cl_uint i = 0; i < num_devices; i++) {
binaries[i] = (unsigned char *) malloc(binary_size[i]);
}
cl_status =
clGetProgramInfo(
*program,
CL_PROGRAM_BINARIES,
sizeof(unsigned char *) * num_devices,
binaries,
NULL);
if (cl_status != CL_SUCCESS) {
for (cl_uint i = 0; i < num_devices; i++) {
free(binaries[i]);
}
return 0;
}
FILE * handle = fopen(filename, "wb");
size_t size = fwrite(binaries[0], sizeof(unsigned char), binary_size[0], handle);
for (cl_uint i = 0; i < num_devices; i++) {
free(binaries[i]);
}
fclose(handle);
return size;
}
size_t
clGetProgramFromSourceFile(
const char * const filename,
const cl_context * const context,
cl_program * const program)
{
/*
* Get a build OpenCL program from source
*/
FILE * handle;
char * buffer;
size_t size;
cl_int cl_status;
cl_uint num_devices;
// get size of kernel source
handle = fopen(filename, "r");
fseek(handle, 0, SEEK_END);
size = ftell(handle);
rewind(handle);
// read kernel source into buffer
buffer = (char*) malloc(size + 1);
buffer[size] = '\0';
if (size != fread(buffer, sizeof(char), size, handle))
{
fclose(handle);
free(buffer);
return 0;
}
fclose(handle);
// create and build program
*program = clCreateProgramWithSource(
*context, 1, (const char**) &buffer, &size, &cl_status);
free(buffer);
if (cl_status != CL_SUCCESS) {
return 0;
}
cl_status = clGetContextInfo(
*context,
CL_CONTEXT_NUM_DEVICES,
sizeof(cl_uint),
&num_devices,
NULL);
if (cl_status != CL_SUCCESS) {
clReleaseProgram(*program);
return 0;
}
cl_device_id devices[num_devices];
cl_status = clGetContextInfo(
*context,
CL_CONTEXT_DEVICES,
sizeof(cl_device_id) * num_devices,
devices,
NULL);
cl_status = clBuildProgram(
*program, 1, devices, "-Werror -cl-std=CL1.1", NULL, NULL);
if (cl_status != CL_SUCCESS) {
clReleaseProgram(*program);
return 0;
}
return size;
}
int
clInit(cl_context * const context)
{
/*
* TODO add failure handling
*/
cl_platform_id platform;
cl_uint num_devices;
// get first available sdk and gpu and create context
clGetPlatformIDs(1, &platform, NULL);
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 10, NULL, &num_devices);
printf("%u devices during init.\n", num_devices);
cl_device_id devices[num_devices];
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, num_devices, devices, NULL);
*context = clCreateContext(NULL, num_devices, devices, NULL, NULL, NULL);
return 0;
}
int main()
{
cl_int cl_status;
cl_context context;
cl_program program;
size_t sourceSize;
size_t count;
clInit(&context);
sourceSize =
clGetProgramFromSourceFile(KERNEL, &context, &program);
assert(sourceSize != 0);
count = clPutProgramBinaryToFile(KERNEL "bin", &program);
assert(count != 0);
clReleaseProgram(program);
clReleaseContext(context);
return 0;
}
// vim: set ft=c ts=4 sw=4: