view twice.cc @ 0:4d6463c84338

Twice example on OpenCL
author Yuuhi TOMARI <yuhi@cr.ie.u-ryukyu.ac.jp>
date Wed, 11 Apr 2012 20:59:20 +0900
parents
children
line wrap: on
line source

#include <stdlib.h>
#include <OpenCL/opencl.h>
#include <stdio.h>

#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;
}