如何在OpenCL

时间:2017-04-30 20:04:50

标签: macros opencl pyopencl

我正在使用PyOpenCL开发算法。为了避免代码重复,我试图使用模板和C宏来替换函数调用,因为OpenCL 1.2不支持函数指针。

我目前在OpenCL内核代码中有以下宏部分:

#define LINEAR_FIT_SEARCH_METHOD ${linear_fit_search_method}

#if LINEAR_FIT_SEARCH_METHOD == MIN_MAX_INTENSITY_SEARCH
#define LINEAR_FIT_SEARCH_METHOD_CALL() determineFitUsingMinMaxIntensitySearch(lineIntensities,imgSizeY,linFitParameter,linFitSearchRangeXvalues)
#elif LINEAR_FIT_SEARCH_METHOD == MAX_INCLINE_SEARCH
#define LINEAR_FIT_SEARCH_METHOD_CALL() determineFitUsingInclineSearch(lineIntensities,imgSizeY,linFitParameter,linFitSearchRangeXvalues,inclineRefinementRange)
#endif

在内核代码中,我还定义了相应的函数determineFitUsingMinMaxIntensitySearchdetermineFitUsingInclineSearch。我现在正在尝试使用宏来交换函数调用,如下所示:

__private struct linearFitResultStruct fitResult = LINEAR_FIT_SEARCH_METHOD_CALL();

以便我选择所需的呼叫(注意:我总是只需要其中一个,并且在程序运行之前完成配置(不需要动态切换两个))。

使用PyOpenCL模板我现在做这样的事情:

def applyTemplating(self):
    tpl = Template(self.kernelString)
    if self.positioningMethod == "maximumIntensityIncline":
        linear_fit_search_method="MAX_INCLINE_SEARCH"
    if self.positioningMethod == "meanIntensityIntercept":
        linear_fit_search_method="MIN_MAX_INTENSITY_SEARCH"
    rendered_tpl = tpl.render(linear_fit_search_method=linear_fit_search_method)
    self.kernelString=str(rendered_tpl)

self.kernelString包含上面的宏以及代码。

不幸的是我收到了这个错误,我不明白:

  

1:455:53:错误:OpenCL中函数'determineFitUsingInclineSearch'的隐式声明无效   1:9:41:注意:从宏'LINEAR_FIT_SEARCH_METHOD_CALL'扩展   1:455:41:错误:使用不兼容类型'int'的表达式初始化'struct linearFitResultStruct'   1:536:30:错误:'determineFitUsingInclineSearch'的冲突类型   1:455:53:注意:先前的隐含声明在这里   1:9:41:注意:从宏'LINEAR_FIT_SEARCH_METHOD_CALL'扩展   1:616:41:错误:使用不兼容类型'int'的表达式初始化'struct linearFitResultStruct'

我对宏的经验非常少:

我是以这种方式尝试甚至可能还是需要走另一条路?

更新1: 当我在单元测试中设置self.positioningMethod = "meanIntensityIntercept"时,此代码运行正常,但在使用上面的错误消息设置self.positioningMethod = "maximumIntensityIncline"时失败。我还没有发现错误。

更新2: 如果有帮助的话,我也受到了这篇文章的启发: how to compare string in C conditional preprocessor-directives

1 个答案:

答案 0 :(得分:0)

正如你所说,你对宏的经验很少,那么我会选择一些简单的东西。 determineFitUsingMinMaxIntensitySearchdetermineFitUsingInclineSearch接受不同数量的参数,因此可以这样做:

kernel_code = """

#ifdef USE_FUNCTION_A

void function_a(
    int x,
    int y,
    int extra_param,
    __global const int* restrict in,
    __global int* restrict out
)
{
    //...
}

#else

void function_b(
    int x,
    int y,
    __global const int* restrict in,
    __global int* restrict out
)
{
    //...
}

#endif

__kernel void my_kernel(
    int x,
    int y,
    __global const int* restrict in,
    __global int* restrict out
)
{
    // ...
#ifdef USE_FUNCTION_A
    function_a(x,y,5,in,out);
#else
    function_b(x,y,in,out);
#endif
    // ...
}
"""

if use_function_a:
    prg = cl.Program(ctx, kernel_code).build("-DUSE_FUNCTION_A")
else:
    prg = cl.Program(ctx, kernel_code).build("")