Skip to content

allocation modifier が --cpus-per-task を出力せず、スレッド実行でランクの cpuset がノード全体になる #30

Open

Description

@yoshifuminakamura

modifiers/allocation/modifier.py の slurm_instructions() は、起動行を
-n {n_ranks}、-N {n_nodes}、および GPU がある場合の --gpus {n_gpus} から
組み立てる。-c / --cpus-per-task は、実験が n_threads_per_proc を設定して
いる場合でも一切出力されない。

したがって R ランク × T スレッドの実験は

srun -n R -N 1

として起動され、各ランクの cpuset はノード全体になる。R × T 本のスレッドが
どこに載るかはノード側の裁量となり、実験からは何も指定されていない。

ジョブは成功し、FOM だけが変わる。すなわち失敗として表面化しない。

測定

riken-rikyu(2 ソケット、計 144 コアの aarch64 ノード)で genesis(8 ランク ×
18 スレッド、1 ノード)を実行した。

  • 同一バイナリで、ノードによって FOM 194.304 と 94.252 に分かれた。前者では
    144 スレッドの領域が片方のソケットに偏って配置されていた。
  • スレッドを広げるノードでもランク同士が重なる。--cpus-per-task=18 を与えた
    場合、5 回の実行が 41.8〜45.0 に収まり、指定なしの最良値の 2 倍以上速い。

効かない対処

最初に思いつく OMP_PROC_BIND=close と OMP_PLACES=cores は解決にならない。
各ランクが依然として 144 CPU すべてを見ているため、cores は各ランクで同一の
リストを列挙し、close はいずれも place 0 から開始する。結果として 8 ランクが
CPU 0-17 に重なり、144 スレッドが 18 コアに載る。genesis は 112 秒から 2 時間の
タイムアウトになった(3 回中 3 回)。OpenMP の束縛が意味を持つのは、各ランクが
自分の cpuset を持ってからであり、持った後には不要である。

対応案

実験が n_threads_per_proc を設定している場合に --cpus-per-task {n_threads_per_proc} を出力する。--gpus {n_gpus} を出力しているのと同じ
考え方であり、determine_allocation() は既に同じ値をノード数の算出に用いて
いる。

現状では、実験ごとに extra_cmd_opts で個別に与えるほかに手段がない。これは
modifier が提供する唯一の経路であるが、スレッドを使う実験すべてに同じ指定を
書き写すことになり、書き忘れても何も警告されない。

なお、本件は特定の機械に固有ではない。スレッドを広げるノードでもランクの重なり
は生じるため、影響の大きさが機械によって異なるだけである。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions