我正在使用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
在内核代码中,我还定义了相应的函数determineFitUsingMinMaxIntensitySearch
和determineFitUsingInclineSearch
。我现在正在尝试使用宏来交换函数调用,如下所示:
__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
答案 0 :(得分:0)
正如你所说,你对宏的经验很少,那么我会选择一些简单的东西。 determineFitUsingMinMaxIntensitySearch
和determineFitUsingInclineSearch
接受不同数量的参数,因此可以这样做:
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("")