Como faço para manter a precisão de um programa Fortran MPI de maneira portátil?

Eu tenho um programa Fortran onde eu especifico okind dos tipos de dados numéricos em uma tentativa de manter um nível mínimo de precisão, independentemente de qual compilador é usado para construir o programa. Por exemplo:

integer, parameter :: rsp = selected_real_kind(4)
...
real(kind=rsp) :: real_var

O problema é que usei MPI para paralelizar o código e preciso ter certeza de que as comunicações MPI estão especificando o mesmo tipo com a mesma precisão. Eu estava usando a seguinte abordagem para me manter consistente com a abordagem do meu programa:

call MPI_Type_create_f90_real(4,MPI_UNDEFINED,rsp_mpi,mpi_err)
...
call MPI_Send(real_var,1,rsp_mpi,dest,tag,MPI_COMM_WORLD,err)

No entanto, descobri que esta rotina MPI não é particularmente bem suportada para diferentes implementações de MPI, por isso está realmente tornando meu programa não portátil. Se eu omitir oMPI_Type_create rotina, então eu sou deixado para confiar no padrãoMPI_REAL eMPI_DOUBLE_PRECISION tipos de dados, mas e se esse tipo não for consistente com o queselected_real_kind escolhe como o tipo real que será repassado pelo MPI? Estou preso apenas usando o padrãoreal declaração para um tipo de dados, semkind atributo e, se eu fizer isso, estou garantido queMPI_REAL ereal sempre terão a mesma precisão, independentemente do compilador e da máquina?

ATUALIZAR:

Eu criei um programa simples que demonstra o problema que vejo quando meus reais internos têm uma precisão maior do que a oferecida peloMPI_DOUBLE_PRECISION tipo:

program main

   use mpi

   implicit none

   integer, parameter :: rsp = selected_real_kind(16)
   integer :: err
   integer :: rank

   real(rsp) :: real_var

   call MPI_Init(err)
   call MPI_Comm_rank(MPI_COMM_WORLD,rank,err)

   if (rank.eq.0) then
      real_var = 1.123456789012345
      call MPI_Send(real_var,1,MPI_DOUBLE_PRECISION,1,5,MPI_COMM_WORLD,err)
   else
      call MPI_Recv(real_var,1,MPI_DOUBLE_PRECISION,0,5,MPI_COMM_WORLD,&
         MPI_STATUS_IGNORE,err)
   end if

   print *, rank, real_var

   call MPI_Finalize(err)

end program main

Se eu construir e rodar com 2 núcleos, recebo:

       0   1.12345683574676513672      
       1   4.71241976735884452383E-3998

Agora mude o 16 para um 15 emselected_real_kind e eu recebo:

       0   1.1234568357467651     
       1   1.1234568357467651  

Será sempre seguro usarselected_real_kind(15) comMPI_DOUBLE_PRECISION não importa qual máquina / compilador é usado para fazer a compilação?

questionAnswers(3)

yourAnswerToTheQuestion