OpenCL clSetEventCallback error - PullRequest
       18

OpenCL clSetEventCallback error

0 голосов
/ 27 февраля 2012

Greatings,

При использовании OpenCL я столкнулся со странным поведением.

main.cpp:

...
Future* future;
for(int k = 0; k < NUMITERATIONS; k++){
    future = execute(arguments);
    while(!future->isReady()){
        cout << future->isReady() << "\n";
        Sleep(500);
    }
    // get the data
    ...
    // ouput results
    ...
    // free resources
    ...
}

Предыдущий код выполняется хостом и цикломзаключается в том, чтобы гарантировать, что он продвигается только после того, как данные готовы.

код выполнения:

IFuture* execute(Argument* arguments[]){
    //inicialize OpenCL data
        ...
    //execute kernel on an a platform wrapper(mine) 
    cl_event event = exec->execute(inputBuffers,outputBuffers);
    void** outputData = (void**) malloc(sizeof(void*)*numOutputEntries);
    IFuture* future = new Future();
    //prepare a struct for callback
    callbackArgs* args = (callbackArgs*) malloc(sizeof(callbackArgs));
    args->outputBuffers = outputBuffers;
    args->inputBuffers = inputBuffers;
    args->future = future;
    args->numOutputEntries = numOutputEntries;
    args->numInputEntries =  numInputEntries;
    args->outputMemSizes = outputMemSizes;
    args->outputData = outputData;
    args->queue = queue;
    args->parser = parser;
    //set callback
    errcode = clSetEventCallback (event, CL_COMPLETE, &execComplete, args);
    //free resources
        ...
    return future;
}

Этот метод ставит в очередь выполнение и готовит функцию обратного вызова.Поскольку функция this является функцией-членом объекта, она должна быть объявлена ​​статической для OpenCL, чтобы принять ее в качестве функции обратного вызова.Поэтому для передачи ему данных нестатического члена я создаю структуру, заполненную указателем на необходимые данные, и передаю указатель на эту структуру в функцию API OpenCL.

обратный вызов завершения выполнения:

void CL_CALLBACK execComplete(cl_event ev, cl_int event_status, void* user_data){
    int i, errcode = 0;
    callbackArgs* args = (callbackArgs*) user_data;
    cl_event event;
    // read data from device memory
        for(...){
        ...
        if(last enqueue)
            errcode = clEnqueueReadBuffer(args->queue, args->outputBuffers[i], CL_FALSE, 0, someSize, args->outputData[i], 0, NULL, &event);
        else
            errcode = clEnqueueReadBuffer(args->queue, args->outputBuffers[i], CL_FALSE, 0, someSize, args->outputData[i], 0, NULL, NULL);
        }
    errcode = clSetEventCallback(event, CL_COMPLETE, &readComplete, user_data);
    clFlush(args->queue);
}

Эта функция ставит в очередь асинхронные чтения из памяти.Эти чтения взаимодействуют с данными внутри структуры.Затем команды сбрасываются и регистрируется новый обратный вызов.

устанавливает обратный вызов результатов:

void CL_CALLBACK readComplete(cl_event ev, cl_int event_status, void* user_data){
    callbackArgs* args = (callbackArgs*) user_data;
    args->future->setData(args->outputData);
    // release resources
        ...
}

Этот обратный вызов просто делает доступными данные.Функция future-> setData переводит будущий объект в состояние готовности, поэтому исходный активный цикл ожидания будет продолжен.Однако ценности, которые исполняют сторонние свидетели, никогда не меняются.

Я распечатал значения внутри и снаружи последней функции обратного вызова, и адрес объекта Future везде одинаков.Но его значения изменяются только внутри обратного вызова readComplete, приводя цикл в бесконечное состояние.

Надеюсь, я прояснил свою проблему.Заранее спасибо за ваши ответы.

...