HALIDE 的最佳发展策略是什么?最终使用将使用生成器提前编译。有没有办法为 JIT 调用生成器中定义的函数?
谢谢
是的,生成器与 JIT 代码一起工作得很好。
一般来说,生成器是封装单个卤化物块以供重用的首选方式。直到最近,在 JIT 模式下使用它们还有些尴尬,但最近添加机器生成的存根的更改大大简化了这一点,并使在 JIT 或 AOT 中使用生成器变得非常简单。
不幸的是,生成器存根太新了,教程中还没有介绍它们。您最好的选择是查看测试/生成器中的自测示例(特别是example_jittest.cpp
和stubtest_jittest.cpp
)。
概述:Generator Stub 的基本思想是它是一个机器生成的 C++ 类,它是基于 Generator 的公共描述创建的。它不会做任何你自己不能直接做的事情,但它确实使 Generator 的使用更加简洁、简单且不易出错。
要生成生成器存根,只需修改您的 Makefile 以添加cpp_stub
到生成器的-e
命令行标志,例如
./example.generator -n Example -o ./bin -e cpp_stub
example.stub.h
这将发出一个名为;的 C++ 源文件文件。在这个文件中,你会发现一个看起来像这样的 C++ 类:
class Example : public Halide::Internal::GeneratorStub {
public:
struct Inputs {
// One field per input to the Generator;
// Buffer inputs will be Halide::Funcs,
// all other (scalar) inputs will be HalideExprs
};
struct GeneratorParams {
// One field per GeneratorParam in the Generator
};
struct ScheduleParams {
// One field per GeneratorParam in the Generator
};
Example();
Example(
const GeneratorContext* context,
const Inputs& inputs,
const GeneratorParams& params = GeneratorParams()
);
void schedule(const ScheduleParams& params = ScheduleParams());
// Output(s)
Func output;
// If the Generator has multiple Outputs, they will be here too
};
您可以在 JIT 代码中使用这个存根,就好像它是一个辅助函数一样(嗯,主要是):
#include "example.stub.h"
Example::Inputs inputs = { ... };
auto gen = Example(context, inputs);
gen.schedule();
Halide::Buffer<int32_t> img = gen.realize(kSize, kSize, 3);
在后台,Stub 正在构建 Generator 的实例,填充 Input 参数(基于您给它的 Inputs 结构),调用 generate() 方法来生成 Output Funcs,并将它们返回给您。
当我输入这个时,存根的使用被严重低估了;我刚刚打开了一个问题,将我们拥有的文档和示例收集到对一般 Halide 用户更有帮助的东西中。
在接受 Expr 和 Func 参数并返回 Func 的隔离函数中定义您的 Halide 代码。或者,您可以传递一个输出 Func 参数:
在thing.h
Func thing1( Func input, Expr param1, Expr param2 );
void thing2( Func input, Expr param1, Expr param2, Func output );
在thing.cpp
Func thing1( Func input, Expr param1, Expr param2 )
{
Var x("x"), y("y");
Func output("output");
output( x, y ) = input( x, y ) * param1 + param2;
return output;
}
void thing2( Func input, Expr param1, Expr param2, Func output )
{
Var x("x"), y("y");
output( x, y ) = input( x, y ) * param1 + param2;
}
现在,您可以同时包含thing.h
AOT 生成器和 JIT 测试。