2

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

谢谢

4

2 回答 2

2

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

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

不幸的是,生成器存根太新了,教程中还没有介绍它们。您最好的选择是查看测试/生成器中的自测示例(特别是example_jittest.cppstubtest_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 用户更有帮助的东西中。

于 2017-01-25T23:38:22.563 回答
1

在接受 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.hAOT 生成器和 JIT 测试。

于 2017-01-25T18:21:16.327 回答