view TaskManager/Gpu/GpuScheduler.cc @ 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 55f92ed3f244
line wrap: on
line source

#include "GpuScheduler.h"
#include "ReferencedDmaManager.h"
#include "GpuThreads.h"
#include "stdio.h"
#include <fcntl.h>
#include <sys/stat.h>

void
GpuScheduler::init_impl(int useRefDma)
{
    fifoDmaManager = new ReferencedDmaManager();
    connector = fifoDmaManager;
}

void
GpuScheduler::run()
{
    memaddr params_addr = connector->task_list_mail_read();

    // Get OpenCL infomation
    GpuThreads* gputhreads = GpuThreads::getInstance();
    cl_context context = gputhreads->context;
    cl_command_queue command_queue = gputhreads->command_queue;
    cl_int ret;

    if ((memaddr)params_addr == (memaddr)MY_SPE_COMMAND_EXIT) {
        clFinish(command_queue);
    }

    TaskListPtr tasklist = (TaskListPtr)connector->dma_load(this, params_addr, 
                                         sizeof(TaskList), DMA_READ_TASKLIST);

    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,);
        }
        // カーネル引数の設定
        
        clEnqueueTask(command_queue, kernel, 0, NULL, NULL);
        
        if ( nextTask->w_size != 0 ) {
            cl_mem memobj = clCreateBuffer(context, CL_MEM_READ_WRITE, nextTask->w_size, NULL, &ret);
            clEnqueueWriteBuffer(command_queue, memobj, CL_TRUE, 0, nextTask->w_size, nextTask->wbuf, 0, NULL, NULL);
        }
    }
    // TaskArrayの処理
}



void
gpu_register_task(int cmd, const char* filename, const char* functionname)
{
    GpuThreads* gputhreads = GpuThreads::getInstance();
    //gputhreads->init();
    cl_context context = gputhreads->context;
    cl_device_id device_id = gputhreads->device_id;
    
    int fp;
    char *source_str;
    size_t source_size;
    
    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");
        exit(1);
    }
    
    source_str = (char*)malloc(size);
    source_size = read(fp, source_str, size);
    close(fp);

    cl_program program = NULL;
    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; 
    *kernel = clCreateKernel(program, functionname, &ret);
     
    task_list[cmd].run = NULL;
    task_list[cmd].load = NULL;
    task_list[cmd].wait = NULL;
    task_list[cmd].name = functionname;
    task_list[cmd].kernel = kernel;
    GpuScheduler::run();

}