view example/OpenCL/twice.cc @ 1786:ba6ffc679a8f draft

minor fix
author Masataka Kohagura <e085726@ie.u-ryukyu.ac.jp>
date Sat, 30 Nov 2013 21:06:44 +0900
parents 2983e9e93d24
children a68dbdf9b429
line wrap: on
line source

#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 = 0;
    cl_device_id device_id = NULL;
    cl_uint ret_num_devices = 0L;
    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);

    //ファイルオープン

    const char* filename = "twice.cl";
    const char* functionname = "twice";

    int 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");
    }

    char *kernel_src_str = new char[size];
    size_t kernel_code_size = read(fp, kernel_src_str, size);
    close(fp);

    cl_program program = clCreateProgramWithSource(context, 1, (const char **)&kernel_src_str,
                                                   (const size_t *)&kernel_code_size, &ret);
    clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
    cl_kernel kernel = clCreateKernel(program,functionname, &ret);

    int *data = new int[task_array_num];
    int *output_data = new int[task_array_num];

    int count = 0;
    for (int c = 0; c < task_array_num ; count++,c++){
        data[c] = c;
    }

    //メモリバッファの作成
    cl_mem data_count = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(int)*count, NULL, &ret);
    cl_mem memobj_in = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(int)*count, NULL, &ret);
    cl_mem memobj_out = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(int)*count, NULL, &ret);


    //メモリバッファに入力データを書き込み
    ret = clEnqueueWriteBuffer(command_queue, data_count, CL_TRUE, 0,
                               sizeof(count), &count, 0, NULL, NULL);

    ret = clEnqueueWriteBuffer(command_queue, memobj_in, CL_TRUE, 0,
                               sizeof(int)*count, data, 0, NULL, NULL);

    print_data(data, count, "before");

    clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&data_count);
    clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&memobj_in);
    clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&memobj_out);


    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");

    clReleaseKernel(kernel);
    clReleaseProgram(program);
    clReleaseMemObject(data_count);
    clReleaseMemObject(memobj_in);
    clReleaseMemObject(memobj_out);
    clReleaseCommandQueue(command_queue);
    clReleaseContext(context);

    delete [] kernel_src_str;
    delete [] data;
    delete [] output_data;

    return 0;
}