この記事は 自動微分の誤った神話 シリーズの一部です。
あなたは、自分のC++ライブラリやアプリケーションに自動微分のメリットを享受させたいと考え、自動微分の適用に成功したと仮定しましょう。NAGでは、物事は変化し、常に新しいコードが開発されることを理解しています。このことは、あなたとあなたの開発チームに、ソースコード内の自動微分を維持するという別の課題を提示しています。自動微分コードのメンテナンスは、開発チーム全体が自動微分を詳細に学び、理解する必要がある大変なプロセスなのでしょうか?それとも、それは誤った神話なのでしょうか? この記事では、自動微分に対して取るアプローチによって、どのようなメンテナンスコストや落とし穴があるのかを見ていきます。
- ADツールを使わず、手作業で微分コードを書く場合
手作業で微分コードを書くのは難しく、ミスが起こりやすいだけでなく、2つの別々のコードベースを作成することになります。1つは原始コード、つまり元のモデル、もう1つは微分コード、アジョイントです。この方法で作業する場合、いくつかの重要なルールを覚えておく必要があります。まず、原始コードに変更があった場合は、微分コードにその変更を反映させる必要があります。チームのすべての開発者はこの重要な事実を認識し、対応する微分コードを書けるようにする必要があります。もし、原始コードと微分コードが同期していない場合、その影響は甚大なものになる可能性があります。さらに、原始コードの一見小さな変更が、微分コードのグローバルな変更を必要とする可能性があることを認識しておくことも重要です。さらに、例えば一次感度だけでなくヘシアンも必要な場合、必要な作業量は増加します。まとめると、手書きの微分コードのメンテナンスには、通常、膨大なコストと時間的な遅れが伴います。 - ソースの自動変換を利用する場合
ソースコードの自動変換が上手く行った場合でも、結局原始コードと微分コードの別々のコードベースを持つことになります(手書きと同じです)。しかし、原始コードに変更を加えるたびに、ソースからソースへの再コンパイルが行えるので、より良い状態ではあります。賢く設計すれば、これをビルドシステムの一部にすることもできます。しかし、経験上、このようなソースからソースへのコンパイラは、求められるほどには堅牢でないことが分かっています。これは通常、このようなコンパイラが処理できるように原始コードに手を加える事と、生成されたコードにも手動で後処理が必要であることを意味します。そしてこれらのステップは簡単に自動化できるものではありません。さらに、ツールの使い勝手によっては、不可解なコンパイルエラーも予想されます。まとめると、自動微分コードを手書きするよりはずっと良い方法ですが、それでも多くの不確定要素や落とし穴があります。 - 演算子オーバーロードのテクニックを使う場合
以前の 自動微分の誤った神話 の記事で説明したように、自動微分を適用するアプローチとしては、dco/c++のような堅牢なツールを使って演算子オーバーローディング技術を用いて行うのが最も簡単な方法です。これは、コードのメンテナンスにも当てはまります。主な利点は、単一のコードベースを持つことができることです。原始コードを変更すると、微分コードに対応する変更も直接的に発生します。C++でテンプレートを使用する場合、問題コード、原始コード、一次コード、高次微分コードのすべてが同じソースに存在することになります。エラーが発生した場合、コンパイラのメッセージはより複雑になる可能性がありますが、標準的なC++であり、開発者は報告されるエラーの種類に慣れているはずです。まとめると、メンテナンスコストが最も低いアプローチは演算子のオーバーローディングです。
手書きやソース自動変換された微分コードをメンテナンスすることは決して不可能ではありません。しかし、これらのアプローチによって得られるかもしれない追加性能が必要である場合、生成およびビルドプロセスを可能な限り堅牢にする必要があります。これにはターゲットテストやオーバーロードツールとのスマートカップリングが役立ちますが、それでもかなり多くの労力を必要とします。
NAGの自動微分ツールセットは過去12年にわたり開発され、さらに10年にわたるC++による自動微分研究開発の経験を基に構築されています。私たちは、細部が重要であることを知っています。レガシーコードは私たちのビジネスであり、私たちが扱うことができないコードに出会ったことは一度もありません。
神話は、真実のように聞こえるかもしれませんが、私たちは、神話について詳しく話し、私たちの経験を共有することによって、企業がこれらの問題を解決する手助けをしたいと願っています。
結果は重要ですが、神話は重要ではありません。