Search code examples
mpifortran90subroutine

MPI subroutines in Fortran


I have looked through all the posts on this topic I could find but they do not seem to solve my problem. I am thankful for any input/help/idea. So here it is:

I have my main program (main.f90):

    program inv_main

    use mod_communication

    implicit none

    include 'mpif.h'   

    ...

    call MPI_INIT(ierr) 

    call MPI_COMM_RANK(MPI_COMM_WORLD,id,ierr)

    call MPI_COMM_SIZE(MPI_COMM_WORLD,nproc,ierr) 

    ...

    call SENDRECEIVE(id, nproc, ierr, VVNP, VVN)

    ...

    call MPI_FINALIZE(ierr) 
    end program inv_main  

And here is the module that includes the subroutine (I am aware that allgather might be a better way to do the same but I could not figure it out yet for my 4D array):

    Module mod_communication

    implicit none

    include 'mpif.h'

    integer, dimension(MPI_STATUS_SIZE) :: STATUS ! MPI

    CONTAINS

    Subroutine SENDRECEIVE(id, nproc, ierr, INPUT, OUTPUT )

    integer, intent (in) :: nproc, id, ierr 

    real (dp), intent(in) ::  INPUT(n,m) 

    real (dp), intent(out) :: OUTPUT(n,m,nty,nty)

    integer :: sndr

    IF (id .eq. 0) THEN

    OUTPUT(1:n,1:m,1,1)=INPUT 

    call MPI_RECV(INPUT,n*m,MPI_DOUBLE_PRECISION,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,STATUS,ierr)
    sndr=STATUS(MPI_SOURCE)

    OUTPUT(1:n,1:m,int(sndr/nty)+1,sndr+1-nty*(int(sndr/nty))) = INPUT

    END IF


    IF (id .ne. 0) THEN 

    call MPI_SEND(INPUT,n*m,MPI_DOUBLE_PRECISION,0,id,MPI_COMM_WORLD,ierr)

    ENDIF

    call MPI_BARRIER(MPI_COMM_WORLD,ierr)

    call MPI_BCAST(OUTPUT,n*m*nty*nty,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD,ierr)

    end Subroutine 

    end Module mod_communication

This is the error message I got when compiling:

    use mod_communication
      2
    Error: Symbol 'mpi_displacement_current' at (1) conflicts with symbol from module  'mod_communication', use-associated at (2)
    mpif-mpi-io.h:71.36:
    Included at mpif-config.h:65:
    Included at mpif-common.h:70:
    Included at mpif.h:59:
    Included at main.f90:27:

    integer MPI_MAX_DATAREP_STRING
                                1
    main.f90:21.6:

    use mod_communication
     2
    Error: Symbol 'mpi_max_datarep_string' at (1) conflicts with symbol from module 'mod_communication', use-associated at (2)
    mpif-mpi-io.h:73.32:
    Included at mpif-config.h:65:
    Included at mpif-common.h:70:
    Included at mpif.h:59:
    Included at main.f90:27:

    parameter (MPI_FILE_NULL=0)

These are just the first two errors, it keeps going like that... And I cannot find my mistake. Also, I have to use "include 'mpif.h'" and not "use mpi" because of the machine I am ultimately going to run it on. If I compile it with use mpi however on my own computer it gives me a different error, which is the following:

    mod_MPI.f90:93.41:

    call MPI_BARRIER(MPI_COMM_WORLD,ierr)
                                     1
    Error: There is no specific subroutine for the generic 'mpi_barrier' at (1)
    mod_MPI.f90:52.41:

Solution

  • Your main program probably gets (or rather tries to get) two copies of all the stuff in mpif.h. By include-ing it in the module you effectively make all its contents module things (variables, routines, parameters, what-nots). Then, in main you both use the module and, thereby, use-associate the module things, and try to include mpif.h and redeclare all those things again.

    Do what @Jonathan Dursi suggests too.