科学アプリケーションでエラーを見つけることの難しさ

これは、単体テストが科学アプリケーションでうまく機能しない理由に関する注記の続きです。 そしてこの記事では、私が今までに遭遇したエラーやデバッグ(科学アプリケーション)を見つけることの難しさについてお話したいと思います。その多くはWeb開発者として私にとって驚くべきものでした。





この記事はいくつかのセクションで構成されます。

  1. ご注文の概要
  2. バグを見つけるのが難しい

    • 並行性
    • エラーの非局所性
    • 証拠の入力
    • 結果に対する設定の影響
    • エラーの識別:エラーかどうか?


  3. おわりに


はじめに



この記事の主な目的は、誰かが興味を持ち、珍しいものになることを期待して、自分の経験を説明することです(特に、私にとっては、産業プログラマーにとって)。 おそらく誰かが卒業証書/コースワーク/研究室を書くためのより良い準備をすることができるでしょう。 前文、科学的問題の声明、アルゴリズムの簡単な説明は、言及された記事[1]で読むことができます。 したがって、読者の視野を広げ、全体として意識を広げるために、エラーを見つける際の異常な(たとえばWeb開発者にとっての)困難のプレゼンテーションにすぐに目を向けます。



バグを見つけるのが難しい



並行性


これは、図を完成させるための非常に短いポイントです。ここで、エラーを検索し、並列プログラムでデバッグすることは、シングルスレッドのプログラムよりもはるかに難しいことを改めて述べます。 そして、ほとんどのリソース集約的な科学プログラムは並行しています。



エラーの非局所性


ここで、あるクラスのコードのエラーが完全に予期しない場所に現れる可能性があることを意味します。 そしてポイントは、貧弱なアプリケーションアーキテクチャとモジュールの高い接続性ではなく、タスクとモデリングの機能です。 たとえば、パイプ内の流体の流れをシミュレートするときに速度プロファイルが壁の近くで歪んでいる場合、これはエラーが壁を計算するアルゴリズムに正確にあるという意味ではなく、どこでも可能です。 逆に、密度が液体の厚さで奇妙に分布している場合、これは壁計算アルゴリズムではないという意味ではありません。



これを一般的なビジネスアプリケーションのシナリオと比較してください。オンラインストアでの購入の処理中に商品の割引が正しく計算されない場合、エラーは商品の割引を計算するコードにほぼ確実に隠されます。



変更の履歴からエラーの原因を簡単に特定できることに反対する場合があります。 たとえば、アプリケーションの動作が停止するとすぐに、変更されたコードでエラーを探す必要があります。 ただし、前の作業バージョン(熱伝達、所定の境界条件など)がないため、このアプローチは、プログラムの最初に追加された部分(例えば、熱伝達、新しい境界条件などを追加する場合)には適用されません。



さらに、科学アプリケーションでのエラーは長時間発生しない場合があります。 たとえば、新しいタイプの境界条件を追加するときに、圧力勾配ではなく力によって駆動されるポアズイユの流れ[2]が突然正しくモデル化されなくなると、境界条件の新しいアルゴリズムではなく、外力を考慮するロジックになることが判明する場合がありますそれ以前は、エラーは重大ではありませんでした。 ([1]の段落「エラーの増加率が遅い」も参照してください)。



証拠の入力


科学的アルゴリズムの問​​題の1つは、それらがしばしば明らかでないことです。 美しいアーキテクチャのプログラムを作成し、アルゴリズムの特別なクラスを取り、それを適切に設計して記述したとしても、おそらくいくつかの問題を避けることはできません。



第一に、これらは意味のない変数名です(これらは意味論的な負荷を持たない元の科学論文からの補助変数であるため)。 次に、これらはクラス変数に対する非自明な操作です(元の記事からも取得されているため、標準偏差の最適化、フレドホルムの代替、空間密度調和関数の計算などのダークマジックメソッドによって取得されています)。



ビジネスアプリケーションから借方記入し、次のような行を観察する場合

bool categoryIsVisible = categoryIsEnabled || productsCount> 0;

条件は論理「AND」でなければならないため、すぐにタイプミスに気付くでしょう。



しかし、あなたがラインの目を引いたと想像してください(実際のプロジェクトから)

二重確率=ラティスベクトル重量*密度*(1.0 + 3.0 * dotProduct + 9.0 / 2.0 * dotProduct * dotProduct-3.0 / 2.0 * velocitySquare);

どこかでプラスとマイナスを混同したと判断することはまずありません。 ところで、変数の名前はここで意味があります。



結果に対する設定の影響


この段落では、科学アプリケーションの作業が(ビジネスアプリケーションと比較して)はるかに強力であることを、入力データ、システムのパラメーター、その初期状態、つまりシステムの設定に依存することを説明します。



依存関係を設定する主なソースは次のとおりです。



1.システムパラメータは、通常は定量的にのみ影響するビジネスアプリケーションとは異なり、プログラムの作業結果に非常に強い(定性的)効果を持ちます(たとえば、CMSの操作は、管理者がページに5つまたは5つのテキストを追加するかどうかに基本的に依存しません) 10行)



2.入力データに応じたアルゴリズムの安定性の小さな領域。 ビジネスアプリケーションでは、データの主な制限はオーバーフローエラーがないことです(そして誰がそれに注意を払っていますか?!)。 科学的アルゴリズム(相違点の1つはより強力なセットで動作することです)では、安定性(および微分方程式、安定性理論、リアプノフ指数などの剛性)を思い出して監視する必要があります。 さらに、ビジネスアプリケーションでは、すべての制限は確定的です(登録時に名前は100文字を超えることはできません、電子メールは特定の正規表現に対応する必要があると言います)が、科学的な問題では、試行錯誤を使用して入力データの有効範囲を決定する必要があることがよくあります。



3.他のすべて(これまでのところ私にとって公式化が難しい)。 具体的には、プログラムの測定単位を物理から測定単位に変換することです。



これらの側面を説明するために、流体力学をモデリングするアプリケーションの無駄なデバッグを数週間行った後、自分用にコンパイルしたチェックリストを示します。 ステップごとの実行で数時間/数日間エラーが見つからなかった場合は、このチェックリストで確認しました。



注意! Habrの主題やほとんどの読者の関心からはやや離れているため、必要に応じてスキップして次の段落に進むことができます。

チェックリスト:

  1. 非圧縮性を確認する
  2. レイノルズ数を確認する
  3. 翻訳を確認する


最初のポイントは、アルゴリズムが弱い圧縮性の流体でのみ機能することを意味します。これは、低速度(流体内の音速よりもはるかに低い)に相当します(フローは密度勾配によって誘導されるため)。 この制限を初めて忘れたとき、外部でプログラムがほぼ正常に動作したため、コード内のエラーを検索するのに数日費やしました。



2番目の項目は、アルゴリズムの安定性ドメインをチェックすることと同等です。 事実は、レイノルズ数によって、流体の動きがどれだけ乱流および不安定になるかが決まるということです[3]。 大きいほど、流れが不安定になり、小さいほど「粘性」が高くなります。 運動が決して物理的に乱流にならない場合でも(ポアズイユの流れで)、計算は十分に大きなレイノルズ数で発散し始めます。 もちろん、このレーキを踏むまで(そして1週間気に入らなかったまで)、安定領域を追跡することは考えませんでした。



3番目の項目は、物理計算と一部のアルゴリズムにのみ固有です。 使用される方法は、格子の特別な単位で入力物理量を取ります(長さの単位が均一な空間格子のステップであり、時間の単位がそれに比例する場合)。 この方法での数量の翻訳に特化した特別な記事[4]に出会うまで、プログラムがまったく正しく動作しなかった理由を理解するために数週間失敗しました。



2番目と3番目の段落ではほとんど自動検証が許可されないことに注意してください。



エラーの識別:エラーかどうか?


この問題は、ビジネスアプリケーションではまったく考えられません。 そして、それはしばしば、プログラムの振る舞いの(予想からの)逸脱が間違いであるかどうかを確実に言うことができないという事実にあります。



例えば、粘性流体が円筒パイプを流れる間の速度プロファイルは放物線になることが知られています[2]。 ただし、パイプの壁で流体をシミュレートするとき、想定よりも少し速く流れると仮定します。 一般的に考慮されるオプションは次のとおりです。

  1. これは実際には間違いです
  2. これはアルゴリズムの機能です
  3. これは、アルゴリズムの不正確または不適切な入力データ(初期条件、物理パラメーター)の結果です(「結果への設定の影響」を参照)


最初の点の単体テストによる検証は、そのようなアプリケーションで単体テストを書くのが難しいため複雑です[1]。



この例の2番目の項目は、壁計算アルゴリズムを置き換えることで簡単に確認できます。 ただし、新しい方法でモデリングすると、結果が歪むこともあります。 この場合、さらに2、3のアルゴリズムを試すことができます(原則として、それらが利用可能であり、検索、分解、実装する時間があれば)。



残念ながら、3番目の段落を確認することはそれほど簡単ではありません。 1つのオプションは、入力パラメーターとシステム設定を変更して、プログラムが動作する初期データの位相空間に領域があるかどうかを判断することです。 悲しいことに、複雑なモデリングの初期条件の自由度が非常に大きいため、これはそれほど単純ではありません(粘度や熱伝導率、システム全体の速度、力、密度の初期分布など、さまざまな物理パラメーターを設定できます) 。 たとえば、流体がパイプを流れるテストでは、定常速度分布ではなく定常流体でモデリングを開始しようとするのに数日かかりました。その後、一定の力で加速され、エラーが消えました。



おわりに



実際、ここで、私が話したいエラーを見つけることのすべての困難。 誰かがそのような影響を回避または効果的に処理する方法について考えを持っているなら、私はそれらを聞いてうれしいです。



読んでくれてありがとう!



参照:


[1] 単体テストが科学アプリケーションで機能しない理由

[2] ポアズイユストリーム

[3] レイノルズ数

[4] 数量のLBMへの変換



All Articles