Как передать строки в MPI_Allgather в Fortran, используя MPI_TYPE_VECTOR - PullRequest
2 голосов
/ 03 октября 2019

У меня есть массив Fortran, в котором каждая строка рассчитывается процессом. Затем я хочу собрать полный массив для всех процессов. Я могу заставить его работать для двух вариантов mpi_allgather, но не для более элегантного, используя приведенный здесь mpi_type_vector, например:

   program allGather
      ! test of MPI_allgather with rows
      use mpi
      implicit none
      integer i, mpierr, myRank, noProc
      integer, allocatable:: survived(:,:)
      integer rowtype
      real(4) ran

      call MPI_INIT( mpierr )
      call MPI_COMM_RANK(MPI_COMM_WORLD, myRank, mpierr) ! get rank of this process in world      
      call MPI_COMM_SIZE(MPI_COMM_WORLD, noProc, mpiErr)

      allocate( survived(noProc,2) ) ! used to find best solution out of all processes

      ! Each process calculates one row of survived and each row is tagged with it's rank for sorting
      ! For this test example, just use a random number
      call RANDOM_SEED()
      call RANDOM_NUMBER(ran)
      survived(myRank+1,:) = [int(1.e6*ran), myRank]
      write(*,'(3(a,i0),a)') 'Rank: ', myRank, ' survived = [', survived(myRank+1,1), ', ', survived(myRank+1,2),']'
      call mpi_barrier(MPI_COMM_WORLD, mpiErr)      

      ! specify type to capture rows of survived
      call MPI_TYPE_VECTOR(2, 1, noProc, MPI_INTEGER, rowtype, mpierr)
      call MPI_TYPE_COMMIT(rowtype, mpierr)
      call MPI_allgather(MPI_IN_PLACE, 1, rowtype, survived     , 1, rowtype, MPI_COMM_WORLD, mpierr)

      if (myRank == 0) then
         write(*,'(/,a)') 'Passed array is:'
         write(*,'(i0,'', '',i0)') (survived(i,:),i=1,noProc)
      end if

      deallocate( survived ) ! used to find best solution out of all processes
      call MPI_FINALIZE(mpierr)          
   end program allGather

Это генерирует вывод для 4 процессов, что-то вроде:

Rank: 0 survived = [819935, 0]
Rank: 1 survived = [971609, 1]
Rank: 2 survived = [859684, 2]
Rank: 3 survived = [747759, 3]

Passed array is:
819935, 0
0, 1
0, 0
0, 0

Очевидно, я что-то упустил. Может кто-нибудь указать на мою ошибку? Спасибо!

...