生成器可以在开发中用于 JIT 吗?

Can generators be used for JIT during development?

HALIDE 的最佳开发策略是什么? 最终使用将使用生成器提前编译。 有没有办法调用 JIT 生成器中定义的函数?

谢谢

在一个单独的函数中定义您的 Halide 代码,该函数采用 Expr 和 Func 参数以及 returns Func。或者,您可以传递输出 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;
}

现在您可以从 AOT 生成器和 JIT 测试中包含 thing.h

是的,生成器与 JIT 代码一起工作得很好。

一般来说,生成器是封装单个卤化物块以供重用的首选方法。直到最近,它们在 JIT 模式下使用起来还有点笨拙,但最近添加 machine-generated 存根的更改极大地简化了这一点,并使得在 JIT 或 AOT 中使用生成器变得非常简单。

不幸的是,生成器存根太新了,教程中还没有介绍它们;最好的办法是查看 tests/generator 中的 self-tests 示例(具体来说,example_jittest.cppstubtest_jittest.cpp)。

概述:生成器存根的基本思想是,它是根据生成器的 public 描述创建的 machine-generated C++ class。它不会做任何你不能直接做的事情,但它确实使 Generator 的使用更简洁、更简单、更少 error-prone.

要生成生成器存根,只需修改您的 Makefile 以将 cpp_stub 添加到生成器的 -e 命令行标志,例如

./example.generator -n Example -o ./bin -e cpp_stub

这将发出一个名为 example.stub.h 的 C++ 源文件文件;在这个文件中你会发现一个 C++ class 看起来像这样:

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 正在构造您的生成器的实例,填充输入参数(基于您提供的输入结构),调用 generate() 方法生成输出函数,并返回它们给你。

在我键入此内容时,存根用法的记录严重不足;我刚刚打开了一个问题来收集我们拥有的文档和示例,这些文档和示例对一般 Halide 用户更有帮助。