#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 であるような演算だけ、とか何らかの性質を使うのだがろうがリテラシー不足でわからん。不安。