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)
Binary file example/OpenCL/twice has changed
--- /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
Binary file example/OpenCL/twice.o has changed