JuliaCon 2024 実況
JuliaCon 2024の発表のうち出席したものを実況形式で簡単にまとめていきます。
State of Julia 2024
毎年やってる"State of Julia"のトーク。例年は最終日にやってるイメージですが、今年は一番最初でした。
- Juila exerience: 言語の基本機能はもちろん、Pkg manager system、juliaup, benchmark tools, GPU supportなどJuliaの特に優れている側面を触れながら紹介。
- Package Server
StatisticsAwards: Pkg serverの統計を紹介。新しいパッケージが7時間ごと、既存パッケージの新しいバージョンが24分ごとにレジスターされているらしい。この数字を他の言語と比べてみたい。 - Industiral Adoption: Juliaを採用している企業の紹介。今回のJuliaConをホストしているASMLをはじめとして錚々たる企業が並んでててちょっと誇らしい。
- Language highlights
- TTFPは 16s (v1.0) → 1.4s (v1.10) と改善されているらしい。改めて見るとすごい改善されててびっくり。
- 1.10が新しいLTSになるらしい。いろんなパッケージでv1.6互換性をサポートし続けるのはなかなか面倒だったのでとても嬉しい。
- Pkg improvements: Project.tomlでURLやpathを指定できるようになる
[sources]
(v1.11)や、サブパッケージをまとめたモノレポとかのシチュエーションで便利な[workspace]
(v1.12)といった新機能をアナウンス。Pkgはどんどん便利になってて本当に素晴らしい。Pkg経由でCommand line toolsを使えるようにする"Apps"も開発中らしくてそれも楽しみ。 - Julia GPU: 改良が続いているらしい。特にGPU用のinferenceの結果をキャッシュすることで、レイテンシーが大幅に改善されたとのこと(69s v1.10 → 12s v1.11)。
- REPL improvements: インラインヒントとか、より分かりやすいエラーメッセージとsuggestionなどなど。ここでは触れられてないけどCompletionも賢くなってるよ。
- JuliaLowering.jl: Juliaのlowering passをJuliaで書き換えるプロジェクト。これによってマクロエクスパンドで起きたエラーのメッセージが改善したり、
esc
を使う必要がなくなるかもしれないらしくて、とても楽しみ。Revise, Cthulhu/JETのようなパッケージにとってもとっても便利になる予感。 -
public
keyword: パッケージのAPIを明確にするための新しいキーワード。
- 最後のスライド: 去年1年だけでもたくさんの新しいJuliaLang/juliaコントリビューターがいたようでスバラシ!
質問コーナーでボックスクッションのマイクを質問者に投げるのが笑いました。
Core.Compiler
Adventures in Julia IR: Plundering JETやCthulhu、あるいはGPUCompilerのようなJulia compilerのabstract interpretation routine/optimization passesを利用したカスタムなcode analysis/generationを行うパッケージがやっていることを紹介しているトーク。かなり分かりやすく紹介してくれているものの、紹介している機能そのものがかなり入り組んでいるのでなかなか上級者向けな内容。頑張ってコンパイラーをハックして欲しいCodeInfo
/IRCode
オブジェクトを生成することができれば、それをCore.OpaqueClosure
に突っ込んで実行できる。この手のことをやっていると、よくsegfaultが起きるのでgdbでJuliaを走らせる必要がある。本当にそう。
Compiler plugins and non-native execution caching
GPUCompilerのようなcompiler pluginがどのようにコードをキャッシュをしているのか説明するトーク。"State of Julia 2024"で触れられていた、GPUコードのレイテンシーの問題がどのように解決されたのかを説明。
- GPUCompilerは、CPUコードを生成するJulia compilerをオーバーロードし、GPUコードを生成するcompiler pluginであるため、これまではキャッシュができておらず、簡単なGPU workloadも最初の実行に60s程度かかっていたらしい
- Juliaのpkgimg(v1.9で追加されたパッケージのmachine codeをキャッシュする仕組み)のインフラストラクチャを再利用して、GPUCompilerの生成するmachine codeもキャッシュできるようになり、最初の実行が12s程度になったとのこと
トークの後半はcompiler pluginの実装方法やアイディアの紹介に当てられていた。
- Comipler pluginを実装するための手法の紹介:
- Cassette.jl: これまで取られていたアプローチ。Generated functionを利用しており、dynamic dispatchも扱うことができるが、inferenceをこんがらせてしまうため、レイテンシー/パフォーマンス上の問題が発生しやすい。
-
AbstractInterpreter
: 新しいアプローチ。GPUCompilerはこれを採用。ただし対象のコードがすべてtype stableであることが必要。 - JuliaLang/julia#52964:
AbstractInterpreter
の上にBase.ScopedValue
を利用した新しいインターフェースを用意し、dynamic dipsatchも扱えるようにする試み。
- Compiler plugin ideas:
- Multiline-fusion: 複数の
broadcast
-callをfusionし、materialize
を呼び出す頻度を減らす。Inferenceが走る前のuntyped IRの方が実装しやすいらしい。
- Multiline-fusion: 複数の
Memory
in Julia
-
Array
のイケないところ- Resizing makes optimization hard
-
push!
などのベーシックな関数はC側で実装しなくてはならなければならない
- 新しい
Memory
-type- Sizeが型情報に含まれているので最適化しやすい: ただしlengthは型情報にはないので、StaticArrays.jlとは異なる
- Generalなポインターをwrapすることができるため、
Array
に限らずgeneralな用途に利用可能
-
MemoryRef
:Memory
のメタ情報を保持するstruct。例えばbounds checkingに役立つ情報を保持できる。 - Benchmarks:
- 28% faster
Array
allocation - 38% faster
push!
- 30 faster
Dict
allocation
- 28% faster
あとでもう一度スライドを見返してデザインを完全に理解したい。
Dude, where's my code?
コンパイラパイプラインのうちlowering passをJuliaで書き換えるプロジェクト JuliaLowering.jl に関するトーク。ソースの情報がLowering passで失われないようにすることがプロジェクトの主眼であるらしい。
- 行番号だけじゃなくてcolumnの情報もloweringで保存されるので、エラーメッセージがかなりより良くなりそう
- 他にもCthulhuのtyped source viewに役立つそう: 現行の実装は行番号とパターンマッチに依存しており、うまくいかない場面があるらしい
- さらにより早いデバッガーの実装にも役立つらしい
- しかもRevise.jlの信頼性とメンテナンス性を改善し、壊れやすい部分を取り除いて、standard libraryにすることができるかもしれないとのこと(Reviseと関連スタックのメンテナンスはかなり面倒なので非常に嬉しい!)
- JuliaLowering.jlのデモ
- マクロの改善:
esc
を使わなくて良くなったり、マクロエクスパンジョン実装のイケてないところを取り除けるようになるらしい
トークでは触れられてなかったけど、JET.jlのエラーメッセージの改善にも大いに役立ちそう。素晴らしいプロジェクトだ。
Infiltrator.jl - No-Overhead Breakpoints in Julia
Debugger.jlやVSCode debuggerのようなJuliaInterpreter.jlベースではないデバッガーであるInfiltrator.jlの紹介。
- すでにあるデバッグ手法
- Debbugger.jl: リアルワールドケースにおいては実行が遅くなってしまうことがある(コードをインタプリターで実行するため)
- gdb/rr: Juliaのinternalsやsegfaultを調査するのには便利だが、デバッグ中のフレームをJulia expressionにマッピングできない上、ユーザーフレンドリーではない(使うのが難しい)
- といってもInfiltratorも2019年くらいからある気がする
- Infiltrator.jl: コードは普通にコンパイルされるため、パフォーマンス上のコストがほとんどない
-
@exfiltrate
: このマクロが埋め込まれているスコープで利用可能なローカル変数をsafehouse::Module
という特殊なモジュールに格納する(Core.eval(Main, :(xxx = $xxx))
を使いやすくした感じかな) -
@infiltrate
: このマクロが埋め込まれている時点のスコープでREPLを起動する
-
- Revise.jl/VSCode inline evaluationと組み合わせると便利。
Infiltratorは知っておくと結構役立つパッケージ。特に@infiltrate
が便利。