keisuke-yanagisawa / exprorer_msmd

MSMD (mixed-solvent molecular dynamics) engine and analysis tools
MIT License
17 stars 4 forks source link

Enabling to use MPS (Multi-Process Service) for better calculation efficiency #35

Closed Ell112a closed 4 months ago

Ell112a commented 5 months ago

--mps "[0,0]" --mps の次に"[0,0]"などの配列を文字列で入力します。配列はgpuIDを指定しており、複数のrunで同一のgpuIDとすることでmpsを実装しています。

keisuke-yanagisawa commented 5 months ago

上記のうち 4. について、ある程度の長文を書きますが、結論としては

ratio_available_gpus = len(get_gpuids(ignore_cuda_visible_devices=True)) / len(get_gpuids(ignore_cuda_visible_devices=False))
ncpus_per_run = int(ncpus * ratio_available_gpus / len(gpuids))
if ncpus_per_run == 0:
  raise EnvironmentError("The number of CPU threads must be equal to "
                         "or greater than the number of runs executed simultaneously")

として、その後も ncpus_per_gpu ではなく ncpus_per_run に変数名を変更してください。


この実装の背景を説明します。TSUBAME3やTSUBAME4では常に nvidia-smi で見える全てのGPUを1つの exprorer_msmd 実行のために使える状態ですが、一方で研究室のサーバなどを利用する場合では、nvidia-smi で見える一部のGPUは他のユーザが利用している、というケースが存在します。

後者の場合、あらかじめ環境変数 CUDA_VISIBLE_DEVICES を指定することで、使うGPUを制限することが考えられます(そうしないと、他のユーザが利用しているGPUを取り合ってしまう)。この時、他人に使ってもらう分だけのCPUも他人に使ってもらうように置いておこう、というのが ncpus_per_gpu の計算の際に ignore_cuda_visible_devices=True にする「お気持ち」です。このお気持ちは、例えば「4このGPUがあるマシンで、私が使わないGPUが3個(3/4=75%)あるのだとしたら、CPU資源も同じ分量(=75%)他人のために残しておこう」という事になります。

今回MPSの対応によって、1つのGPUが複数のrunを受け持つことになります。その場合でもやはり、使っていないGPUの比率に応じてCPUの資源を残し、残りのCPU資源をみんなで等分する、という事が良いでしょう。 それを計算するために、まず「そのマシンが持つGPUを(個数ベースで)どのくらい利用するのか?を比率で表す ratio_available_gpus」を求め、それに基づいて、自分が使っていい総CPUコア数を考えます(ncpus / ratio_available_gpus に相当)。そのCPUコアを、同時に実行する予定のジョブ数で均等割すると、各ジョブがCPUコアを何コア使ってもいいのか?が計算できます。これが ncpus_per_run です。

keisuke-yanagisawa commented 5 months ago

さらに微修正加えました。動作チェックお願いして良いですか?