HPCメモ

HPC(High Performance Computing)に関連したりしなかったりすることのメモ書き

数値計算屋にはFortranは捨てなくても良いけどソフトウェアエンジニアリングを学んでほしい

twitterでこちらの記事をみかけたので、Fortran完全に理解したエンジニアの一人として便乗記事を書いときます。

qhapaq.hatenablog.com

ちなみに、私は学生時代からかれこれ20年近く数値計算屋をやってますが、メインの言語はC、C++Pythonときて今は主にJavascriptを使ってます。とはいえ、就職してからは基本的にチューニング屋なので、普通の数値計算屋さんの数倍は他人の(主にFortran)コードを読み書きしてきたと思っています。その中で日頃感じていたもやもやをこの機会にまとめてみました。

元記事には3つFortranを捨てるべき理由が挙げられていますが、個々の内容に対しては概ねその通りだと思います。(細かいところで異論は色々とあるんですが、そこは本筋ではないので省略します)

ところが、残念ながらFortranを捨てても何も解決しないのです。

私が今までに見た最も残念なC++のコードは、全ての処理がMainクラスのrunメソッドに書かれていて、main文からはそのメソッドが呼ばれているだけでした。 また、運良く(?)Fortranのコードを全て捨ててC++に移行したOpenFOAMみたいな例がありますが、ロジックの途中にコードのスニペットをincludeするとかいう凶悪な仕様になっていて、よりによってなんでそんなカプセル化しちゃったのか問いつめたいところです。

Rustにも言及されてましたが、プログラミング言語を変えたところでソフトウェアの品質が良くなるわけではないのです。

どうしてこうなった?

数値計算屋の中にはこんな形でキャリアが始まった方も多いのではないでしょうか

  1. 大学で非情報系の分野を専攻
  2. 研究室に配属されたらなんかコンピュータがいっぱいあった
  3. ソフトウェア遺産を読みつつ(もしくは先輩に教わりつつ)プログラミングを始める

こういう方々にとってはソフトウェアの開発は目的ではなくて研究のための手段なのです。ソフトウェアの品質に多少の難があっても研究の成果が得られていれば、良い方向に進んでいると判断されるし、「動いているコードになるべく手を入れない」というのは経験豊富なソフトウェアエンジニア以外には、とても素晴しいノウハウのように思えるものです。*1

そういった幾人もの研究者が、先代から受けついでいった秘伝のタレみたいなコードが数値計算の世界ではそこそこ生き残っているし、公開されて広く使われてたりもするので「Fortran死すべし!!」みたいな話になるのは理解できなくもないですが、別の言語で書いたところで、同じようなものを再生産するだけじゃないでしょうか。

Fortranを捨てることの是非はさておき、この不幸なサイクルを断ち切るために、数値計算屋を志す若者には次の3つを心に留めてほしいと思っています。

1. 関心の分離、KISS、DRY、YAGNIといったソフトウェアエンジニアリングの基本的な概念を知る

何かの目的があってプログラムを書き始めた時は、当初の機能が実現できたらあとは使うだけというように思えるものですが、使っているうちに何か新しい機能を追加したくなったり、OSやハードウェアの更新にともなって不具合がでてきたりと何だかんだで改修を迫られます。

その度に難解なコードを解読したり、複数の場所に同じ処理が書かれていて何箇所も同じような修正作業を繰り返す羽目になったりというような非生産的な苦行を繰返してきた先人達が、「この辺に気をつけておけば後々楽できる」といった観点で研究してきたものがソフトウェアエンジニアリングです。*2

あなただけがこの苦行から逃れられる確率は非常に低いので、先人の知恵にのっかりましょうw

2. デザインパターンを学ぶ

デザパタ自体を数値計算のプログラムに適用する機会はあまり無いかもしれませんが、色々なデザパタ本で紹介されている手法は、1で挙げたソフトウェアエンジニアリングの概念をJAVAC++で実装するためのものとも言えます。

抽象的な概念だけ聞いててもイマイチ分からんという人はこっち方面から勉強してみるのも良いと思います。

3. VCS、ビルドシステムやテストフレームワークといったツールを使う

多くのプログラマは、きりが良いところまでコードを書いたらビルド&テストをして実際に想定しているとおりに動作するか確認しつつ開発を進めていくと思います。

ソフトウェアエンジニアリングについて学んでいくと、たいていの場合コードが細ぎれになり、ビルド&テストのサイクルはどんどん短かくなります。 そうすると、これまで手作業でやっていたコンパイル -> 実行 -> 結果確認 というプロセスが邪魔になってきて、ふと気付いたらコンパイルすらせずに数十もの関数を書いていたなんて悪夢がおきます。

まっとうなビルドシステム(makeでも十分ですが移植性を考えるとautomakeやらcmakeやらも欲しい)であれば、コマンド一発でビルドしてテストすることも簡単ですし、そこにテストフレームワーク(googletestとか)を導入しておけば、単体テストなんかも楽に書けます。

VCS(Version Control System 要するにgitとか)は、開発プロセスに大量のセーブポイントを持ち込んでくれるものです。 数日かけてようやく完成させた機能が、まったく使いものにならないことが判明した時とか気軽に元の状態に戻すことができます。 逆に、お試し実装をポコポコと追加して、駄目だったら消すようなトライアンドエラーも簡単にできるようになるわけです。

特に性能面で「両方作って試してみるかー」みたいな話になりがちな数値計算屋にとっては、大変心強い味方です。 さらにgithubみたいなwebサービスを使っておけば、「手元のコードとスパコンのフロントエンドに置いてあるコードが違う」なんていう不慮の事故も防ぐことができます。(たまに外に出ていけないシステムがあってちょっと面倒ですが)

おわりに

長々と妄言を書いてきましたが、特定の数値計算ソフトウェアのプロジェクトや、特定の数値計算屋さんを非難するつもりで書いたものではありません。これから数値計算の世界に足を踏み入れる若い人が、過去の遺物に学んで負のスパイラルに陥いらないことを願って先輩風を吹かせただけの駄文ですので、ご笑覧いただければ幸いです。でもってこれを読んだ優秀な若手が育って、素晴しい開発プロジェクトを立ちあげた際には弊社にも何かお仕事を・・・

*1:まさにレガシーコード改善ガイドの冒頭に書かれているような感じで

*2:個人の感想です