#include #include #include #include "cl_util.h" const char * program_src = "__kernel\n" "void pi(__global float * out) \n" "{\n" " out[0] = 3.14159f;\n" "}\n"; int main(int argc, char ** argv) { cl_int error; cl_uint total_platforms; cl_platform_id platform_id; cl_uint total_gpu_devices; cl_device_id device_id; cl_context context; cl_command_queue command_queue; cl_program program; cl_kernel kernel; cl_mem out_buffer; float out_value = 0.0; size_t global_work_size = 1; error = clGetPlatformIDs( 1, /* Max number of platform IDs to return */ &platform_id, /* Pointer to platform_id */ &total_platforms); /* Total number of platforms * found on the system */ if (error != CL_SUCCESS) { fprintf(stderr, "clGetPlatformIDs() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "There are %u platforms.\n", total_platforms); error = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, &total_gpu_devices); if (error != CL_SUCCESS) { fprintf(stderr, "clGetDeviceIDs() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "There are %u GPU devices.\n", total_gpu_devices); context = clCreateContext(NULL, /* Properties */ 1, /* Number of devices */ &device_id, /* Device pointer */ NULL, /* Callback for reporting errors */ NULL, /* User data to pass to error callback */ &error); /* Error code */ if (error != CL_SUCCESS) { fprintf(stderr, "clCreateContext() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clCreateContext() succeeded.\n"); command_queue = clCreateCommandQueue(context, device_id, 0, /* Command queue properties */ &error); /* Error code */ if (error != CL_SUCCESS) { fprintf(stderr, "clCreateCommandQueue() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clCreateCommandQueue() succeeded.\n"); program = clCreateProgramWithSource(context, 1, /* Number of strings */ &program_src, NULL, /* String lengths, 0 means all the * strings are NULL terminated. */ &error); if (error != CL_SUCCESS) { fprintf(stderr, "clCreateProgramWithSource() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clCreateProgramWithSource() suceeded.\n"); error = clBuildProgram(program, 1, /* Number of devices */ &device_id, NULL, /* options */ NULL, /* callback function when compile is complete */ NULL); /* user data for callback */ if (error != CL_SUCCESS) { char build_str[10000]; error = clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, 10000, /* Size of output string */ build_str, /* pointer to write the log to */ NULL); /* Number of bytes written to the log */ if (error != CL_SUCCESS) { fprintf(stderr, "clGetProgramBuildInfo() failed: %s\n", clUtilErrorString(error)); } else { fprintf(stderr, "Build Log: \n%s\n\n", build_str); } return EXIT_FAILURE; } fprintf(stderr, "clBuildProgram() suceeded.\n"); kernel = clCreateKernel(program, "pi", &error); if (error != CL_SUCCESS) { fprintf(stderr, "clCreateKernel() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clCreateKernel() suceeded.\n"); out_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, /* Flags */ sizeof(float), /* Size of buffer */ NULL, /* Pointer to the data */ &error); /* error code */ if (error != CL_SUCCESS) { fprintf(stderr, "clCreateBuffer() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clCreateBuffer() succeeded.\n"); error = clSetKernelArg(kernel, 0, /* Arg index */ sizeof(cl_mem), &out_buffer); if (error != CL_SUCCESS) { fprintf(stderr, "clSetKernelArg failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clSetKernelArg() succeeded.\n"); error = clEnqueueNDRangeKernel(command_queue, kernel, 1, /* Number of dimensions */ NULL, /* Global work offset */ &global_work_size, &global_work_size, /* local work size */ 0, /* Events in wait list */ NULL, /* Wait list */ NULL); /* Event object for this event */ if (error != CL_SUCCESS) { fprintf(stderr, "clEnqueueNDRangeKernel() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clEnqueueNDRangeKernel() suceeded.\n"); error = clFinish(command_queue); if (error != CL_SUCCESS) { fprintf(stderr, "clFinish() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clFinish() succeeded.\n"); error = clEnqueueReadBuffer(command_queue, out_buffer, CL_TRUE, /* TRUE means it is a blocking read. */ 0, /* Buffer offset to read from. */ sizeof(float), /* Bytes to read */ &out_value, /* Pointer to store the data */ 0, /* Events in wait list */ NULL, /* Wait list */ NULL); /* Event object */ if (error != CL_SUCCESS) { fprintf(stderr, "clEnqueueReadBuffer() failed: %s\n", clUtilErrorString(error)); return EXIT_FAILURE; } fprintf(stderr, "clEnqueueReadBuffer() suceeded.\n"); fprintf(stderr, "pi = %f\n", out_value); return EXIT_SUCCESS; }