2019年にやったこと

多分細々したことをもうちょっとやってるけど忘れた。

書いてない部分で去年書き上げた論文のためのデータ集めとか研究用ソフトの開発とか解析とか先行研究調査とか論文執筆をしてる。一つは同僚と一緒に(co-1st)、一つは一人で。開発を研究の隙間でやっていると言わないと怒られが発生しますが(時間的にもそっちの方が正確)、表現の問題に過ぎません。

1月

RustでRay tracing in one weekendをやったようだ。2日目の「2日で終わらすぞ」圧がコミット履歴から感じられる。一応本の内容は2日で終わったようだが、その後数日リファクタリングをしたりthe next weekの内容をちょっと足したりしている。ちょっと待てこれ前回の記事で引き合いに出したレポジトリなんだが、あの話そんな長いこと記事にせずに置いてたの?

github.com

あと、自作の分子動力学シミュレータのための一人グループを作っている。これは研究室で永きに渡って改造され続けてハウルの動く城みたいなビジュアルになっているFortran製のシミュレータをオリャッとC++11で書き直したものだ。機能拡張が容易になった(同僚談)上に数千〜数万粒子程度の入力で安定して2倍程度の高速化を果たした。グラフを外挿するに粒子数に対してこの速度差は開き続ける一方に見える。以降、1ヶ月に1回、その月に実装できた機能をまとめてリリースタグを打っている。書くと長くなるのでこれ以降はこれに対する機能追加は省略しているが、これもいずれ纏めておかなければ。絶対リリースノートと一緒に月一でちゃんと書いた方がいいんだよそういうの。

github.com

ちなみに今でもFortran製のin houseシミュレータの並列絡みのヤバいバグ修正を助けたりとかはちょいちょいしている。初期に想定してなかった改造によってデザインレベルで無理が来ているところは深いところから書き直す以外に直しようがないが、水漏れにダクトテープを巻きつける程度のことはできる。設計に無理が出ていて困るのは水漏れ箇所に行き着くのが難しくなることだ。現在そこが努力によって補われているが、そろそろ厳しくなっているようにも見える。

とはいえレビュー1分で落とせるだろ、くらいの明らかなデータ競合とかも残っていたので、どうも並列プログラミングの知識・経験を持った人が内部に足りていないように思う。プログラミング学習や教育を評価できる体制ができていないのでさもありなんというところだが、そこからとなると改善はそう簡単にはいかないだろうな……。

あと、練習がてら分子動力学計算の解析用ツールをRustでちょっとだけ書こうとしていた。C++テンプレートよりも制約が厳しいRustのジェネリクスの洗礼を受けている跡が見られる。もうちょっとゆるくやった方が簡単そうだが。結局あまり使い物にはならない状態で放置してしまっている。まあ今まで書いてきた分で何とかなってるからな……。

github.com

他に、gitbookの使い心地をいくつかのレポジトリを実験台として使って試しているようだ。

2月

去年の冬はレイトレを楽しんでいたらしく、GPUでレイトレをするコードを書いている。やっぱりカッコいい画像がすぐに目に見えるというのはモチベーション維持に良い。 CUDAからOpenGLのバッファに書き込むのに非常に苦労した記憶があるし、結局どれが一番いい方法だったのかいまだにあやふやだ。そこ以外特に困ることはなかった。まあこれは空間分割とかちゃんとやってないし……(あとでGPUでBVH作るやつの話が出てきます)。

github.com

この月は、toml11をwindowsで使った時だけおかしくなるという問題に対応していたようだ。これは結局なんだったのかと言うと、asciiモードでファイルを開いた際に¥r¥n¥nに変換されるせいで、バッファのサイズと読み込める文字に差が出てしまっていたことが問題だった。中でバイナリモードで開いて変換を抑制した記憶がある。それと、この月にtomlのシリアライズを実装したようだ。

3月

toml11に怒涛の機能追加とバグ修正をしている。これは、Burntsushi氏のテストケース群を使ってバグを探していたからだろう。エッジケースを見つけるのに重宝した。最近はケース追加が止まっているようだが。

github.com

ここで主にエッジケースでのtoml規格への適合度がかなり上がった。これらの修正はBoost.tomlにはあまり取り込めていない。なのでBost.tomlのTOML規格適合度はtoml11やcpptomlと比較して若干低い。それは意識してはいるのだが、どうにも時間がなく手を出せずにいる。

toml11にはこの月に""_tomlリテラルも追加されている。

4月

toml11のパーサの速度が結構遅いことがわかったのでオーダーで改善し、平均100カラムくらいで数万行とかのファイルもそんなに待たずに読み込めるようになった。これは記事にしていた気がする。

他に、""_tomlリテラルの曖昧なケースについて対処していた。例えば以下のようなケースだ。

const auto v = "[1]"_toml;

""_tomlリテラルではキーのない値だけのリテラルを許容していたことと、tomlが数字のみのキーを認めていることが組み合わさった結果、これは「1」という空テーブルの宣言とも、整数1だけが入った配列とも取れるようになってしまった。この曖昧さを取り除くため、このような場合はテーブルと解釈することにした。確実にテーブル名と明示する方法はないが、確実に配列にしたければ、以下のようにできるはずだからだ。

const auto v = "[1,]"_toml;

インライン配列でのtrailing commaは特に禁止されていないので使えるはずだが、実はインラインテーブルではtrailing commaは許可されていない。これは数少ない現行のtomlへの不満点というか、意味がわからないところだ。

# toml
a = {b = 42, c = "foo",} # これはダメ

全然関係ないけどこのへんでV-langがバズっていたような記憶がある。あれ今どうなったのかな。ちょっと前にまだ続いてるっぽい話を聞いたけど。

5月

自作のシミュレータのスレッド並列化をしていた。分子動力学計算の並列性は自明なのでそんなに詰まる部分はなかったが、一つだけ面白いことがあった。近接リスト構築をロックフリーにしたくてメモリをバカ喰いするクラスを作ったら、メモリアクセスが遅すぎて数倍遅くなってしまったのだった。これも書いておかないと。

後、ゴールデンウイークに小さなlispを動かせるインタプリタを書いた。GW後半にさしかかって普段通りの生活しかしていないことに焦りを覚えて何か簡単に作れるものを作ろうとしたことを覚えている。これは日記に書いたな。

後この月にTypes and Programming Languages (TaPL)の勉強会が始まった。これそんな前の話なのか。

6月

Expression templateとチェーンルールを使って型レベルで自動微分をするライブラリ(?)を作った。数式を書くと関数オブジェクトが帰ってきて、微分できるらしい。

github.com

    constexpr auto x  = kaysha::variable<double>{};
    constexpr auto _2 = kaysha::constant<double>{2.0};
    constexpr auto _1 = kaysha::constant<double>{1.0};

    constexpr auto f = x * x + _2 * x + _1;

    std::cout << "f(x) = x^2 + 2x + 1" << std::endl;
    std::cout << "f(1) = " << f(1.0)   << std::endl;

    constexpr auto df = kaysha::differentiate(f);

    std::cout << "f'(x) = 2x + 2"       << std::endl;
    std::cout << "f'(1) = " << df(1.0)  << std::endl;

    constexpr auto ddf = kaysha::differentiate(df);

    std::cout << "f''(x) = 2"            << std::endl;
    std::cout << "f''(1) = " << ddf(1.0) << std::endl;

この時はフォワードモードだとかリバースモードだとかの存在を知らず、チェーンルールをゴリ押しで適用しているだけの実装になっている。ちょっとその辺勉強したくなってきたな。

7月

toml11のメジャーアップデートをしている。こんなペースなのか。これは記事にしたと思う。

それとの時系列がいまいち思い出せないが、この月にtoml11への寄付として10ドル相当の暗号通貨を見知らぬ人から貰ったのがかなり嬉しかった。

この数ヶ月くらいは、長く関わっているecellという細胞シミュレータのconda-forgeサポートに他のメンバーと共に奮闘しており、それに関連したことが色々とある。CI先でだけ落ちる現象を直そうとしてフラストレーションを高めた数ヶ月だったが、まあ上手くいってない時はそんなもんだろう。

それに関連してpybind11にC++14の機能が使われていたのを見つけて、ワークアラウンドを書いて取り除いたりした。これでpybind11コントリビュータだぞ! この程度ででかい顔するな。

github.com

後、Parallel Linear BVHのCUDA実装をした。しばらく探したのにブログ記事と論文とOpenMP実装以外は見つからなかったので……。そんなにちゃんとテストしてないけど多分動くと思う。このレポジトリは無言で上げたにしては微妙に反響があった。まあいつも宣伝なんかしてないんですけどね。Twitterとかで宣伝をしてはどうか。

github.com

そういえばnvidiaのRTXシリーズに積んであるRT coreはBVHをハードレベルで実装しているという噂で、いつcudaから叩けるようになるのか心待ちにしているのだが、なんかそういう話あるんですかね? まだcuda11とかは出てなさそうだし、そもそもnvidiaAPI公開する気があるのかわからないけども。是非使いたいから公開して欲しいんだけどな。

待ってたらそのうち変な人たちがoptixをリバースエンジニアリングしてやり方見つけ出しそう。

8月

おっ、この月は何も新しいレポジトリを作ったりしてないぞ。

月一で足している分子動力学シミュレータにはまたいくつか機能を足しているが、他のレポジトリは普通にバグ修正とかリファクタリングをしていたっぽい。まあ普通そういう月があるものだ。

9月

この月も同じ感じのようだ。何かで忙しかったっけな? 分子動力学シミュレータの方は粛々と開発を続けているようだが。そういえば2つ目の論文サブミットしたのこの月か。

10月

Rustのmdbookでpdfを出したくて、mdbook-latexをちょっと弄っていた。ざっと読んだ感じ基本的にlatexのテンプレートのdocument部分にmarkdownから変換していったものを貼り付けていくという作りっぽかったので(シンプルでわかりやすいのは好印象)、日本語文書を使うためにはテンプレートを置き換える必要があり、その部分を実装してプルリクを出したらすぐマージされた。

この月はtoml11のマイナーアップデートもしている。

11月

研究に使うコードを主に書いていた。進捗報告会があったからだな。

12月

conda-forgeの諸々が片付いて、事にあたっていた他のメンバーと一緒にconda-forgeグループのメンバーになった。

それと、ecellに追加した新たなシミュレーションアルゴリズムのバグを概ね取り切ったと思われるので、これもどこかにまとめておきたい。副産物として、ヤバい積分をした結果の特殊関数だらけの無限級数を計算するライブラリの行数が減りこれまた倍程度速くなった(未公開)。どうも研究の現場で使われているコードを私が書き直すと倍近く高速化するっぽい(自慢)。まあ最初に書かれたプロトタイプは色々試した結果ちょっと変になっているところが多いので、ちゃんと理解して整理したら無駄が消えて速くなるのは後出しジャンケンみたいなもので、ある程度は当然のことだろう。

研究用途のものでも高速化は重要だと思うんだけど、これは当然分野に依るのだろうが、速くするだけだと手間がかかる割に論文になりづらいので誰もしたがらず結果ノウハウが蓄積しないというイメージがある。たまに凄くできる人もいるが、そういう人はスッと企業に転職したりする。研究を支えるソフトウェア技術に関する評価体制をもっと整備した方がいいのではないかと思う。まあ観測範囲が狭いだけかもしれないが。

あと、いつの間にかcppreferenceのライブラリリストにtoml11が足されていた事に気づいた。

en.cppreference.com

結構嬉しい。

そういえば、他のライブラリのTOML規格準拠度とか使いやすさを秋くらいに調べたりしたのだが、私がそういう記事を書くと公平な判断になりようがないのではないかと思いお蔵入りにしてしまった。でも日本でTOMLの細かな仕様とそのパーサのC++での実装に現時点で一番詳しいのは私だろうから、書くのに一番向いているのではないかとも思っていて、非常に難しいところだ。最初に注意書きをしたらOKだろうか。

まとめ

博士課程は精神や肉体を病むそうで1、知り合いはそれぞれストレス性の神経麻痺で入院したり胃に穴が開いたり鬱になったりしていたそうだが、私は今の所まだ自覚症状がない。だがメンタル的にすでに結構厳しいのはわかっているので自分をいたわっていきたい。最近腹を下していないのに腹が痛いことがあったのでちょっとやばいかもしれない。胃に穴か?

思い出しながらここまで書いていて思ったが、もう少しアウトプットをこまめにした方がいいのだろう。細かいことでも短くても非自明なことがなくても記事にしていった方がいい。記録していないことは忘れてしまうし、私にとって自明になってしまったものでも後から来た誰かの助けになるかもしれないからだ。知識の高速道路を整備するのは必要なことだ。

去年はPullReqを出すだけではなく来たのを捌いた一年でもあった。ライブラリを使ってもらえるようになるのが嬉しいという一心で捌いてきたし、大半は見つけにくいバグを見つけてくれているものなのでありがたかったのだが、それでも「そんなことある!?」みたいな想定外のことは対応がやはり難しい。時間がかかってしまったものもあった。それなりに素早く対応できているのは、私がプライマリ作者で広く使われているライブラリはtoml11一つだからだろう。もっとたくさんのライブラリ・ツール群を保守している人は大変だろうなと思う。よく放置しないよな。放置してる人も結構いるけど、気持ちはよくわかる。これが10倍になったら「ちょっと待って」と思って別のことを始めたまま永遠に忘れたりしそうだ。

PullReqは基本的に英語で来る。なので返事も英語でするわけだが、問題なのは、私の英語力が拙いため、こちらの返信が十分丁寧かどうかがわからない事だ。PullReq送ってくれるような善意溢れる人をないがしろにしたくないので頑張って丁寧と思われる英語を書いてみたりしていたのだが、基本的にCould youとかを使いつつ婉曲的に提案を出すだけになっており、実際にはこれで丁寧になっているかわからない。流石に4 letter wordsを使わないくらいはわかる(「Remove this fxxking code」がダメなのはわかる)けれども。まあ名前から非ネイティブだとわかってるだろうし気にしないでくれるだろうと祈っておく。PullReqとかIssueの返事丁寧さ問題はみんながどう対応しているのか気になっているところだ。

今年一年実感したことだが、以下の4つの問題はそれぞれ質的に異なる。

  • 決まった目的のための保守しなくていいスクリプトを素早く実装する
  • 決まった目的のための保守する必要のあるプログラムを設計し、実装し、メンテする
  • 目的の全貌がわからないプログラムを設計し、機能を順次足していく
  • 目的の全貌がわからず誰がどんな環境で使うかもわからないライブラリを設計し、実装し、メンテする

時間制限がある場合は特有の難しさがあるので例外だが、時間制限がないなら私にとっては下に行くほど大変だった。考えないといけないことが増えていくからだと思う。日本では絶対に再現しないバグとかがあって、サマータイムに詳しくなったりした。機能を足す時に設計に無理が来ることがわかって頭を抱えたこともあった(結局設計を少し変えた)。3つめまでは極論自分で頑張ることで経験できるが、最後のは少しは使ってくれる人がいないと経験できない。toml11を使ってくれる人が増えてこういうことを経験できたのは技術力の観点からとても良かったと思う。

そういう意味で、去年は技術面ではそれなりに恵まれた1年だった。今年も頑張らなければならない。後、来年以降の身の振り方をそろそろちゃんと考えないといけない……。