From a364f222cb07110b7db59c7587038ecb06d6f272 Mon Sep 17 00:00:00 2001 From: Juan Escobar <juan.escobar@aero.obs-mip.fr> Date: Fri, 17 Sep 2021 09:09:32 +0200 Subject: [PATCH] Juan 17/09/2021:get_halo.f90, add GET_2D_HALO_DDC for turb.f90 --- src/ZSOLVER/get_halo.f90 | 628 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 626 insertions(+), 2 deletions(-) diff --git a/src/ZSOLVER/get_halo.f90 b/src/ZSOLVER/get_halo.f90 index 201e1170b..717d08414 100644 --- a/src/ZSOLVER/get_halo.f90 +++ b/src/ZSOLVER/get_halo.f90 @@ -114,6 +114,26 @@ INTERFACE ! END SUBROUTINE GET_HALO_DDC END INTERFACE +INTERFACE + SUBROUTINE GET_2D_HALO_DD(PSRC, HDIR, HNAME) + IMPLICIT NONE + ! + REAL, DIMENSION(:,:), INTENT(INOUT) :: PSRC ! variable at t + CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction + character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added + ! + END SUBROUTINE GET_2D_HALO_DD +END INTERFACE +INTERFACE + SUBROUTINE GET_2D_HALO_DDC(PSRC, HDIR, HNAME) + IMPLICIT NONE + ! + REAL, DIMENSION(:,:), INTENT(INOUT) :: PSRC ! variable at t + CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction + character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added + ! + END SUBROUTINE GET_2D_HALO_DDC +END INTERFACE #endif ! INTERFACE @@ -217,6 +237,13 @@ MODULE MODD_HALO_D REAL, SAVE , ALLOCATABLE, DIMENSION(:,:) :: ZNORTH2_IN, ZSOUTH2_IN, ZWEST2_IN, ZEAST2_IN REAL, SAVE , ALLOCATABLE, DIMENSION(:,:) :: ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT + + REAL, SAVE , ALLOCATABLE, DIMENSION(:,:) :: ZNORTH_2D_IN, ZSOUTH_2D_IN, ZWEST_2D_IN, ZEAST_2D_IN + REAL, SAVE , ALLOCATABLE, DIMENSION(:,:) :: ZNORTH_2D_OUT, ZSOUTH_2D_OUT, ZWEST_2D_OUT, ZEAST_2D_OUT + + REAL, SAVE , ALLOCATABLE, DIMENSION(:,:) :: ZNORTHC_2D_IN, ZSOUTHC_2D_IN, ZWESTC_2D_IN, ZEASTC_2D_IN + REAL, SAVE , ALLOCATABLE, DIMENSION(:,:) :: ZNORTHC_2D_OUT, ZSOUTHC_2D_OUT, ZWESTC_2D_OUT, ZEASTC_2D_OUT + LOGICAL, SAVE :: GFIRST_GET_HALO_D = .TRUE. @@ -282,8 +309,36 @@ CONTAINS ALLOCATE ( ZNORTH2_OUT ( IIU , IKU ) ) ALLOCATE ( ZWEST2_OUT ( IJU , IKU ) ) ALLOCATE ( ZEAST2_OUT ( IJU , IKU ) ) - !$acc enter data create (ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT) - + !$acc enter data create (ZNORTH2_OUT, ZSOUTH2_OUT, ZWEST2_OUT, ZEAST2_OUT) + ! + ! Init HALO_2D + ! + ALLOCATE ( ZSOUTH_2D_IN ( IIB:IIE , IJB:IJB+IHALO_1 ) ) + ALLOCATE ( ZNORTH_2D_IN ( IIB:IIE , IJE-IHALO_1:IJE ) ) + ALLOCATE ( ZWEST_2D_IN ( IIB:IIB+IHALO_1 , IJB:IJE ) ) + ALLOCATE ( ZEAST_2D_IN ( IIE-IHALO_1:IIE , IJB:IJE ) ) + !$acc enter data create (ZNORTH_2D_IN, ZSOUTH_2D_IN, ZWEST_2D_IN, ZEAST_2D_IN) + ! + ALLOCATE ( ZSOUTH_2D_OUT ( IIB:IIE , 1:IJB-1) ) + ALLOCATE ( ZNORTH_2D_OUT ( IIB:IIE , IJE+1:IJU) ) + ALLOCATE ( ZWEST_2D_OUT ( 1:IIB-1 , IJB:IJE ) ) + ALLOCATE ( ZEAST_2D_OUT ( IIE+1:IIU , IJB:IJE ) ) + !$acc enter data create (ZNORTH_2D_OUT, ZSOUTH_2D_OUT, ZWEST_2D_OUT, ZEAST_2D_OUT) + ! + ! Init HALO 2D with Corner + ! + ALLOCATE ( ZSOUTHC_2D_IN ( 1:IIU , IJB:IJB+IHALO_1 ) ) + ALLOCATE ( ZNORTHC_2D_IN ( 1:IIU , IJE-IHALO_1:IJE ) ) + ALLOCATE ( ZWESTC_2D_IN ( IIB:IIB+IHALO_1 , IJB:IJE ) ) + ALLOCATE ( ZEASTC_2D_IN ( IIE-IHALO_1:IIE , IJB:IJE ) ) + !$acc enter data create (ZNORTHC_2D_IN, ZSOUTHC_2D_IN, ZWESTC_2D_IN, ZEASTC_2D_IN) + ! + ALLOCATE ( ZSOUTHC_2D_OUT ( 1:IIU , 1:IJB-1 ) ) + ALLOCATE ( ZNORTHC_2D_OUT ( 1:IIU , IJE+1:IJU ) ) + ALLOCATE ( ZWESTC_2D_OUT ( 1:IIB-1 , IJB:IJE ) ) + ALLOCATE ( ZEASTC_2D_OUT ( IIE+1:IIU , IJB:IJE ) ) + !$acc enter data create (ZNORTHC_2D_OUT, ZSOUTHC_2D_OUT, ZWESTC_2D_OUT, ZEASTC_2D_OUT) + IF (.NOT. GWEST ) THEN NP_WEST = ( IP-1 -1 ) + 1 ELSE @@ -918,6 +973,275 @@ END IF !$acc end data END SUBROUTINE GET_HALO_DD +! ######################################## + SUBROUTINE GET_2D_HALO_DD(PSRC, HDIR, HNAME) +! ######################################## +#define MNH_GPUDIRECT +! +USE MODD_HALO_D +USE MODE_ll +USE MODD_ARGSLIST_ll, ONLY : LIST_ll +USE MODD_PARAMETERS, ONLY : JPHEXT +! +USE MODD_IO, ONLY : GSMONOPROC +USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH +! +USE MODD_CONF, ONLY : NHALO +USE MODE_DEVICE +USE MODE_MPPDB + +USE MODD_VAR_ll, ONLY : IP,NPROC,NP1,NP2 +USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD +USE MODD_MPIF, ONLY : MPI_STATUSES_IGNORE +USE MODD_PRECISION, ONLY : MNHREAL_MPI +! +USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU +USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE +! +IMPLICIT NONE +! +REAL, DIMENSION(:,:), INTENT(INOUT) :: PSRC ! variable at t +CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction +character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added +! +character(len=:), allocatable :: yname +TYPE(LIST_ll) , POINTER :: TZ_PSRC_ll ! halo +INTEGER :: IERROR ! error return code + +INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4 + +LOGICAL :: LX , LY + +INTEGER :: INB_REQ , IREQ(8) +INTEGER :: IERR + +if ( NPROC == 1 ) RETURN + +CALL INIT_HALO_D() + +!$acc data present ( PSRC ) + +NULLIFY( TZ_PSRC_ll) +! + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +LX = .FALSE. +LY = .FALSE. + +IF (.NOT. PRESENT(HDIR) ) THEN +LX = .TRUE. +LY = .TRUE. +ELSE + ! + ! Problem of reproductibility in ppm_s0_x/y if only S0_X or S0_Y + ! so add S0_X + S0_Y for ppm_s0* + ! +!!$LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" ) +!!$LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" ) +LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" ) +LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" ) +END IF + +!!$LX = .TRUE. +!!$LY = .TRUE. + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +INB_REQ = 0 + +! +! Post the recieve of Zxxxx_2D_OUT buffer first via MPI(Gpu_direct) +! + +IF (LX) THEN + IF (.NOT. GWEST) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZWEST_2D_OUT) +#endif + INB_REQ = INB_REQ + 1 + CALL MPI_IRECV(ZWEST_2D_OUT,SIZE(ZWEST_2D_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + END IF + IF (.NOT.GEAST) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZEAST_2D_OUT) +#endif + INB_REQ = INB_REQ + 1 + CALL MPI_IRECV(ZEAST_2D_OUT,SIZE(ZEAST_2D_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF +END IF + +IF (LY) THEN + IF (.NOT.GSOUTH) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZSOUTH_2D_OUT) +#endif + INB_REQ = INB_REQ + 1 + CALL MPI_IRECV(ZSOUTH_2D_OUT,SIZE(ZSOUTH_2D_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF + IF (.NOT.GNORTH) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZNORTH_2D_OUT) +#endif + INB_REQ = INB_REQ + 1 + CALL MPI_IRECV(ZNORTH_2D_OUT,SIZE(ZNORTH_2D_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF +END IF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +!Copy the halo on the device PSRC to Zxxxx_2D_IN + +IF (LX) THEN + IF (.NOT. GWEST) THEN + !$acc kernels async(IS_WEST) + ZWEST_2D_IN ( IIB:IIB+IHALO_1 , IJB:IJE ) = PSRC( IIB:IIB+IHALO_1 , IJB:IJE ) + !$acc end kernels + END IF + IF (.NOT.GEAST) THEN + !$acc kernels async(IS_EAST) + ZEAST_2D_IN ( IIE-IHALO_1:IIE , IJB:IJE ) = PSRC( IIE-IHALO_1:IIE , IJB:IJE ) + !$acc end kernels + ENDIF +END IF +IF (LY) THEN + IF (.NOT.GSOUTH) THEN + !$acc kernels async(IS_SOUTH) + ZSOUTH_2D_IN ( IIB:IIE , IJB:IJB+IHALO_1 ) = PSRC( IIB:IIE , IJB:IJB+IHALO_1 ) + !$acc end kernels + ENDIF + IF (.NOT.GNORTH) THEN + !$acc kernels async(IS_NORTH) + ZNORTH_2D_IN ( IIB:IIE , IJE-IHALO_1:IJE ) = PSRC( IIB:IIE , IJE-IHALO_1:IJE ) + !$acc end kernels + ENDIF +ENDIF +!$acc wait + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! +! Send Zxxxx_2D_IN buffer via MPI(Gpu_direct) or copy to host +! +IF (LX) THEN + IF (.NOT. GWEST) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZWEST_2D_IN) +#else + !$acc update host(ZWEST_2D_IN) +#endif + INB_REQ = INB_REQ + 1 + CALL MPI_ISEND(ZWEST_2D_IN,SIZE(ZWEST_2D_IN) ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + END IF + IF (.NOT.GEAST) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZEAST_2D_IN) +#else + !$acc update host(ZEAST_2D_IN) +#endif + INB_REQ = INB_REQ + 1 + CALL MPI_ISEND(ZEAST_2D_IN,SIZE(ZEAST_2D_IN) ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF +END IF + +IF (LY) THEN + IF (.NOT.GSOUTH) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZSOUTH_2D_IN) +#else + !$acc update host(ZSOUTH_2D_IN) +#endif + INB_REQ = INB_REQ + 1 + CALL MPI_ISEND(ZSOUTH_2D_IN,SIZE(ZSOUTH_2D_IN) ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF + IF (.NOT.GNORTH) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZNORTH_2D_IN) +#else + !$acc update host(ZNORTH_2D_IN) +#endif + INB_REQ = INB_REQ + 1 + CALL MPI_ISEND(ZNORTH_2D_IN,SIZE(ZNORTH_2D_IN) ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQ(INB_REQ),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF +ENDIF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +IF ( INB_REQ > 0 ) THEN + CALL MPI_WAITALL(INB_REQ,IREQ,MPI_STATUSES_IGNORE,IERR) +END IF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +! Is update halo + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + +IF (LX) THEN + IF (.NOT.GWEST) THEN +#ifndef MNH_GPUDIRECT + !$acc update device(ZWEST_2D_OUT) async(IS_WEST) +#endif + !$acc kernels async(IS_WEST) + PSRC( 1:IIB-1 , IJB:IJE ) = ZWEST_2D_OUT( 1:IIB-1 , IJB:IJE ) + !$acc end kernels + ENDIF + IF (.NOT.GEAST) THEN +#ifndef MNH_GPUDIRECT + !$acc update device(ZEAST_2D_OUT) async(IS_EAST) +#endif + !$acc kernels async(IS_EAST) + PSRC( IIE+1:IIU , IJB:IJE ) = ZEAST_2D_OUT( IIE+1:IIU , IJB:IJE ) + !$acc end kernels + ENDIF +END IF +IF (LY) THEN + IF (.NOT.GSOUTH) THEN +#ifndef MNH_GPUDIRECT + !$acc update device(ZSOUTH_2D_OUT) async(IS_SOUTH) +#endif + !$acc kernels async(IS_SOUTH) + PSRC( IIB:IIE , 1:IJB-1) = ZSOUTH_2D_OUT( IIB:IIE , 1:IJB-1 ) + !$acc end kernels + ENDIF + IF (.NOT.GNORTH) THEN +#ifndef MNH_GPUDIRECT + !$acc update device(ZNORTH_2D_OUT) async(IS_NORTH) +#endif + !$acc kernels async(IS_NORTH) + PSRC( IIB:IIE , IJE+1:IJU) = ZNORTH_2D_OUT ( IIB:IIE , IJE+1:IJU ) + !$acc end kernels + ENDIF +END IF +!$acc wait + +!$acc end data + +END SUBROUTINE GET_2D_HALO_DD !------------------------------------------------------------------------------- ! ######################################## SUBROUTINE GET_HALO_DDC(PSRC, HDIR, HNAME) @@ -1219,6 +1543,306 @@ END IF END SUBROUTINE GET_HALO_DDC !------------------------------------------------------------------------------- +! ######################################## + SUBROUTINE GET_2D_HALO_DDC(PSRC, HDIR, HNAME) +! ######################################## +#define MNH_GPUDIRECT +! +USE MODD_HALO_D +USE MODE_ll +USE MODD_ARGSLIST_ll, ONLY : LIST_ll +USE MODD_PARAMETERS, ONLY : JPHEXT +! +USE MODD_IO, ONLY : GSMONOPROC +USE MODE_MNH_ZWORK, ONLY : GWEST , GEAST, GSOUTH , GNORTH +! +USE MODD_CONF, ONLY : NHALO +USE MODE_DEVICE +USE MODE_MPPDB + +USE MODD_VAR_ll, ONLY : IP,NPROC,NP1,NP2 +USE MODD_VAR_ll, ONLY : NMNH_COMM_WORLD +USE MODD_MPIF, ONLY : MPI_STATUSES_IGNORE +USE MODD_PRECISION, ONLY : MNHREAL_MPI +! +USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU +USE MODE_MNH_ZWORK, ONLY : IIB,IJB ,IIE,IJE +! +IMPLICIT NONE +! +REAL, DIMENSION(:,:), INTENT(INOUT) :: PSRC ! variable at t +CHARACTER(len=4), OPTIONAL :: HDIR ! to send only halo on X or Y direction +character(len=*), optional, intent(in) :: HNAME ! Name of the field to be added +! +character(len=:), allocatable :: yname +TYPE(LIST_ll) , POINTER :: TZ_PSRC_ll ! halo +INTEGER :: IERROR ! error return code + +INTEGER,PARAMETER :: IS_WEST=1 , IS_EAST=2, IS_SOUTH=3, IS_NORTH=4 + +LOGICAL :: LX , LY + +INTEGER :: INB_REQEW , IREQEW(4) +INTEGER :: INB_REQNS , IREQNS(4) +INTEGER :: IERR + +if ( NPROC == 1 ) RETURN + +CALL INIT_HALO_D() + +!$acc data present ( PSRC ) + +NULLIFY( TZ_PSRC_ll) +! + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +LX = .FALSE. +LY = .FALSE. + +IF (.NOT. PRESENT(HDIR) ) THEN +LX = .TRUE. +LY = .TRUE. +ELSE + ! + ! Problem of reproductibility in ppm_s0_x/y if only S0_X or S0_Y + ! so add S0_X + S0_Y for ppm_s0* + ! +!!$LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" ) +!!$LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" ) +LX = ( HDIR == "01_X" .OR. HDIR == "S0_X" .OR. HDIR == "S0_Y" ) +LY = ( HDIR == "01_Y" .OR. HDIR == "S0_Y" .OR. HDIR == "S0_X" ) +END IF + +!!$LX = .TRUE. +!!$LY = .TRUE. + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! +! Post first the recieve of ZxxxxC_2D_OUT buffer via MPI(Gpu_direct) +! +!-------------------------------------------------------------------------------! +! IRecv E/W ! +!-------------------------------------------------------------------------------! +INB_REQEW = 0 +IF (LX) THEN + IF (.NOT. GWEST) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZWESTC_2D_OUT) +#endif + INB_REQEW = INB_REQEW + 1 + CALL MPI_IRECV(ZWESTC_2D_OUT,SIZE(ZWESTC_2D_OUT),MNHREAL_MPI,NP_WEST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + END IF + IF (.NOT.GEAST) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZEASTC_2D_OUT) +#endif + INB_REQEW = INB_REQEW + 1 + CALL MPI_IRECV(ZEASTC_2D_OUT,SIZE(ZEASTC_2D_OUT),MNHREAL_MPI,NP_EAST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF +END IF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +!Copy the halo E/W on the device PSRC to ZxxxxC_2D_IN + +IF (LX) THEN + IF (.NOT. GWEST) THEN + !$acc kernels async(IS_WEST) + ZWESTC_2D_IN ( IIB:IIB+IHALO_1 , IJB:IJE ) = PSRC( IIB:IIB+IHALO_1 , IJB:IJE ) + !$acc end kernels + END IF + IF (.NOT.GEAST) THEN + !$acc kernels async(IS_EAST) + ZEASTC_2D_IN ( IIE-IHALO_1:IIE , IJB:IJE ) = PSRC( IIE-IHALO_1:IIE , IJB:IJE ) + !$acc end kernels + ENDIF + !$acc wait +END IF +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! +! Send E/W ZxxxxC_2D_IN buffer via MPI(Gpu_direct) or copy to host +! +IF (LX) THEN + IF (.NOT. GWEST) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZWESTC_2D_IN) +#else + !$acc update host(ZWESTC_2D_IN) +#endif + INB_REQEW = INB_REQEW + 1 + CALL MPI_ISEND(ZWESTC_2D_IN,SIZE(ZWESTC_2D_IN) ,MNHREAL_MPI,NP_WEST-1,1000+IS_WEST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + END IF + IF (.NOT.GEAST) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZEASTC_2D_IN) +#else + !$acc update host(ZEASTC_2D_IN) +#endif + INB_REQEW = INB_REQEW + 1 + CALL MPI_ISEND(ZEASTC_2D_IN,SIZE(ZEASTC_2D_IN) ,MNHREAL_MPI,NP_EAST-1,1000+IS_EAST,NMNH_COMM_WORLD,IREQEW(INB_REQEW),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF +END IF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +IF ( INB_REQEW > 0 ) THEN + CALL MPI_WAITALL(INB_REQEW,IREQEW,MPI_STATUSES_IGNORE,IERR) +END IF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +! Update halo E/W from buffer to PSRC + +IF (LX) THEN + IF (.NOT.GWEST) THEN +#ifndef MNH_GPUDIRECT + !$acc update device(ZWESTC_2D_OUT) async(IS_WEST) +#endif + !$acc kernels async(IS_WEST) + PSRC( 1:IIB-1 , IJB:IJE ) = ZWESTC_2D_OUT( 1:IIB-1 , IJB:IJE ) + !$acc end kernels + ENDIF + IF (.NOT.GEAST) THEN +#ifndef MNH_GPUDIRECT + !$acc update device(ZEASTC_2D_OUT) async(IS_EAST) +#endif + !$acc kernels async(IS_EAST) + PSRC( IIE+1:IIU , IJB:IJE ) = ZEASTC_2D_OUT( IIE+1:IIU , IJB:IJE ) + !$acc end kernels + ENDIF + !$acc wait +END IF +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! +! Post first the recieve of N/S ZxxxxC_2D_OUT buffer via MPI(Gpu_direct) +! +!-------------------------------------------------------------------------------! +! IRecv N/S ! +!-------------------------------------------------------------------------------! +INB_REQNS = 0 +IF (LY) THEN + IF (.NOT.GSOUTH) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZSOUTHC_2D_OUT) +#endif + INB_REQNS = INB_REQNS + 1 + CALL MPI_IRECV(ZSOUTHC_2D_OUT,SIZE(ZSOUTHC_2D_OUT),MNHREAL_MPI,NP_SOUTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF + IF (.NOT.GNORTH) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZNORTHC_2D_OUT) +#endif + INB_REQNS = INB_REQNS + 1 + CALL MPI_IRECV(ZNORTHC_2D_OUT,SIZE(ZNORTHC_2D_OUT),MNHREAL_MPI,NP_NORTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF +END IF + +! +!Copy the halo N/S on the device PSRC to ZxxxxC_2D_IN +! +IF (LY) THEN + IF (.NOT.GSOUTH) THEN + !$acc kernels async(IS_SOUTH) + ZSOUTHC_2D_IN ( 1:IIU , IJB:IJB+IHALO_1 ) = PSRC( 1:IIU , IJB:IJB+IHALO_1 ) + !$acc end kernels + ENDIF + IF (.NOT.GNORTH) THEN + !$acc kernels async(IS_NORTH) + ZNORTHC_2D_IN ( 1:IIU , IJE-IHALO_1:IJE ) = PSRC( 1:IIU , IJE-IHALO_1:IJE ) + !$acc end kernels + ENDIF + !$acc wait +ENDIF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! +! Send N/S ZxxxxC_2D_IN buffer via MPI(Gpu_direct) or copy to host +! +IF (LY) THEN + IF (.NOT.GSOUTH) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZSOUTHC_2D_IN) +#else + !$acc update host(ZSOUTHC_2D_IN) +#endif + INB_REQNS = INB_REQNS + 1 + CALL MPI_ISEND(ZSOUTHC_2D_IN,SIZE(ZSOUTHC_2D_IN) ,MNHREAL_MPI,NP_SOUTH-1,1000+IS_SOUTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF + IF (.NOT.GNORTH) THEN +#ifdef MNH_GPUDIRECT + !$acc host_data use_device(ZNORTHC_2D_IN) +#else + !$acc update host(ZNORTHC_2D_IN) +#endif + INB_REQNS = INB_REQNS + 1 + CALL MPI_ISEND(ZNORTHC_2D_IN,SIZE(ZNORTHC_2D_IN) ,MNHREAL_MPI,NP_NORTH-1,1000+IS_NORTH,NMNH_COMM_WORLD,IREQNS(INB_REQNS),IERR) +#ifdef MNH_GPUDIRECT + !$acc end host_data +#endif + ENDIF +ENDIF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +IF ( INB_REQNS > 0 ) THEN + CALL MPI_WAITALL(INB_REQNS,IREQNS,MPI_STATUSES_IGNORE,IERR) +END IF + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +! Update halo N/S + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +! Update halo N/S/W from buffer to PSRC + +IF (LY) THEN + IF (.NOT.GSOUTH) THEN +#ifndef MNH_GPUDIRECT + !$acc update device(ZSOUTHC_2D_OUT) async(IS_SOUTH) +#endif + !$acc kernels async(IS_SOUTH) + PSRC( 1:IIU , 1:IJB-1) = ZSOUTHC_2D_OUT( 1:IIU , 1:IJB-1 ) + !$acc end kernels + ENDIF + IF (.NOT.GNORTH) THEN +#ifndef MNH_GPUDIRECT + !$acc update device(ZNORTHC_2D_OUT) async(IS_NORTH) +#endif + !$acc kernels async(IS_NORTH) + PSRC( 1:IIU , IJE+1:IJU) = ZNORTHC_2D_OUT ( 1:IIU , IJE+1:IJU ) + !$acc end kernels + ENDIF + !$acc wait +END IF + +!$acc end data + +END SUBROUTINE GET_2D_HALO_DDC +!------------------------------------------------------------------------------- ! ######################################## SUBROUTINE GET_HALO2_DD(PSRC, TP_PSRC_HALO2_ll, HNAME) ! ######################################## -- GitLab