#45 - Resuming Halide Tutorial

05:00. よく見ると #41 が重複していたので #44 はスキップ。

Halide やんぞ。

  • しかしもう忘れちゃったよ・・・
  • Lesson 05 done. 最適化の話。可視化がクール。
    • 変数を前もって宣言して in-out 引数のように扱うのは若干 ugly に感じ、どうせならたとえば split() の結果として2つの Halide::Var を返せばいいと思ったが、そうすると builder 的な fluent interface にできないね。言語内 DSL だとこんなもんかな。
    • 強力さは理解した。でも真価を発揮するのは multi-stage の pipeline だろうなー。
  • Lesson 07.
    • Multi-stage!
    • Expr と Func の違いをいまいち附に落とせていなかったが、さわるとわかるね。つまり Expr はスカラな変数で Func はベクトル化された値、と考えればよさそう。たとえば blur_x と blur_y を一つの blur Func で表現しようとすると blur_x に相当するフェーズがベクトル化されず、実行もシリアルになってしまう。計算結果の再利用の仕方とかも埋め込んでしまう。Func にするとそれらを Halide に任せられる。なるほど。
    • Buffer の set_min とか何に使うのかと思ったら halo を表現する必要があるのか。なるほど・・・。
  • Lesson 08. めんどくさくなってきたので読むだけ。コメントを丁寧に読むのが大事とわかってきた。重要情報が書いてあるので。
    • compute_at() とか store_at() は producer 側に指定するのだな。すると consumer 側がどう producer を使うかコントロールできる。
    • 単一ステージだと comput_at() とか store_at() に意味がないのは、そこに consumer がいないからである。というデザイン。
    • store_root() しても中間バッファの量は最小化される!なぜなら: "Note that my claimed amount of memory allocated doesn't match the reference C code. Halide is performing one more optimization under the hood. It folds the storage for the producer down into a circular buffer of two scanlines." ほー。逆に store_root() しないと隣接行は再利用してくれないのか。
    • scheduler についていまいちメンタルモデルを form できないね。ステージとステージの間を調停してくれる、と考えるとだいたい合ってるのかなあ。
  • Lesson09. Update functions
    • Histogram!
    • RDom はほんとにループを綺麗に書けるだけ、という存在だった。本来ループが存在しない Halide の世界になぜループの話があるかというと、Update functions はHalide の原則から例外的にはずれて副作用のある世界になるから。そんな話だったなそういえば。
    • しかしなんで振る舞いを決定的にできるのかわからないな。associative であるような演算だけ、とか何らかの性質を使うのだがろうがリテラシー不足でわからん。不安。