Here is a simple code of fortran with MPI:
program mpi_broadcast_example
use mpi
implicit none
integer :: ierr, rank, size, root
integer :: a
call MPI_Init(ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
call MPI_Comm_size(MPI_COMM_WORLD, size, ierr)
root = 0
if (rank == root) then
! Initialize the value of variable a on the root process
a = 42
endif
! Broadcast the value of variable a from the root process to all other processes
call MPI_Bcast(a, 1, MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
! Output the received value of variable a on all processes
write(*,*) 'Process', rank, ': Received a =', a
call MPI_Finalize(ierr)
end program mpi_broadcast_example
It just use MPI_Bcast to pass the a
to other ranks from rank 0.
When I use Intel Fortran + Intel MPI to compile it, it report a warn:
mpiifx test.f90 -o test -warn all
test.f90(21): warning #8889: Explicit interface or EXTERNAL declaration is required. [MPI_BCAST]
call MPI_Bcast(a, 1, MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
---------^
I was puzzled by this warning.
I use MPI_Bcast heavily in another project, so there are plenty of warnings, but for other MPI subroutines, there are no warnings at all. Is this a compiler bug? I find it doesn't seem to affect usage, but it does affect mood.
And if I change implicit none
to implicit none(type, external)
, an error will be reported directly:
mpiifx test.f90 -o test -warn all
test.f90(21): error #8889: Explicit interface or EXTERNAL declaration is required. [MPI_BCAST]
call MPI_Bcast(a, 1, MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
---------^
compilation aborted for test.f90 (code 1)
I wish someone could explain to me what is going on and whether this is a compilation error.
The reason is, as the warning says, the mpi
module contains no interface for mpi_bcast
. The reason no warning is given for the other routines is that the mpi
module does have an interface for these routines.
Why is this? Well you would have to ask the those who implemented the mpi
module for a definitive answer. But as a step to a guess at an answer let me note mpi_bcast
has one fundamental difference from the other routines - it has a choice argument. In other words the interface for mpi_bcast
has to deal with lots of different types, kinds and ranks for its first argument, while, for examples and in contrast, mpi_comm_rank
always takes exactly the same type, kind and rank for all its arguments. Pre Fortran-2003 it was impossible to write an interface for a routine with choice arguments that caught all possible cases. Thus the mpi
module is not required to contain an interface for any routine which has one or more choice arguments. On the other hand the more modern mpi_f08
module is required to contain appropriate interfaces, and changing your code to use this module results in the warning message disappearing:
ijb@ijb-Latitude-5410:~/work/stack$ cat bcast_f08.f90
program mpi_broadcast_example
use mpi_f08
implicit none
integer :: ierr, rank, size, root
integer :: a
call MPI_Init(ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
call MPI_Comm_size(MPI_COMM_WORLD, size, ierr)
root = 0
if (rank == root) then
! Initialize the value of variable a on the root process
a = 42
endif
! Broadcast the value of variable a from the root process to all other processes
call MPI_Bcast(a, 1, MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
! Output the received value of variable a on all processes
write(*,*) 'Process', rank, ': Received a =', a
call MPI_Finalize(ierr)
end program mpi_broadcast_example
ijb@ijb-Latitude-5410:~/work/stack$ ifx -v
ifx version 2023.2.0
ijb@ijb-Latitude-5410:~/work/stack$ mpiifx -warn all bcast_f08.f90
ijb@ijb-Latitude-5410:~/work/stack$
On the other hand if we go back to the original program and add another routine with choice arguments it complains about that as well as mpi_bcast
ijb@ijb-Latitude-5410:~/work/stack$ cat bcast.f90
program mpi_broadcast_example
use mpi
implicit none
integer :: ierr, rank, size, root
integer :: a, b
call MPI_Init(ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
call MPI_Comm_size(MPI_COMM_WORLD, size, ierr)
root = 0
if (rank == root) then
! Initialize the value of variable a on the root process
a = 42
endif
! Broadcast the value of variable a from the root process to all other processes
call MPI_Bcast(a, 1, MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
Call MPI_Allreduce( a, b, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, ierr )
! Output the received value of variable a on all processes
write(*,*) 'Process', rank, ': Received a =', a
call MPI_Finalize(ierr)
end program mpi_broadcast_example
ijb@ijb-Latitude-5410:~/work/stack$ mpiifx -warn all bcast.f90
bcast.f90(21): warning #8889: Explicit interface or EXTERNAL declaration is required. [MPI_BCAST]
call MPI_Bcast(a, 1, MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
---------^
bcast.f90(22): warning #8889: Explicit interface or EXTERNAL declaration is required. [MPI_ALLREDUCE]
Call MPI_Allreduce( a, b, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, ierr )
---------^
ijb@ijb-Latitude-5410:~/work/stack$