C ++でパラメータースタディを実行する良い方法は何ですか


29

問題

現在、有限要素ナビエストークスシミュレーションに取り組んでおり、さまざまなパラメータの影響を調査したいと思います。一部のパラメーターは、入力ファイルまたはコマンドラインオプションで指定されます。他のパラメーターはMakefileでフラグとして提供されるため、これらのオプションを変更するたびにコードを再コンパイルする必要があります。パラメータ空間を体系的に探索するための良い方法についてアドバイスをもらいたいと思います。

  • この種のことを支援できる便利なC ++ / Pythonライブラリ/フレームワークはありますか?たとえば、コマンドライン引数で入力ファイルオプションをオーバーロードすることができるため、boost.Program_optionsを発見することは大きな助けになりました。また、一部の人々が各ケースを非常に効果的に説明するジョブファイルを使用しているのを見たことがあり、同僚はコメントブロックとしてパラメーターをvtuファイルに書き込むこともできると提案しました。
  • おそらく、これに多くの時間を投資する価値はまったくありませんか?それは単なる気晴らしと時間の浪費であり、テストプロセスのブルートフォースとアドホックを筋肉だけで行うのが最善ですか?

いくつかの考え

私は現在ほとんど手作業で仕事をしており、次の問題に直面しています。

  • テストケースの命名。アンダースコアで区切られた実行パラメーターなどの名前のフォルダーに結果を保存しようとしましたRe100_dt02_BDF1...。これらは、省略しすぎるとすぐに長くなり、読みにくくなります。また、実数のパラメータにはa .が含まれていますが、これは厄介です。
  • 実行データのロギング。時々、端末に書き込まれ、テキストファイルに保存された結果を確認したいことがあります。たとえば、StackOverflowからのこの回答は多少役立ちますが、解決策は少し煩わしいようです。
  • パラメータに従ってデータをプロットします。さまざまなログファイルから関連するデータを1つのファイルに収集し、それをプロットするのにかなり時間がかかります。より良いシステムであれば、おそらくこれがより簡単になります。
  • データに関するコメントの記録。結果を調べた後、テキストファイルにコメントを書き込みますが、これを結果フォルダーと同期させることは難しい場合があります。

「探索」の意味に大きく依存します。目標をより正確に述べてください。
アーノルドノイマイアー

回答:


10

あなたのポイントのうちの2つについてのコメント:

  • 実行データのロギング:最善の策は、ほとんどのシェルで使用できるはずのteeコマンドを介して出力をパイプすることです。

  • パラメーターに従ってデータをプロットする:好みの問題だと思いますが、複雑なデータの集計を行う必要がある場合、結果をプレーンテキストで保存し、マトリックスとしてMatlabに読み込み、すべての計算、プロット、さらにLaTeX出力さえ行いますそこから。明らかに、あなたが最もよく知っているプログラミング/スクリプト言語はどれでもあなたに最高の結果を与えます。


おかげで、teeコマンドは非常に便利です
マティヤケックマン

11

汎用の何かを書きたい場合は、Pedroが示唆するように、非常に単純な場合はシェルスクリプトを使用するか、PythonやMATLABなどの高レベルの数学プログラミング言語で集約することができます。プレーンテキストファイルは少量のデータには便利ですが、おそらく数メガバイトを超えるバイナリデータに切り替える必要があります。

一方、パラメータ推定を行うだけの場合は、これに特に適したソフトウェアを使用することをお勧めします。私の大学の何人かの研究者は、Sandia National Laboratoriesの不確実性定量化ツールボックスであるDAKOTAGNU Lesser General Public Licenseの下で利用可能)で幸運を持っています

以下は、DAKOTAを説明するサンディアのページからの抜粋です。

ユーザーがコンピューターシミュレーションのコレクションを実行して、モデル入力に対するモデル出力の感度を評価できるようにするさまざまな方法を提供します。一般的なカテゴリには、パラメータ研究、サンプリング方法、実験計画が含まれます。パラメータスタディでは、他の入力パラメータを固定したまま範囲内でいくつかの入力パラメータをステップし、出力の変化を評価します。サンプリング方法では、入力空間分布からサンプルを生成し、入力値での出力応答を計算します。DAKOTA内で利用可能な特定のサンプリング方法には、モンテカルロ、ラテンハイパーキューブ、および準モンテカルロが含まれます。実験計画では、代表的な方法で空間をサンプリングするために選択された一連の入力「設計」ポイントで出力が評価されます。DAKOTA内で利用可能な実験方法の具体的な設計には、Box-Behnken、Central Composite、およびFactorial設計が含まれます。感度メトリックは、入力に対する出力の依存性を表す数学的な方法です。Dakotaでは、単純相関係数や部分相関係数、ランク相関など、さまざまな感度メトリックが利用可能です。私たちの現在の研究は、最小限の実行回数で感度測定基準を生成する方法と、ベイジアン解析手法を使用したコンピューターモデルのパラメーターの最適な推定に焦点を当てています。


このような別のツールは、ドイツのGRSによって開発されたSUSAです。しかし、これは無料ではありません。
GertVdE

バイナリ形式の問題は、それらを維持するのがより難しいことです。ファイル形式が時間とともに進化することは珍しいことではないため、バイナリ形式の解析とサポートが苦痛になる可能性があります。私の経験では、プレーンテキスト、圧縮(gzip)、および一緒にスティッチするためのコマンドラインまたはpythonがすべて、数百GBでもうまく機能します。
フクルス

1
@fcruzはい、またはbzip27zipテキストの圧縮率をさらに向上させます。
アジャシャ

8

私の博士課程では、あなたと同じような問題に直面しています。ただし、私が使用しているのは私のコードではないので、私はあなたとまったく同じ柔軟性を持っていません。とはいえ、いくつかの提案があります。

ペドロが示唆したように、ティーコマンドがあります。しかし、それが利用できない場合、またはソフトウェア自体に何かを組み込みたい場合は、boost::iostreamsライブラリます。これは、標準ライブラリにはない入力ソースと出力シンクを定義するメカニズムを提供します。特に、tee_device2つの出力シンクをストリームに接続することができ、他のストリームはシンクとして機能できます。これによりstdout、ログファイル構成への同時出力と依存関係を作成できます。

boost::program_options1iniファイルはそれを達成するための苦痛な方法です。2つ目、さらに重要なことboost::program_optionsは、出力機能がないため、状態を構成ファイルとして保存して、後で検査したり、停止したコードを再開したりできないことです。別の方法として、boost::property_tree階層構成ファイルをサポートするものを使用し、後で再利用するためにツリーを保存することをお勧めします。これには、コードをチェックポイントする必要がある場合、再起動時に現在の状態を入力として保存できるという追加の利点があります。

さまざまな計算からデータを収集するには、セットに含めるすべてのデータファイルをループし、awkを使用してファイルに1行を生成し、すべての結果を出力にパイプします。これには数分かかる場合がありますが、残念ながら、私にはこれ以上の方法はありません。

データの処理/コメントに関して、Mathematicaノートブック形式の有用性を十分に強調することはできません。これにより、観測、推測、視覚化をすべて1か所で整理できます。しかし、私のノートブックは定期的に100 MBを超えています。良い測定のために、 Mathematicaは行列タスクでMatlabと同じように実行します。さらに、リアルタイムで完全な数学的フォーマットでメモ取るために使用できます。

命名の問題に対するより良い解決策があればいいのですが、それはかなり有害です。このため、データの一部をデータベースに出力することを検討する価値があります。ただし、それを望まない場合は、XFS の拡張属性を使用してシミュレーションに関するより完全な情報を取得し、生成に使用されたデータと共に構成ファイルを保存することを検討してください。

1.階層構成ファイルが必要な例として、私の友人は、AFMのさまざまなチップジオメトリの影響を調べていましたが、各ジオメトリには異なるパラメータセットがありました。さらに、これと並行して、彼はいくつかの計算スキームをテストして、それらを実験と比較できるようにしました。


1
私が最近していることは、Mathematicaからシミュレーションを駆動することです。構成ファイル、入力ファイルなどを使用してシミュレーションをコマンドラインプログラムにする代わりに、MathematicaへのLibraryLinkインターフェースを定義するだけです。この方法で、構造化された方法でパラメーターまたはデータを渡すことができ、あらゆる種類のコマンドラインオプション/入出力ファイル形式を処理する苦痛を回避できます。視覚化/作図にすぐにアクセスでき、複雑なシナリオのさまざまなパラメーターのシミュレーションの実行を簡単に自動化できます。
ザボルクス

(これがアダプティブサンプリングの問題に対処する方法です。コマンドラインからプログラムを呼び出す場合、このような処理を実装するのは非常に手間がかかり、非常に正当な理由なしに作業を開始するのは面倒です。 Mathematicaのような高レベルのシステムを使用すると、アイデアが自然に生まれるほど実験が簡単になりました。他の高レベルのシステムも同じように使用できると思います。)
Szabolcs

あなたの役に立つ答えをありがとう、私は見てみましょうboost::property_tree。別の問題boost::program_optionsは、ヘッダーのみのライブラリとしては使用できないように見えることです。これは、アプリケーションをブーストヘッダーのみを持つマシンで実行したい場合は厄介です。ちなみに、これはなぜだれか知っていますか?どうやらそれは非常に小さなライブラリです。(おそらくそれはブーストユーザーリストにこれを投稿する方が良いでしょう)
マティヤKecman

@ mk527 boost::program_optionsライブラリを強制的に作成するために何が必要かわかりません。ただし、ブーストのサブセットを抽出するためのbcpユーティリティを検討しましたか?
-rcollyer

3

PETSCをインストールするときにPyTablesを知ることができます。そして、私はまだ試していませんが、テーブル(またはデータベース)メソッドはパラメーター空間の探索に適していると思います。特定のパラメーターを使用してすべての実行を記録し、特定の条件を満たしている集計を参照できます。たとえば、dt、BDF1を修正し、関連するすべてのレコードを検索して、他のパラメーターによる変動を調べることができます。

パラメータ空間を探索するために実際にテーブル(またはデータベース)メソッドを使用している人々から話を聞きたいです。詳細な例に感謝します。


3

あなたがやろうとしているようにパラメータ空間を探索することは、すぐに扱いにくくなります。これを行うには非常に多くの異なる方法があるため、実際のソリューションはありません。

通常、作業でこの制限に達した場合、階層データ形式HDF5を調査することができます。HDF5では、シミュレーションの複雑な出力を明確に定義されたファイル形式で保存できます。利点は、データが明確に定義された単一のファイル形式で保存されることです。さまざまなパラメーターで識別される複数のシミュレーション実行をファイルに追加し、後で操作することができます。データは圧縮でき、さまざまなツールを使用して簡単に抽出できます。c / c ++ / pythonなどのAPIが簡単で、ファイルを操作するためのコマンドラインツールがたくさんあります。欠点は、hdf5への書き込みがコンソールへの書き込みほど簡単ではないことです。HDF5の例には多くのプログラム例があります


2

変数値のインデックス付きテーブルを保持する必要があります。インデックスは、各シミュレーションの入力と出力を保持するフォルダーに対応しています。したがって、これは単なるインデックスであり、各フォルダーに対応するパラメーター値を検索するため、命名規則やフォルダー階層について心配する必要はありません。

したがって、このテーブルを使用して、後処理、プロット(分析)、ログ、およびコメントを整理できます。テーブルはワークフローの中心です。

これは基本的な考え方であり、概念的にのみ行うことをお勧めします。最初の応答で、私が開発したフレームワークを調べることを提案しました。最近、スマトラを発見しました。私が個人的に開発した、苦労している卒業生よりもはるかに開発されており、Pythonの取り組みは初めてですが、やり過ぎと思います。私のフレームワークはワークフローの効率性に焦点を当てていますが、出所情報に焦点を当てています。また、職人神聖、およびlencetがいます。

あなたが何を選択したとしても、Pythonでワークフロー全体を管理できるので、これらのタイプのタスクに取り組むことを強くお勧めします。ちょっとした話として、同僚がDAKOTA、bash、GNUplot、ファイル命名規則、sed / awkオクターブなどで作業しているのを見ました。計算作業を行います。これらの各ツールはそれ自体で問題ありませんが、Pythonの科学的スタックとともに作業を管理するためにpythonを使用すると、統合グルー言語としてのpythonの力が本当に発揮されます。フレームワークを開発した後、文字通り計算作業の管理に問題はありませんでした。

/私の最初の応答が続きます/

私はpythonを使用してこの問題を解決したと思います。これらすべての問題について考えてきました。

私のレポをチェックしてください http://msdresearch.blogspot.com/2012/01/parameter-study-management-with-python.htmlをご覧ください

しかし、今のところ、フレームワークのより良い文書化に取り組んでいます。(readmeに記入するよりも複雑です!)

-マジッド・アルドサリ


1
こんにちはMajid、貢献に感謝し、SciCompへようこそ。一般に、StackExchangeサイトは外部ページへのリンクを推奨せず、サイト自体に関する詳細な回答を推奨します。シングルリンクの「広告」は強く推奨されません。この回答は現在の形式では受信されない可能性が高いため、この回答を修正または削除することをお勧めします。
アロンアフマディア14年

わかった。解決策が投稿という形で与えられるとは思わない。問題は非常に一般的です。
マジダルドサリ14年

1
あなたが考えているこれらの問題に対するあなたのアプローチを少なくとも要約してもらえますか?
クリスチャンクラソン14年

1

ここここここにあるように、調査作業中に開発した次の実装に同意する傾向があります

変数をプログラムに渡し、変更できるようにするには、定義するbashスクリプトを使用するというパラダイムを使用します

export aValue=10
export bValue=2
export idName=test

そして、C / C ++で使用します

char *env_aValue = getenv("aValue");
char *env_bValue = getenv("bValue");
char *env_idName = getenv("idName");

aValue = atoi(env_aValue)
...

これの大きな利点は次のとおりです。

  • グローバルスコープでアクセスできます。
  • Sun Grid Engine(クラスター)に移植可能です。
  • bashスクリプトで簡単に変更できます。
  • プラットフォームに依存しない、
  • パラメーターの数は非常に多くなる可能性があります(潜在的に無限)

その上、私は常にidNameを渡します。このidNameには、その実行可能ファイルによって書き込まれたすべてのファイルに初期識別情報があり(必要に応じて他のパラメーターを続けることができます)、また、 bashスクリプト、およびその実行可能ファイルのすべてのファイルが保存されます。このようにして、結果はディレクトリごとに整理されます(オプション)。


0

ほぼ完全にpythonでコーディングされた有限要素プログラムであるsfepyをチェックアウトできます。サンプルのNavier Stokes問題もあります。sfepyの操作手順は非常に簡単です。


1
この回答が質問に答えているとは思わない。ポスターにはシミュレーションがあります。別のソフトウェアでシミュレーションを完全にやり直すのではなく、既存のシミュレーションをフレームワークでラップしたいという印象を受けます。
ジェフオックスベリー

sfepyはフレームワークとしても機能し、これをブラックボックスPDEソルバーとして使用できます。しかし、ポスターはすでにかなりの時間をコーディングに費やしているので、あなたは正しいと思います。
-ShadowWarrior

0

MySQLデータベースの使用について考えたことはありますか?私はそれをやったことがありませんが、私はあなたがこのシステムを非常によくクエリできると想像できます!おそらくMongoDBのような他のシステムの方が優れているでしょう。したがって、これは単なるアイデアです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.