2014-10-07 37 views
0

我想用Opencl做一個卷積圖像。設置主機和執行功能有什麼區別?

__kernel void convolution_read4(__global uchar *in1, __global uchar* in2, 
__constant float* mask, int height, int width, int kernelSize, 
__local float* lMem, int localHeight, int localWidth) 
{ 
    convolution(in1, in2, mask, height, width, kernelSize, lMem, localHeight, localWidth); 
    convolution(in2, in1, mask, height, width, kernelSize, lMem, localHeight, localWidth); 
    convolution(in1, in2, mask, height, width, kernelSize, lMem, localHeight, localWidth); 
} 

上面的代碼執行相同的功能3次。

err = kernel.setArg(0, d_inputImage); 
    err |= kernel.setArg(1, d_outputImage); 
    err |= kernel.setArg(2, d_filter); 
    err |= kernel.setArg(3, Height); 
    err |= kernel.setArg(4, Width);  
    err |= kernel.setArg(5, kernelSize); 
    err |= kernel.setArg(6, localSize, NULL); 
    err |= kernel.setArg(7, localHeight); 
    err |= kernel.setArg(8, localWidth);   

    int totalWorkItemX = roundUp(Width - paddingPixels, wgWidth); 
    int totalWorkItemY = roundUp(Height - paddingPixels , wgHeight); 

    cl::NDRange globalws(totalWorkItemX, totalWorkItemY); 
    cl::NDRange localws(wgWidth, wgHeight); 

    err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, 
     globalws, localws, NULL, NULL); 

    err = kernel.setArg(1, d_inputImage); 
    err |= kernel.setArg(0, d_outputImage); 
    err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, 
     globalws, localws, NULL, NULL); 

    err = kernel.setArg(0, d_inputImage); 
    err |= kernel.setArg(1, d_outputImage); 
    err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, 
     globalws, localws, NULL, NULL); 

    queue.finish(); 

該代碼也執行相同的函數「卷積」,但內核代碼被改變了。

__kernel void convolution_read4(__global uchar *in1, __global uchar* in2, 
    __constant float* mask, int height, int width, int kernelSize, 
    __local float* lMem, int localHeight, int localWidth) 
    { 
     convolution(in1, in2, mask, height, width, kernelSize, lMem, localHeight, localWidth);     
    } 

我認爲這兩個代碼是相同的代碼。但第一個代碼畫了一個錯誤的輸出。 我不知道這兩者有什麼區別。

回答

2

您的convolution函數可能會從全局內存中獲取整個輸入圖像,並在全局內存中生成整個輸出圖像。在單個內核調用中調用此函數三次與從三次單獨的內核調用中調用一次函數的區別在於,通過一個工作項寫入全局內存對同一內核調用中的其他工作項不可見。這意味着在第一個示例中第二次調用convolution期間,工作項目將讀取陳舊值,而不會看到第一次調用此函數的輸出。

OpenCL不提供任何方法來在整個內核調用中同步全局內存。您可以使用barrier函數同步工作組中的內存,這可能允許您在單個內核調用中實現算法,並進行一些修改。

相關問題