为什么 MPI_REDUCE returns 在编译时会出现语法错误?
Why does MPI_REDUCE returns a syntax error at compile time?
自 70 年代末上大学以来,我就没有用 Fortran 编写过代码(那是用打孔卡!),但现在我正在尝试学习如何将 MPI 与该语言一起使用。我在调用 MPI_REDUCE 时遇到语法错误,但我不知道为什么。我只知道我错过了一些简单的东西。
C Test program
program pi_reduce
include 'mpif.h'
double precision PI25DT
parameter (PI25DT = 3.141592535897932384662643d0)
double precision mypi, pi, h, sum, x, f, a
integer n, myid, numprocs, i, ierr
f(a) = 4.d0/(1.d0 + a*a)
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr)
do
if (myid .eq. 0) then
print *, 'Enter the number of intervals: (0 quits) '
read(*,*) n
endif
call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
if (n .le. 0) exit
h = 1.0d0/n
sum = 0.0d0
do i = myid + 1, n, numprocs
x = h * (dble(i) - 0.5d0)
sum = sum + f(x)
enddo
mypi = h * sum
call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
if (myid .eq. 0) then
print *, 'pi is ', pi, ' Error is', abs(pi-PI25DT)
endif
enddo
call MPI_FINALIZE(ierr)
end
如评论中所述,您的其中一行太长了。使用 gfortran 至少如果你将警告调到最大(如果开发代码你应该这样做)你会得到更多信息
ian@eris:~/work/stack$ mpif90 --version
GNU Fortran (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ian@eris:~/work/stack$ mpif90 -O -fcheck=all -std=f2008 -Wall -Wextra long.f
long.f:8:72:
f(a) = 4.d0/(1.d0 + a*a)
1
Warning: Obsolescent feature: Statement function at (1)
long.f:27:72:
call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
1
Warning: Line truncated at (1) [-Wline-truncation]
long.f:27:72:
call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
1
Error: Syntax error in argument list at (1)
我建议您移动“新”(即可用 30 年)免费格式,它比基于陈旧穿孔卡的格式更灵活。事实上,总的来说,这将是一个很好的机会来学习现代的、比你多年前使用的更安全的做法(我猜从你说的我们是一个非常相似的年份)。这是您的代码的现代化版本
ian@eris:~/work/stack$ cat long.f90
program pi_reduce
Use, Intrinsic :: iso_fortran_env, Only : wp => real64
! Even better Use mpi_f08
Use :: mpi, Only : mpi_init, mpi_comm_rank, mpi_comm_size, mpi_reduce, &
MPI_INTEGER, MPI_DOUBLE_PRECISION, MPI_COMM_WORLD, MPI_SUM
Implicit None
Real( wp ), Parameter :: PI25DT = 3.141592535897932384662643_wp
Real( wp ) :: mypi, pi, h, sum, x
integer :: n, myid, numprocs, i, ierr
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr)
do
if (myid == 0) then
print *, 'Enter the number of intervals: (0 quits) '
read(*,*) n
endif
call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
if (n .le. 0) exit
h = 1.0_wp/n
sum = 0.0_wp
do i = myid + 1, n, numprocs
x = h * ( Real( i , wp ) - 0.5_wp)
sum = sum + f(x)
enddo
mypi = h * sum
call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
if (myid .eq. 0) then
print *, 'pi is ', pi, ' Error is', abs(pi-PI25DT)
endif
enddo
call MPI_FINALIZE(ierr)
Contains
Pure Function f( a )
Use, Intrinsic :: iso_fortran_env, Only : wp => real64
Implicit None
Real( wp ) :: f
Real( wp ), Intent( In ) :: a
f = 4.0_wp / ( 1.0_wp + a * a )
End Function f
end program pi_reduce
ian@eris:~/work/stack$ mpif90 --version
GNU Fortran (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ian@eris:~/work/stack$ mpif90 -O -fcheck=all -std=f2008 -Wall -Wextra long.f90
ian@eris:~/work/stack$ mpirun -np 8 ./a.out
Enter the number of intervals: (0 quits)
345435
pi is 3.1415926535904788 Error is 1.1769254637528093E-007
Enter the number of intervals: (0 quits)
0
ian@eris:~/work/stack$
自 70 年代末上大学以来,我就没有用 Fortran 编写过代码(那是用打孔卡!),但现在我正在尝试学习如何将 MPI 与该语言一起使用。我在调用 MPI_REDUCE 时遇到语法错误,但我不知道为什么。我只知道我错过了一些简单的东西。
C Test program
program pi_reduce
include 'mpif.h'
double precision PI25DT
parameter (PI25DT = 3.141592535897932384662643d0)
double precision mypi, pi, h, sum, x, f, a
integer n, myid, numprocs, i, ierr
f(a) = 4.d0/(1.d0 + a*a)
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr)
do
if (myid .eq. 0) then
print *, 'Enter the number of intervals: (0 quits) '
read(*,*) n
endif
call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
if (n .le. 0) exit
h = 1.0d0/n
sum = 0.0d0
do i = myid + 1, n, numprocs
x = h * (dble(i) - 0.5d0)
sum = sum + f(x)
enddo
mypi = h * sum
call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
if (myid .eq. 0) then
print *, 'pi is ', pi, ' Error is', abs(pi-PI25DT)
endif
enddo
call MPI_FINALIZE(ierr)
end
如评论中所述,您的其中一行太长了。使用 gfortran 至少如果你将警告调到最大(如果开发代码你应该这样做)你会得到更多信息
ian@eris:~/work/stack$ mpif90 --version
GNU Fortran (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ian@eris:~/work/stack$ mpif90 -O -fcheck=all -std=f2008 -Wall -Wextra long.f
long.f:8:72:
f(a) = 4.d0/(1.d0 + a*a)
1
Warning: Obsolescent feature: Statement function at (1)
long.f:27:72:
call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
1
Warning: Line truncated at (1) [-Wline-truncation]
long.f:27:72:
call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
1
Error: Syntax error in argument list at (1)
我建议您移动“新”(即可用 30 年)免费格式,它比基于陈旧穿孔卡的格式更灵活。事实上,总的来说,这将是一个很好的机会来学习现代的、比你多年前使用的更安全的做法(我猜从你说的我们是一个非常相似的年份)。这是您的代码的现代化版本
ian@eris:~/work/stack$ cat long.f90
program pi_reduce
Use, Intrinsic :: iso_fortran_env, Only : wp => real64
! Even better Use mpi_f08
Use :: mpi, Only : mpi_init, mpi_comm_rank, mpi_comm_size, mpi_reduce, &
MPI_INTEGER, MPI_DOUBLE_PRECISION, MPI_COMM_WORLD, MPI_SUM
Implicit None
Real( wp ), Parameter :: PI25DT = 3.141592535897932384662643_wp
Real( wp ) :: mypi, pi, h, sum, x
integer :: n, myid, numprocs, i, ierr
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr)
do
if (myid == 0) then
print *, 'Enter the number of intervals: (0 quits) '
read(*,*) n
endif
call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
if (n .le. 0) exit
h = 1.0_wp/n
sum = 0.0_wp
do i = myid + 1, n, numprocs
x = h * ( Real( i , wp ) - 0.5_wp)
sum = sum + f(x)
enddo
mypi = h * sum
call MPI_REDUCE(mypi, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)
if (myid .eq. 0) then
print *, 'pi is ', pi, ' Error is', abs(pi-PI25DT)
endif
enddo
call MPI_FINALIZE(ierr)
Contains
Pure Function f( a )
Use, Intrinsic :: iso_fortran_env, Only : wp => real64
Implicit None
Real( wp ) :: f
Real( wp ), Intent( In ) :: a
f = 4.0_wp / ( 1.0_wp + a * a )
End Function f
end program pi_reduce
ian@eris:~/work/stack$ mpif90 --version
GNU Fortran (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ian@eris:~/work/stack$ mpif90 -O -fcheck=all -std=f2008 -Wall -Wextra long.f90
ian@eris:~/work/stack$ mpirun -np 8 ./a.out
Enter the number of intervals: (0 quits)
345435
pi is 3.1415926535904788 Error is 1.1769254637528093E-007
Enter the number of intervals: (0 quits)
0
ian@eris:~/work/stack$