Halide函数返回Func数组及命名Func数组的技术问询
Halide中返回Func数组+单个Func的简洁实现及数组元素命名方案
一、给Func数组元素分配名称
直接通过循环遍历数组,为每个元素调用set_name方法,结合索引生成唯一名称:
const int s = 8; Func pyramid[s]; // 为数组中每个Func设置名称 for (int i = 0; i < s; ++i) { pyramid[i].set_name("pyramid_" + std::to_string(i)); } Func X("X"); // 已有的命名方式
这样每个pyramid[i]会被命名为pyramid_0、pyramid_1……pyramid_7,修改s值时命名逻辑会自动适配。
二、简洁返回包含Func数组和单个Func的Tuple
由于Halide的Tuple构造需要逐个传入Expr(即Func的调用表达式),直接传数组无法识别。利用C的编译期索引序列(C14及以上支持),可以实现无需手动罗列数组元素的返回逻辑:
1. 实现辅助模板函数
#include <utility> // 用于std::index_sequence和std::make_index_sequence template<int... Is> Tuple make_combined_tuple(Func pyramid[], Func& X, int x, int y, std::index_sequence<Is...>) { // 展开索引序列,自动生成所有pyramid元素的调用表达式,再追加X的调用 return Tuple(pyramid[Is](x, y)..., X(x, y)); }
2. 在主函数中调用
Tuple myFunc() { const int s = 8; Func pyramid[s]; // 先为pyramid元素命名(参考第一部分代码) for (int i = 0; i < s; ++i) { pyramid[i].set_name("pyramid_" + std::to_string(i)); } Func X("X"); // 假设这里已经完成pyramid和X的定义逻辑 Var x, y; // 示例:给每个pyramid元素简单赋值 for (int i = 0; i < s; ++i) { pyramid[i](x, y) = x + y + i; } X(x, y) = x * y; // 利用索引序列生成Tuple,修改s值无需修改此语句 return make_combined_tuple(pyramid, X, x, y, std::make_index_sequence<s>()); }
原理说明
std::make_index_sequence<s>会生成一个包含0到s-1的编译期索引序列,模板函数中的Is...会被展开为这些索引,最终自动生成pyramid[0](x,y), pyramid[1](x,y), ..., pyramid[s-1](x,y), X(x,y)的参数列表传入Tuple构造函数。
注意事项
- 确保使用支持C14及以上的编译器,
std::index_sequence是C14引入的特性; - 如果使用更早的C++标准,可以手动实现类似的编译期索引展开逻辑,或者使用Boost库的相关组件替代;
- 原代码中
Tuple Func myFunc()的写法错误,正确的返回类型应为Tuple。
内容的提问来源于stack exchange,提问作者Cordovan
相关产品推荐
相关产品推荐

