トップ 一覧 Farm 検索 ヘルプ RSS ログイン

Diary/2018-3-27の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!ASPLOS(4)
本会議2日目.
キーノートは量子コンピュータの話.
分野によって発表する人の雰囲気がにてるような気がするなあ,とか.


夜は懇親会.立食かと思いきやテーブル式.
隣に座っていた人がMobileでの発表があった著者だったので,
いろいろと話を聞くなど.


懇親会では,グラスモニカの演奏が.
とても澄んだいい音色でした.


!Halide AOTについて調べる(1)

Halideについて,ちょっと調査.気になるのはAOTコンパイラまわり.
というわけで,とりあえずチュートリアルを動かしてみつつ,何やってるのか眺めてみる.
Halide/tutorialからみて,../../halide_buildの下で一式をコンパイルした環境.

::lesson_10_aot_compilation_generate.cppをコンパイル

 g++ lesson_10_aot_compilation_generate.cpp -g -std=c++11 \
     -I ../../halide_build/include \
     -L ../../halide_build/bin/ \
     -lHalide -lpthread -ldl -o lesson_10_generate

これで,lesson_10_generateが生成される

::生成されたlesson_10_generateを実行

 LD_LIBRARY_PATH=../../halide_build/bin ./lesson_10_generate

すると,lesson_10_halide.aとlesson10_halide.hが生成される.
これは,lesson_10_aot_compilation_generate.cppの

 brighter.compile_to_static_library("lesson_10_halide", {input, offset}, "brighter");

で決められた名前.lesson_10_halide.hをみると,

 int brighter(struct halide_buffer_t *_input_buffer, uint8_t _offset, struct halide_buffer_t *_brighter_buffer) HALIDE_FUNCTION_ATTRS;

が定義されている.lesson_10_halide.aを

 objdump -d lesson_10_halide.a | grep \^000000

とダンプしてみると,いろいろと関数がまとまっていることがわかる(中を追うのはあとまわし)

::実行ファイルの生成

 g++ lesson_10_aot_compilation_run.cpp lesson_10_halide.a -g -std=c++11 \
     -I ../../halide_build/include \
     -L ../../halide_build/bin/ -lHalide -lpthread -ldl -o lesson_10_run

と,generateで生成した.aファイルと一緒にコンパイル.

::_generateと_run

_generateで,brighterを作っている.

    Func brighter;
    Var x, y;
    Param<uint8_t> offset;
    ImageParam input(type_of<uint8_t>(), 2);
    brighter(x, y) = input(x, y) + offset;
    brighter.vectorize(x, 16).parallel(y);
    brighter.compile_to_static_library("lesson_10_halide", {input, offset}, "brighter");

データの箱と操作を定義してライブラリにコンパイルする,と.
で,_runで,

    Halide::Runtime::Buffer<uint8_t> input(640, 480), output(640, 480);
    int offset = 5;
    int error = brighter(input, offset, output);

と呼び出している,と.

::compile_to_static_library?

AOTコンパイラの本体はFuncに定義された,compile_to_static_libraryのようなので,
Halide/src/Func.cppを眺めてみると,

 void Func::compile_to_static_library(const string &filename_prefix,
                                      const vector<Argument> &args,
                                      const std::string &fn_name,
                                      const Target &target) {
     pipeline().compile_to_static_library(filename_prefix, args, fn_name, target);
 }

というのがある.pipline()とは?と,Func.cppの中で検索してみると,

 Pipeline Func::pipeline() {
     if (!pipeline_.defined()) {
         pipeline_ = Pipeline(*this);
     }
     internal_assert(pipeline_.defined());
     return pipeline_;
 }

と,Pipelineのインスタンスを用意する関数のよう.
実際には,Pipelineのインスタンスのcompile_to_static_libaryを呼び出している,と.
Pipelineのcompile_to_static_libraryの定義をみてみると

 void Pipeline::compile_to_static_library(const string &filename_prefix,
                                          const vector<Argument> &args,
                                          const std::string &fn_name,
                                          const Target &target) {
     Module m = compile_to_module(args, fn_name, target);
     Outputs outputs = static_library_outputs(filename_prefix, target);
     m.compile(outputs);
 }

となっている.

::もっとAOT

lesson15では,Generatorを継承するチュートリアルなので,そっちもみてみよう.
src/Generator.hには,

 * Generator is a class used to encapsulate the building of Funcs in user
 * pipelines. A Generator is agnostic to JIT vs AOT compilation; it can be used for
 * either purpose, but is especially convenient to use for AOT compilation.
 *
 * A Generator explicitly declares the Inputs and Outputs associated for a given
 * pipeline, and (optionally) separates the code for constructing the outputs from the code from
 * scheduling them. For instance:

とか書いてある.