Created
June 19, 2015 04:27
-
-
Save abhijangda/7e6420bd373cfd45117d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma OPENCL EXTENSION cl_khr_icd : enable | |
#include <CL/cl.h> | |
#include <errno.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#define NUM_DATA 100 | |
#define CL_CHECK(_expr) \ | |
do { \ | |
cl_int _err = _expr; \ | |
if (_err == CL_SUCCESS) \ | |
break; \ | |
fprintf(stderr, "OpenCL Error: '%s' returned %d!\n", #_expr, (int)_err); \ | |
abort(); \ | |
} while (0) | |
#define CL_CHECK_ERR(_expr) \ | |
({ \ | |
cl_int _err = CL_INVALID_VALUE; \ | |
typeof(_expr) _ret = _expr; \ | |
if (_err != CL_SUCCESS) { \ | |
fprintf(stderr, "OpenCL Error: '%s' returned %d!\n", #_expr, (int)_err); \ | |
abort(); \ | |
} \ | |
_ret; \ | |
}) | |
void pfn_notify(const char *errinfo, const void *private_info, size_t cb, void *user_data) | |
{ | |
fprintf(stderr, "OpenCL Error (via pfn_notify): %s\n", errinfo); | |
} | |
int main() | |
{ | |
cl_platform_id platforms[100]; | |
cl_uint platforms_n = 0; | |
//CL_CHECK(clIcdGetPlatformIDsKHR(100, platforms, &platforms_n)); | |
CL_CHECK(clGetPlatformIDs(100, platforms, &platforms_n)); | |
printf("=== %d OpenCL platform(s) found: ===\n", platforms_n); | |
for (int i=0; i<platforms_n; i++) | |
{ | |
char buffer[10240]; | |
printf(" -- %d --\n", i); | |
CL_CHECK(clGetPlatformInfo(platforms[i], CL_PLATFORM_PROFILE, 10240, buffer, NULL)); | |
printf(" PROFILE = %s\n", buffer); | |
CL_CHECK(clGetPlatformInfo(platforms[i], CL_PLATFORM_VERSION, 10240, buffer, NULL)); | |
printf(" VERSION = %s\n", buffer); | |
CL_CHECK(clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, 10240, buffer, NULL)); | |
printf(" NAME = %s\n", buffer); | |
CL_CHECK(clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, 10240, buffer, NULL)); | |
printf(" VENDOR = %s\n", buffer); | |
CL_CHECK(clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 10240, buffer, NULL)); | |
printf(" EXTENSIONS = %s\n", buffer); | |
} | |
if (platforms_n == 0) | |
return 1; | |
cl_device_id devices[100]; | |
cl_uint devices_n = 0; | |
// CL_CHECK(clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, 100, devices, &devices_n)); | |
CL_CHECK(clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_GPU, 100, devices, &devices_n)); | |
printf("=== %d OpenCL device(s) found on platform:\n", platforms_n); | |
for (int i=0; i<devices_n; i++) | |
{ | |
char buffer[10240]; | |
cl_uint buf_uint; | |
cl_ulong buf_ulong; | |
printf(" -- %d --\n", i); | |
CL_CHECK(clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(buffer), buffer, NULL)); | |
printf(" DEVICE_NAME = %s\n", buffer); | |
CL_CHECK(clGetDeviceInfo(devices[i], CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL)); | |
printf(" DEVICE_VENDOR = %s\n", buffer); | |
CL_CHECK(clGetDeviceInfo(devices[i], CL_DEVICE_VERSION, sizeof(buffer), buffer, NULL)); | |
printf(" DEVICE_VERSION = %s\n", buffer); | |
CL_CHECK(clGetDeviceInfo(devices[i], CL_DRIVER_VERSION, sizeof(buffer), buffer, NULL)); | |
printf(" DRIVER_VERSION = %s\n", buffer); | |
CL_CHECK(clGetDeviceInfo(devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(buf_uint), &buf_uint, NULL)); | |
printf(" DEVICE_MAX_COMPUTE_UNITS = %u\n", (unsigned int)buf_uint); | |
CL_CHECK(clGetDeviceInfo(devices[i], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(buf_uint), &buf_uint, NULL)); | |
printf(" DEVICE_MAX_CLOCK_FREQUENCY = %u\n", (unsigned int)buf_uint); | |
CL_CHECK(clGetDeviceInfo(devices[i], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(buf_ulong), &buf_ulong, NULL)); | |
printf(" DEVICE_GLOBAL_MEM_SIZE = %llu\n", (unsigned long long)buf_ulong); | |
} | |
if (devices_n == 0) | |
return 1; | |
cl_context context; | |
context = CL_CHECK_ERR(clCreateContext(NULL, 1, devices, &pfn_notify, NULL, &_err)); | |
const char *program_source[] = { | |
"__kernel void simple_demo(__global int *src, __global int *dst, int factor)\n", | |
"{\n", | |
"int i = get_global_id(0);\n", | |
"src[i] = src[i] * factor;\n", | |
"}\n" | |
}; | |
cl_program program; | |
program = CL_CHECK_ERR(clCreateProgramWithSource(context, sizeof(program_source)/sizeof(*program_source), program_source, NULL, &_err)); | |
if (clBuildProgram(program, 1, devices, "", NULL, NULL) != CL_SUCCESS) { | |
char buffer[10240]; | |
clGetProgramBuildInfo(program, devices[0], CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, NULL); | |
fprintf(stderr, "CL Compilation failed:\n%s", buffer); | |
abort(); | |
} | |
CL_CHECK(clUnloadCompiler()); | |
int* a = (int *)malloc (sizeof (int)*NUM_DATA); | |
int *c = (int*)malloc(sizeof (int)*NUM_DATA); | |
int i; | |
for (int i = 0; i < NUM_DATA; i++) | |
{ | |
a[i] = i; | |
c[i] = 0; | |
} | |
cl_mem input_buffer; | |
input_buffer = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(int)*NUM_DATA, a, &_err)); | |
cl_mem output_buffer; | |
output_buffer = CL_CHECK_ERR(clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, sizeof(int)*NUM_DATA, c, &_err)); | |
int factor = 2; | |
cl_kernel kernel; | |
kernel = CL_CHECK_ERR(clCreateKernel(program, "simple_demo", &_err)); | |
CL_CHECK(clSetKernelArg(kernel, 0, sizeof(input_buffer), &input_buffer)); | |
CL_CHECK(clSetKernelArg(kernel, 1, sizeof(output_buffer), &output_buffer)); | |
CL_CHECK(clSetKernelArg(kernel, 2, sizeof(factor), &factor)); | |
cl_command_queue queue; | |
queue = CL_CHECK_ERR(clCreateCommandQueue(context, devices[0], 0, &_err)); | |
int *input_map = (int *)CL_CHECK_ERR(clEnqueueMapBuffer(queue, input_buffer, CL_TRUE,CL_MAP_READ | CL_MAP_WRITE, 0, sizeof(int)*NUM_DATA, 0, NULL, NULL, &_err)); | |
clEnqueueUnmapMemObject (queue, input_buffer, input_map, 0, NULL, NULL); | |
cl_event kernel_completion; | |
size_t global_work_size[1] = { NUM_DATA }; | |
CL_CHECK(clEnqueueNDRangeKernel(queue, kernel, 1, NULL, global_work_size, NULL, 0, NULL, &kernel_completion)); | |
CL_CHECK(clWaitForEvents(1, &kernel_completion)); | |
CL_CHECK(clReleaseEvent(kernel_completion)); | |
input_map = (int *)CL_CHECK_ERR(clEnqueueMapBuffer(queue, input_buffer, CL_TRUE,CL_MAP_READ | CL_MAP_WRITE, 0, sizeof(int)*NUM_DATA, 0, NULL, NULL, &_err)); | |
clEnqueueUnmapMemObject(queue,input_buffer,input_map,0,NULL,NULL); | |
printf("Result:"); | |
for (int i=0; i<NUM_DATA; i++) { | |
int data; | |
//CL_CHECK(clEnqueueReadBuffer(queue, input_buffer, CL_TRUE, i*sizeof(int), sizeof(int), &a[i], 0, NULL, NULL)); | |
printf(" %d", a[i]); | |
} | |
printf("\n"); | |
clFinish (queue); | |
CL_CHECK(clReleaseMemObject(input_buffer)); | |
CL_CHECK(clReleaseMemObject(output_buffer)); | |
CL_CHECK(clReleaseKernel(kernel)); | |
CL_CHECK(clReleaseProgram(program)); | |
CL_CHECK(clReleaseContext(context)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment