Search code examples
fortranmpiintel-fortranintel-mpi

Why Intel Fortran + Intel MPI report warn(error) when using MPI_Bcast?


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.


Solution

  • 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$