Mercurial > hg > Game > Cerium
changeset 1455:2b886dcc0e7d draft
add OpenCL example
author | Yuhi TOMARI <yuhi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 May 2012 18:40:10 +0900 |
parents | 5b79077e4e1f |
children | 5533106cc437 |
files | TaskManager/Gpu/GpuScheduler.cc TaskManager/test/GpuRegistTaskTest/GpuRegistTaskTest.cc TaskManager/test/GpuRegistTaskTest/GpuRegistTaskTest.cc.orig TaskManager/test/GpuRegistTaskTest/Makefile.orig example/OpenCL/Makefile example/OpenCL/twice example/OpenCL/twice.cc example/OpenCL/twice.cc~ example/OpenCL/twice.cl example/OpenCL/twice.o |
diffstat | 10 files changed, 418 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/TaskManager/Gpu/GpuScheduler.cc Sun Apr 29 19:21:26 2012 +0900 +++ b/TaskManager/Gpu/GpuScheduler.cc Tue May 08 18:40:10 2012 +0900 @@ -19,7 +19,7 @@ // Get OpenCL infomation GpuThreads* gputhreads = GpuThreads::getInstance(); - cl_context& context = gputhreads->context; + cl_context context = gputhreads->context; cl_command_queue command_queue = gputhreads->command_queue; cl_int ret; @@ -33,10 +33,11 @@ for (int cur_index = 0; cur_index < tasklist->length; cur_index++) { SimpleTaskPtr nextTask = &tasklist->tasks[cur_index]; cl_kernel& kernel = *task_list[nextTask->command].kernel; - + if ( nextTask->r_size != 0 ) { cl_mem memobj = clCreateBuffer(context, CL_MEM_READ_WRITE, nextTask->r_size, NULL, &ret); clEnqueueWriteBuffer(command_queue, memobj, CL_TRUE, 0, nextTask->r_size, nextTask->rbuf, 0, NULL, NULL); + //clSetKernleArg(kernel, cur_index,); } // カーネル引数の設定 @@ -56,10 +57,10 @@ gpu_register_task(int cmd, const char* filename, const char* functionname) { GpuThreads* gputhreads = GpuThreads::getInstance(); - // gputhreads->init(); + //gputhreads->init(); cl_context context = gputhreads->context; cl_device_id device_id = gputhreads->device_id; - + int fp; char *source_str; size_t source_size; @@ -81,15 +82,13 @@ } source_str = (char*)malloc(size); - source_size = read(fp, source_str, size); close(fp); cl_program program = NULL; - cl_int ret; + cl_int ret = gputhreads->ret; program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret); - clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); cl_kernel *kernel = new cl_kernel; @@ -100,5 +99,6 @@ task_list[cmd].wait = NULL; task_list[cmd].name = functionname; task_list[cmd].kernel = kernel; + GpuScheduler::run(); }
--- a/TaskManager/test/GpuRegistTaskTest/GpuRegistTaskTest.cc Sun Apr 29 19:21:26 2012 +0900 +++ b/TaskManager/test/GpuRegistTaskTest/GpuRegistTaskTest.cc Tue May 08 18:40:10 2012 +0900 @@ -23,60 +23,52 @@ //チェック int check = 0; - for (int c=0; c<num; c++){ - if(outdata[c] == indata[c]*2){ - // printf("outdata:%d indata:%d\n\n",outdata[c],indata[c]); + for (int c=0; c<num; c++) { + if(outdata[c] == indata[c]*2) { check++; - }else { - printf("\n\n incorrect number! outdata[%d]:%d indata[%d]:%d\n\n",c,outdata[c],c,indata[c]); } } + printf("Computed '%d/%d' correct values\n",check,num); + } void test(int task_array_num){ - int cmd = 1; GpuThreads* gputhreads = GpuThreads::getInstance(); gputhreads->init(); + + int cmd = 1; GpuSchedRegister(cmd, "twice.cl", "twice"); - cl_platform_id platform_id = NULL; - cl_uint ret_num_platforms = NULL; - cl_device_id device_id = NULL; - cl_uint ret_num_devices = NULL; - cl_int ret; - clGetPlatformIDs(1, &platform_id, &ret_num_platforms); - clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, - &ret_num_devices); - cl_context context = gputhreads->context; - - cl_command_queue command_queue = gputhreads->command_queue; - - int *indata,*outdata; - indata = new int[task_array_num]; - outdata = new int[task_array_num]; + + int *indata = new int[task_array_num]; + int *outdata = new int[task_array_num]; int count; for (count=0; count < task_array_num ;count++) { indata[count] = count; } + print_data(indata, count, "before"); + + cl_int ret = gputhreads->ret; + cl_context context = gputhreads->context; cl_mem memobj_in = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); cl_mem memobj_out = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); cl_mem data_count = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + cl_command_queue command_queue = gputhreads->command_queue; ret = clEnqueueWriteBuffer(command_queue, memobj_in, CL_TRUE, 0, sizeof(int)*count, indata, 0, NULL, NULL); ret = clEnqueueWriteBuffer(command_queue, data_count, CL_TRUE, 0, sizeof(count), &count, 0, NULL, NULL); - - print_data(indata, count, "before"); - - cl_kernel kernel = NULL; - kernel= *(task_list[cmd].kernel); - + + cl_kernel kernel = *(task_list[cmd].kernel); + clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobj_in); + + clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&memobj_out); clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&data_count); @@ -87,7 +79,6 @@ sizeof(int)*count, outdata, 1, &ev, NULL); print_data(outdata, count, "after"); - tester(indata,outdata,count); delete [] indata; @@ -103,11 +94,12 @@ main(int argc, char* argv[]) { int task_array_num = DEFAULT; - if (argc > 1){ - if(atoi(argv[1])){ + + if (argc > 1) { //引数が渡されていて、 + if(atoi(argv[1])) {//数字なら task_array_num = atoi(argv[1]); } } test(task_array_num); - printf("regist task succeed\n"); + return 0; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/test/GpuRegistTaskTest/GpuRegistTaskTest.cc.orig Tue May 08 18:40:10 2012 +0900 @@ -0,0 +1,101 @@ +#include <stdio.h> +#include <OpenCL/opencl.h> +#include "GpuThreads.h" +#include "GpuScheduler.h" +#include "CellTaskManagerImpl.h" + +#define DEFAULT 5 +extern void gpu_register_task(int, char*, char*); + +void +print_data(int *data, int size, const char *title){ + printf("%s ---\n", title); + + for ( int i = 0; i < size; i++) { + printf("%2d ", data[i]); + } + + printf("\n"); +} + +void +tester(int *indata,int *outdata, int num){ + //チェック + int check; + for (int c=0; c<num; c++){ + if(outdata[c] == indata[c]*2){ + check++; + } + printf("Computed '%d/%d' correct values\n",check,num); + } +} + +void +test(int task_array_num){ + + GpuThreads* gpuThreads = GpuThreads::getInstance(); + gpuThreads->init(); + + int *indata,*outdata; + int count; + indata = (int *)malloc(sizeof(int)*task_array_num); + outdata = (int *)malloc(sizeof(int)*task_array_num); + for (count=0; count < task_array_num ;count++) { + indata[count] = count; + } + printf("%d",count); + + GpuSchedRegister(1,"./twice.cl","Twice"); + + + cl_int ret; + cl_context context = gpuThreads->context; + cl_mem memobj_in, memobj_out, data_count = NULL; + memobj_in = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + memobj_out = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + data_count = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + + cl_command_queue command_queue = gpuThreads->command_queue; + ret = clEnqueueWriteBuffer(command_queue, memobj_in, CL_TRUE, 0, + sizeof(int)*count, indata, 0, NULL, NULL); + ret = clEnqueueWriteBuffer(command_queue, data_count, CL_TRUE, 0, + sizeof(count), &count, 0, NULL, NULL); + + print_data(indata, count, "before"); + + + cl_kernel *kernel = task_list[1].kernel; + clSetKernelArg(*kernel, 0, sizeof(cl_mem), (void *)&memobj_in); + clSetKernelArg(*kernel, 1, sizeof(cl_mem), (void *)&memobj_out); + clSetKernelArg(*kernel, 2, sizeof(cl_mem), (void *)&data_count); + + cl_event ev; + clEnqueueTask(command_queue, *kernel, 0, NULL, &ev); + + clEnqueueReadBuffer(command_queue, memobj_out, CL_TRUE, 0, + sizeof(int)*count, outdata, 1, &ev, NULL); + + + print_data(outdata, count, "after"); + + free(indata); + free(outdata); + clReleaseCommandQueue(command_queue); + clReleaseContext(context); + + tester(indata,outdata,count); + + delete gpuThreads; +} + +int +main(int argc, char* argv[]) +{ + int task_array_num; + if ( ((task_array_num = atoi(argv[1])) == 0) || argc != 1 ){ + // 無効な引数ならデフォルトの値として5を設定 + task_array_num = DEFAULT; + } + test(task_array_num); + printf("regist task succeed\n"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/test/GpuRegistTaskTest/Makefile.orig Tue May 08 18:40:10 2012 +0900 @@ -0,0 +1,15 @@ +include ../../Makefile.def + +CPPFLAGS += -g -Wall -I../../../include/TaskManager -m$(ABIBIT) + +TARGET= GpuRegistTaskTest -framework opencl + +$(TARGET) : + +LIBS += ../../libGpuManager.a + +CpuRegistTaskTest : GpuRegistTaskTest.o + $(CC) $(CFLAGS) -o $@ $? $(LIBS) + +clean: + rm -rf *.o $(TARGET)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/OpenCL/Makefile Tue May 08 18:40:10 2012 +0900 @@ -0,0 +1,11 @@ +CFLAGS = -g -Wall -framework opencl +CC = g++ +OPT = -g + +TARGET=twice + +twice : twice.o + $(CC) $(OPT) $(CFLAGS) -o $@ $? + +clean: + rm -rf *.o $(TARGET)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/OpenCL/twice.cc Tue May 08 18:40:10 2012 +0900 @@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <OpenCL/opencl.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/stat.h> + +#define DEFAULT 432 + +void +print_data(int *data, int size, const char *title) +{ + printf("%s ---\n", title); + for ( int i = 0; i < size; i++) { + printf("%2d ", data[i]); + } + printf("\n"); +} + +int main(int argc, char *argv[]) { + + // 無効な引数ならデフォルトの値として432を設定 + int task_array_num = DEFAULT; + + if (argc>1) { + if (atoi(argv[1])) { + task_array_num = atoi(argv[1]); + } + } + + cl_platform_id platform_id = NULL; + cl_uint ret_num_platforms = NULL; + cl_device_id device_id = NULL; + cl_uint ret_num_devices = NULL; + cl_int ret; + + clGetPlatformIDs(1, &platform_id, &ret_num_platforms); + clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, + &ret_num_devices); + + cl_context context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret); + cl_command_queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret); + + //ファイルオープン + int fp; + char *kernel_src_str; + size_t kernel_code_size; + const char* filename = "twice.cl"; + const char* functionname = "twice"; + + fp = open(filename, O_RDONLY); + + if (!fp) { + fprintf(stderr, "Failed to load kernel.\n"); + exit(1); + } + + struct stat stats; + fstat(fp,&stats); + off_t size = stats.st_size; + + if (!size) { + fprintf(stderr, "Failed to load kernel.\n"); + } + + kernel_src_str = (char*)malloc(size); + + kernel_code_size = read(fp, kernel_src_str, size); + close(fp); + + + + cl_program program = NULL; + cl_kernel kernel = NULL; + program = clCreateProgramWithSource(context, 1, (const char **)&kernel_src_str, + (const size_t *)&kernel_code_size, &ret); + clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); + kernel = clCreateKernel(program,functionname, &ret); + + int *data,*output_data; + data = (int *)malloc(sizeof(int)*task_array_num); + output_data = (int *)malloc(sizeof(int)*task_array_num); + + int count = 0; + for (int c = 0; c < task_array_num ; count++,c++){ + data[c] = c; + } + + cl_mem memobj_in, memobj_out, data_count = NULL; + //メモリバッファの作成 + memobj_in = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + memobj_out = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + data_count = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + + //メモリバッファに入力データを書き込み + ret = clEnqueueWriteBuffer(command_queue, memobj_in, CL_TRUE, 0, + sizeof(int)*count, data, 0, NULL, NULL); + ret = clEnqueueWriteBuffer(command_queue, data_count, CL_TRUE, 0, + sizeof(count), &count, 0, NULL, NULL); + + print_data(data, count, "before"); + + clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobj_in); + clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&memobj_out); + clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&data_count); + + cl_event ev = NULL; + ret = clEnqueueTask(command_queue, kernel, 0, NULL, &ev); + + //メモリバッファから結果を取得 + ret = clEnqueueReadBuffer(command_queue, memobj_out, CL_TRUE, 0, + sizeof(int)*count, output_data, 1, &ev, NULL); + + print_data(output_data, count, "after"); + + free(data); + free(output_data); + clReleaseKernel(kernel); + clReleaseProgram(program); + clReleaseCommandQueue(command_queue); + clReleaseContext(context); + + free(kernel_src_str); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/OpenCL/twice.cc~ Tue May 08 18:40:10 2012 +0900 @@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <OpenCL/opencl.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/stat.h> + +#define DEFAULT 432 + +void +print_data(int *data, int size, const char *title) +{ + printf("%s ---\n", title); + for ( int i = 0; i < size; i++) { + printf("%2d ", data[i]); + } + printf("\n"); +} + +int main(int argc, char *argv[]) { + + // 無効な引数ならデフォルトの値として432を設定 + int task_array_num = DEFAULT; + + if (argc>1) { + if (atoi(argv[1])) { + task_array_num = atoi(argv[1]); + } + } + + cl_platform_id platform_id = NULL; + cl_uint ret_num_platforms = NULL; + cl_device_id device_id = NULL; + cl_uint ret_num_devices = NULL; + cl_int ret; + + clGetPlatformIDs(1, &platform_id, &ret_num_platforms); + clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, + &ret_num_devices); + + cl_context context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret); + cl_command_queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret); + + //ファイルオープン + int fp; + char *kernel_src_str; + size_t kernel_code_size; + const char* filename = "twice.cl"; + const char* functionname = "twice"; + + fp = open(filename, O_RDONLY); + + if (!fp) { + fprintf(stderr, "Failed to load kernel.\n"); + exit(1); + } + + struct stat stats; + fstat(fp,&stats); + off_t size = stats.st_size; + + if (!size) { + fprintf(stderr, "Failed to load kernel.\n"); + } + + kernel_src_str = (char*)malloc(size); + + kernel_code_size = read(fp, kernel_src_str, size); + close(fp); + + + + cl_program program = NULL; + cl_kernel kernel = NULL; + program = clCreateProgramWithSource(context, 1, (const char **)&kernel_src_str, + (const size_t *)&kernel_code_size, &ret); + clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); + kernel = clCreateKernel(program,functionname, &ret); + + int *data,*output_data; + data = (int *)malloc(sizeof(int)*task_array_num); + output_data = (int *)malloc(sizeof(int)*task_array_num); + + int count = 0; + for (int c = 0; c < task_array_num ; count++,c++){ + data[c] = c; + } + + cl_mem memobj_in, memobj_out, data_count = NULL; + //メモリバッファの作成 + memobj_in = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + memobj_out = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + data_count = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int)*count, NULL, &ret); + + //メモリバッファに入力データを書き込み + ret = clEnqueueWriteBuffer(command_queue, memobj_in, CL_TRUE, 0, + sizeof(int)*count, data, 0, NULL, NULL); + ret = clEnqueueWriteBuffer(command_queue, data_count, CL_TRUE, 0, + sizeof(count), &count, 0, NULL, NULL); + + print_data(data, count, "before"); + + clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&memobj_in); + clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&memobj_out); + clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&data_count); + + cl_event ev = NULL; + ret = clEnqueueTask(command_queue, kernel, 0, NULL, &ev); + + //メモリバッファから結果を取得 + ret = clEnqueueReadBuffer(command_queue, memobj_out, CL_TRUE, 0, + sizeof(int)*count, output_data, 1, &ev, NULL); + + print_data(output_data, count, "after"); + + free(data); + free(output_data); + clReleaseKernel(kernel); + clReleaseProgram(program); + clReleaseCommandQueue(command_queue); + clReleaseContext(context); + + free(kernel_src_str); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/OpenCL/twice.cl Tue May 08 18:40:10 2012 +0900 @@ -0,0 +1,11 @@ +__kernel void +twice(__global int *input_data, + __global int *output_data, + __global int *data_count) +{ + int count = *data_count; + for (int i = 0; i<count; i++) { + output_data[i] = input_data[i] * 2; + } + +} \ No newline at end of file