3

自分が書いたスクリプトを並列化しようとしています。各プロセスは計算を実行し、データを配列の特定の部分(リストのリスト)に格納する必要があります。各プロセスはデータを計算して保存していますが、データをファイルに出力できるように、非ルートプロセスからルートプロセスにデータを取得する方法がわかりません。スクリプトの最小限の作業例を作成しました---これは、単純化のために2つのコアでのみ実行するように設計されています。

from mpi4py import MPI 
import pdb 
import os

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

# Declare the array that will store all the temp results
temps = [[0 for x in xrange(5)] for x in xrange(4)]

# Loop over all directories
if rank==0:
   counter = 0 
   for i in range(2):
      for j in range(5):
         temps[i][j] = counter
     counter = counter + 1 

else:
   counter = 20
   for i in range(2,4):
      for j in range(5):
         temps[i][j] = counter
         counter = counter + 1 

temps = comm.bcast(temps,root=0)

if rank==0:

   print temps

次を使用してスクリプトを実行します。

mpiexec -n 2 python mne.py

ケースが終了すると、出力は次のようになります。

[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

したがって、データ共有が期待どおりに機能していないことがわかります。誰かがデータをルートプロセスに戻す正しい方法を教えてもらえますか?

4

1 に答える 1

5

コードは正しく機能していますが、希望どおりに動作していません。

この行

temps = comm.bcast(temps,root=0)

tempsプロセッサ 0 の変数をすべてのプロセッサ (ランク 0 を含む) にブロードキャストします。もちろん、上記の結果が正確に得られます。gather(またはallgather、すべてのプロセッサに答えを持たせたい場合は)を使用します。それは次のようになります。

from mpi4py import MPI
import pdb
import os

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

assert size == 2

# Declare the array that will store all the temp results
temps = [[0 for x in xrange(5)] for x in xrange(4)]

# declare the array that holds the local results
locals =[[0 for x in xrange(5)] for x in xrange(2)]

# Loop over all directories
if rank==0:
   counter = 0
   for i in range(2):
      for j in range(5):
         locals[i][j] = counter
         counter = counter + 1

else:
   counter = 20
   for i in range(2):
      for j in range(5):
         locals[i][j] = counter
         counter = counter + 1

temps = comm.gather(locals,temps,root=0)

if rank==0:
   print temps

本当にインプレースでコレクションを実行したい場合、およびすべての実際のデータがデータを初期化したゼロよりも大きくなることが (たとえば) わかっている場合は、リダクション操作を使用できますが、そのほうが簡単です。 numpy 配列を使用:

from mpi4py import MPI
import numpy

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

assert size == 2

# Declare the array that will store all the temp results
temps = numpy.zeros((4,5))

# Loop over all directories
if rank==0:
   counter = 0
   for i in range(2):
      for j in range(5):
         temps[i,j] = counter
         counter = counter + 1

else:
   counter = 20
   for i in range(2,4):
      for j in range(5):
         temps[i,j] = counter
         counter = counter + 1

comm.Allreduce(MPI.IN_PLACE,temps,op=MPI.MAX)

if rank==0:
   print temps
于 2012-12-14T15:48:28.093 に答える