2015-11-01 58 views
0

我的內核調用有問題。 我的代碼如下所示:內核不會等待事件

std::vector<cl::Event> events; 
... 

queue.enqueueWriteBuffer(arrayFirst, CL_FALSE, 0, sizeOfArray, NULL, NULL, &arrayEvent); 
events.push_back(arrayEvent); 

queue.enqueueWriteBuffer(arraySecond, CL_FALSE, 0, sizeOfArraySecond, this->arraySecond, NULL, &arraySecondEvent); 
events.push_back(arraySecondEvent); 

kernel(cl::EnqueueArgs(queue, events, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond); 

當我運行它,它不走內核代碼裏面,但是當我改變「make_kernel」調用此:

kernel(cl::EnqueueArgs(queue, arraySecondEvent, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond); 

它走了進去內核,但我沒有這樣的記憶「arrayFirst」正確分配擔保人,我檢查的OpenCL 1.2包裝的文檔,我發現應該是調用看起來是這樣的:

cl::EnqueueArgs::EnqueueArgs(CommandQueue &queue, 
const VECTOR_CLASS<Event> &events, NDRange offset, NDRange global, 
NDRange local) //page 42 

但是當我試圖通過一個活動載體,我得到的編譯錯誤,存在與下面的參數沒有合適的方法的地址..

錯誤:

error: no instance of constructor "cl::EnqueueArgs::EnqueueArgs" matches the argument list 
      argument types are: (cl::CommandQueue, std::vector<cl::Event, std::allocator<cl::Event>> *, cl::NDRange, cl::NDRange) 
       valueOfImageKernel(cl::EnqueueArgs(valueOfImageQueue, &events, cl::NDRange(512), cl::NDRange(128)), 

人有一個想法,我什麼做錯了?

+0

如何使用阻塞寫入(將CL_TRUE傳遞給enqueueWriteBuffer)? – doqtor

+0

我不想使用阻止寫入/讀取,因爲我關心運行時。 – MNie

+0

你的第一個代碼剪斷應該工作。 「它不在內核代碼中」是什麼意思?你怎麼知道?你有任何錯誤,等? – doqtor

回答

1

看來下面的線,你不需要是造成你的麻煩: queue.enqueueWriteBuffer(arrayFirst, CL_FALSE, 0, sizeOfArray, NULL, NULL, &arrayEvent); 需要調用寫緩衝區,當你確實有東西可寫有這是不是這裏的情況。

下面的完整工作示例,在PHI測試(只是省略清晰的錯誤處理):

#include <iostream> 
#include <vector> 
#include <string> 

#include <CL/cl.hpp> 

int main() 
{ 
    const char *kernel_str{ 
     "kernel void k1(global int *data1, global int *data2){" 
     " int local_id = get_local_id(0);" 
     " data1[local_id] = data2[local_id] + data2[local_id];" 
     "}" }; 

    cl_int err = CL_SUCCESS; 

    std::vector<cl::Platform> platforms; 
    cl::Platform::get(&platforms); 
    cl::Platform plat; 
    for (auto &p : platforms) 
    { 
     std::vector<cl::Device> devices; 
     p.getDevices(CL_DEVICE_TYPE_ACCELERATOR, &devices); 
     if (!devices.empty()) 
     { 
      plat = p; 
      break; 
     } 
    } 
    if (plat() == 0) 
    { 
     std::cout << "No OpenCL platform found."; 
     return -1; 
    } 

    cl_context_properties properties[] = 
    { CL_CONTEXT_PLATFORM, (cl_context_properties)(plat)(), 0 }; 
    cl::Context context(CL_DEVICE_TYPE_ACCELERATOR, properties); 

    std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>(); 

    cl::Program::Sources source(1, std::make_pair(kernel_str, strlen(kernel_str))); 
    cl::Program program = cl::Program(context, source); 
    err = program.build(devices); 

    cl::CommandQueue queue(context, devices[0], 0, &err); 

    size_t sizeOfArray = 512, sizeOfArraySecond = 512; 
    std::vector<int> varrayFirst(sizeOfArray); 
    std::vector<int> varraySecond(sizeOfArraySecond); 
    for (size_t x = 0; x < sizeOfArraySecond; ++x) 
     varraySecond[x] = x; 

    cl::Buffer arrayFirst(context, CL_MEM_WRITE_ONLY, sizeOfArray*sizeof(varrayFirst[0])); 
    cl::Buffer arraySecond(context, CL_MEM_READ_ONLY, sizeOfArraySecond*sizeof(varraySecond[0])); 

    cl::Event arraySecondEvent; 

    std::vector<cl::Event> events; 
    err = queue.enqueueWriteBuffer(arraySecond, CL_FALSE, 0, sizeOfArraySecond*sizeof(varraySecond[0]), &varraySecond[0], NULL, &arraySecondEvent); 
    events.push_back(arraySecondEvent); 

    cl::make_kernel<cl::Buffer&, cl::Buffer&> kernel(program, "k1"); 

    cl::Event ev = kernel(cl::EnqueueArgs(queue, events, cl::NDRange(512), cl::NDRange(128)), arrayFirst, arraySecond); 

    std::vector<cl::Event> evs(1, ev); 

    err = queue.enqueueReadBuffer(arrayFirst, CL_TRUE, 0, sizeOfArray*sizeof(varrayFirst[0]), &varrayFirst[0], &evs); // final blocking read 

    std::cout << "Outputting first 10 values: " << std::endl; 
    for (int x = 0; x < 10; ++x) 
     std::cout << varrayFirst[x] << ", "; 
    std::cout << std::endl; 

    return 0; 
} 

輸出:

Outputting first 10 values: 
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 
+0

是的這看起來這是一個問題,我刪除了所有隻應在內核上分配數據的enququwritebuffer,並且一切正常。當然,爲將來記住它很好:)謝謝你! – MNie

0

你的事件的集合是正確的,內核調用也正確。現在問題是......你確定內核被阻塞了嗎? 它可能只是在啓動緩慢。

我會檢查它與event.finish()內核事件。 你的應用程序發生死鎖,那麼這是事件的問題。

否則,它可能只是您的可執行文件在內核運行之前完成(因爲它正在等待第一個緩衝區副本,需要很長時間)。所以你不會看到任何日誌,因爲當內核printfs的應用程序已經清理。

此外,如果您可以添加事件的所有代碼,則可能對調試有用。由於我們沒有看到事件數組的完整生命週期。