# HG changeset patch # User Yuuhi TOMARI # Date 1334145560 -32400 # Node ID 4d6463c84338bbdb5b75d81255249c492875890f Twice example on OpenCL diff -r 000000000000 -r 4d6463c84338 twice.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/twice.cc Wed Apr 11 20:59:20 2012 +0900 @@ -0,0 +1,98 @@ +#include +#include +#include + +#define MAX_SOURCE_SIZE (0x100000) +#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[]) { + + cl_platform_id platform_id = NULL; + cl_uint ret_num_platforms; + cl_device_id device_id = NULL; + cl_uint ret_num_devices; + cl_context context = NULL; + cl_command_queue command_queue = NULL; + cl_mem memobj_in, memobj_out, data_count = NULL; + cl_program program = NULL; + cl_kernel kernel = NULL; + size_t kernel_code_size; + char *kernel_src_str; + cl_int ret; + FILE *fp; + cl_event ev; + + clGetPlatformIDs(1, &platform_id, &ret_num_platforms); + clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, + &ret_num_devices); + context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret); + + command_queue = clCreateCommandQueue(context, device_id, 0, &ret); + fp = fopen("twice.cl", "r"); + kernel_src_str = (char*)malloc(MAX_SOURCE_SIZE); + kernel_code_size = fread(kernel_src_str, 1, MAX_SOURCE_SIZE, fp); + fclose(fp); + + program = clCreateProgramWithSource(context, 1, (const char **)&kernel_src_str, + (const size_t *)&kernel_code_size, &ret); + clBuildProgram(program, 1, &device_id, "", NULL, NULL); + kernel = clCreateKernel(program, "twice", &ret); + + int task_array_num; + if ( ((task_array_num = atoi(argv[1])) == 0) || argc != 1 ){ + // 無効な引数ならデフォルトの値として432を設定 + task_array_num = DEFAULT; + } + + int count,*data,*output_data; + data = (int *)malloc(sizeof(int)*task_array_num); + output_data = (int *)malloc(sizeof(int)*task_array_num); + + for (count = 0; count < task_array_num ; count++){ + data[count] = count; + } + + //メモリバッファの作成 + 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); + 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; +} diff -r 000000000000 -r 4d6463c84338 twice.cl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/twice.cl Wed Apr 11 20:59:20 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