2017-07-21 5 views
0

私はFortranでMPIをやや新しくしています。私は各プロセッサがNsシミュレーションを行うMPIコードを持っています。だから私はそれぞれのシミュレーションと各procにPHIという2次元配列とPHIの各値を2乗する2番目の配列PHI^2を作成するので、(mysize x Ns x 2)の結果が得られるはずです。配列をMPI Fortranの配列に減らす

次に、Nsの中のすべてのシミュレーションの後、私は基本的に同様SUM PHI^2(PHI)/ NsとおよびPHI^2_AVG_RANK、あるPROC PHI_AVG_RANKアレイ毎に生成します。

私は両方とも、その後、mysize上で再び平均を行うには、削減和を通じて母親プロセッサに各プロセッサから来ている結果の行列PHI_AVG_RANK(mysize行列の合計)のすべてを送信したいですPHI_AVG_RANKとPHI ** 2_AVG_RANKについては、これを行う理由は、すべて(mysize x Ns)実現、つまりsqrt(SUM(PHI^2_AVG_RANK)/ mysize - (SUM(PHI_AVG_RANK)/ mysize)^ 2のRMS行列を計算したいからです。 )を入力し、txtに保存します。

これを行うには、どのデータ型を使用できますか?連続、ベクトル、またはサブアレイ?ここでやるべき最善の呼びかけを減らすのですか?

これはこれまでの私の計画です(すべてのNsシミュレーションを行った後、各プロセッサのphi_moyen_1_2と呼ばれる100x100行列を思い出して、それをすべてmean_2_025という新しい行列100x100に集計したい)それ:

call MPI_BARRIER(MPI_COMM_WORLD,ierr) 
    call MPI_TYPE_CONTIGUOUS(100,MPI_REAL,row,ierr) 
    call MPI_TYPE_CONTIGUOUS(100,row,matrix,ierr) 
    if (myrank==0) then 
     call MPI_REDUCE(phi_moyen1_2,mean_2_025,1,matrix,MPI_SUM,0,MPI_COMM_WORLD,ierr) 
     open(unit=1234, file='../results/PHI1/TESTE/teste.txt') 
      do i=0,Nx-1 
       write(ligne, *) mean_2_025(i,:) 
       write(1234,'(a)') trim(ligne) 
      end do 
     close(unit=1234) 
    endif 

EDIT:@デビッドヘンティの提案を実装した後、我々は連続したデータ型を使用する必要はありません私たちは、実際には各Fortranのアクセス以来、ストレート任意の中間データ型withuotそれを行うと句をコミットすることができます。その後、私はフォローしました:

if (myrank==0) then 
     call MPI_REDUCE(phi_moyen1_2,mean_2_025,100*100,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD,ierr) 
     mean_2_025=mean_2_025/(mysize) 
     write(*,*) mean_2_025(1,1) 

しかし、プログラムは(無限ループを通過したように)終了せず、出力ファイルに何も印刷しません(のnprocsのため、マトリックスmean_2_025の最初のエントリの番号が上記のを書く)。私はプログラムの終わりにいくつかのcpu_timeを実行しました。それはnprocs CPU時間を示しています。

編集:解説:@Vladimir Fが指摘したように、総コールREDUCEはすべてのプロセッサによって(呼び出し内にルートプロセッサがあるにもかかわらず)行われます。したがって、if節の中にあって無限ループを引き起こすことはできません(他のプロセッサはREDUCEにアクセスできませんでした)。

ありがとうございました。

+1

多くのことを明確にする必要があります。あなたのコードを表示してください。言葉で説明し、あなたが意味することを解釈しようとするよりはるかに良いです。 See [ask]。 –

+0

@VladimirFコードは非常に長いですが、私は関連する部分、つまり、削減部分の質問を更新しました – arturtheking

答えて

1

あなたがする必要があるのは、タイプをMPI_REAL、カウントを100 * 100として指定するだけです。 reduceの場合、配列の各要素に対して個別に還元が行われます。つまり、iとjの100 * 100の値のすべてに対して、rank_2上のmean_2_025(i、j)は、 phi_moyen1_2(i、j)のすべてのランクにわたって合計します。

call MPI_REDUCE(phi_moyen1_2,mean_2_025,100*100,MPI_REAL,MPI_SUM,0,MPI_COMM_WORLD,ierr) 

平均を得るには、単にサイズで除算します。技術的なメモでは、MPIが集団内で必要とするすべての同期を行うため、障壁は必要ありません。

データ型を使用すると、ここで過度に複雑になります。最初にコミットする必要がありますが、より重要なのは、リダクション操作では、独自のリダクション操作を定義して登録することによって何をすべきかを指示しない限り、「行列」型のデータをどうしたらよいか分かりません。

+0

ありがとう、私はそれを知らなかった。私はこれを実装しました。コードは数秒で実行されるはずでしたが、無限ループ内にあるかのように終了することはありません。私は、次のことをやった:(myrank == 0)、その後 コールMPI_REDUCE(phi_moyen1_2、mean_2_025,100 * 100、MPI_DOUBLE、MPI_SUM、0、MPI_COMM_WORLD、IERR) mean_2_025 = mean_2_025 /(mysize) 書き込み(*場合は、 *)mean_2_025(1,1) しかし、出力ファイルには何も印刷されません。私はREDUCEコールの前と後にいくつかの書き込み呼び出しを行っており、各プロセッサが呼び出しを行っても明らかに何もしないことを示しています。 – arturtheking

+0

質問をより明確にするためにアップロードしました。 – arturtheking

+0

あなたのREDUCEの使用は間違っています。コミュニケータのすべてのランクはそれを呼び出す必要があります。集合的な活動について学ぶ。もしmyrank ==何かがあれば何もできません。 –

関連する問題