2010-12-05 7 views
1

私は次のようにファイルに書きます。 (本質的にシリアルコードにおけるだろうと私はそれが、Kによって注文を受けることができれば、それはいいだろうが)順番は必ずしも私は、これは最悪の選択肢である可能性が高い承知しているMPIでファイルに書き込む

  CALL MPI_BARRIER(MPI_COMM_WORLD, IERR) 
      OPEN(EIGENVALUES_UP_IO, FILE=EIGENVALUES_UP_PATH, ACCESS='APPEND') 
      WRITE(EIGENVALUES_UP_IO, *) K * 0.0001_DP * PI, (EIGENVALUES(J), J = 1, ATOM_COUNT) 
      CLOSE(EIGENVALUES_UP_IO) 

問題ではありません。

私はMPI_FILE_WRITE_ATなどを見てきましたが、私は彼らが(直接)私が持っているフォームでデータを取るかどうか分かりません。

ファイルは、これと同じ形式でなければなりません。この形式は、ATOM_COUNT + 1列のK行ごとに出力されます。値はREALです(8)

私は何度も探し続けてきましたが、これを達成するための簡単なリファレンスは見つかりませんでした。どんな助け? :) Cで

同様のコード(それは基本的にはFORTRANと同じだと仮定)は、ちょうどとして有用

感謝です!

+0

ここでは、各タスクに1つ(またはいくつかの数)の?誰も同じATOM_COUNTを持っていますか? –

+0

ああ、私はフォーマットされていない書き込みに気付かなかった。あなたはこれをASCIIでやっていますか?もしそうなら、(a)あなたは本当にすべきではありません(それは遅く、大きなファイルを作成し、実際に印刷して目で分析するのではなく、なぜ気にしませんか?)、そして(b)パラレルIOのアプローチの任意の並べ替えと幸運から。あなたがやっていることは、出力データが小さいので、すべてのデータを一緒にMPI_GATHER()にランク付けして、障壁を越えるのではなく書く方が良いでしょう。 –

+0

これはgnuplotに入りますので、このようにフォーマットしなければなりません(AFAIK) –

答えて

2

正しいIO戦略を決定するには、多くの要因が必要です。あなたがほんの一意の固有値を返すだけで、ASCIIを書き留めているのであれば、すべてのデータをプロセス0に送って書き込むほうが良いかもしれません。これはではありません。通常、勝利戦略です。しかし、データ量が非常に少ない場合、共有ファイル(ASCIIではより難しい)に書き出す際の競合よりも優れている可能性があります。

誰もが同じ量のデータを持っていると仮定すると、以下のコードでは、データ量をproc 0に戻します。

もうひとつのアプローチは、誰もが独自のksと固有値を書き出し、プログラムが終了した後の後処理ステップとして、それらをすべてまとめて猫にすることです。それはMPIのステップを避け、(適切なファイルシステムで)かなりの方法でスケールアップすることができ、簡単です。それが良いかどうかは、かなり簡単にテスト可能であり、データ量、プロセッサ数、および基礎となるファイルシステムに依存します。

program testio 
    use mpi 
    implicit none 

    integer, parameter :: atom_count = 5 
    integer, parameter :: kpertask = 2 
    integer, parameter :: fileunit = 7 
    integer, parameter :: io_master = 0 
    double precision, parameter :: pi = 3.14159 

    integer :: totalk 
    integer :: ierr 
    integer :: rank, nprocs 

    integer :: handle 
    integer(kind=MPI_OFFSET_KIND) :: offset 
    integer :: filetype 

    integer :: j,k 
    double precision, dimension(atom_count, kpertask) :: eigenvalues 
    double precision, dimension(kpertask) :: ks 

    double precision, allocatable, dimension(:,:):: alleigenvals 
    double precision, allocatable, dimension(:) :: allks 

    call MPI_INIT(ierr) 
    call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr) 
    call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) 

    totalk = nprocs*kpertask 

    !! setup test data 

    do k=1,kpertask 
     ks(k) = (rank*kpertask+k)*1.d-4*PI 
     do j=1,atom_count 
      eigenvalues(j,k) = rank*100+j 
     enddo 
    enddo 

    !! Everyone sends proc 0 their data 

    if (rank == 0) then 
     allocate(allks(totalk)) 
     allocate(alleigenvals(atom_count, totalk)) 
    endif 

    call MPI_GATHER(ks, kpertask, MPI_DOUBLE_PRECISION, & 
        allks, kpertask, MPI_DOUBLE_PRECISION, & 
        io_master, MPI_COMM_WORLD, ierr) 

    call MPI_GATHER(eigenvalues, kpertask*atom_count, MPI_DOUBLE_PRECISION, & 
        alleigenvals, kpertask*atom_count, MPI_DOUBLE_PRECISION, & 
        io_master, MPI_COMM_WORLD, ierr) 

    if (rank == 0) then 
     open(unit=fileunit, file='output.txt') 
     do k=1,totalk 
      WRITE(fileunit, *) allks(k), (alleigenvals(j,k), j = 1, atom_count) 
     enddo 
     close(unit=fileunit) 

     deallocate(allks) 
     deallocate(alleigenvals) 
    endif 
    call MPI_FINALIZE(ierr) 
end program testio 
+0

ありがとうございます。私は言及しなかったと思いますが、これはK(0〜1000)のループであり、EIGENVALUESは多くの要素を持つことができます(500は正常です)。したがって、ループEIGENVALUESのすべての反復が失われます。実現可能である。しかし、異なるプロセッサ上の異なるファイルに保存することは可能であり、今のところ簡単な解決策として役立つかもしれません:) –

+0

私は、各プロセスごとに別々のファイルに行き、それらを一緒に縫い合わせました。私はgnuplotのフォーマットを維持しなければならないので、MPIを使って直接書くと苦痛になるようです。これは今のところうまくいく、ありがとう –

0

あなたは各ランクの書き込みがされる時間を決定することができます場合は、各ランクがで開始する必要があり、その後、彼らはすべてのMPI_FILE_WRITE_ATを呼び出すことができるというオフセットを計算するためにMPI_SCAN(size, offset, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD)を呼び出すことができます。これはおそらく、データが大量にあり、MPIの実装が効率的に書き込みを行う(内部的に直列化しないなど)場合には、おそらくより適しています。