Macros 如何在OpenCL中使用宏替换/注入函数调用
我正在使用PyOpenCL开发一个算法。为了避免代码重复,我尝试使用模板和C宏来替换函数调用,因为OpenCL1.2不支持函数指针 我目前在OpenCL内核代码中有以下宏部分:Macros 如何在OpenCL中使用宏替换/注入函数调用,macros,opencl,pyopencl,Macros,Opencl,Pyopencl,我正在使用PyOpenCL开发一个算法。为了避免代码重复,我尝试使用模板和C宏来替换函数调用,因为OpenCL1.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() de
#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
和determinefitusingclinesearch
。我现在尝试使用宏来交换函数调用,如下所示:
__private struct linearFitResultStruct fitResult = LINEAR_FIT_SEARCH_METHOD_CALL();
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)
因此,我选择所需的调用(注意:我总是只需要其中一个调用,并且在程序运行之前完成配置(不需要动态切换这两个调用))
使用PyOpenCL模板,我现在可以执行以下操作:
__private struct linearFitResultStruct fitResult = LINEAR_FIT_SEARCH_METHOD_CALL();
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:错误:函数“DetermineFitusingClineSearch”的隐式声明在OpenCL中无效
1:9:41:注意:从宏“线性拟合搜索方法调用”展开
1:455:41:错误:使用不兼容类型“int”的表达式初始化“struct LinearFirtResultStruct”
1:536:30:错误:“DetermineFitusingClineSearch”的类型冲突
1:455:53:注意:前面的隐式声明在这里
1:9:41:注意:从宏“线性拟合搜索方法调用”展开
1:616:41:错误:使用不兼容类型“int”的表达式初始化“struct LinearFirtResultStruct”
我很少使用宏,因此:
我所尝试的是以这种方式实现的,还是我需要走另一条路
更新1:
当我在单元测试中设置self.positioningMethod=“meanIntensityIntercept”
时,此代码运行正常,但在设置self.positioningMethod=“maximumIntensityIncline”
时失败,并显示上述错误消息。我现在还不能发现这个错误
更新2:
我也受到了这篇文章的启发,如果这有帮助的话:
正如你所说,你对宏几乎没有经验,那么我会选择一些简单的东西
determineFitUsingMinMaxIntensitySearch
和determinefitusingclinesearch
接受不同数量的参数,因此可以通过以下方式完成:
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("")
正如你所说,你对宏几乎没有经验,那么我会选择一些简单的东西
determineFitUsingMinMaxIntensitySearch
和determinefitusingclinesearch
接受不同数量的参数,因此可以通过以下方式完成:
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("")
C宏复制代码。如果您担心代码密度,请信任编译器并编写正确的函数。我不确定是否理解您的观点。我尝试的是使用宏“注入”函数调用,以在另一个函数中修改该调用的行为。这是必要的,因为函数指针在OpenCL1.2下不可用。一个相关的帖子是这样的:事实证明,上面提出的方法正如预期的那样有效。问题是,两种方法中的一种(通过“注入”宏)证明上述方法可以按预期工作。问题是,当使用宏“注入”函数时,两个函数中的一个是在第一次引用该函数之后定义的。这就是注入第一个函数有效而第二个函数无效(第一次调用后定义的函数)的原因。我不确定是否应该将此作为答案发布,因为问题与宏本身无关,其他人无法使用提供的信息找到问题的解决方案…C宏复制代码。如果您担心代码密度,请信任编译器并编写正确的函数。我不确定是否理解您的观点。我尝试的是使用宏“注入”函数调用,以在另一个函数中修改该调用的行为。这是必要的,因为函数指针在OpenCL1.2下不可用。一个相关的帖子是这样的:事实证明,上面提出的方法正如预期的那样有效。问题是,两种方法中的一种(通过“注入”宏)证明上述方法可以按预期工作。问题是,当使用宏“注入”函数时,两个函数中的一个是在第一次引用该函数之后定义的。这就是注入第一个函数有效而第二个函数无效(第一次调用后定义的函数)的原因。我不确定是否应该将此作为答案发布,因为问题与宏本身无关,其他人无法使用提供的信息找到问题的解决方案。。。