module mod_comm_lib implicit none private public :: comm_start public :: comm_finalize public :: init_comm_types public :: mpistop public :: mpistop_gpu contains !> Initialize the MPI environment subroutine comm_start use mod_global_parameters integer(kind=MPI_ADDRESS_KIND) :: lb integer(kind=MPI_ADDRESS_KIND) :: sizes ! Each process stores its rank, which ranges from 0 to N-1, where N is the ! number of processes. call MPI_COMM_RANK(MPI_COMM_WORLD,mype,ierrmpi) ! Store the number of processes call MPI_COMM_SIZE(MPI_COMM_WORLD,npe,ierrmpi) ! Use the default communicator, which contains all the processes icomm = MPI_COMM_WORLD ! Get size of double/integer call MPI_TYPE_GET_EXTENT(MPI_REAL,lb,sizes,ierrmpi) if (sizes /= size_real) call mpistop("Incompatible real size") call MPI_TYPE_GET_EXTENT(MPI_DOUBLE_PRECISION,lb,sizes,ierrmpi) if (sizes /= size_double) call mpistop("Incompatible double size") call MPI_TYPE_GET_EXTENT(MPI_INTEGER,lb,sizes,ierrmpi) if (sizes /= size_int) call mpistop("Incompatible integer size") call MPI_TYPE_GET_EXTENT(MPI_LOGICAL,lb,sizes,ierrmpi) if (sizes /= size_logical) call mpistop("Incompatible logical size") end subroutine comm_start !> Finalize (or shutdown) the MPI environment subroutine comm_finalize use mod_global_parameters call MPI_BARRIER(MPI_COMM_WORLD,ierrmpi) call MPI_FINALIZE(ierrmpi) end subroutine comm_finalize !> Create and store the MPI types that will be used for parallel communication subroutine init_comm_types use mod_global_parameters integer, dimension(ndim+1) :: sizes, subsizes, start integer :: i1,i2,i3, ic1,ic2,ic3, nx1,nx2,nx3, nxCo1,nxCo2,nxCo3, nxG1,& nxG2,nxG3, idir nx1=ixMhi1-ixMlo1+1;nx2=ixMhi2-ixMlo2+1;nx3=ixMhi3-ixMlo3+1; nxG1=ixGhi1-ixGlo1+1;nxG2=ixGhi2-ixGlo2+1;nxG3=ixGhi3-ixGlo3+1; nxCo1=nx1/2;nxCo2=nx2/2;nxCo3=nx3/2; sizes(1)=ixGhi1;sizes(2)=ixGhi2;sizes(3)=ixGhi3; sizes(ndim+1)=nw subsizes(1)=nxG1;subsizes(2)=nxG2;subsizes(3)=nxG3; subsizes(ndim+1)=nw start(1)=ixGlo1-1;start(2)=ixGlo2-1;start(3)=ixGlo3-1; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_block,ierrmpi) call MPI_TYPE_COMMIT(type_block,ierrmpi) size_block=nxG1*nxG2*nxG3*nw*size_double sizes(1)=ixGhi1/2+nghostcells;sizes(2)=ixGhi2/2+nghostcells sizes(3)=ixGhi3/2+nghostcells; sizes(ndim+1)=nw subsizes(1)=nxCo1;subsizes(2)=nxCo2;subsizes(3)=nxCo3; subsizes(ndim+1)=nw start(1)=ixMlo1-1;start(2)=ixMlo2-1;start(3)=ixMlo3-1; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_coarse_block,ierrmpi) call MPI_TYPE_COMMIT(type_coarse_block,ierrmpi) if(stagger_grid) then sizes(1)=ixGhi1+1;sizes(2)=ixGhi2+1;sizes(3)=ixGhi3+1; sizes(ndim+1)=nws subsizes(1)=nx1+1;subsizes(2)=nx2+1;subsizes(3)=nx3+1; subsizes(ndim+1)=nws start(1)=ixMlo1-1;start(2)=ixMlo2-1;start(3)=ixMlo3-1; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_block_io_stg,ierrmpi) call MPI_TYPE_COMMIT(type_block_io_stg,ierrmpi) size_block_io_stg=(nx1+1)*(nx2+1)*(nx3+1)*nws*size_double sizes(1)=ixGhi1/2+nghostcells+1;sizes(2)=ixGhi2/2+nghostcells+1 sizes(3)=ixGhi3/2+nghostcells+1; sizes(ndim+1)=nws do ic3=1,2 do ic2=1,2 do ic1=1,2 do idir=1,ndim subsizes(1)=nxCo1+kr(ic1,1)*kr(idir,1) subsizes(2)=nxCo2+kr(ic2,1)*kr(idir,2) subsizes(3)=nxCo3+kr(ic3,1)*kr(idir,3); subsizes(ndim+1)=1 start(1)=ixMlo1-kr(ic1,1)*kr(idir,1) start(2)=ixMlo2-kr(ic2,1)*kr(idir,2) start(3)=ixMlo3-kr(ic3,1)*kr(idir,3); start(ndim+1)=idir-1 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION,& type_coarse_block_stg(idir,ic1,ic2,ic3),ierrmpi) call MPI_TYPE_COMMIT(type_coarse_block_stg(idir,ic1,ic2,ic3),& ierrmpi) end do end do end do end do sizes(1)=ixGhi1+1;sizes(2)=ixGhi2+1;sizes(3)=ixGhi3+1; sizes(ndim+1)=nws do ic3=1,2 do ic2=1,2 do ic1=1,2 do idir=1,3 subsizes(1)=nxCo1+kr(ic1,1)*kr(idir,1) subsizes(2)=nxCo2+kr(ic2,1)*kr(idir,2) subsizes(3)=nxCo3+kr(ic3,1)*kr(idir,3); subsizes(ndim+1)=1 start(1)=ixMlo1-kr(ic1,1)*kr(idir,1)+(ic1-1)*nxCo1 start(2)=ixMlo2-kr(ic2,1)*kr(idir,2)+(ic2-1)*nxCo2 start(3)=ixMlo3-kr(ic3,1)*kr(idir,3)+(ic3-1)*nxCo3; start(ndim+1)=idir-1 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_sub_block_stg(idir,& ic1,ic2,ic3),ierrmpi) call MPI_TYPE_COMMIT(type_sub_block_stg(idir,ic1,ic2,ic3),ierrmpi) end do end do end do end do end if sizes(1)=ixGhi1;sizes(2)=ixGhi2;sizes(3)=ixGhi3; sizes(ndim+1)=nw do ic3=1,2 do ic2=1,2 do ic1=1,2 subsizes(1)=nxCo1;subsizes(2)=nxCo2;subsizes(3)=nxCo3; subsizes(ndim+1)=nw start(1)=ixMlo1-1+(ic1-1)*nxCo1;start(2)=ixMlo2-1+(ic2-1)*nxCo2 start(3)=ixMlo3-1+(ic3-1)*nxCo3; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_sub_block(ic1,ic2,ic3),& ierrmpi) call MPI_TYPE_COMMIT(type_sub_block(ic1,ic2,ic3),ierrmpi) end do end do end do sizes(1)=ixGhi1;sizes(2)=ixGhi2;sizes(3)=ixGhi3; sizes(ndim+1)=nw subsizes(1)=nx1;subsizes(2)=nx2;subsizes(3)=nx3; subsizes(ndim+1)=nw start(1)=ixMlo1-1;start(2)=ixMlo2-1;start(3)=ixMlo3-1; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_block_io,ierrmpi) call MPI_TYPE_COMMIT(type_block_io,ierrmpi) size_block_io=nx1*nx2*nx3*nw*size_double sizes(1)=ixMhi1-ixMlo1+1;sizes(2)=ixMhi2-ixMlo2+1 sizes(3)=ixMhi3-ixMlo3+1; sizes(ndim+1)=3 subsizes(1)=sizes(1);subsizes(2)=sizes(2);subsizes(3)=sizes(3); subsizes(ndim+1)=3 start(1)=0;start(2)=0;start(3)=0; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_block_xcc_io,ierrmpi) call MPI_TYPE_COMMIT(type_block_xcc_io,ierrmpi) sizes(1)=ixMhi1-ixMlo1+2;sizes(2)=ixMhi2-ixMlo2+2 sizes(3)=ixMhi3-ixMlo3+2; sizes(ndim+1)=3 subsizes(1)=sizes(1);subsizes(2)=sizes(2);subsizes(3)=sizes(3); subsizes(ndim+1)=3 start(1)=0;start(2)=0;start(3)=0; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_block_xc_io,ierrmpi) call MPI_TYPE_COMMIT(type_block_xc_io,ierrmpi) sizes(1)=ixMhi1-ixMlo1+1;sizes(2)=ixMhi2-ixMlo2+1 sizes(3)=ixMhi3-ixMlo3+1; sizes(ndim+1)=nw+nwauxio subsizes(1)=sizes(1);subsizes(2)=sizes(2);subsizes(3)=sizes(3); subsizes(ndim+1)=nw+nwauxio start(1)=0;start(2)=0;start(3)=0; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_block_wcc_io,ierrmpi) call MPI_TYPE_COMMIT(type_block_wcc_io,ierrmpi) sizes(1)=ixMhi1-ixMlo1+2;sizes(2)=ixMhi2-ixMlo2+2 sizes(3)=ixMhi3-ixMlo3+2; sizes(ndim+1)=nw+nwauxio subsizes(1)=sizes(1);subsizes(2)=sizes(2);subsizes(3)=sizes(3); subsizes(ndim+1)=nw+nwauxio start(1)=0;start(2)=0;start(3)=0; start(ndim+1)=0 call MPI_TYPE_CREATE_SUBARRAY(ndim+1,sizes,subsizes,start,& MPI_ORDER_FORTRAN,MPI_DOUBLE_PRECISION, type_block_wc_io,ierrmpi) call MPI_TYPE_COMMIT(type_block_wc_io,ierrmpi) end subroutine init_comm_types !> Exit MPI-AMRVAC with an error message ! cray does not allow char type on the GPU subroutine mpistop(message) use mod_global_parameters #ifndef _CRAYFTN #endif character(len=*), intent(in) :: message !< The error message !> Exit status handed to MPI_ABORT integer :: ierrcode write(*, *) "ERROR for processor", mype, ":" #if defined(_OPENACC) || defined(_OPENMP) write(*, *) message STOP #else write(*, *) trim(message) ! Must be set: a job scheduler or CI run keys off the exit status, and ! an undefined ierrcode returns a junk one. ierrcode = 1 call MPI_ABORT(icomm, ierrcode, ierrmpi) #endif end subroutine mpistop subroutine mpistop_gpu() use mod_global_parameters integer :: ierrcode write(*, *) "ERROR for processor", mype STOP end subroutine mpistop_gpu end module mod_comm_lib