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
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:
|