(メモ)使用するGPUとCPUを考慮して

nvidia-smiのコマンドオプションに「--matrix 」がある。実行してみると

[root@i ~]# nvidia-smi topo --matrix
        GPU0    GPU1    CPU Affinity
GPU0     X      SOC     0-9
GPU1    SOC      X      10-19
 
Legend:
 
  X   = Self
  SOC = Path traverses a socket-level link (e.g. QPI)
  PHB = Path traverses a PCIe host bridge
  PXB = Path traverses multiple PCIe internal switches
  PIX = Path traverses a PCIe internal switch
[root@i ~]#

と各GPUカードが繋がっているCPUが分かる。また「lscpu」コマンドを実行すると

[root@i ~]# lscpu
Socket(s):             2
NUMA node(s):          2
 :
NUMA node0 CPU(s):     0-9
NUMA node1 CPU(s):     10-19
[root@i ~]#

node0が0-9(core)担当でnode1が10-19(core)の担当と分かる。
次に、refine実行中に「nvidia-smi」を実行すると

[root@i ~]# nvidia-smi
 :
+-----------------------
| Processes:            
|  GPU       PID  Type  
|=======================
|    0     32681    C   
|    1     32682    C   
+-----------------------
[root@i ~]#

と表記される。2つのGPUカードがそれぞれ、プロセスID 32681と32682で動いている。このプロセスIDは、/procから

[root@i ~]# cat /proc/32681/status |grep Cpus_allowed_list
Cpus_allowed_list:      10-19
[root@i ~]# 
[root@i ~]# cat /proc/32682/status |grep Cpus_allowed_list
Cpus_allowed_list:      0-9
[root@i ~]#

と分かる。
「GPU 0」に割り当てられたプロセスID 32681は、node1の10-19で動いており、「--matrix 」からすれば順当ではないと見える。
これも「--gpu 」の指定方法で「--matrix 」に会うように配置が可能のようで、試した結果「--gpu 0:1:1:0 」で順当にアサインされた。
あと、「mpirun 」の際に「--bind-to socket 」を使う必要があった。「--bind-to none 」だと「Cpus_allowed_list:」の値が「0-19」となり区別が付かなくなる
けど、、、これで計算が速くなるって訳ではない。。。明らかな違いが「まだ」見えない....

(メモ)複数のGPUノードを使って計算したい

2017y03m25d_110120939.png
こんな感じで、2台のGPUノードにはそれぞれ2基のGPUカードが搭載されている。CPUは1socket。これでrelion_refine_mpiを稼動させるには
1.mpirunのオプション
2.relionでのGPU指定
を工夫する必要があるみたい。具体的には下記のような実行になる

  1
  2
  3
  4
mpirun --display-map --bind-to socket  --map-by ppr:3:node \
-machinefile $PBS_NODEFILE -np 5 `which relion_refine_mpi` \
  (略)
--scratch_dir /scratch --gpu 0:1:0:1

1行目の--display-mapは各ノードへのmpiプロセスの配分が表示されるオプション。--bind-to socketハイブリッドなプログラムなのでmpiプロセスはsocket単位で繋ぐ。あるいは1socket(1way)マシンなので--bind-to noneでも構わないかも。--map-by ppr:3:nodeは、ノード単位でpprは「processes per resource」。この場合node当たり3つずつmpiプロセスをアサインすることを意味する。
なので、合計5つのmpiを投入するので(-np 5)、
第1mpi(rank0)はgpu1のマシンへ
第2mpi(rank1)はgpu1のマシンへ
第3mpi(rank2)はgpu1のマシンへ
第4mpi(rank3)はgpu2のマシンへ
第5mpi(rank4)はgpu2のマシンへ
と分配される。
4行目の--scratch_dir /scratchは、各ノードの/scratchにデータを配置させ、--gpu 0:1:0:1は、relion_refine_mpiがrank0以外でならGPUを活用するので、第2mpi以降に順にGPUがアサインされる。
第1mpi(rank0)はgpu1のマシンへ
第2mpi(rank1)はgpu1のマシンへ --> gpu 0がアサイン
第3mpi(rank2)はgpu1のマシンへ --> gpu 1がアサイン
第4mpi(rank3)はgpu2のマシンへ --> gpu 0がアサイン
第5mpi(rank4)はgpu2のマシンへ --> gpu 1がアサイン

もし--map-by ppr:3:nodeを指定しないと既定は「socket」なので、gpu1のcore数が4なら、
第1mpi(rank0)はgpu1のマシンへ
第2mpi(rank1)はgpu1のマシンへ --> gpu 0がアサイン
第3mpi(rank2)はgpu1のマシンへ --> gpu 1がアサイン
第4mpi(rank3)はgpu1のマシンへ --> gpu 0がアサイン --> 第2mpiの[gpu 0]とかち合う
第5mpi(rank4)はgpu2のマシンへ --> gpu 1がアサイン

もし--map-by ppr:3:nodeを指定しないと既定は「socket」なので、gpu1のcore数が6なら、他のノードを使わなくなる
第1mpi(rank0)はgpu1のマシンへ
第2mpi(rank1)はgpu1のマシンへ --> gpu 0がアサイン
第3mpi(rank2)はgpu1のマシンへ --> gpu 1がアサイン
第4mpi(rank3)はgpu1のマシンへ --> gpu 0がアサイン --> 第2mpiの[gpu 0]とかち合う
第5mpi(rank4)はgpu1のマシンへ --> gpu 1がアサイン --> 第3mpiの[gpu 1]とかち合う

間違っているかもしれません
*「gpu 0」は実際のマザーボード上でのGPUカードの位置を規定してる訳ではありません。

(めも)--jの値とmpirun

  1
  2
  3
  4
mpirun --display-map --bind-to core  --map-by ppr:3:node:pe=2 \
-machinefile $PBS_NODEFILE -np 5 `which relion_refine_mpi` \
  (略)
--scratch_dir /scratch --gpu 0:1:0:1 --j 2

relion_refine_mpiの--jの値と mpirun の map-by に掛かる pe と同じ値にすべきかなと思っている


トップ   編集 添付 複製 名前変更     ヘルプ   最終更新のRSS
Last-modified: 2017-07-31 (月) 00:46:18 (83d)