Skip to content

Instantly share code, notes, and snippets.

@fltermare
Last active August 29, 2015 13:57
Show Gist options
  • Save fltermare/9449806 to your computer and use it in GitHub Desktop.
Save fltermare/9449806 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
#define MAX_SOURCE_SIZE (0x100000)
struct node {
int value;
node* next;
};
int main(void) {
int i;
const int LIST_SIZE = 1024;
// Load the kernel source code into the array source_str
FILE *fp;
char *source_str;
size_t source_size;
fp = fopen("kernel.cl", "r");
if (!fp) {
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
source_str = (char*)malloc(MAX_SOURCE_SIZE);
source_size = fread( source_str, 1, MAX_SOURCE_SIZE, fp);
fclose( fp );
// Get platform and device information
cl_platform_id platform_id = NULL;
cl_device_id device_id = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_ALL, 1, &device_id, &ret_num_devices);
// Create an OpenCL context
cl_context context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);
// Create a command queue
cl_command_queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
// Create memory buffers on the device for each vector
node **a = (node**)clSVMAlloc(context, CL_MEM_READ_ONLY,
LIST_SIZE*sizeof(node), NULL, 0);
node **b = (node**)clSVMAlloc(context, CL_MEM_READ_ONLY,
LIST_SIZE*sizeof(node), NULL, 0);
node **c = (node**)clSVMAlloc(context, CL_MEM_WRITE_ONLY,
LIST_SIZE*sizeof(node), NULL, 0);
for (int i = 0; i < LIST_SIZE; ++i) {
a[i] = (node*)clSVMAlloc(context, CL_MEM_WRITE_ONLY,
sizeof(node), NULL, 0);
b[i] = (node*)clSVMAlloc(context, CL_MEM_WRITE_ONLY,
sizeof(node), NULL, 0);
c[i] = (node*)clSVMAlloc(context, CL_MEM_WRITE_ONLY,
sizeof(node), NULL, 0);
a[i]->next = (node*)clSVMAlloc(context, CL_MEM_WRITE_ONLY,
sizeof(node), NULL, 0);
b[i]->next = (node*)clSVMAlloc(context, CL_MEM_WRITE_ONLY,
sizeof(node), NULL, 0);
c[i]->next = (node*)clSVMAlloc(context, CL_MEM_WRITE_ONLY,
sizeof(node), NULL, 0);
a[i]->next->next = (node*)clSVMAlloc(context, CL_MEM_READ_ONLY,
sizeof(node), NULL, 0);
b[i]->next->next = (node*)clSVMAlloc(context, CL_MEM_READ_ONLY,
sizeof(node), NULL, 0);
c[i]->next->next = (node*)clSVMAlloc(context, CL_MEM_WRITE_ONLY,
sizeof(node), NULL, 0);
}
// XXX: SVMmap Page 173
for (int i = 0; i < LIST_SIZE; ++i) {
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, a[i], sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, a[i]->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, a[i]->next->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, b[i], sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, b[i]->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, b[i]->next->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_WRITE, c[i], sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_WRITE, c[i]->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_WRITE, c[i]->next->next, sizeof(node),
0, NULL, NULL);
}
for(int i = 0; i < LIST_SIZE; ++i) {
a[i]->value = LIST_SIZE-3;
a[i]->next->value = LIST_SIZE-2;
a[i]->next->next->value = LIST_SIZE-1;
b[i]->value = 3;
b[i]->next->value = 2;
b[i]->next->next->value = 1;
c[i]->value = 0;
c[i]->next->value = 0;
c[i]->next->next->value = 0;
}
// : svmunmap
for (int i = 0; i < LIST_SIZE; ++i) {
clEnqueueSVMUnmap(command_queue, a[i],
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, a[i]->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, a[i]->next->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, b[i],
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, b[i]->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, b[i]->next->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, c[i],
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, c[i]->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, c[i]->next->next,
0, NULL, NULL);
}
// Copy the lists A and B to their respective memory buffers
// Create a program from the kernel source
cl_program program = clCreateProgramWithSource(context, 1,
(const char **)&source_str, (const size_t *)&source_size, &ret);
// Build the program
ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
// Create the OpenCL kernel
cl_kernel kernel = clCreateKernel(program, "vector_add", &ret);
// Set the arguments of the kernel
ret = clSetKernelArgSVMPointer(kernel, 0, (void *)a);
ret = clSetKernelArgSVMPointer(kernel, 1, (void *)b);
ret = clSetKernelArgSVMPointer(kernel, 2, (void *)c);
void *ptr_arr[];
for (int i = 0; i < LIST_SIZE; i++) {
ptr_arr[0+i*9] = a[i];
ptr_arr[1+i*9] = b[i];
ptr_arr[2+i*9] = c[i];
ptr_arr[3+i*9] = a[i]->next;
ptr_arr[4+i*9] = a[i]->next->next;
ptr_arr[5+i*9] = b[i]->next;
ptr_arr[6+i*9] = b[i]->next->next;
ptr_arr[7+i*9] = c[i]->next;
ptr_arr[8+i*9] = c[i]->next->next;
}
// : set kern arg exec info ???:value? Page:214
ret = clSetKernelExecInfo(kernel, CL_KERNEL_EXEC_INFO_SVM_PTRS,
9*LIST_SIZE*sizeof(void *), ptr_arr);
// XXX: flatten, move data from our pool to buffer
// XXX: kernel rewriting
// Execute the OpenCL kernel on the list
size_t global_item_size = LIST_SIZE; // Process the entire lists
size_t local_item_size = 64; // Process in groups of 64
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
&global_item_size, &local_item_size, 0, NULL, NULL);
// : svnmap
for(int i = 0; i < LIST_SIZE; i++) {
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, a[i], sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, a[i]->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, a[i]->next->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, b[i], sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, b[i]->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_READ, b[i]->next->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_WRITE, c[i], sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_WRITE, c[i]->next, sizeof(node),
0, NULL, NULL);
clEnqueueSVMMap(command_queue, CL_TRUE,
CL_MAP_WRITE, c[i]->next->next, sizeof(node),
0, NULL, NULL);
}
// Display the result to the screen
for (int i = 0; i < LIST_SIZE = 3; ++i) {
printf("%d + %d = %d\n", a[i]->value, b[i]->value, c[i]->value);
printf("%d + %d = %d\n", a[i]->next->value, b[i]->next->value, c[i]->next->value);
printf("%d + %d = %d\n", a[i]->next->next->value, b[i]->next->next->value, c[i]->next->next->value);
}
// : svmunmap
for (int i = 0; i < LIST_SIZE; ++i) {
clEnqueueSVMUnmap(command_queue, a[i],
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, a[i]->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, a[i]->next->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, b[i],
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, b[i]->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, b[i]->next->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, c[i],
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, c[i]->next,
0, NULL, NULL);
clEnqueueSVMUnmap(command_queue, c[i]->next->next,
0, NULL, NULL);
}
// Clean up
ret = clFlush(command_queue);
ret = clFinish(command_queue);
ret = clReleaseKernel(kernel);
ret = clReleaseProgram(program);
for (int i = 0; i < LIST_SIZE; i++){
ret = clSVMFree(context, a[i]->next->next);
ret = clSVMFree(context, b[i]->next->next);
ret = clSVMFree(context, c[i]->next->next);
ret = clSVMFree(context, a[i]->next);
ret = clSVMFree(context, b[i]->next);
ret = clSVMFree(context, c[i]->next);
ret = clSVMFree(context, a[i]);
ret = clSVMFree(context, b[i]);
ret = clSVMFree(context, c[i]);
}
ret = clSVMFree(context, a);
ret = clSVMFree(context, b);
ret = clSVMFree(context, c);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment