У меня есть программа Fortran, где я указываю 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
всегда будут иметь одинаковую точность, независимо от того, компилятор и машина?
UPDATE:
Я создал простую программу, которая демонстрирует проблему, которую я вижу, когда мои внутренние значения имеют более высокую точность, чем то, что предоставляется типом 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
Если я создам и запускаю с двумя ядрами, я получаю:
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
независимо от того, какой компьютер/компилятор используется для сборки?