设置主机和执行功能有什么区别?

时间:2014-10-07 13:53:00

标签: c++ opencl

我正在尝试使用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();

这段代码也执行相同的功能“Convolution”,但内核代码却是这样改变的。

__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);                  
    }

我认为这两个代码是相同的代码。但第一个代码输出错误。 我不知道这两者有什么区别。

1 个答案:

答案 0 :(得分:2)

您的convolution函数可能会从全局内存中获取整个输入图像,并在全局内存中生成整个输出图像。在单个内核调用中调用此函数三次与在三个单独的内核调用中调用一次之间的区别在于,一个工作项对全局内存的写入对于同一内核调用中的其他工作项是不可见的。这意味着在第一个示例中第二次调用convolution期间,工作项将读取失效值,而不会看到第一次调用此函数的输出。

OpenCL没有提供任何在整个内核调用中同步全局内存的方法。您可以使用barrier函数同步工作组中的内存,这可能允许您在单个内核调用中实现算法,并进行一些修改。