:ref:mdrun から最適なパフォーマンスを得る

ここでは、|Gromacs|が使用する並列化および高速化の仕組みについて概説します。目的は、|Gromacs|が分子動力学シミュレーションにおいて最も高速なパッケージの一つである理由となる、その背後にあるメカニズムを理解することです。提示された情報は、適切な並列化オプション、実行構成、および加速オプションを選択し、最適なシミュレーション性能を実現するためののに役立ちます。まず、クイックチェックリストから始めます。その後、性能に影響を与えるさまざまな側面について、より詳細な議論を行います。

パフォーマンスチェックリスト

GROMACS でのシミュレーションのパフォーマンスに影響を与える要素は多数あります。ほとんどのシミュレーションでは、大量の計算リソースが必要となるため、それらのリソースを最適化することは有益です。以下に挙げたいくつかの問題は、パフォーマンスに 2 倍の差を生じさせる可能性があります。そのため、チェックリストを確認することをお勧めします。

GROMACS 設定

  • ダブル精度を使用する場合は、本当に必要な場合にのみ使用してください。

  • FFTWライブラリをx86でコンパイルします(通常、正しいフラグは自動的に設定されます)。

  • x86環境では、gccをコンパイラとして使用してください(icc、pgi、またはCrayコンパイラではありません)。

  • POWER環境では、IBMのxlcではなく、gccを使用してください。

  • 新しいコンパイラ版を使用してください。

  • MPIライブラリ: OpenMPIは通常、優れたパフォーマンスを発揮し、問題を引き起こすことはほとんどありません。

  • 必ず、コンパイラがOpenMPをサポートしていることを確認してください(一部のClangのバージョンではサポートされていません)。

  • CUDA、OpenCL、SYCL、またはHIPをサポートするGPUをお持ちの場合は、それらを使用してください。

    • 以下のいずれかのオプションで構成してください: -DGMX_GPU=CUDA-DGMX_GPU=OpenCL-DGMX_GPU=SYCL、または -DGMX_GPU=HIP.

    • GPUを使用する場合は、最新のパフォーマンス向上機能を利用するために、お使いのGPUに対応した最新のSDKを使用してください。

    • 最新のGPUドライバーを使用してください。

    • 必ず、CPU アーキテクチャに適した GMX_SIMD を使用した gmx mdrun を使用してください。ログファイルには、不適切な設定が使用された場合に警告が表示されます。ただし、GPU や高度に並列な MPI 実行の場合、AVX2AVX512 よりも優先してください(詳細については、intra-core parallelization を参照)。

    • クラスタのヘッドノードでコンパイルする場合は、「GMX_SIMD」が、計算ノードに適していることを確認してください。

設定の実行

  • ほぼ球形の溶質の場合は、菱面体十二面体の単位セルを使用してください。

  • 2.5 fs以下の時間ステップを使用する場合は、`:mdp-value:`constraints=h-bonds`(`constraints=all-bonds`ではなく)を使用してください。その理由は次のとおりです:

    • これは、特にGPUを使用する場合に、高速です。

    • GPUを使用するモードを使用するには、これは必要です。

    • また、ほとんどの力場は、水素を含む結合のみが制約されている状態でパラメータ化されています。

  • CPUのみ、またはCPUとGPUを併用する場合、PMEメッシュ計算を1ステップごとに実行するために、複数の時間ステップを使用できます。この設定を行うには、`:mdp-value:`mts`を`yes`に設定します。

  • 多くの場合、mass-repartition-factor MDPオプションを使用して水素の質量を再分割することで、時間ステップを4 fsに増やすことができます。これにより、平衡分布には影響しませんが、ダイナミクスはわずかに遅くなります。

  • 大規模並列実行(PME)の場合、最適なパフォーマンスを得るために、PMEの実行スレッド数(gmx mdrun -npme ???)を調整する必要がある場合があります。 gmx tune_pme を使用すると、この調整を自動化できます。

  • 大規模並列実行(「gmx mdrun -multidir」など)や、ネットワークが遅い場合に、グローバルな通信がボトルネックになることがあります。この問題を軽減するには、温度や圧力などのアルゴリズムのステップサイズを大きく設定することを検討してください。

パフォーマンスの確認と改善

  • ``md.log``ファイルの末尾にアクセスして、MD計算のさまざまな部分のパフォーマンス、サイクルカウンター、および経過時間を確認してください。PP/PMEの負荷比も表示され、不均衡によりパフォーマンスが大幅に低下した場合に警告が表示されます。

  • ``md.log``には、6つのパフォーマンス指標が記録されています。シミュレーションの目的に応じて、適切な指標を選択してベンチマークを実施してください。

    ns/日

    シミュレーションシステムの特定の条件とハードウェアに合わせて、シミュレーションの処理能力を測定するための一般的な指標です。

    時間/ナノ秒

    「ns/日」の逆数として、「時間/ns」を使用すると、目的のシミュレーション時間を推定できます。

    ms/ステップ

    これは、時間ステップに依存しない指標であり、特定のシステムでパフォーマンスを測定するために使用できる、時間ステップごとの実時間(ウォールタイム)を直接測定します。

    マトム*ステップ/秒

    これは、時間ステップに依存せず、システムサイズで正規化されたシミュレーションのスループットを示す指標です。これは、同じ種類のシステムとシミュレーション設定において、ワークの量が原子の数とほぼ線形に比例するため、シミュレーションの効率を測定するものです。

    メガノンバインド力(メガ単位で、1秒あたりの値)

    このスループット指標は時間ステップに依存せず、システムサイズによって部分的に正規化されます。シミュレーションにおいて非結合相互作用が支配的となる場合、Mnbf/s を使用してハードウェアまたはアルゴリズムの効率を比較できます。

    MFlops (メガ浮動小数点演算/秒)

    これはMD固有の指標ではなく、達成されたFLOPS(1秒あたりの浮動小数点演算回数)の見積もりであり、ハードウェアの理論上の最大FLOPSと比較することができます。ただし、これはコード内の実際に実行される浮動小数点演算の見積もりであり、コンパイラによって生成されたものやプロファイリング中に測定されたものとは異なります。MFlopsとMnbf/sは、「GMX_DETAILED_PERF_STATS」という環境変数が設定されている場合にのみ表示されます。

  • PP/PMEの不均衡が大きい場合は、PMEのランク数と/またはカットオフとPMEのグリッド間隔を調整してください。 報告された不均衡が小さい場合でも、自動的なPME調整によって初期の不均衡が軽減されている可能性があります。 mdpパラメータを変更したり、PMEのランク数を増やしたりすることで、依然としてパフォーマンスを向上させることができます。

  • (特に)GPUを使用する実行時(`-update gpu`オプションを使用):

    • 頻繁なバイラルまたはエネルギー計算は、大きなオーバーヘッドを引き起こす可能性があります(そして、これはサイクルカウンターには表示されません)。このオーバーヘッドを軽減するには、nstcalcenergy の値を増やしてください。

    • 頻繁な温度または圧力の結合は、大きなオーバーヘッドを引き起こす可能性があります。これを軽減するため、アルゴリズムが許可する限り、結合の回数をできるだけ少なくしてください(通常は50〜100ステップ以上)。

  • 「近傍探索と/またはドメイン分割に時間がかかる場合は、nstlist の値を増やしてください。Verlet バッファの許容範囲を使用する場合は、gmx mdrun によって自動的に行われ、ペアリストのバッファが拡張されてエネルギードリフトが一定に保たれます。」

    • 特にマルチGPUでの実行の場合、mdrun`の起動時に`nstlist`を自動的に増やすことは、保守的で、より大きな値を使用することが最適である(例:PMEとデフォルトのVerletバッファ許容範囲を使用する場合、`nstlist=200-300)。

    • CUDAグラフを使用する場合、オーバーヘッドを最小限に抑えるために、nstlist の奇数値を避けることが推奨されます。

  • もし Comm. energies の計算に時間がかかりすぎる場合(ログファイルにメッセージが表示される)、nstcalcenergy の値を大きくしてください。

  • もしすべての通信に時間がかかりすぎる場合は、複数のコアを使用している可能性があります。あるいは、MPI/OpenMPを組み合わせて、MPIプロセスごとに2または4のスレッドを使用することを試してみてください。

  • マルチGPU環境では、コア(またはハードウェアスレッド)の数よりも、MPIの複数のランクを使用しないようにしてください。これは、複数のMPIランク間でGPUを共有することに関連するオーバーヘッドにより、大きな非効率を生み出すためです。通常、GPUあたり数ランクを使用するのが最適で、1~3ランクが推奨されます。GPUにローカルなモードや直接的なGPU間通信を使用する場合は、通常1ランク/GPUが最適です。

GROMACS のビルドシステムと :ref:`gmx mdrun ツールは、ハードウェアを検出し、効率的に活用するための、多くの組み込み機能と設定可能な機能を備えています。多くの一般的なおよび専門的な gmx mdrun の使用において、自動機能は十分に機能します。しかし、ハードウェアを最大限に活用し、科学的な成果を最大化するには、以下の内容をご覧ください!

ハードウェアに関する背景情報

現代のコンピュータハードウェアは複雑で多様であるため、いくつかの背景情報と定義を説明する必要があります。経験豊富なHPCユーザーは、このセクションをスキップできます。

コア

実際に命令を実行するハードウェアの計算ユニット。プロセッサには通常、複数のコアが含まれており、多くの場合、さらに多くのコアが含まれています。

キャッシュ

特定の種類の、コア(コア)に固有のメモリで、メインメモリよりもアクセスが非常に高速なもの。これは、人間の机の上にある書類や文具に例えられます。通常、コアには複数のキャッシュレイヤーが関連付けられています。

ソケット

同じような局所性(例えば、共有キャッシュ)を持つコアのグループ。これにより、ソケット内のコア間で計算処理を分散させるよりも、異なるソケット内のコア間で分散させる方が効率的になります。現代のサーバーおよびワークステーションクラスの機器には、通常、複数のCPUソケットが搭載されています。

ノード

同じメモリへの共有アクセスを必要とせず、ネットワークハードウェアを必要としない、粗いレベルでの局所性を共有するソケットのグループ。通常のパーソナルコンピュータまたはラックサーバがノードです。ノードは、ユーザーが利用できる、大規模な計算クラスタの最小単位であることがよくあります。

スレッド

複数のスレッドで分散処理を行うための、コアが実行する命令の流れです。 OpenMP、pthreads、winthreads、CUDA、SYCL、OpenCL、OpenACCなどの、さまざまなプログラミング抽象化が、このような分散処理の作成と管理を可能にします。 一部のハードウェアでは、1つのコアに複数のソフトウェアスレッドをマッピングできます。 Intel x86プロセッサでは、これを「ハイパースレッディング」と呼びます。より一般的な概念は、通常「同時マルチスレッディング (SMT)」と呼ばれます。 例えば、IBM Power8は、1つのコアあたり最大8つのハードウェアスレッドを使用できます。 この機能は、通常、ハードウェアBIOSまたはLinuxオペレーティングシステムの設定を通じて、有効または無効にすることができます。 |Gromacs|は、この機能を利用することで、ある程度のパフォーマンス向上を実現できます。 ほとんどの場合、新しいx86プロセッサでは、デフォルトで有効になっていますが、一部のシステムでは、管理者によって無効になっている可能性があります。 その場合、有効に戻してもらうようにお問い合わせください。有効になっているかどうか不明な場合は、ログファイル内のCPU情報の出力を確認し、オンラインで入手できるCPU仕様と比較してください。

スレッドの優先度 (ピンニング)

通常、ほとんどのオペレーティングシステムは、ソフトウェアのスレッドがコア(またはハードウェアスレッド)間で移動できるようにすることで、自動的にワークロードを調整するのを支援します。ただし、この設定を許可すると、gmx mdrun のパフォーマンスが低下する可能性があります。特に、1つのノード内でマルチスレッドを使用する場合に、その影響は顕著です。この問題を回避するために、gmx mdrun はデフォルトで、ユーザーまたはソフトウェア環境がすでに設定している場合を除き、スレッドの親プロセスを個々のコア/ハードウェアスレッドに割り当てるように設定します(または、ノード全体が実行に使用されていない場合、つまりノード共有の可能性がある場合)。スレッドの親プロセスを割り当てることは、しばしば「スレッドの固定」と呼ばれます。

MPI (メッセージパッシングインターフェース)

主要なマルチノード並列化スキームであり、プログラムが複数のノードで動作するように、標準化された言語を提供します。

順位

MPI では、ランクとは、マルチノード並列化スキームで使用される最小のハードウェアグループのことです。このグループはユーザーによって制御でき、個々のコア、ソケット、ノード、またはノードのグループに対応します。最適な選択は、ハードウェア、ソフトウェア、および計算タスクによって異なります。場合によっては、MPI ランクは MPI プロセスとも呼ばれます。

GPU

グラフィックス処理ユニット(GPU)は、特定の種類の計算ワークロードにおいて、従来のプロセッサよりも高速かつ効率的な場合があります。GPUは常に特定のノードに関連付けられており、多くの場合、そのノード内の特定のソケットに関連付けられています。

OpenMP

複数のコアで計算負荷を共有するための標準化された技術であり、多くのコンパイラでサポートされています。 頻繁にMPIと組み合わせて、ハイブリッドなMPI/OpenMP並列性を実現するために使用されます。

CUDA

NVIDIAが開発した、独自の並列コンピューティングフレームワークおよびAPIで、NVIDIAのアクセラレータハードウェアをターゲットにすることができます。|Gromacs|は、NVIDIAハードウェアでのGPUアクセラレーションをサポートするためにCUDAを使用しています。

OpenCL

C99をベースとしたコンパイラと、異種ハードウェアおよびアクセラレータ向けプログラミングAPIで構成される、オープン標準に基づく並列コンピューティングフレームワーク。|Gromacs|は、AMDデバイス(GPUおよびAPUの両方)、Intel統合GPU、Apple Silicon統合GPUでGPUアクセラレーションのためにOpenCLを使用します。また、一部のNVIDIAハードウェアもサポートしています。|Gromacs|では、OpenCLはSYCLに置き換えられています。

SYCL

C++17 をベースとしたオープンな標準で、異種システムをターゲットとするために使用されます。SYCL には複数の実装があり、そのうち GROMACS は 2 つをサポートしています: Intel oneAPI DPC++AdaptiveCpp。GROMACS は、SYCL を使用して AMD および Intel の GPU での GPU 加速を行うことができます。NVIDIA の GPU への実験的なサポートも提供しています。

HIP

AMDが開発した、その(および理論上はNVIDIA)アクセラレータハードウェアをターゲットとする並列コンピューティングフレームワークおよびAPI。|Gromacs|は、GCN、CDNA、およびRDNA AMDハードウェア上でGPUアクセラレーションのためにHIPを使用できます。

SIMD

現代のCPUコアが、1回のサイクルで複数の浮動小数点演算を実行できる、CPU命令の1つの種類。

並列化による作業の分散 GROMACS

`:ref:`gmx mdrun`で使用されるアルゴリズムとその実装は、ハードウェアを最大限に活用する方法を選択する上で最も重要です。詳細については、:ref:`Reference Manual <gmx-reference-manual-rst>`をご参照ください。特に重要なのは以下のとおりです。

ドメイン分割

ドメイン分解 (DD) アルゴリズムは、非相互作用項の (短距離) 成分を、空間的な局所性を共有するドメインに分割します。これにより、効率的なアルゴリズムの使用が可能になります。各ドメインは、ドメイン内のすべての粒子間の (PP) 相互作用を処理し、単一の MPI ランクにマッピングされます。PP ランク内では、OpenMP スレッドがタスクを共有し、一部のタスクを GPU にオフロードできます。PP ランクは、ドメイン内のすべての粒子間の結合相互作用も処理します。GPU は複数の PP ランクのタスクを実行できますが、通常は 1 つの GPU ごとに 1 つの PP ランクを使用し、そのランクに数千の粒子を使用することが最も効率的です。PP ランクのタスクを CPU で実行する場合、mdrun は、コアの SIMD 機能を広範囲に使用します。ドメイン分解アルゴリズムの動作を制御するための、さまざまな コマンドラインオプション があります。

パーティクル・メッシュ・エワルド

パーティクル・メッシュ・エワルド (PME) アルゴリズムは、非結合相互作用(クーロンおよび可能であればレンナー・ジョーズ)の長距離成分を扱います。 長距離成分の計算には、すべてのランクまたは一部のランクのみが参加できます(多くの場合、「PME」成分として単に呼ばれます)。 このアルゴリズムは、グローバルな通信を必要とする3D FFTを使用するため、参加するランク数が増えると並列効率が悪化します。 そのため、ランクのサブセット(たとえば、ランクの1分の4から1分の半分)のみを使用することが最も効率的になる場合があります。 独立したPMEランクがある場合、残りのランクはPPの計算を行います。 それ以外の場合、すべてのランクがPPとPMEの両方の計算を行います。

並列化の仕組み

GROMACS は、パフォーマンスを重視しているため、効率的な並列化に重点を置いています。 複数の並列化スキームが利用可能であるため、異なる実行構成を選択することで、同じハードウェア上でシミュレーションを実行できます。

コア内での並列化(SIMDによる):SSE、AVXなど

|Gromacs|で利用できるパフォーマンス向上レベルの1つは、Single Instruction Multiple Data (SIMD) 命令の使用です。詳細については、インストールガイドの SIMD サポート のセクションを参照してください。

GROMACS では、SIMD 命令を使用して、最もパフォーマンスに影響を与えるコードのセクションを並列化します(非結合および結合力の計算、PME および近傍検索)。これは、ハードウェア固有の SIMD カーネルを使用して実現され、これらは利用可能な 3 つのレベルの非結合カーネルの 1 つです。具体的には、参照または汎用カーネル(遅いですが、テスト用の参照値を生成するのに役立ちます)、最適化された C 言語カーネル(クロスプラットフォームで使用できますが、依然として遅い)、および SIMD 命令を加速したカーネルです。

SIMD インターニックコードはコンパイラによってコンパイルされます。技術的には、異なるレベルの加速を1つのバイナリにコンパイルすることが可能ですが、コードの多くの部分で加速を管理するのは困難です。そのため、ターゲットCPUのSIMD機能に合わせて|Gromacs|を構成し、コンパイルする必要があります。デフォルトでは、コンパイルが行われるホスト環境でサポートされている最も高い加速が検出されます。異なるアーキテクチャの異なるマシンに対してクロスコンパイルする場合は、ターゲットの加速を設定するために、-DGMX_SIMD CMakeオプションを使用できます。複数の異なるマシンで1つのインストールを使用する場合は、SIMD加速に依存しないため、最も一般的なSIMD命令セットで分析ツールをコンパイルするのが便利ですが、最高のパフォーマンスを得るには、|Gromacs|がサポートするターゲットアーキテクチャの最新の(最新)「native」SIMD命令セットを使用して、|mdrun|を個別にコンパイルする必要があります。

一部のIntel CPUアーキテクチャでは、CPUの最大クロック周波数(つまり、その速度)と、実行するSIMD命令の幅(つまり、特定の速度での処理能力)との間にトレードオフが生じます。特に、Intelの「Skylake」および「Cascade Lake」プロセッサ(例:Xeon SP Gold/Platinum)は、より高いクロック周波数が利用できるため、より狭いSIMDを使用することで、より高い処理能力を提供できます。GPUによる加速や、高度に並列化されたMPI実行においては、`GMX_SIMD=AVX2_256`を使用する:ref:`mdrun <gmx mdrun>`を、`GMX_SIMD=AVX512`を使用する代わりに、より高いパフォーマンスを得ることを検討してください。

最新のARMベースのCPU、例えば富士通のA64fxは、スケーラブルなベクトル拡張 (SVE) をサポートしています。SVEは、比較的効率的なベクトル長に依存しない (VLA) コードを生成するために使用できますが、これは|Gromacs|には適していません。なぜなら、SIMDベクトルの長さはCMake時に固定されているからです。デフォルトでは、CMake時にデフォルトのベクトル長を自動的に検出します (/proc/sys/abi/sve_default_vector_length``という疑似ファイルを使用し、``GMX_SIMD_ARM_SVE_LENGTH=<len>``で構成を変更することも可能です)。サポートされているベクトル長は128、256、512、および1024です。ただし、SIMDの短距離非結合カーネルは、各SIMDベクトルあたり最大16個の浮動小数点数のみをサポートするため、1024ビットのベクトル長は、単精度 (例:-DGMX_DOUBLE=on``) でのみ有効です。注意点として、:ref:`mdrun <gmx mdrun>`が実行時にSIMDベクトルの長さをチェックするとしても、CMake時に使用されたものとは異なるベクトル長で実行することは、定義外の動作となり、:ref:`mdrun <gmx mdrun>`がチェックに到達する前にクラッシュする可能性があります (これにより、ユーザーフレンドリーなエラーメッセージが表示されます)。

OpenMPを使用したプロセス(またはスレッド)レベルでの並列化

GROMACS mdrun は、コードのすべての部分で OpenMP マルチスレッディングをサポートしています。 OpenMP はデフォルトで有効になっており、CMake 変数 GMX_OPENMP と実行時に -ntomp オプション(または環境変数 OMP_NUM_THREADS)を使用して、構成時と実行時に有効/無効にすることができます。 OpenMP の実装は非常に効率的であり、Intel の CPU では最大 12~24 スレッド、AMD の CPU では 6~8 スレッドで良好にスケールします。

ノードレベルでの並列化:GPUオフロードとスレッド-MPIによる

マルチスレッドによるスレッドとMPIの連携

スレッド-MPIライブラリは、システムのスレッドサポートに基づいて、MPI仕様のサブセットを実装しています。POSIX pthreadsとWindowsスレッドの両方をサポートしています。MPIの代わりとして動作し、スレッド-MPIを使用すると、ネットワークを介さずに単一のコンピューター上で:ref:`mdrun <gmx mdrun>`をコンパイルして実行できます(つまり、ネットワークを介さずに)。さらに、スレッド-MPIは、場合によっては:ref:`mdrun <gmx mdrun>`をMPIを使用した場合よりもわずかに高速に実行できます。

スレッド-MPIは|Gromacs|のソースコードに含まれており、デフォルトの並列化モードであり、実質的にシリアル版の:ref:`mdrun <gmx mdrun>`は使用されなくなっています。スレッド-MPIを使用したコンパイルは、``GMX_THREAD_MPI``というCMake変数を介して制御されます。

Thread-MPI は、OpenMP、GPU などのほとんどの mdrun の機能と並列化スキームと互換性があります。ただし、MPI とマルチシミュレーションには対応していません。

デフォルトでは、スレッド-MPIコマンド <ref>`mdrun` は、適切な数のスレッドまたは OpenMP スレッドを使用して、マシン上のすべての利用可能なコアを占有します。 スレッドの数は、-nt および -ntmpi オプションを使用して制御できます。 -nt は、使用するスレッドの総数を指定します(これにはスレッド-MPI スレッドと OpenMP スレッドの両が含まれる場合があります)。

ハイブリッド/異種アクセラレーション

ハイブリッドな加速とは、利用可能なCPUとGPUの間で計算処理を分散することで、シミュレーションのパフォーマンスを向上させることを意味します。 新しい非相互作用アルゴリズムは、CPUとGPUの両方で効率的な加速を目的として開発されました。

シミュレーションの中で最も計算負荷の高い部分、すなわち非相互作用力計算、およびPME(ポテンシャルメディエイトポテンシャル)、結合力計算と更新、および制約は、GPUにオフロードして、残りのCPU処理と並行して実行できます。 |Gromacs|で最も一般的に使用されているアルゴリズムに対して、ネイティブなGPUアクセラレーションがサポートされています。GPUカーネルに関する詳細については、:ref:`インストールガイド <gmx-gpu-support>`を参照してください。

ネイティブなGPUアクセラレーションは、実行時に`:ref:mdrun <gmx mdrun>`コマンドの-nb`オプションを使用するか、設定時に`GMX_GPU`というCMake変数を設定することで、有効または無効にすることができます。

利用可能なすべての計算リソースを効率的に活用するために、CPUとGPUでの計算を同時に行います。CPUでは、OpenMPによるマルチスレッド化された力場計算とPMEによる長距離静電計算を並行して実行し、GPUでは非結合の力を計算します。ドメイン分割により、複数のGPU(単一ノード内だけでなく、複数のノード間でも)をサポートします。各ドメインの非結合計算には、単一のGPUが割り当てられるため、使用するGPUの数は、シミュレーションを開始するMPIプロセス(またはスレッド-MPIスレッド)の数と一致する必要があります。利用可能なCPUコアはプロセス(またはスレッド-MPIスレッド)間で分割され、GPUを搭載したコアがそれぞれのドメインで計算を行います。

PME静電力を利用する場合、mdrun は、CPU で実行される PME メッシュ計算から、GPU で実行される粒子間の非相互作用計算へのワークロードの自動的な CPU-GPU の負荷分散をサポートします。 起動時に、最初の数千ステップの MD の間に、いくつかの調整フェーズが実行されます。 これらのフェーズでは、CPU-GPU の最適な負荷分散を得るために、静電力のカットオフと PME グリッド間隔を調整し、その値を決定します。 rcoulomb オプションを使用して指定されるカットオフ値(=rvdw)は、調整を開始する最小の静電力カットオフを表し、したがって、可能な限り小さく(ただし、シミュレーションされる物理に適した値)設定する必要があります。 レン・ハード・ジョーンズカットオフ(rvdw)は固定されます。 より短いカットオフにスケールすることは許可しません。なぜなら、rvdw を変更すると、力場パラメータの有効性が損なわれ、パフォーマンスの向上が見られないからです。

自動的なCPU-GPU負荷分散は、常に最適なカットオフ設定を見つけようとしますが、必ずしもCPUとGPUの負荷を完全に分散できるとは限りません。これは、最短カットオフ設定を用いても、CPUスレッドが結合力を計算し、PMEを完了する前に、GPUが非結合力計算を完了しない場合に発生します。このような場合、CPUはGPUの待機状態となり、ログファイルの最後に表示されるサイクルとタイミングのサマリーテーブルには「Wait GPU NB local」と表示されます。

複数のノードでの並列化によるMPI

|Gromacs|におけるMPI並列化の中核は、動的な負荷分散を備えた中立領域:ref:ドメイン分割 <gmx-domain-decomp>`です。複数のマシン(例えば、クラスタのノード)でシミュレーションを並列化するには、`mdrun <gmx mdrun>`をMPIでコンパイルする必要があります。これは、``GMX_MPI` CMake変数を設定することで有効にできます。

ドメイン分割アルゴリズムの制御

このセクションでは、ドメイン分割アルゴリズムが利用可能な並列ハードウェアにタスクをどのように割り当てるかを制御するオプションをリストしています。

-rdd

これを使用して、インターチャージグループ間の結合相互作用に必要な最大距離を設定できます。非結合距離以下の二体結合相互作用の通信は、常に非結合通信と共に行われます。非結合距離を超える粒子は、結合相互作用が欠けている場合にのみ通信されます。つまり、追加のコストはわずかであり、-rdd`の値にほとんど依存しません。動的な負荷分散を使用する場合、オプション `-rdd はドメイン分割セルの最小サイズも設定します。デフォルトでは、-rddgmx mdrun に基づいて、初期座標から決定されます。選択した値は、相互作用範囲と通信コストのバランスになります。

-ddcheck

デフォルトで有効になっています。インターチャージ・グループ間の結合相互作用が結合のカットオフ距離を超えた場合、gmx mdrun はエラーメッセージとともに終了します。ペア相互作用や、除外を生成しない結合相互作用については、オプション -noddcheck を使用して、このチェックを無効にすることができます。

-rcon

制約が存在する場合、オプション -rcon はセルサイズの制限にも影響します。NC制約によって接続された粒子(NCはLINCSの1を加えた値)は、最小のセルサイズを超えてはなりません。このような場合、エラーメッセージが表示され、ユーザーは分割方法を変更するか、LINCSの順序を減らし、LINCSの反復回数を増やす必要があります。デフォルトでは、gmx mdrun はP-LINCSに必要な最小のセルサイズを保守的に推定します。高い並列化の場合、P-LINCSに必要な距離をオプション -rcon で設定することが役立つ場合があります。

-dds

動的な負荷分散を行う際に、セルの最小許容 x、y および/または z スケーリングを設定します。 gmx mdrun は、セルのサイズが少なくともこの要因で縮小されることを保証します。 このオプションは、自動的な空間分割(-dd を使用しない場合)だけでなく、グリッドパルスの数を決定するために使用され、これにより最小許容セルのサイズが設定されます。 状況によっては、システムにおける空間的不均一性が高い場合や低い場合に、-dds の値を調整する必要がある場合があります。

マルチレベル並列化: MPIとOpenMP

マルチコアのトレンドは、CPU開発における並列化の必要性を裏付けています。現在のマルチプロセッサマシンには、64個までのコアを持つ2~4個のCPUを搭載できます。メモリとキャッシュサブシステムがマルチコアの進化に追いついていないため、これは非均一なメモリアクセス(NUMA)の影響を強調し、それがパフォーマンスのボトルネックとなる可能性があります。同時に、すべてのコアは同じネットワークインターフェースを共有します。純粋なMPI並列化のシナリオでは、すべてのMPIプロセスが同じネットワークインターフェースを使用し、MPIのノード内での通信は通常効率的ですが、ノード間の通信が並列化の制約となる可能性があります。特に、PME(非常に通信集約的な処理)や、遅いネットワークで接続された「太い」ノードを使用する、高度な並列シミュレーションにおいては、この問題が顕著になります。マルチレベル並列化は、効率的なノード内並列化(通常はマルチスレッディング)を使用して、NUMAおよび通信に関連する問題を解決することを目的としています。

OpenMPとMPIを組み合わせることで、特に個別のマルチスレッドPME(並列プログラム実行モデル)を実行する場合、追加のオーバーヘッドが発生します。アーキテクチャ、入力システムのサイズ、その他の要因によって、MPI+OpenMPの実行は、少数のプロセス(例:マルチプロセッサのIntel WestmereまたはSandy Bridge)で既に高速または高速になる可能性がありますが、他のシステム(例:マルチプロセッサのAMD Interlagosマシン)では大幅に遅くなることもあります。ただし、高度に並列化された実行では、マルチレベルの並列化によるメリットがより顕著です。

PME のランクを分離する

CPU ランクにおいては、粒子-粒子 (PP) および PME 計算は、順番に同じプロセスで行われます。PME は、すべてのプロセス間のグローバル通信を必要とするため、これは大規模なコア数での並列化における最も制限要因となることが多いです。PME 計算のみに一部のランクを割り当てることで、並列実行のパフォーマンスを大幅に向上させることができます。

PME のランクでの OpenMP マルチスレッディングも可能です。PME でマルチスレッディングを使用すると、高い並列化においてパフォーマンスが向上する可能性があります。その理由は、N > 1 のスレッドを使用する場合、通信するプロセスの数、およびそれによって送信されるメッセージの数が N 倍に減少するためです。ただし、現代の通信ネットワークは複数のメッセージを同時に処理できるため、より多くのプロセスが通信することが有利になる場合があります。

低レベルでの並列化では、個別のPME(プロセスのメッシュ)の割り当ては行われません。並列化レベルが高くなると、この割り当ては自動的に行われます(16プロセスを超える場合)。mdrunは、PMEの負荷とPP(プロセスのペア)の負荷に基づいて、PMEの数を推定します。PMEの負荷がPPの負荷よりも高い場合、mdrunは自動的に負荷を分散しますが、これにより追加の(非結合)計算が発生します。これにより、多数のPMEの割り当てがアイドル状態になるのを防ぎます。通常、PMEの割り当てはPPの割り当ての3/4程度です。ただし、高い並列化における最高の絶対的なパフォーマンスを確保するためには、この数を調整することをお勧めします。この調整は、:ref:`tune_pme`ツールによって自動的に行われます。

PME のランク数は、コマンドラインで -npme オプションを使用することで手動で設定できます。また、PME スレッドの数は、コマンドラインで -ntomp_pme オプションを使用するか、または環境変数 GMX_PME_NUM_THREADS を使用して指定できます。特に、異なる数のコアを持つ計算ノードで実行する場合に便利です。この方法を使用すると、異なるノードで異なる数の PME スレッドを設定できます。

単一ノード内で `:ref:`mdrun`<gmx mdrun>`を実行する

gmx mdrun は、単一の ノード`内で効率的に使用できるように、いくつかの異なる方法で構成およびコンパイルできます。 適切なコンパイラを使用したデフォルト構成を使用すると、CUDA/SYCL/OpenCL、OpenMP、およびハードウェア固有のスレッドプラットフォームを使用するマルチレベルのハイブリッド並列処理が展開されます。 プログラミングの利便性のため、|Gromacs| では、これらのハードウェア固有のスレッドを使用して、ノード間の使用される同じ MPI スキーమ్‌を単一ノードで実装できますが、はるかに効率的です。 これをスレッド-MPI と呼びます。 ユーザーの視点からは、実際の MPI とスレッド-MPI はほぼ同じように見え、|Gromacs| は、注記されている場合を除き、MPI レングをどちらか一方のいずれかとして参照します。 実際の外部 MPI は :ref:`gmx mdrun のために単一ノード内で使用できますが、スレッド-MPI バージョンよりも実行速度が遅くなります。

デフォルトでは、gmx mdrun は実行時に利用可能なハードウェアを調べ、ノード全体を効率的に使用するように努めます。ログファイル、stdout、stderr は、ユーザーに選択内容と、それに関連する可能性のある影響について通知するための診断情報を出力するために使用されます。

いくつかのコマンドラインパラメータを使用して、デフォルトの動作を変更できます。

-nt

使用するスレッドの総数。デフォルト値は0で、利用可能なコア数と同じ数のスレッドを開始します。スレッドがMPIランクのスレッド、またはそのようなランク内のOpenMPスレッドであるかどうかは、他の設定によって異なります。

-ntmpi

使用するスレッド-MPIのランクの総数。デフォルト値は0で、GPU(存在する場合)ごとに1つのランクを開始し、それ以外の場合は1つのランクをコアごとに開始します。

-ntomp

利用可能なコアごとに開始するOpenMPスレッドの総数。デフォルト値は0で、これにより各利用可能なコアに1つのスレッドが開始されます。あるいは、mdrun <gmx mdrun>`は、設定されている場合は適切なシステム環境変数(例:``OMP_NUM_THREADS`)を尊重します。ただし、OpenMPスレッド(1つのランクあたり)の最大数は、効率を考慮して128に制限されています。通常、この数を超えるスレッドを使用することは推奨されませんが、GMX_OPENMP_MAX_THREADS CMake変数を変更することで、この制限を増やすことができます。

-npme

PME の長距離コンポーネントに割り当てる、合計のランク数。 デフォルト値 -1 は、合計のスレッド数が 12 以上の場合にのみランクを割り当て、その場合、長距離コンポーネントに約 1 分の 4 のランクを割り当てます。

-ntomp_pme

PME を使用して個別の PME ランクを使用する場合、各 PME ランクごとの OpenMP スレッドの総数は、デフォルト値である 0 は -ntomp からの値を使用します。

-pin

「auto」、「on」、「inherit」、または「off」に設定することで、mdrun がスレッドをコアに割り当てることを試みるかどうかを制御できます。 デフォルトは「auto」で、これは mdrun がノード上のすべてのコアが mdrun 用に使用されていることを検出し、外部ツール(MPIランチャーや numactl など)によって外部の CPU アフィニティ設定が明示的に設定されていない場合、"on" の動作と同じように、アフィニティを設定しようとします。 「on」の場合、mdrun はスレッドのアフィニティを設定し、外部の CPU アフィニティ設定を上書きします。「inherit」の場合、mdrun は外部のアフィニティマスク内でスレッドのアフィニティを設定します。つまり、外部ツールまたはジョブスケジューラが各プロセスを特定のコア/ハードウェアスレッドのセットに制限する CPU アフィニティを設定した場合、ref:mdrun のスレッドはこれらの境界内で固定されます。「on」と「inherit」の動作は類似しており、どちらもスレッドの固定を有効にします。ただし、範囲が異なります。「on」はシステム上のすべての利用可能な CPU コアにスレッドを固定しますが、「inherit」は外部のアフィニティマスク内のスレッドのみを固定します。この範囲の違いは、-pinoffset および -pinstride オプションの動作にも影響します。

-pinoffset

「-pin on」または「-pin inherit」を指定すると、最初のスレッドを論理的なコアに固定するコア番号を指定できます。ノードで複数の mdrun インスタンスを実行する場合、このオプションを使用して、異なる mdrun インスタンスのスレッドを同じコアに固定しないようにします。「-pin on」を使用する場合、オフセットはすべての利用可能なCPUに対して適用されます。一方、「-pin inherit」を使用する場合、オフセットは外部のアフィニティマスク内のコアに対して適用されます。

-pinstride

「-pin on」または「-pin inherit」を指定すると、mdrun がスレッドを割り当てる論理的なコアの数におけるコアを指定できます。ノードで mdrun の複数のインスタンスを実行する場合は、異なる mdrun インスタンスのスレッドを同じコアに割り当てるのを防ぐために、このオプションを使用します。デフォルト値である 0 を使用して、各物理コアあたりのスレッド数を最小限に抑えることができます。これにより、mdrun は、ハードウェア、OS、および構成固有の詳細に基づいて、論理的なコアを物理的なコアにマッピングする方法を管理できます。「-pin on」を使用する場合、スレッドは利用可能なすべての CPU に適用されます。一方、「-pin inherit」を使用する場合、スレッドは外部のアフィニティマスク内でのみ適用されます。

-ddorder

設定できる値は「interleave」、「pp_pme」、または「cartesian」です。デフォルトは「interleave」で、これにより個別のPMEランクは、PP、PP、PME、PP、PP、PMEなどの順序でMPIランクにマッピングされます。これにより、利用可能なハードウェアを最大限に活用できます。「pp_pme」は、まずすべてのPPランク、次にすべてのPMEランクをマッピングします。「cartesian」は、特殊なトポロジーネットワーク(特に、カルテシアン通信を高速化するグローバル通信をサポートするネットワーク)でのみ役立つ特殊なマッピングです。個別のPMEランクがない場合は効果がありません。

-nb

短距離非相互作用の実行場所を設定するために使用します。 "auto"、"cpu"、または "gpu" のいずれかに設定できます。 デフォルトは "auto" で、利用可能な互換性のある GPU が使用されます。 "cpu" を設定するには、GPU は使用しないでください。 "gpu" を設定するには、互換性のある GPU が利用可能で、使用されます。

-pme

使用して、長距離の非結合相互作用の実行場所を設定します。 "auto"、"cpu"、または "gpu" のいずれかに設定できます。 デフォルトは "auto" で、利用可能な互換性のある GPU を使用します。 "gpu" を設定するには、互換性のある GPU が利用可能である必要があります。 GPU で PME を使用する場合、複数の PME ランクはサポートされません。 そのため、GPU を使用して PME を計算する場合は、-npme を 1 に設定する必要があります。

-bonded

ドメイン内のPPワークロードの一部である、結合相互作用の実行場所を設定するために使用されます。 「auto」、「cpu」、「gpu」のいずれかに設定できます。 デフォルトは「auto」で、利用可能な場合にのみ互換性のあるCUDAまたはSYCL GPUを使用し、短距離相互作用はGPUで、長距離相互作用(静電またはLJ)はCPUで処理します。 結合相互作用の処理は、短距離相互作用と同じGPUで行われ、個別に割り当てることはできません。「gpu」を設定する場合、互換性のあるGPUが利用可能である必要があります。

-update

使用して、更新と制約を実行する場所を設定します(存在する場合)。「auto」、「cpu」または「gpu」に設定できます。デフォルトは「auto」で、現在は常にCPUを使用します。「gpu」を設定するには、互換性のあるCUDAまたはSYCL GPUが利用可能である必要があります。シミュレーションでは、単一のランクが使用されます。GPUでの更新と制約は、現在、マージと制約のない自由エネルギー摂動、ドメイン分解、仮想サイト、Ewald表面補正、レプリカ交換、制約引き、方向制約、および計算電生理学にはサポートされていません。

-gpu_id

各ノードでタスクが使用できるGPUのID番号を指定する文字列。例えば、「12」と指定すると、GPUのIDが1と2(GPUランタイムによって報告される)を使用できます。これは、他の計算と共有されたノードを使用する場合、またはディスプレイ用に割り当てられたGPUを|Gromacs|が使用しない場合に役立ちます。このパラメータを指定しない場合、mdrun <gmx mdrun>`はすべてのGPUを使用します。多数のGPUが存在する場合、カンマを使用してIDを区切ることができます。例えば、「12,13」と指定すると、GPU 12と13を:ref:`mdrun <gmx mdrun>`が使用できるようになります。シミュレーションの異なるノードで異なるGPUを使用する必要がある場合、環境変数 ``GMX_GPU_ID` を異なるノードのタスクごとに異なる値に設定することで、これを実現できます。|Gromacs|の2018年以前のバージョンでは、このパラメータはGPUの可用性とGPUタスクの割り当ての両方を指定するために使用されていました。現在、GPUタスクの割り当ては、``-gputasks``パラメータを使用して行われます。

-gputasks

このノードで実行される対応するGPUタスクが使用するGPUのID番号を指定する文字列です。たとえば、「0011」は、最初の2つのGPUタスクがGPU 0を使用し、残りの2つがGPU 1を使用することを指定します。このオプションを使用する場合、:ref:`mdrun``に対して、タスクの種類ごとにどこで実行するか(たとえば、-nb gpu`を使用するなど)を知っている必要があります。ただし、このオプションを使用する場合、タスクがGPUで実行されるように設定されているもののみがマッピングの解析に使用されます。詳細については、「GPUへのタスクの割り当て」を参照してください。注意:-gpu_id`と-gputasks`は同時に使用できません!|Gromacs|の2018年以前のバージョンでは、任意のランクで1種類のGPUタスク(「PP」)のみを実行できました。現在、PMEをGPUで実行するためのサポートがあるため、単一のランクでのシミュレーションでは、GPUタスク(および`-gputasks`文字列で期待されるGPUIDの数)は実際には3つになる可能性があります。ただし、複数のGPUを単一のランクで使用する機能はまだ実装されていません。したがって、IDは同じである必要があります。文字列内のランクごとのGPUタスクの順序は、PPが最初に、PMEが2番目に実行されます。異なる種類のGPUタスクを持つランクの順序はデフォルトでは同じですが、-ddorder`オプションを使用して変更でき、複数のノードを使用する場合に非常に複雑になります。注意:PPタスクの結合相互作用は、短距離の計算と同じGPUで実行されるか、CPUで実行される可能性があります。これは、-bonded`フラグを使用して制御できます。GPUタスクの割り当て(手動で設定するか、自動化するか)は、シミュレーションの最初の物理ノードの`:ref:`mdrun``の出力で報告されます。たとえば:

gmx mdrun -gputasks 0001 -nb gpu -pme gpu -npme 1 -ntmpi 4

以下のような出力がログファイル/ターミナルに表示されます:

On host tcbl14 2 GPUs selected for this run.
Mapping of GPU IDs to the 4 GPU tasks in the 4 ranks on this node:
PP:0,PP:0,PP:0,PME:1

この場合、ユーザーはGPU 0でPPの計算に3つのスレッド、およびGPU 1でPMEの計算に1つのスレッドを設定します。GPUの詳細なインデックスもログファイルに報告されます。

GPUタスクに関する詳細については、 GPUタスクの種類 を参照してください。

-pmefft

3D FFT の計算を CPU または GPU で実行するかどうかを選択できます。「auto」、「cpu」、または「gpu」のいずれかに設定できます。PME を GPU にオフロードする場合(例:-pmefft gpu)、デフォルトでは GPU 上で PME の計算全体が実行されます。ただし、比較的遅い GPU または古い世代の GPU と、高速な CPU コアを組み合わせた場合に、CPU で FFT を計算することで、一部の処理を GPU から CPU に戻すことで、パフォーマンスを向上させることができます。

例:mdrun を 1 つのノードで実行する

gmx mdrun

開始:mdrun を利用可能なすべてのリソースを使用して開始します。mdrun は、自動的に効率的なスレッドと MPI、OpenMP スレッドの割り当て、および互換性のある GPU にタスクを割り当てる、比較的効率的な割り当てを行います。詳細は、ハードウェアと実行されているシミュレーションの種類によって異なります。

gmx mdrun -nt 8

開始:mdrun を 8 スレッドで実行します。スレッドは、ハードウェアと実行中のシミュレーションの種類に応じて、スレッド-MPI または OpenMP スレッドになります。

gmx mdrun -ntmpi 2 -ntomp 4

開始:mdrun を、合計8つのスレッドを使用して実行します。スレッドとMPIのランクは2つ、各ランクあたり4つのOpenMPスレッドを使用します。これらのオプションは、最適なパフォーマンスを得る場合にのみ使用し、作成したランクのすべてのOpenMPスレッドが同じソケットで実行されるように注意してください。ランクの数はソケットの数で割り切れる数である必要があります。また、ノードあたりのコア数は、各ランクあたりのスレッドの数で割り切れる数である必要があります。

gmx mdrun -ntmpi 4 -nb gpu -pme cpu

開始:mdrun を、4つのスレッドとMPIランクを使用して実行します。利用可能なCPUコアは、OpenMPスレッドを使用して、各ランクに均等に割り当てられます。長距離の力の計算は、CPUで行われます。これは、CPUがGPUよりも比較的強力なハードウェアでは最適です。結合された力の計算は、長距離の力の計算がCPUで行われているため、自動的にGPUに割り当てられます。

gmx mdrun -ntmpi 1 -nb gpu -pme gpu -bonded gpu -update gpu

開始:mdrun を、利用可能なすべての CPU コアを使用する単一のスレッド/MPI レングを使用します。GPU で実行できるすべてのインタラクション タイプが実行されます。これは、CPU が GPU よりも非常に弱いハードウェアの場合に最適です。

gmx mdrun -ntmpi 4 -nb gpu -pme cpu -gputasks 0011

開始:mdrun を 4 つのスレッド(MPI ランク)を使用して実行し、それらを GPU 0 と GPU 1 にマッピングします。利用可能な CPU コアは、OpenMP スレッドを使用して、各ランクに均等に割り当てられます。最初の 2 つのランクは、GPU 0 に短距離の非相互作用力計算をオフロードし、最後の 2 つのランクは GPU 1 にオフロードします。力の長距離コンポーネントは CPU で計算されます。これは、CPU が GPU よりも比較的強力なハードウェアでは最適です。

gmx mdrun -ntmpi 4 -nb gpu -pme gpu -npme 1 -gputasks 0001

開始:mdrun を 4 つのスレッド(MPI ランク)を使用して実行します。そのうち 1 つは、長距離の PME 計算に専用です。最初の 3 つのスレッドは、GPU ID 0 に割り当てられた短距離の非相互作用計算をオフロードし、4 番目のスレッド(PME)は GPU ID 1 に計算をオフロードします。

gmx mdrun -ntmpi 4 -nb gpu -pme gpu -npme 1 -gputasks 0011

上記例と同様に、3つのランクを割り当てて短距離の非相互作用力を計算し、1つのランクを割り当てて長距離の力を計算します。この場合、3つの短距離ランクのうち2つがGPU 0に非相互作用力の計算をオフロードします。IDが1のGPUは、3番目の短距離ランクの短距離力と、PME専用のランクの長距離力を計算します。この例または上記の例が最適であるかは、個々のGPUとシステムの構成によって異なります。

gmx mdrun -gpu_id 12

開始:mdrun を、ID 1 と 2 の GPU を使用して実行します(たとえば、GPU 0 がディスプレイの実行用に予約されている場合)。これには、2 つのスレッド-MPI ランクと、OpenMP スレッドを使用して利用可能な CPU コアをそれらに分割する必要があります。

gmx mdrun -nt 6 -pin on -pinoffset 0 -pinstride 1
gmx mdrun -nt 6 -pin on -pinoffset 6 -pinstride 1

開始します。2つの`:ref:mdrun`プロセスを開始し、それぞれに合計6つのスレッドを配置します。スレッドは、物理的なコアを異なるセットに割り当てることで、プロセス同士の影響を最小限に抑えます。スレッドは、それぞれ1番目と7番目の論理的なコアにアフィニティを設定します。上記の構成は、6つの物理コアとハイパースレッディングを有効にしたIntel CPUでうまく機能します。この構成は、:ref:`mdrun`を特定のコアに制限し、他のプロセスとノードを共有する場合にのみ使用してください。注意点:論理的なCPU/コアと物理的なコアの間のマッピングは、オペレーティングシステムによって異なる場合があります。Linuxでは、`cat /proc/cpuinfo`を使用してこのマッピングを確認できます。

mpirun -np 2 gmx_mpi mdrun

外部MPIでコンパイルされた:ref:`gmx mdrun`を使用する場合、このプログラムは2つのプロセスと、ハードウェアおよびMPIの設定が許可する範囲内のOpenMPスレッドを開始します。MPIの設定が1つのノードに制限されている場合、結果の:ref:`gmx mdrun`は、そのノードに局所化されます。

gmx mdrun -ntmpi 8 -nb gpu -pme gpu -npme 1 -bonded gpu -update gpu

開始:mdrun を、利用可能なすべての CPU コアと GPU を使用する 8 つのスレッドと MPI ランクを使用して実行します。 GPU で実行できるすべてのインタラクションタイプが実行されます。 1 つの GPU (および MPI ランク) は、長距離の力に専念されます。 これは、データセンターの GPU を使用するハードウェアでは最適です。

mpirun -np 8 gmx_mpi mdrun -nb gpu -pme gpu -npme 2 -bonded gpu -update gpu

開始:mdrun を、8つのMPIランクを使用して実行します。これにより、mpirun がCPUコアとGPUをMPIランクにマッピングする方法を決定できます。GPUで実行できるすべてのインタラクションが実行されます。2つのGPU(およびMPIランク)は、長距離の力に割り当てられ、|Gromacs|が適切なライブラリ(例:cuFFTMpまたはHeFFTe)で分散GPU 3D-FFT用に構成され、および環境変数`GMX_GPU_PME_DECOMPOSITION`が設定されている場合にのみ動作します(この実行パスは現在検証中です)。NVLINKのような特殊なインターコネクトを備えたHPCノードでは、これが最適である可能性があります。

複数のノードで `:ref:`mdrun`<gmx mdrun>`を実行する

これには、外部MPIライブラリを使用してGromacsをビルドするように設定する必要があります。 デフォルトでは、この mdrun <gmx mdrun>`実行可能ファイルは、``gmx_mpi mdrun``を使用して実行されます。 単一ノードでの :ref:`mdrun <gmx mdrun>`の実行に関するすべての考慮事項は適用されますが、`-ntmpi``および``-nt``は致命的なエラーを引き起こし、代わりにMPI環境でスレッド数を制御します。 複数のノードを使用する場合は、``-npme``のような設定が非常に重要になります。 通常、1つのコアあたり1つのスレッドを生成するようにMPI環境を設定することは、強スケール限界に近づくまで良好です。 その時点で、MPIスレッドのワークを1つ以上のコアに分散するためにOpenMPを使用することで、絶対的なパフォーマンスを向上させることができます。 スケーリング限界の場所は、プロセッサ、GPUの有無、ネットワーク、シミュレーションアルゴリズムによって異なりますが、最大スループットが必要な場合は、約200粒子/コアあたりで測定することをお勧めします。

これらの状況では、さらに関連するコマンドラインパラメータがあります。

-tunepme

デフォルトでは「オン」に設定されます。「オン」に設定されている場合、シミュレーションはPMEの`:mdp:rcoulomb`とfourierspacing`パラメータを、両方を同じ値でスケーリングすることで最適化します。これにより、計算負荷が異なるスレッドやGPU間で分散され、最適なパフォーマンスを得ることができます。一部の:ref:`mdrun <gmx mdrun>`機能はこのオプションと互換性がないため、このオプションは無視されます。許容できる程度の等価性は、使用状況によって異なる場合があります。例えば、レプリカ交換などのマルチレプリカシミュレーションでは、異なるレプリカに対してPMEパラメータを異なる値に設定することで、異なるレプリカが使用するPMEパラメータに応じて、わずかに異なるポテンシャルエネルギーを計算できます。

-dlb

「auto」、「no」、または「yes」に設定できます。デフォルトは「auto」です。MPIのランク間で動的な負荷分散を行うことで、最高のパフォーマンスを得ることができます。特に、粒子や相互作用の密度が異なる分子系では重要です。パフォーマンスの損失が特定の閾値を超えると、DLBが起動し、粒子をランク間で移動させてパフォーマンスを向上させます。利用可能な場合は、-bonded gpu``を使用すると、DLBがパフォーマンスを最大化する能力が向上すると期待されます。DLBは、GPU上で並列化された実行(-update gpu``を使用した場合)には互換性がないため、そのようなシミュレーションでは無効になります。

シミュレーション中に、:ref:`gmx mdrun は、ログファイルへのレポートや、例えば温度カップリングなどの計算に必要な量について、すべての PP ランク間で通信する必要があります。デフォルトでは、これは、複数の :ref:`mdp オプション<mdp-general> を尊重するために、必要なときに自動的に発生します。そのため、通信フェーズ間の期間は、nstcalcenergy:mdp:`nsttcouple、および :mdp:`nstpcouple の最大公約数を表します。

注意:オプション -tunepme は、複数の :term:node が存在する場合に、より大きな効果を発揮します。これは、PP と PME のランク間の通信コストが異なるためです。ただし、PP と PME のランク間の負荷分散は引き続き行われますが、使用されている PME のランクの数は変わりません。

また、-dlb-tunepme は互いに干渉する可能性があるため、そのようなパフォーマンスの変動が発生する場合は、PME を個別に調整し、結果を mdrun -notunepme -dlb yes で実行することを検討してください。

コマンドラインツール :ref:`gmx tune_pme を使用すると、より広範なパラメータ空間を探索できます。これには、:ref:`tpr ファイルの安全な変更や -npme の値を変更することが含まれます。このツールは、MPI 環境によって作成されたスレッドの数を認識するだけで、最適化中に OpenMP のどの側面も明示的に管理しません。

例:複数のノードで mdrun を実行する

以下の例と説明は、単一ノードでの mdrun の使用に依然として適用されますが、-ntmpi オプションは、MPI のプロセス数を指定する方法としては使用されなくなりました。

mpirun -np 16 gmx_mpi mdrun

開始:gmx mdrun を 16 のランクで実行します。これらのランクは、MPIライブラリによってハードウェアにマッピングされ、例えば、MPIホストファイルで指定されたようにします。利用可能なコアは、OpenMPスレッドを使用して、ハードウェアと環境設定(例えば、OMP_NUM_THREADS)に応じて自動的にランク間で分割されます。

mpirun -np 16 gmx_mpi mdrun -npme 5

開始:gmx mdrun を 16 ランクで起動し、上記の構成を使用します。そのうち 5 ランクは PME コンポーネントに割り当てます。

mpirun -np 16 gmx_mpi mdrun -ntomp 2 -npme 6 -ntomp_pme 1

開始:gmx mdrun を 16 ランクで実行し、上記のように、6 つのランクを PME コンポーネントに割り当て、それぞれ 1 つの OpenMP スレッドを使用します。残りの 10 ランクは PP コンポーネントを実行し、それぞれ 2 つの OpenMP スレッドを使用します。

mpirun -np 4 gmx_mpi mdrun -ntomp 6 -nb gpu -gputasks 00

開始:gmx mdrun を、2つのノードを持つマシンで実行し、合計4つのランクを使用します。各ランクには6つのOpenMPスレッドがあり、両方のランクは同じノードにGPU(ID 0)を共有します。

mpirun -np 8 gmx_mpi mdrun -ntomp 3 -gputasks 0000

上記と同様/類似のハードウェアを使用し、2つのノードを持つマシンで gmx mdrun を実行します。この構成では、合計8つのランクを使用し、各ランクには3つのOpenMPスレッドがあり、ノード内の4つのランクがID 0のGPUを共有します。同じハードウェアを使用した場合、この構成が以前の設定よりも高速になるかどうかは不明です。

mpirun -np 20 gmx_mpi mdrun -ntomp 4 -gputasks 00

開始:gmx mdrun を 20 のランクで実行し、各ランクに OpenMP スレッドを均等に割り当てます。この設定は、10 台のノード(各ノードに 1 つの GPU があり、各ノードに 4 つのコアが 2 つのソケットを持つ場合)に適している可能性があります。

mpirun -np 10 gmx_mpi mdrun -gpu_id 1

開始:gmx mdrun を 10 のランクで実行し、各ランクに CPU コアを均等に割り当てます。各コアを 1 つの OpenMP スレッドに割り当てる設定は、各ノードに 2 つの GPU がある 10 個のノードの場合に適しています。ただし、各ノードで別のジョブが GPU 0 を使用している場合です。ジョブスケジューラは、両方のジョブのスレッドの親プロセスを割り当てられたコアに設定する必要があります。そうしないと、gmx mdrun のパフォーマンスが大幅に低下します。

mpirun -np 20 gmx_mpi mdrun -gpu_id 01

開始:gmx mdrun を 20 のランクで実行します。この設定は、10 台のノード(各ノードに 2 つの GPU が搭載されている場合)に適している可能性がありますが、通常、ノード上のすべての GPU が使用可能である場合は、-gpu_id を指定する必要はありません。

mpirun -np 16 gmx_mpi mdrun -nb gpu -pme gpu -npme 4 -bonded gpu -update gpu

開始:mdrun を、16 の MPI ランクを使用して実行します。これにより、mpirun が CPU コアと GPU を MPI ランクにマッピングする方法を決定します。通常、これは 2 つのノード(それぞれ 8 つの GPU を含む)で実行されます。GPU で実行できるすべてのインタラクションが実行されます。4 つの GPU(および MPI ランク)は、長距離の力に割り当てられ、GROMACS が適切なライブラリ(例:cuFFTMp または HeFFTe)で分散 GPU 3D-FFT 用に構成され、環境変数 GMX_GPU_PME_DECOMPOSITION が設定されている場合にのみ動作します(この実行パスは現在検証中です)。NVLINK などの特殊なインターコネクトを備えた HPC ノードでは、これが最適になる可能性があります。

制約によるコミュニケーションの回避

MDステップの実行時間が非常に短い(特にスケール上限に近い場合)、通信は、レイテンシーと同期のオーバーヘッドにより、必ずパフォーマンスに悪影響を及ぼします。 ほとんどの通信を回避することはできませんが、制約に関する座標の通信を完全に回避できる場合があります。 以下に示すポイントは、一般的にパフォーマンスを向上させ、特にスケール上限(約100原子/コアまたは約10000原子/GPU)付近で非常に大きな効果を発揮します。 可能な限り高速にシミュレーションを実行したり、スケーリングベンチマークを実施する場合は、これらのポイントを考慮して設定してください。

可能な限り、P-LINCSを使用する際には、`constraints = all-bonds`の使用を避けるべきです。これは、大量の通信が必要になるだけでなく、ドメインのサイズに対する人工的な最小値を設定します。もし、原子レベルの力場を使用し、2 fsの時間ステップでシミュレーションを行っている場合、通常は他の設定を変更せずに、`constraints = h-bonds`に設定を変更できます。これらの設定は、ほとんどの力場がパラメータ化されたものなので、科学的に見てより適切です。

完全に通信を回避したり、ドメイン分割を使用する場合に更新をGPUで実行したりするためには、システムは「更新グループ」(または全くの制約なし)をサポートする必要があります。更新グループとは、ドメイン間で1つのグループとして移動される原子のグループであり、これにより、グループ内の原子のみに関わる制約や仮想サイトに関する通信の必要性がなくなります。更新グループは、関連するすべての制約原子が1つの中心原子に直接関連付けられ、連続的に配置されている場合にサポートされます。非制約原子との混在は避ける必要があります。例えば、コンパクトに記述されたメチル基が挙げられます。原子力場において「constraints = h-bonds」を使用する場合、これは実際には、トポロジーにおいて水素原子が、接続されている重原子に隣接するように配置されることを意味します。さらに、仮想サイトが存在する場合、構成原子はすべて一緒に制約され、仮想サイトと構成原子が連続している必要がありますが、順序は重要ではありません。TIP4P水モデルはその例です。更新グループを使用しているかどうかは、ログファイルに記録されます。使用できない場合は、その理由も記録されます。

:ref:mdrun をより効率的に実行する方法を見つける

Wallcycle モジュールは、gmx mdrun の実行時のパフォーマンス測定に使用されます。 各実行のログファイルの最後に、「リアルサイクルと時間の計測」セクションには、gmx mdrun コードのさまざまな部分の実行時間統計に関する表が含まれています。 この表には、表の行ごとに、実行された部分、およびすべてのスレッドとランクを対象とした、実行時間、サイクル数(平均値)などの列が含まれています。 最後の列には、各行が全体の実行時間に占める割合も表示されます。 留意点として、gmx mdrun のタイマーのリセット機能(-resethway および -resetstep)は、パフォーマンスカウンターをリセットするため、実行の開始時に、負荷分散によるパフォーマンスの不安定さや起動オーバーヘッドを回避するために役立ちます。

パフォーマンスカウンターは以下のとおりです:

  • 粒子-粒子法における粒子メッシュ・エウラド

  • ドメイン分割

  • ドメイン分割における通信負荷

  • ドメイン分割における通信範囲

  • 仮想サイトの制約

  • Particle mesh EwaldにXを送信する

  • 近傍検索

  • GPU 演算の開始

  • 座標の伝達

  • 強制

  • 待機と力の伝達

  • パーティクル・メッシュ・エウォード

  • PME 再配布。X/F

  • PME の展開

  • PME 収集

  • PME 3D-FFT

  • PME 3D-FFT 通信

  • PME は Lennard-Jones 問題を解く

  • PMEでLJを解く

  • PME で Elec を解決

  • PMEは粒子間の待ち状態

  • 待機 + PME による強制

  • GPU の非同期処理を待機する

  • GPUローカルで待機

  • PME GPU の分散を待つ

  • PME GPU の集約を待つ

  • GPU の PME (Power Management Engine) の強制を減らす

  • 非相互作用的な位置/力のバッファ操作

  • 仮想サイトの分散

  • COMへのプル力

  • AWH (加速された重みヒストグラム法)

  • 軌跡を記述する

  • 更新

  • エネルギーの伝達

  • 強制的なローテーション

  • 回転力を追加する

  • 位置の入れ替え

  • インタラクティブなMD

  • MDグラフ

実行ごとにパフォーマンスデータが収集されるため、これらは gmx mdrun のパフォーマンスを評価し、調整するために不可欠です。したがって、開発者とプログラムの利用者両方に役立ちます。これらのカウンターは、シミュレーションのさまざまな部分が消費する時間/サイクルの平均値であり、そのため、単一の実行中の変動を直接的に示すことはできません(ただし、複数の実行間の比較は依然として非常に役立ちます)。

カウンターは、関連するコードの一部が gmx mdrun 実行中に実行された場合にのみ、MDログファイルに表示されます。「Rest」という特別なカウンターも存在し、上記のカウンターによってカウントされない時間の量を表します。したがって、大幅な「Rest」時間(数パーセント以上)は、多くの場合、並列化の非効率性(例:シリアルコード)を示唆しており、開発者に報告することを推奨します。

追加のサブカウンターを使用することで、パフォーマンスをより詳細に分析できます。以下にその例を示します。

  • ドメイン分割による再分配

  • DD 探索グリッド + ソート

  • DD の設定における通信

  • DD ネットワーク構成を作成

  • DD 制約を適用する

  • DDトポロジーに関するその他の情報

  • ローカルな近傍検索グリッド

  • NSグリッドの非局所

  • ローカルでのNS検索

  • NS 検索をローカル範囲に限定

  • 結合力

  • 結合されたFEP力

  • 制約による強制

  • リストされたバッファ操作

  • 非相互作用の剪定

  • 非相互作用力

  • 非結合 GPU タスクの実行

  • PME GPU タスクの実行

  • Ewald の力場補正

  • 非共有位置バッファ操作

  • 非相互作用力バッファの操作

サブカウンターは開発者向けであり、コンパイル時に有効にする必要があります。詳細については、ビルドシステムの概要 を参照してください。

GPUを使用した mdrun の実行

GPUタスクの種類

より詳細な情報を得るために、計算における異なるGPUの使用方法に関する後続のセクション(特に:ref:short range, PME, bonded interactions)を理解するために、まず異なるGPUタスクの概念を紹介します。シミュレーションを実行する場合、原子間のさまざまな種類の相互作用を計算する必要があります(詳細については、リファレンスマニュアルを参照してください)。したがって、計算をいくつかの独立した部分に分割できます(そのため、順番に、または並行して計算できます)。各部分からの情報を、時間ステップの最後に組み合わせて、各原子に対する最終的な力を取得し、システムを次の時間ステップに伝播させることができます。より深く理解するためには、:ref:`domain decomposition <gmx-domain-decomp>`のセクションも参照してください。

GROMACS は、MDステップに必要なすべての計算において、各ステップを最も低いレベル(SIMDユニット、コア、ソケット、アクセラレータなど)から段階的に最適化し、パフォーマンスを向上させることを目指しています。そのため、多くの個別の計算ユニットは、特にSIMDユニットにおいて、ハードウェア並列性の最も低いレベルに合わせて高度に調整されています。さらに、GPUアクセラレータを*共処理*として使用することで、一部の計算をアクセラレータデバイス上でCPUと並行して実行し、その結果をCPUに転送することができます。現在、GROMACS は、以下の2つのタスクのGPUアクセラレータによるオフロードをサポートしています:短い距離の:ref:非相互作用(リアル空間)、および:ref:PME

GROMACS は、主に2つの主要なオフロードモードをサポートしています:force-offload と GPU 搭載モード。前者では、積分計算の一部またはすべてを CPU で実行し、それに対応するデータ転送が必要になります。一方、GPU 搭載モードでは、積分と制約(使用する場合)を GPU で実行することで、データ転送の必要性が低くなります。

フォースオフロードモードは、より広範にサポートされているGPUアクセラレーションモードであり、NVIDIA、AMD、Intelなどの幅広いGPUアクセラレータで、短距離の非結合オフロードがサポートされています。このモードは、ほとんどの機能と並列化モードと互換性があり、大規模なマシンへのスケーリングにも使用できます。同時に、短距離の非結合および長距離のPMEのワークの両方をGPUアクセラレータにオフロードすることは、機能および並列化の互換性の点でいくつかの制限があります(詳細は:<gmx-pme-gpu-limitations>を参照)。CUDAおよびSYCLでは、結合相互作用(ほとんどのタイプ)のオフロードがサポートされています。GPU上で動作するモードは、CUDAおよびSYCLでサポートされていますが、:ref:`GPUアップデートセクション <gmx-gpu-update>`に記載されている追加の制限があります。

GPUを使用した短距離間の非相互作用の計算

GPU を使用して短距離の非相互作用を計算することで、CPU のみを使用した場合と比較して、利用可能な速度向上をほとんど得ることができます。この場合、GPU はこの問題を効果的に並列化し、計算時間を短縮できるアクセラレータとして機能します。

PMEのGPUによる高速計算

GROMACS は、PME 計算を GPU にオフロードすることで、CPU への負荷をさらに軽減し、CPU と GPU 間の使用効率を向上させることができます。この場合、短距離相互作用の計算と PME の解法を同じ GPU 上で実行します。

既知の制限事項

以下の制限事項を再度ご注意ください!

  • GPUでは、PME注文は4件までのみサポートされています。

  • 複数のランキング(したがって複数のGPU)でPMEを実行する場合、サポートは限られています。2022リリース以降のハイブリッドモード(-pmefft cpu)でのCUDAを使用した実験的なPME分解、および2023リリース以降のCUDAまたはSYCLを使用したフルGPU PME分解、および2026リリース以降のHIP(|Gromacs|が:ref:`cuFFTMp <cufftmp installation>`または:ref:`HeFFTe <heffte installation>`でビルドされている場合)をサポートしています。

  • Dynamicalな積分器のみがサポートされています(つまり、leap-frog、Velocity Verlet、確率的ダイナミクス)。

  • LJ PME は GPU ではサポートされていません。

  • GROMACS が GPU FFT ライブラリなしでビルドされた場合 (-DGMX_GPU_FFT_LIBRARY=none)、ハイブリッドモード (-pmefft cpu) のみサポートされます。

GPUによる結合相互作用の計算(CUDA、SYCL、HIP)

GROMACS は、PP の結合部分のワークを互換性のある GPU にオフロードすることを可能にします。 これを PP のワークの一部として扱っており、短距離の非結合タスクも GPU で実行する必要があります。 通常、結合相互作用を GPU にオフロードすることで、特に GPU ごとの CPU リソースが比較的少ない場合(CPU が弱い場合や、実行中に GPU に割り当てられた CPU コアが少ない場合)に、パフォーマンス上の利点が得られます。 また、他の CPU 側での計算がある場合にも有効です。 例えば、自由エネルギー計算などが該当します。

GPUによる制約の計算と座標の更新 (CUDA, SYCL, HIP)

GROMACS は、GPU 上で座標更新と(必要に応じて)制約計算の両方を実行できるようにします。この並列化モードは、「GPU 搭載」と呼ばれ、力と座標のデータは通常、温度/圧力カップリングまたは近傍探索ステップの間(通常は数ステップ)にGPU 上で保持されます。GPU 搭載モードでは、シミュレーションステップのすべての(サポートされている)計算をGPU 上で実行できます。これにより、CPU ホストとGPU 間の結合が少なくなり、典型的なMDステップでは、CPU と GPU 間の座標と力の転送が不要になります(これは、force-offload スキームでは、座標と力をCPU と GPU 間の各ステップで転送する必要があります)。ただし、GPU 搭載スキームは、GPU 計算と並行して、CPU 上でも一部の計算を実行できます。これにより、GROMACS の幅広い機能をサポートし、GPU に移植されていない機能も活用できます。同時に、通常はアイドル状態のCPU を活用することで、パフォーマンスを向上させることも可能です。多くの場合、結合またはPME計算をCPU に戻すことが有利ですが、これは、シミュレーションでGPU とペアになったCPU コアの相対的なパフォーマンスによって異なります。

GPUモードは、サポートされている場合はデフォルトで有効になっています(ビルド構成またはシミュレーション設定がそれに合わない場合に、自動的にCPUへの切り替えが行われます)。デフォルトの動作を変更するには、``GMX_FORCE_UPDATE_DEFAULT_CPU``環境変数を設定します。この場合、デフォルトの動作に従うシミュレーション(例:-update auto)は、CPUで更新を実行します。

この並列化モードを使用することは、一般的に、高速なGPUと比較的遅いCPUを組み合わせて使用する場合に有利です。特に、GPUに単一のシミュレーションのみが割り当てられている場合に有効です。ただし、複数のシミュレーションを各GPUに割り当てる典型的なケースでは、特に一部の処理をCPUに戻さずにすべてオフロードする場合、単に力計算のみをオフロードする並列化モードよりもパフォーマンスが低下する可能性があります。

GPUへのタスクの割り当て

実行する mdrun に関する情報に基づいて、同じまたは異なる GPU で、実行する必要があるタスクとハードウェアに応じて、さまざまな種類の計算を組み合わせることができます。

異なる計算タスクを同じGPUに割り当てることも可能です。これにより、同じデバイス上の計算リソースを共有するか、または異なる処理ユニットに割り当て、各ユニットでそれぞれ1つのタスクを実行することができます。

以下に、可能なタスクの割り当てに関する概要を示します。

GROMACS バージョン 2018:

利用可能な2種類のGPUアクセラレーテッドタスクは、(短距離) 非相互作用とPMEの2種類です。各PPランクには、GPUにオフロードできる非相互作用タスクがあります。PMEタスクを持つランク(PMEのみのランクを含む)が1つしかない場合、そのタスクをGPUにオフロードできます。このようなPMEタスクは、GPU上で完全に実行することも、後段の処理のみをCPUで実行することも可能です。

制限事項は、GPUでのPMEはPMEのドメイン分割をサポートしていないため、PMEの異なるランクに割り当てられた個別のGPUに、1つのPMEタスクのみをオフロードできるのに対し、非相互作用部分は複数のGPUに分割してオフロードできることです。

GROMACS バージョン 2019:

新しい割り当て可能なGPUタスクは利用できませんが、PPタスクの短い範囲の相互作用と同じGPUで実行できる、結合された相互作用は可能です。これは、``-bonded``フラグを使用して調整できます。

GROMACS バージョン 2020:

PPタスクにおける、近距離の非相互作用および結合相互作用の計算を同じGPUで実行し、更新と制約を同時に適用できます。これは、``-update``フラグによって制御できます。

GROMACS 2021/2022版:

CUDAビルドでは、通信および補助タスクもオフロードできます。ドメイン分割におけるハロー交換とPP-PMEの通信では、CPUを経由したGPU間の転送ではなく、GPU間の直接通信が可能です。ハロー交換の補助タスクとして、データパックとアンパックもGPUにオフロードされます。2021年のリリースでは、これに対応するために「thread-MPI」がサポートされており、2022年のリリースからは「GPU-aware MPI」もサポートされます。直接的なGPU間の通信はデフォルトでは有効になっていませんが、「GMX_ENABLE_DIRECT_GPU_COMM」という環境変数を設定することで有効にできます(ただし、対応するシステムでのみ有効になります)。

GROMACS バージョン 2023:

現在、「Update」は、サポートされているシミュレーション設定で、デフォルトでGPU上で実行されます。ただし、これはCUDAとSYCLのみで利用可能です。OpenCLでは利用できません。

PME分解のサポートにより、グリッドのパッキングや削減演算など、並列処理に関連する追加の補助GPUタスク、および分散GPUFFT計算が可能です。

CUDA-グラフのスケジューリングに対する実験的なサポートが追加されました。これにより、ほとんどのGPU上で実行される場合に、CPUによる強制計算が不要なケースに対応できます。

GROMACS バージョン 2025:

現在、サポートされている環境では、直接のGPU通信がデフォルトで有効になっています。この機能を無効にするには、``GMX_DISABLE_DIRECT_GPU_COMM``という環境変数を設定します。

GPUタスクのパフォーマンスに関する考慮事項

  1. パフォーマンスのバランスは、CPUコアとGPUの速度と数によって決まります。

  2. GPUに搭載された並列化モード(更新/制約のオフロードを無効化)は、強制オフロードモードよりも、適切なCPU-GPUバランスに敏感ではありません。

  3. 低スペック/古いGPUと/または高性能/最新のマルチコアCPUの場合、PMEの計算をCPUに任せ、GPUをノンバウンド計算に集中させる方が効率的である可能性があります。

  4. 高速/最新のGPUと/または低速/古いCPU(コア数が少ない場合)を使用している場合は、通常、GPUにPMEの処理を割り当てる方が効果的です。

  5. GPUへのバインドされた計算のオフロードは、効率的なCPUベースのカーネルが、GPUが他のオフロードされた作業を完了する前に、バインドされた計算を完了できるため、シミュレーションのパフォーマンスを向上させるとは限りません。したがって、PMEがオフロードされている場合、`gmx mdrun`はデフォルトでバインドされたオフロードを無効にします。パフォーマンスが向上する可能性のある一般的なケースは次のとおりです

  6. ほとんどの最新ハードウェアでは、GPU上で動作するモード(デフォルト)が、強制的にCPUにオフロードするモードよりも高速ですが、CPUがアイドル状態になる可能性があります。結合されたワークをCPUに戻す(-bonded cpu)ことは、統合と制約をCPUに残すよりも、高速なCPUを最大限に活用する方法です。ただし、各GPUに多数のシミュレーションが割り当てられているマルチシミュレーションの場合、この方法が適さない場合があります。

  7. 直接のGPU間通信は、通常、段階的な通信(スレッドとMPIの両方を使用する場合)よりも優れたパフォーマンスを発揮します。 理想的には、GPU上で動作するモードと組み合わせて使用することで、最大限の効果を得ることができます。

  8. 最適な代替手段がご自身のマシンに最も適しているかどうかを確実に知る唯一の方法は、テストを行い、パフォーマンスを確認することです。

GPUアクセラレーションによる実行時のオーバーヘッドを削減する

CPUコアとGPUが並行して実行されるようにするため、タスクはGPU上で非同期に開始され実行されます。一方、CPUコアはオフロードされていない力計算(例えば、結合力を計算したり、自由エネルギーを計算したりする)を実行します。非同期タスクの開始は、GPUデバイスドライバによって処理され、CPUの関与が必要です。したがって、GPUタスクのスケジューリングには、他のCPUタスクと競合し、干渉を引き起こし、結果としてパフォーマンスが低下する可能性のあるCPUリソースが必要です。

CPUの実行遅延は、GPUタスクの起動遅延によるもので、シミュレーションのns/dayが増加するにつれて(つまり、ステップごとのウォールタイムが短い場合)、この遅延は顕著になる可能性があります。GPUでの作業の起動コストは、:ref:`gmx mdrun`によって測定され、ログファイルのパフォーマンスサマリーセクション(「Launch PP GPU ops.」/「Launch PME GPU ops.」行)に報告されます。実行時間のほんの一部が作業の起動に費やされるのは正常ですが、高速な反復とマルチGPU並列実行では、10%以上のコストが見られることがあります。この遅延がパフォーマンスに大きな影響を与えるかどうかは、メインのMDステップ内でCPUに割り当てられている作業の量によって異なります。ほとんどまたはすべての力計算がCPUにオフロードされ、CPUが通信に関与していない場合(たとえば、スレッド-MPIと直接GPU通信を有効にした場合)、大きな起動コストは大きなパフォーマンス低下を引き起こさない可能性があります。ただし、CPUに計算が割り当てられている場合(たとえば、自由エネルギーまたはプル/AWHシミュレーションの場合)またはCPUからMPI通信が開始された場合(GPUを意識したMPIを使用する場合でも)、GPUの起動コストは他のCPUの作業と競合するため、オーバーヘッドとして現れます。一般的に、ユーザーはこのようなオーバーヘッドを回避することはできませんが、いくつかのケースでは、調整を行うことでパフォーマンスの向上が可能です。OpenCLでのGPUタスクのタイミングは、デフォルトで有効になっており、ほとんどの場合、その影響は小さいですが、高速な実行ではパフォーマンスに影響を与える可能性があります。このような場合、「Launch GPU ops」の時間で数パーセント以上の遅延が見られる場合は、環境変数``GMX_DISABLE_GPU_TIMING``を設定してタイミングを無効にすることをお勧めします。マルチGPUを共有する多数のランクを持つ並列実行では、GPUごとに開始するスレッド-MPIまたはMPIのランク数を減らすことで、起動オーバーヘッドを削減することもできます。たとえば、スレッドまたはコアごとに1ランクを使用することは、多くの場合最適ではありません。CUDAグラフ機能(GROMACS 2023で追加)は、このようなオーバーヘッドを削減し、GPUでの作業のスケジューリング効率を向上させることを目的としており、特に、高速なGPUで実行される小さなシミュレーションシステムでは、大幅な改善をもたらす可能性があります。これは新しい機能であるため、2023リリースでは、CUDA-graphのサポートを有効にするために、環境変数``GMX_CUDA_GRAPH``を設定する必要があります。

GPUランタイムまたはドライバがCPU計算と干渉する、もう1つのオーバーヘッドは、GPUタスクのスケジューリングと連携によって引き起こされます。別個のGPUランタイム/ドライバスレッドはCPUリソースを必要とし、これにより、同時に実行されている非オフロードタスク(存在する場合)と競合し、このCPUタスクのパフォーマンスを低下させる可能性があります。オーバーヘッドを最小限に抑えるには、gmx mdrun`を起動する際に、少なくとも1つのCPUハードウェアスレッドを未使用にすることを検討してください。特に、多数のコアと/または同時マルチスレッディングが有効なCPUの場合に有効です。たとえば、16コアと32スレッドのCPUの場合、次のように実行します:`gmx mdrun -ntomp 31 -pin on。これにより、GPUタスクのスケジューリングに必要なCPUリソースを確保し、CPU計算との干渉を軽減できます。ただし、`gmx mdrun`に割り当てるCPUリソースを減らすことは、トレードオフを含みます。多数のCPUコアがGPUと連携する場合、このトレードオフは必ずしも重要ではないかもしれませんが、特定の状況(たとえば、マルチランクMPI実行の場合)では、複雑なリソース割り当てにつながり、GPUスケジューリングのオーバーヘッドを軽減するメリットを上回る可能性があります。そのため、このような手法を採用する前に、代替案をテストすることをお勧めします。

OpenCL版のmdrunの実行

現在サポートされているハードウェアアーキテクチャは以下のとおりです。

  • AMD の GCN アーキテクチャおよび CDNA アーキテクチャに基づく GPU;

  • NVIDIA製のGPU(Volta以前の世代)

  • インテル製のiGPU。

最新のドライバーがインストールされていることを確認してください。AMD GPUの場合、計算に最適化された`ROCm`スタックが推奨されます。また、AMDGPU-PROスタックも互換性があります。古いバージョンの`fglrx`プロパティドライバとランタイムを使用することは推奨されませんが(ただし、特定の古いハードウェアではこれが唯一のサポート方法となる場合があります)。さらに、Mesa 17.0以降またはLLVM 4.0以降を使用することも可能です。NVIDIA GPUの場合、オープンソースの`nouveau`ドライバ(Mesaで利用可能)はOpenCLのサポートを提供しないため、プロパティドライバの使用が必須です。Intel統合GPUの場合、`Neoドライバ <https://github.com/intel/compute-runtime/releases>`が推奨されます。

必要な最小のOpenCLバージョンは|REQUIRED_OPENCL_MIN_VERSION|です。また、:ref:`既知の制限事項 <opencl-known-limitations>`も参照してください。

AMD GCN アーキテクチャ(すべてのシリーズ)のデバイスは互換性があり、定期的にテストされています。NVIDIA Kepler以降(計算能力3.0)も動作を確認していますが、本番環境での実行を行う前に、必ずハードウェア上で|Gromacs|のテストが正常に実行されることを確認してください。

OpenCL GPUカーネルは実行時にコンパイルされます。そのため、OpenCLプログラムのビルドには数秒かかる場合があります。これにより、gmx mdrun`の起動にわずかな遅延が生じることがあります。これは、長期間の生産環境でのMDでは通常問題ではありませんが、例えば、非常に少ないステップしか実行しないような作業(例:上記の `-nb`` を参照)をCPUのみで行うことをお勧めします。

同じ -gpu_id オプション(または GMX_GPU_ID 環境変数)を使用して、CUDA または SYCL デバイスを選択したり、GPU を PP レンクにマッピングしたりする場合に使用されるものが、OpenCL デバイスにも使用されます。

開発者は、他のいくつかの OpenCL 管理 環境変数も関心を持つ可能性があります。

OpenCLサポートに関する既知の制限

GROMACS ユーザーにとって、現在のOpenCLサポートの制限事項

  • Intel製の統合GPUはサポートされています。Intel製のCPUはサポートされていません。「-DGMX_GPU_NB_CLUSTER_SIZE=4」を設定して|Gromacs|をコンパイルすることで、消費グレードのIntel GPU(Ponte Vecchio / Data Center Max GPUとは異なる)上で実行できます。

  • NVIDIA OpenCL ランタイム内の一部のア非同期タスクキューイング関数のブロック動作により、影響を受けるドライバーバージョンでは、NVIDIA GPUを使用してもパフォーマンスの向上がほとんど見られません。この問題は、349シリーズまでのドライバーバージョンに影響しますが、352以降のドライバーリリースで修正されています。

  • NVIDIA GPUでは、NVIDIA OpenCLコンパイラの制限により、同等のCUDAカーネルと比較してOpenCLカーネルのパフォーマンスが大幅に低下します。

  • NVIDIA Volta および Turing アーキテクチャでは、OpenCL コードがバージョン 440.x までのドライバーで実行されると、不正確な結果を生成することが知られています(これは、コンパイラの問題による可能性が高い)。これらのアーキテクチャでの実行は、通常失敗します。

SYCL版のmdrunの実行

最新のドライバーがインストールされていることを確認し、互換性のあるハードウェアとソフトウェアのリスト、および推奨されるコンパイル時のオプションについては、:ref:`インストールガイド <SYCL GPU 加速>`を参照してください。

以下の環境変数は、パフォーマンスの最適化に役立つ可能性がありますので、ご注意ください。

  • oneAPI ランタイムを使用する場合:

    • SYCL_CACHE_PERSISTENT=1: GPUカーネルのキャッシュを有効にし、gmx mdrun の起動時間を短縮します。

-gpu_id オプションに加えて、バックエンド固有の環境変数(例:ONEAPI_DEVICE_SELECTOR または ROCR_VISIBLE_DEVICES)を使用して、GPUを選択することも可能です。

HIP版のmdrunの実行

必ず、最新バージョンのROCmツールキットを使用していることを確認し、:ref:`AMD HIPのインストールガイド <AMD-HIP>`を参照してください。

CDNAハードウェアを使用している場合は、|Gromacs|のビルドが、デバイス上で64ビット幅の実行するように構成されていることを確認してください。RDNAハードウェアを使用する場合は、GMX_GPU_FFT_LIBRARYにVkFFT(デフォルト)を使用することを推奨します。なぜなら、rocFFTに対するRDNAの公式サポートは普遍的ではないため、これにより実行時にデバイスの使用が拒否される可能性があるためです。