Как сохранить точность для программы Fortran MPI портативным способом?

У меня есть программа на Фортране, где я указываюkind числовых типов данных в попытке сохранить минимальный уровень точности, независимо от того, какой компилятор используется для сборки программы. Например:

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

Проблема в том, что я использовал MPI для распараллеливания кода, и мне нужно убедиться, что связи MPI задают один и тот же тип с одинаковой точностью. Я использовал следующий подход, чтобы оставаться в соответствии с подходом в моей программе:

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)

Однако я обнаружил, что эта подпрограмма MPI не особенно хорошо поддерживается для различных реализаций MPI, поэтому она фактически делает мою программу непереносимой. Если я опущуMPI_Type_create рутина, то мне осталось положиться на стандартMPI_REAL а такжеMPI_DOUBLE_PRECISION типы данных, но что, если этот тип не соответствует тому, чтоselected_real_kind выбирает как реальный тип, который в конечном итоге будет передан MPI? Я застрял только с использованием стандартаreal декларация для типа данных, безkind атрибут и, если я это сделаю, я гарантирую, чтоMPI_REAL а такжеreal всегда будет иметь одинаковую точность, независимо от компилятора и машины?

ОБНОВИТЬ:

Я создал простую программу, которая демонстрирует проблему, которую я вижу, когда мои внутренние реалы имеют более высокую точность, чем то, что даетMPI_DOUBLE_PRECISION тип:

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

Если я собираю и запускаю с 2 ядрами, я получаю:

       0   1.12345683574676513672      
       1   4.71241976735884452383E-3998

Теперь измените 16 на 15 вselected_real_kind и я получаю:

       0   1.1234568357467651     
       1   1.1234568357467651  

Всегда ли это будет безопасно использоватьselected_real_kind(15) с участиемMPI_DOUBLE_PRECISION независимо от того, какая машина / компилятор используется для сборки?

Ответы на вопрос(3)

Ваш ответ на вопрос