/Functional-MPI-Wrapper

Functional MPI wrapper for Fortran

Primary LanguageFortranBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

Functional MPI Wrapper

Functional MPI wrapper for Fortran.

Getting started

You should have some MPI Fortran wrapper compiler. For example, mpifort, mpiifort, etc.

Installation:

mkdir build
cd build
cmake ..
make

or

sh cmake.sh

And then you can include the module in your code:

use mod_mpifw

Why MPI wrapper?

MPI wrapper contains overloaded functions for standard functions of MPI API. The wrapper enables you to write your parallel code more semantic, more simple and more functional. Currently, it includes just a few standard functions and overloaded functions, see What's included?.

What's included?

Variables:

  • num_procs - The number of MPI processes.
  • this_proc - The id of the calling process. It can range from 0 to num_procs-1.

Subroutines:

  • init_mpi() - Initializes the MPI execution environment and set Variables
  • finish_mpi() - The function terminates MPI execution environment
  • sync_mpi() - Synchronization of MPI processes
  • stop_mpi([msg]) - The function terminates MPI execution environment. Replacement for a stop statement. Argument msg is an optional character variable which will send to STDOUT before termination.

Functions:

  • send_mpi(msg, p_from, p_to) - Send msg from process p_from to process p_to.
  • bcast_mpi(msg, p_from) - Send msg from p_from to all processes.
  • reduce_mpi(msg, n_to, op) - Reduce msg on all process via operation op, and the result send on process n_to.
  • allreduce_mpi(msg, op) - Same as the reduce_mpi but the result is sent to all processes.

All of the above functions are compatible with the standard Fortran 2008 kinds: int8, int16, int32, int64 real32, real64, real128 complex(real32), complex(real64), complex(real128) and logical

Argumets:

  • msg - can by scalar or array with dimension of range 1 to 7 - accepted kinds: int8, int16, int32, int64 real32, real64, real128, complex(real32), complex(real64), complex(real128) and logical
  • p_from, p_to - are int32 variables with range from 0 to num_procs-1.
  • op - is character and can take the vlues:
    • "sum" - sum
    • "prod" - product
    • "min" - minimum value
    • "max" - maximum value
    • "and" - logical and
    • "or" - logical or

Example usage

You can found examples in /examples. All examples in /example you can run by python script run_examples_mpifort.py

send_mpi example

use mod_mpi_wrapper
use iso_fortran_env
implicit none

integer(int32) :: i, a(3) , b(3)    
    
call init_mpi()

a = [( this_proc*i , i=1,3)]
b = 0

write(*,'(*(g0,1x))') this_proc,")", a

call sync_mpi()
if(this_proc==0) write(*,*) "=================="
call sync_mpi()

b = send_mpi(a, 1, 3)

write(*,'(*(g0,1x))') this_proc,")",a,"|",b

call finish_mpi()

Typical output (for 4 processes):

1 ) 1 2 3
3 ) 3 6 9
2 ) 2 4 6
0 ) 0 0 0
 ==================
0 ) 0 0 0 | 0 0 0
3 ) 3 6 9 | 1 2 3
1 ) 1 2 3 | 1 2 3
2 ) 2 4 6 | 2 4 6

bcast_mpi example

use mod_mpi_wrapper
use iso_fortran_env
implicit none

integer(int32) :: i, a(3) , b(3)    
    
call init_mpi()

a = [( this_proc*i , i=1,3)]

write(*,'(*(g0,1x))') this_proc,")", a

call sync_mpi()
if(this_proc==0) write(*,*) "=================="
call sync_mpi()

a = bcast_mpi(a, 3)

write(*,'(*(g0,1x))') this_proc,")", a

call finish_mpi()

Typical output (for 4 processes):

1 ) 1 2 3
2 ) 2 4 6
3 ) 3 6 9
0 ) 0 0 0
 ==================
3 ) 3 6 9
1 ) 3 6 9
2 ) 3 6 9
0 ) 3 6 9

reduce_mpi and allreduce_mpi example

use mod_mpi_wrapper
use iso_fortran_env
implicit none

integer(int32) :: i, a(3) , b(3)  
    
call init_mpi()

a = [( this_proc*i , i=1,3)]

write(*,'(*(g0,1x))') this_proc,")", a

call sync_mpi()
if(this_proc==0) write(*,*) "=================="
call sync_mpi()

write(*,*) this_proc,reduce_mpi(a, 0, "sum")

call sync_mpi()
if(this_proc==0) write(*,*) "=================="
call sync_mpi()

write(*,'(*(g0,1x))') this_proc,")",allreduce_mpi(a, "sum")

call finish_mpi()

Typical output (for 4 processes):

0 ) 0 0 0
3 ) 3 6 9
1 ) 1 2 3
2 ) 2 4 6
 ==================
3 ) 3 6 9
1 ) 1 2 3
2 ) 2 4 6
0 ) 6 12 18
 ==================
2 ) 6 12 18
3 ) 6 12 18
1 ) 6 12 18
0 ) 6 12 18

Contributing

In /raw folder are "raw" Fortran files where are use some tags. Tags are used for automated generation of src files by raw_to_src.py python script.

Bug reports and requests, please submit here.

References