Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <CL/opencl.h>
- cl_int cl_error; // OpenCL error code
- cl_device_id device_id; // The chosen device
- cl_program program; // OpenCL program
- /** Formats the standard MACROS __FILE__ and __LINE__ for message print.
- */
- #define STRINGIFY(x) #x
- #define TOSTRING(x) STRINGIFY(x)
- #define AT __FILE__ ":" TOSTRING(__LINE__)
- #define DEBUG_BUFFER_SIZE 4096
- char * OpenCL_error_to_string(int error);
- #define dump(msg,...) \
- fprintf(stderr, AT msg,##__VA_ARGS__)
- #define OpenCL_test_execution(msg,error) \
- do { \
- if(CL_SUCCESS != error) { \
- dump("The runtime error is %s\n", \
- (char *)OpenCL_error_to_string(error)); \
- exit(EXIT_FAILURE); \
- } \
- } while (0)
- static double t_start, t_end; // Timing
- double timer_get_time()
- {
- struct timeval t;
- if (gettimeofday (&t, NULL) != 0) {
- perror("Error gettimeofday !\n");
- exit(1);
- }
- return (t.tv_sec + t.tv_usec * 1.0e-6);
- }
- void timer_start() {
- t_start = timer_get_time();
- }
- void timer_stop_display( char *msg ) {
- t_end = timer_get_time();
- printf ("%s : %0.1lf\n", msg, (t_end - t_start)*1000);
- }
- void openclSimpleCopy(cl_context context, cl_command_queue queue, cl_kernel kernel, size_t n) {
- // Host data
- int a[n],b[n];
- int _i;
- // Init
- for(_i=0;_i<n;_i++) {
- a[_i]=n-_i;
- b[_i]=0;
- }
- // Buffers on the device
- cl_mem a_dev = clCreateBuffer(context,
- CL_MEM_READ_WRITE,
- n * sizeof(int),
- NULL,
- &cl_error);
- OpenCL_test_execution("Create Buffer",cl_error);
- cl_mem b_dev = clCreateBuffer(context,
- CL_MEM_READ_WRITE,
- n * sizeof(int),
- NULL,
- &cl_error);
- OpenCL_test_execution("Create Buffer",cl_error);
- // 3 events is enough here
- cl_event event1;
- cl_event event2;
- cl_event event3;
- // Initialize buffer on the device
- cl_error = clEnqueueWriteBuffer(queue,
- a_dev,
- CL_TRUE,
- 0,
- n * sizeof(int),
- a,
- 0,
- NULL,
- &event1);
- OpenCL_test_execution("Write to Buffer",cl_error);
- // Shouldn't be useful, I used a blocking write !
- clFlush(queue);
- clWaitForEvents(1,&event1);
- // Arguments for the kernel
- cl_error = clSetKernelArg(kernel,0,sizeof(a_dev), &a_dev);
- OpenCL_test_execution("Set argument 0 ",cl_error);
- cl_error = clSetKernelArg(kernel,1,sizeof(b_dev), &b_dev);
- OpenCL_test_execution("Set argument 1",cl_error);
- timer_start();
- cl_error = clEnqueueNDRangeKernel(queue,
- kernel,
- 1,
- NULL,
- &n,
- NULL,
- 1,
- &event1,
- &event2);
- timer_stop_display("Time for Enqueue");
- OpenCL_test_execution("Enqueue kernel",cl_error);
- OpenCL_test_execution("clWaitForEvents",clWaitForEvents(1,&event2));
- cl_error = clEnqueueReadBuffer(queue,
- b_dev,
- CL_TRUE,
- 0,
- n * sizeof(int),
- b,
- 1,
- &event2,
- &event3);
- OpenCL_test_execution("Read from buffer",cl_error);
- OpenCL_test_execution("clWaitForEvents",clWaitForEvents(1,&event3));
- // Check result
- for(_i=0;_i<n;_i++) {
- if(a[_i]!=b[_i]) {
- printf("Error %d : %d!=%d\n",_i,a[_i],b[_i]);
- exit(-1);
- }
- }
- OpenCL_test_execution("Release mem object",clReleaseMemObject (a_dev));
- OpenCL_test_execution("Release mem object",clReleaseMemObject (b_dev));
- }
- int main(int argc, char **argv) {
- int platform_num = 0; // Platform number
- int device_num = 0; // Device number
- #define DEVICE_TYPE CL_DEVICE_TYPE_ALL
- cl_int cl_error; // OpenCL error code
- cl_kernel kernel = NULL;
- // Chosing platform
- cl_uint num_platforms;
- clGetPlatformIDs(0, NULL, &num_platforms);
- if(num_platforms <= 0) {
- dump("No OpenCL platforms found :-(\n");
- exit(-1);
- }
- cl_platform_id platform_ids[num_platforms];
- clGetPlatformIDs(num_platforms, platform_ids, NULL);
- if(platform_num < 0 || platform_num >= num_platforms) {
- dump("Invalid platform: %d\n", platform_num);
- exit(EXIT_FAILURE);
- }
- // platform_id hold the chosen platform
- cl_platform_id platform_id = platform_ids[platform_num];
- // Chosing the device
- cl_uint num_devices;
- OpenCL_test_execution("Get number of devices", clGetDeviceIDs(platform_id, DEVICE_TYPE, 0, NULL, &num_devices));
- if(num_devices <= 0) {
- dump("No devices found associated to this OpenCL platform :-(\n");
- exit(-1);
- }
- // Allocate spaces for devices
- cl_device_id devices[num_devices];
- // Get devices list
- OpenCL_test_execution("Get devices list", clGetDeviceIDs(platform_id, DEVICE_TYPE, num_devices, devices, NULL));
- /* Create a context for all devices */
- cl_context context = clCreateContext(0,
- num_devices,
- devices,
- NULL,
- "from 'context'",
- &cl_error);
- OpenCL_test_execution("Context creation",cl_error);
- // Here is the device ID
- device_id = devices[device_num];
- /* Create an in-order queue for this device */
- cl_command_queue queue = clCreateCommandQueue(context, device_id, 0, &cl_error);
- OpenCL_test_execution("Create command queue",cl_error);
- // END OF OPENCL INITIALIZATION
- const char *kernel_str = " __kernel void copy(__global int *a, __global int *b) {"
- " int i = get_global_id(0);"
- " b[i]=a[i];"
- "}";
- program = clCreateProgramWithSource(context,
- 1,
- &kernel_str,
- NULL,
- &cl_error);
- OpenCL_test_execution("Create program with source",cl_error);
- cl_error = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
- OpenCL_test_execution("Build Program",cl_error);
- kernel = clCreateKernel(program, "copy", &cl_error);
- OpenCL_test_execution("Create kernel",cl_error);
- // Size of problem, 10^5 will give me 1.5ms for the enqueue, 10^6 up to 30ms!
- size_t n = 10000000;
- int _i;
- // Run the sequence many times
- printf("Run with n = %zu\n",n);
- for(_i=0;_i<10;_i++) {
- openclSimpleCopy(context, queue, kernel,n);
- }
- // Run the same sequence with a smaller problem size
- n = n/100;
- printf("Run with n = %zu\n",n);
- for(_i=0;_i<10;_i++) {
- openclSimpleCopy(context, queue, kernel,n);
- }
- }
- char * OpenCL_error_to_string(int error) {
- switch (error)
- {
- case CL_SUCCESS:
- return (char *)"Success";
- case CL_DEVICE_NOT_FOUND:
- return (char *)"Device Not Found";
- case CL_DEVICE_NOT_AVAILABLE:
- return (char *)"Device Not Available";
- case CL_COMPILER_NOT_AVAILABLE:
- return (char *)"Compiler Not Available";
- case CL_MEM_OBJECT_ALLOCATION_FAILURE:
- return (char *)"Mem Object Allocation Failure";
- case CL_OUT_OF_RESOURCES:
- return (char *)"Out Of Ressources";
- case CL_OUT_OF_HOST_MEMORY:
- return (char *)"Out Of Host Memory";
- case CL_PROFILING_INFO_NOT_AVAILABLE:
- return (char *)"Profiling Info Not Available";
- case CL_MEM_COPY_OVERLAP:
- return (char *)"Mem Copy Overlap";
- case CL_IMAGE_FORMAT_MISMATCH:
- return (char *)"Image Format Mismatch";
- case CL_IMAGE_FORMAT_NOT_SUPPORTED:
- return (char *)"Image Format Not Supported";
- case CL_BUILD_PROGRAM_FAILURE: {
- #define CL_BUILD_PROGRAM_FAILURE_MSG "Build Program Failure : "
- static char debug_buffer[DEBUG_BUFFER_SIZE]; // Static to be returned
- strncat(debug_buffer,CL_BUILD_PROGRAM_FAILURE_MSG,DEBUG_BUFFER_SIZE);
- clGetProgramBuildInfo(program,
- device_id,
- CL_PROGRAM_BUILD_LOG ,
- DEBUG_BUFFER_SIZE,
- debug_buffer+strlen(CL_BUILD_PROGRAM_FAILURE_MSG),
- NULL);
- return (char *)debug_buffer;
- }
- case CL_MAP_FAILURE:
- return (char *)"Map Failure";
- case CL_INVALID_VALUE:
- return (char *)"Invalid Value";
- case CL_INVALID_DEVICE_TYPE:
- return (char *)"Invalid Device Type";
- case CL_INVALID_PLATFORM:
- return (char *)"Invalid Platform";
- case CL_INVALID_DEVICE:
- return (char *)"Invalid Device";
- case CL_INVALID_CONTEXT:
- return (char *)"Invalid Context";
- case CL_INVALID_QUEUE_PROPERTIES:
- return (char *)"Invalid Queue Properties";
- case CL_INVALID_COMMAND_QUEUE:
- return (char *)"Invalid Command Queue";
- case CL_INVALID_HOST_PTR:
- return (char *)"Invalid Host Ptr";
- case CL_INVALID_MEM_OBJECT:
- return (char *)"Invalid Mem Object";
- case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR:
- return (char *)"Invalid Image Format Descriptor";
- case CL_INVALID_IMAGE_SIZE:
- return (char *)"Invalid Image Size";
- case CL_INVALID_SAMPLER:
- return (char *)"Invalid Sampler";
- case CL_INVALID_BINARY:
- return (char *)"Invalid Binary";
- case CL_INVALID_BUILD_OPTIONS:
- return (char *)"Invalid Build Options";
- case CL_INVALID_PROGRAM:
- return (char *)"Invalid Program";
- case CL_INVALID_PROGRAM_EXECUTABLE:
- return (char *)"Invalid Program Executable";
- case CL_INVALID_KERNEL_NAME:
- return (char *)"Invalid Kernel Name";
- case CL_INVALID_KERNEL_DEFINITION:
- return (char *)"Invalid Kernel Definition";
- case CL_INVALID_KERNEL:
- return (char *)"Invalid Kernel";
- case CL_INVALID_ARG_INDEX:
- return (char *)"Invalid Arg Index";
- case CL_INVALID_ARG_VALUE:
- return (char *)"Invalid Arg Value";
- case CL_INVALID_ARG_SIZE:
- return (char *)"Invalid Arg Size";
- case CL_INVALID_KERNEL_ARGS:
- return (char *)"Invalid Kernel Args";
- case CL_INVALID_WORK_DIMENSION:
- return (char *)"Invalid Work Dimension";
- case CL_INVALID_WORK_GROUP_SIZE:
- return (char *)"Invalid Work Group Size";
- case CL_INVALID_WORK_ITEM_SIZE:
- return (char *)"Invalid Work Item Size";
- case CL_INVALID_GLOBAL_OFFSET:
- return (char *)"Invalid Global Offset";
- case CL_INVALID_EVENT_WAIT_LIST:
- return (char *)"Invalid Event Wait List";
- case CL_INVALID_EVENT:
- return (char *)"Invalid Event";
- case CL_INVALID_OPERATION:
- return (char *)"Invalid Operation";
- case CL_INVALID_GL_OBJECT:
- return (char *)"Invalid GL Object";
- case CL_INVALID_BUFFER_SIZE:
- return (char *)"Invalid Buffer Size";
- case CL_INVALID_MIP_LEVEL:
- return (char *)"Invalid Mip Level";
- case CL_INVALID_GLOBAL_WORK_SIZE:
- return (char *)"Invalid Global Work Size";
- default:
- break;
- }
- return "Unknown";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement