#include #include #include #ifdef __APPLE__ #include #else #include #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: