diff --git a/python_utils/fieldType.py b/python_utils/fieldType.py index fa4cd869..90bfcd3a 100755 --- a/python_utils/fieldType.py +++ b/python_utils/fieldType.py @@ -27,6 +27,9 @@ def __init__ (self, **kwargs): self.viewRank = self.rank-1 self.viewShape = ','.join ([':'] * (self.rank-1)) self.lbptr = ', '.join (list (map (lambda i: "LBOUNDS(" + str (i+1) + "):", range (0, self.rank)))) + self.lbptr_blk = ', '.join([ f"LBOUNDS({i}):" for i in range(1, self.rank)] + ["BLK_BOUNDS(1):"]) + self.hst_blk = ':, ' * (self.rank-1) + 'BLK_BOUNDS(1):BLK_BOUNDS(2)' + self.devptr_blk = ':, ' * (self.rank-1) + f'LBOUNDS({self.rank}):LBOUNDS({self.rank}) + BLK_BOUNDS(2)-BLK_BOUNDS(1)' self.hasView = self.rank > 1 self.ganged = self.rank > 2 diff --git a/src/buffer/field_RANKSUFF_gang_module.fypp b/src/buffer/field_RANKSUFF_gang_module.fypp index 8d65ff86..8d9de7bb 100644 --- a/src/buffer/field_RANKSUFF_gang_module.fypp +++ b/src/buffer/field_RANKSUFF_gang_module.fypp @@ -64,11 +64,12 @@ PUBLIC :: ${ftn}$_GANG_${type}$ CONTAINS - SUBROUTINE ${ftn1}$_CREATE_DEVICE_DATA_WRAPPER_HELPER (SELF) + SUBROUTINE ${ftn1}$_CREATE_DEVICE_DATA_WRAPPER_HELPER (SELF, BLK_BOUNDS) CLASS(${ftn1}$_WRAPPER_HELPER) :: SELF + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) IF (ASSOCIATED (SELF%PARENT)) THEN - CALL SELF%PARENT%CREATE_DEVICE_DATA () + CALL SELF%PARENT%CREATE_DEVICE_DATA (BLK_BOUNDS=BLK_BOUNDS) ENDIF END SUBROUTINE @@ -93,22 +94,23 @@ CONTAINS END SUBROUTINE #:for what in ['HOST', 'DEVICE'] - SUBROUTINE ${ftn1}$_GET_${what}$_DATA_WRAPPER_HELPER (SELF, MODE, PTR, QUEUE) + SUBROUTINE ${ftn1}$_GET_${what}$_DATA_WRAPPER_HELPER (SELF, MODE, PTR, QUEUE, BLK_BOUNDS) CLASS(${ftn1}$_WRAPPER_HELPER) :: SELF INTEGER (KIND=JPIM), INTENT(IN) :: MODE ${ft1.type}$, POINTER, INTENT(INOUT) :: PTR(${ft1.shape}$) INTEGER (KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) INTEGER(KIND=JPIM) :: LBOUNDS(${ft1.rank}$) IF (ASSOCIATED (SELF%PARENT)) THEN IF (IAND (MODE, NWR) /= 0) THEN - CALL SELF%PARENT%SYNC_${what}$_RDWR (QUEUE) + CALL SELF%PARENT%SYNC_${what}$_RDWR (QUEUE, BLK_BOUNDS) ELSEIF (IAND (MODE, NRD) /= 0) THEN - CALL SELF%PARENT%SYNC_${what}$_RDONLY (QUEUE) + CALL SELF%PARENT%SYNC_${what}$_RDONLY (QUEUE, BLK_BOUNDS) ENDIF ENDIF - CALL SELF%${ftn1}$_WRAPPER%GET_${what}$_DATA (MODE, PTR, QUEUE) + CALL SELF%${ftn1}$_WRAPPER%GET_${what}$_DATA (MODE, PTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE @@ -250,11 +252,12 @@ CONTAINS END SUBROUTINE ${ftn}$_GANG_${type}$_DELETE_DEVICE_DATA - SUBROUTINE ${ftn}$_GANG_${type}$_CREATE_DEVICE_DATA (SELF) + SUBROUTINE ${ftn}$_GANG_${type}$_CREATE_DEVICE_DATA (SELF, BLK_BOUNDS) CLASS(${ftn}$_GANG_${type}$) :: SELF + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) INTEGER (KIND=JPIM) :: JFLD - CALL SELF%${ftn}$_${type}$%CREATE_DEVICE_DATA () + CALL SELF%${ftn}$_${type}$%CREATE_DEVICE_DATA (BLK_BOUNDS=BLK_BOUNDS) #:set ar = ', '.join ([':'] * (ft.rank-2)) DO JFLD = 1, SIZE (SELF%CHILDREN) diff --git a/src/core/dev_alloc_module.fypp b/src/core/dev_alloc_module.fypp index 22c9e936..9b9d4b72 100644 --- a/src/core/dev_alloc_module.fypp +++ b/src/core/dev_alloc_module.fypp @@ -80,11 +80,12 @@ CONTAINS #:if defined('USE_BUDDY_MALLOC') or defined('CUDA') -SUBROUTINE ${ft.name}$_DEV_ALLOCATE_HST (DEV, HST, MAP_DEVPTR) +SUBROUTINE ${ft.name}$_DEV_ALLOCATE_HST (DEV, HST, MAP_DEVPTR, BLK_BOUNDS) ${ft.type}$, POINTER :: DEV(${ft.shape}$) ${ft.type}$, POINTER :: HST(${ft.shape}$) LOGICAL, INTENT(IN) :: MAP_DEVPTR +INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) INTEGER :: ILBOUNDS (${ft.rank}$) INTEGER :: IUBOUNDS (${ft.rank}$) @@ -92,6 +93,11 @@ INTEGER :: IUBOUNDS (${ft.rank}$) ILBOUNDS = LBOUND (HST) IUBOUNDS = UBOUND (HST) +IF ( PRESENT(BLK_BOUNDS) ) THEN +ILBOUNDS(${ft.rank}$) = BLK_BOUNDS(1) +IUBOUNDS(${ft.rank}$) = BLK_BOUNDS(2) +ENDIF + CALL ${ft.name}$_DEV_ALLOCATE_DIM (DEV, UBOUNDS=IUBOUNDS, LBOUNDS=ILBOUNDS, MAP_DEVPTR=MAP_DEVPTR) END SUBROUTINE ${ft.name}$_DEV_ALLOCATE_HST @@ -174,20 +180,25 @@ END SUBROUTINE ${ft.name}$_DEV_DEALLOCATE #:else -SUBROUTINE ${ft.name}$_DEV_ALLOCATE_HST (DEV, HST, MAP_DEVPTR) +SUBROUTINE ${ft.name}$_DEV_ALLOCATE_HST (DEV, HST, MAP_DEVPTR, BLK_BOUNDS) USE FIELD_STATISTICS_MODULE ${ft.type}$, POINTER :: DEV(${ft.shape}$) ${ft.type}$, POINTER :: HST(${ft.shape}$) LOGICAL, INTENT(IN) :: MAP_DEVPTR +INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) +IF ( PRESENT(BLK_BOUNDS) ) THEN + ALLOCATE (DEV (${ ' '.join([f'LBOUND (HST, {i}):UBOUND (HST, {i}),' for i in range (1, ft.rank)]) + 'BLK_BOUNDS(1):BLK_BOUNDS(2)'}$)) +ELSE #if __INTEL_COMPILER == 1800 && __INTEL_COMPILER_UPDATE == 5 -! Bug with Intel 18.0.5.274 -ALLOCATE (DEV (${ ', '.join (map (lambda i: 'LBOUND (HST, ' + str (i) + '):UBOUND (HST,' + str (i) + ')', range (1, ft.rank+1))) }$)) + ! Bug with Intel 18.0.5.274 + ALLOCATE (DEV (${ ', '.join (map (lambda i: 'LBOUND (HST, ' + str (i) + '):UBOUND (HST,' + str (i) + ')', range (1, ft.rank+1))) }$)) #else -ALLOCATE (DEV, MOLD=HST) + ALLOCATE (DEV, MOLD=HST) #endif +ENDIF !$acc enter data create (DEV) diff --git a/src/core/field_RANKSUFF_data_module.fypp b/src/core/field_RANKSUFF_data_module.fypp index 6bc409c6..d3f9f6d5 100644 --- a/src/core/field_RANKSUFF_data_module.fypp +++ b/src/core/field_RANKSUFF_data_module.fypp @@ -101,9 +101,9 @@ CONTAINS INTEGER (KIND=JPIM), INTENT (IN) :: KDIR INTEGER (KIND=JPIM), OPTIONAL, INTENT (IN) :: QUEUE - PROCEDURE (${ftn}$_COPY_INTF), POINTER :: FUNC + PROCEDURE (${ftn}$_COPY_INTF), POINTER :: FUNC - FUNC => ${ftn}$_COPY_FUNC (HST, DEV) + FUNC => ${ftn}$_COPY_FUNC (HST, DEV) CALL FUNC (HST, DEV, MAP_DEVPTR, KDIR, QUEUE) diff --git a/src/core/field_RANKSUFF_module.fypp b/src/core/field_RANKSUFF_module.fypp index 0a7c1518..e6d9834f 100644 --- a/src/core/field_RANKSUFF_module.fypp +++ b/src/core/field_RANKSUFF_module.fypp @@ -426,15 +426,31 @@ CONTAINS END SUBROUTINE ${ftn}$_WIPE_OBJECT - SUBROUTINE ${ftn}$_COPY_DATA (SELF, KDIR, QUEUE) + SUBROUTINE ${ftn}$_COPY_DATA (SELF, KDIR, QUEUE, BLK_BOUNDS) + + USE FIELD_ABORT_MODULE CLASS(${ftn}$) :: SELF INTEGER (KIND=JPIM), INTENT(IN) :: KDIR INTEGER (KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) + + INTEGER(KIND=JPIM) :: LB, UB + ${ft.type}$, POINTER :: HST_BLK(${ft.shape}$) => NULL() REAL :: START, FINISH CALL CPU_TIME(START) - CALL SELF%COPY_FUNC (SELF%PTR, SELF%DEVPTR, SELF%MAP_DEVPTR, KDIR, QUEUE) + IF ( .NOT. PRESENT(BLK_BOUNDS) ) THEN + CALL SELF%COPY_FUNC (SELF%PTR, SELF%DEVPTR, SELF%MAP_DEVPTR, KDIR, QUEUE) + ELSE + LB = LBOUND(SELF%PTR, ${ft.rank}$) + UB = UBOUND(SELF%PTR, ${ft.rank}$) + IF ( BLK_BOUNDS(1) < LB .OR. BLK_BOUNDS(2) > UB ) THEN + CALL FIELD_ABORT("BLOCK DIMENSIONS ARE OUT OF RANGE") + END IF + HST_BLK => SELF%PTR(${ft.hst_blk}$) + CALL SELF%COPY_FUNC(HST_BLK, SELF%DEVPTR, SELF%MAP_DEVPTR, KDIR, QUEUE) + END IF CALL CPU_TIME(FINISH) IF (KDIR == NH2D) THEN @@ -445,32 +461,37 @@ CONTAINS END SUBROUTINE ${ftn}$_COPY_DATA - SUBROUTINE ${ftn}$_GET_HOST_DATA (SELF, MODE, PTR, QUEUE) + SUBROUTINE ${ftn}$_GET_HOST_DATA (SELF, MODE, PTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF INTEGER (KIND=JPIM), INTENT(IN) :: MODE - ${ft.type}$, POINTER, INTENT(INOUT) :: PTR(${ft.shape}$) INTEGER (KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) INTEGER(KIND=JPIM) :: LBOUNDS(${ft.rank}$) LBOUNDS=LBOUND(SELF%PTR) IF (IAND (SELF%GET_STATUS (), NHSTFRESH) == 0) THEN - CALL SELF%COPY_DATA (ND2H, QUEUE) + CALL SELF%COPY_DATA (ND2H, QUEUE, BLK_BOUNDS=BLK_BOUNDS) CALL SELF%SET_STATUS (IOR (SELF%GET_STATUS (), NHSTFRESH)) ENDIF - PTR (${ft.lbptr}$) => SELF%PTR (${','.join(':' for _ in range(ft.rank))}$) + IF ( PRESENT(BLK_BOUNDS) ) THEN + PTR ( ${ft.lbptr_blk}$) => SELF%PTR (${ft.hst_blk}$) + ELSE + PTR (${ft.lbptr}$) => SELF%PTR (${','.join(':' for _ in range(ft.rank))}$) + END IF IF (IAND (MODE, NWR) /= 0) THEN CALL SELF%SET_STATUS (IAND (SELF%GET_STATUS (), NOT (NDEVFRESH))) ENDIF END SUBROUTINE ${ftn}$_GET_HOST_DATA - SUBROUTINE ${ftn}$_OWNER_GET_HOST_DATA (SELF, MODE, PTR, QUEUE) + SUBROUTINE ${ftn}$_OWNER_GET_HOST_DATA (SELF, MODE, PTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$_OWNER) :: SELF INTEGER (KIND=JPIM), INTENT(IN) :: MODE ${ft.type}$, POINTER, INTENT(INOUT) :: PTR(${ft.shape}$) INTEGER (KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) IF(SELF%GET_STATUS ()==UNALLOCATED)THEN CALL SELF%CREATE_HOST_DATA () @@ -479,68 +500,92 @@ CONTAINS CALL SELF%SET_STATUS (NHSTFRESH) ENDIF ENDIF - CALL SELF%${ftn}$_GET_HOST_DATA(MODE, PTR, QUEUE) + CALL SELF%${ftn}$_GET_HOST_DATA(MODE, PTR, QUEUE=QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_OWNER_GET_HOST_DATA - SUBROUTINE ${ftn}$_GET_HOST_DATA_RDONLY (SELF, PPTR, QUEUE) + SUBROUTINE ${ftn}$_GET_HOST_DATA_RDONLY (SELF, PPTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF ${ft.type}$, POINTER, INTENT(INOUT) :: PPTR(${ft.shape}$) INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) - CALL SELF%GET_HOST_DATA (NRD, PPTR, QUEUE) + CALL SELF%GET_HOST_DATA (NRD, PPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_GET_HOST_DATA_RDONLY - SUBROUTINE ${ftn}$_SYNC_HOST_RDONLY (SELF, QUEUE) + SUBROUTINE ${ftn}$_SYNC_HOST_RDONLY (SELF, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) ${ft.type}$, POINTER :: ZPTR(${ft.shape}$) - CALL SELF%GET_HOST_DATA_RDONLY (ZPTR, QUEUE) + CALL SELF%GET_HOST_DATA_RDONLY (ZPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_SYNC_HOST_RDONLY - SUBROUTINE ${ftn}$_GET_HOST_DATA_RDWR (SELF, PPTR, QUEUE) + SUBROUTINE ${ftn}$_GET_HOST_DATA_RDWR (SELF, PPTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF ${ft.type}$, POINTER, INTENT(INOUT) :: PPTR(${ft.shape}$) INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) - CALL SELF%GET_HOST_DATA (IOR (NRD, NWR), PPTR, QUEUE) + CALL SELF%GET_HOST_DATA (IOR (NRD, NWR), PPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_GET_HOST_DATA_RDWR - SUBROUTINE ${ftn}$_SYNC_HOST_RDWR (SELF, QUEUE) + SUBROUTINE ${ftn}$_SYNC_HOST_RDWR (SELF, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) ${ft.type}$, POINTER :: ZPTR(${ft.shape}$) - CALL SELF%GET_HOST_DATA_RDWR (ZPTR, QUEUE) + CALL SELF%GET_HOST_DATA_RDWR (ZPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_SYNC_HOST_RDWR - SUBROUTINE ${ftn}$_CREATE_DEVICE_DATA (SELF) + SUBROUTINE ${ftn}$_CREATE_DEVICE_DATA (SELF, BLK_BOUNDS) CLASS(${ftn}$) :: SELF + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) + INTEGER(KIND=JPIM) :: DEVPTR_SIZE + + IF ( PRESENT(BLK_BOUNDS) ) THEN + DEVPTR_SIZE = SIZE(SELF%PTR(${':,'*(ft.rank-1)}$ BLK_BOUNDS(1):BLK_BOUNDS(2))) + ELSE + DEVPTR_SIZE = SIZE(SELF%PTR) + ENDIF + + IF (.NOT. ASSOCIATED (SELF%DEVPTR) ) THEN + CALL DEV_ALLOCATE_HST (DEV=SELF%DEVPTR, HST=SELF%PTR, MAP_DEVPTR=SELF%MAP_DEVPTR, BLK_BOUNDS=BLK_BOUNDS) + ELSE IF ( SIZE(SELF%DEVPTR) < DEVPTR_SIZE ) THEN + CALL SELF%DELETE_DEVICE_DATA() + CALL DEV_ALLOCATE_HST (DEV=SELF%DEVPTR, HST=SELF%PTR, MAP_DEVPTR=SELF%MAP_DEVPTR, BLK_BOUNDS=BLK_BOUNDS) + ENDIF - CALL DEV_ALLOCATE_HST (DEV=SELF%DEVPTR, HST=SELF%PTR, MAP_DEVPTR=SELF%MAP_DEVPTR) END SUBROUTINE - SUBROUTINE ${ftn}$_GET_DEVICE_DATA (SELF, MODE, PTR, QUEUE) + SUBROUTINE ${ftn}$_GET_DEVICE_DATA (SELF, MODE, PTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF INTEGER (KIND=JPIM), INTENT(IN) :: MODE ${ft.type}$, POINTER, INTENT(INOUT) :: PTR(${ft.shape}$) INTEGER (KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) + INTEGER(KIND=JPIM) :: LBOUNDS(${ft.rank}$) LBOUNDS=LBOUND(SELF%PTR) - IF (.NOT. ASSOCIATED (SELF%DEVPTR)) THEN - CALL SELF%CREATE_DEVICE_DATA - ENDIF + + CALL SELF%CREATE_DEVICE_DATA(BLK_BOUNDS=BLK_BOUNDS) + IF (IAND (SELF%GET_STATUS (), NDEVFRESH) == 0) THEN - CALL SELF%COPY_DATA (NH2D, QUEUE) + CALL SELF%COPY_DATA (NH2D, QUEUE, BLK_BOUNDS=BLK_BOUNDS) CALL SELF%SET_STATUS (IOR (SELF%GET_STATUS (), NDEVFRESH)) ENDIF - PTR (${ft.lbptr}$) => SELF%DEVPTR (${','.join(':' for _ in range(ft.rank))}$) + IF ( PRESENT(BLK_BOUNDS) ) THEN + PTR (${ft.lbptr_blk}$) => SELF%DEVPTR (${ft.devptr_blk}$) + ELSE + PTR (${ft.lbptr}$) => SELF%DEVPTR (${','.join(':' for _ in range(ft.rank))}$) + END IF IF (IAND (MODE, NWR) /= 0) THEN CALL SELF%SET_STATUS (IAND (SELF%GET_STATUS (), NOT (NHSTFRESH))) ENDIF @@ -573,68 +618,72 @@ CONTAINS END FUNCTION #:endif - - SUBROUTINE ${ftn}$_OWNER_GET_DEVICE_DATA (SELF, MODE, PTR, QUEUE) + SUBROUTINE ${ftn}$_OWNER_GET_DEVICE_DATA (SELF, MODE, PTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$_OWNER) :: SELF INTEGER (KIND=JPIM), INTENT(IN) :: MODE ${ft.type}$, POINTER, INTENT(INOUT) :: PTR(${ft.shape}$) INTEGER (KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) IF(SELF%GET_STATUS ()==UNALLOCATED)THEN CALL SELF%CREATE_HOST_DATA () IF (SELF%HAS_INIT_VALUE) THEN - CALL SELF%CREATE_DEVICE_DATA SELF%PTR=SELF%INIT_VALUE CALL SELF%SET_STATUS (NHSTFRESH) ENDIF ENDIF - CALL SELF%${ftn}$_GET_DEVICE_DATA(MODE, PTR, QUEUE) + CALL SELF%${ftn}$_GET_DEVICE_DATA(MODE, PTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_OWNER_GET_DEVICE_DATA - SUBROUTINE ${ftn}$_GET_DEVICE_DATA_RDONLY (SELF, PPTR, QUEUE) + SUBROUTINE ${ftn}$_GET_DEVICE_DATA_RDONLY (SELF, PPTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF ${ft.type}$, POINTER, INTENT(INOUT) :: PPTR(${ft.shape}$) INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) - CALL SELF%GET_DEVICE_DATA (NRD, PPTR, QUEUE) + CALL SELF%GET_DEVICE_DATA (NRD, PPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_GET_DEVICE_DATA_RDONLY - SUBROUTINE ${ftn}$_GET_DEVICE_DATA_WRONLY (SELF, PPTR, QUEUE) + SUBROUTINE ${ftn}$_GET_DEVICE_DATA_WRONLY (SELF, PPTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF ${ft.type}$, POINTER, INTENT(INOUT) :: PPTR(${ft.shape}$) INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) CALL SELF%SET_STATUS (IOR (SELF%GET_STATUS (), NDEVFRESH)) - CALL SELF%GET_DEVICE_DATA (NWR, PPTR, QUEUE) + CALL SELF%GET_DEVICE_DATA (NWR, PPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_GET_DEVICE_DATA_WRONLY - SUBROUTINE ${ftn}$_SYNC_DEVICE_RDONLY (SELF, QUEUE) + SUBROUTINE ${ftn}$_SYNC_DEVICE_RDONLY (SELF, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) ${ft.type}$, POINTER :: ZPTR(${ft.shape}$) - CALL SELF%GET_DEVICE_DATA_RDONLY (ZPTR, QUEUE) + CALL SELF%GET_DEVICE_DATA_RDONLY (ZPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_SYNC_DEVICE_RDONLY - SUBROUTINE ${ftn}$_GET_DEVICE_DATA_RDWR (SELF, PPTR, QUEUE) + SUBROUTINE ${ftn}$_GET_DEVICE_DATA_RDWR (SELF, PPTR, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF ${ft.type}$, POINTER, INTENT(INOUT) :: PPTR(${ft.shape}$) INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE - - CALL SELF%GET_DEVICE_DATA (IOR (NRD, NWR), PPTR, QUEUE) + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) + + CALL SELF%GET_DEVICE_DATA (IOR (NRD, NWR), PPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_GET_DEVICE_DATA_RDWR - SUBROUTINE ${ftn}$_SYNC_DEVICE_RDWR (SELF, QUEUE) + SUBROUTINE ${ftn}$_SYNC_DEVICE_RDWR (SELF, QUEUE, BLK_BOUNDS) CLASS(${ftn}$) :: SELF INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: QUEUE + INTEGER(KIND=JPIM), OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) ${ft.type}$, POINTER :: ZPTR(${ft.shape}$) - CALL SELF%GET_DEVICE_DATA_RDWR (ZPTR, QUEUE) + CALL SELF%GET_DEVICE_DATA_RDWR (ZPTR, QUEUE, BLK_BOUNDS=BLK_BOUNDS) END SUBROUTINE ${ftn}$_SYNC_DEVICE_RDWR diff --git a/src/core/field_basic_module.F90 b/src/core/field_basic_module.F90 index 344928bf..1e0e0018 100644 --- a/src/core/field_basic_module.F90 +++ b/src/core/field_basic_module.F90 @@ -57,18 +57,21 @@ MODULE FIELD_BASIC_MODULE PUBLIC :: FIELD_BASIC ABSTRACT INTERFACE - SUBROUTINE FIELD_BASIC_SYNC (SELF, QUEUE) + SUBROUTINE FIELD_BASIC_SYNC (SELF, QUEUE, BLK_BOUNDS) IMPORT FIELD_BASIC CLASS(FIELD_BASIC) :: SELF INTEGER, OPTIONAL, INTENT(IN) :: QUEUE + INTEGER, OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) + END SUBROUTINE SUBROUTINE FIELD_BASIC_DELETE_DEVICE_DATA (SELF) IMPORT FIELD_BASIC CLASS(FIELD_BASIC) :: SELF END SUBROUTINE - SUBROUTINE FIELD_BASIC_CREATE_DEVICE_DATA (SELF) + SUBROUTINE FIELD_BASIC_CREATE_DEVICE_DATA (SELF, BLK_BOUNDS) IMPORT FIELD_BASIC CLASS(FIELD_BASIC) :: SELF + INTEGER, OPTIONAL, INTENT(IN) :: BLK_BOUNDS(2) END SUBROUTINE #ifdef WITH_FIAT INTEGER*8 FUNCTION FIELD_BASIC_CRC64 (SELF) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 62bf2ce7..8b02fea1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -79,6 +79,7 @@ list(APPEND TEST_FILES test_field1d.F90 test_field_array.F90 test_field_delete_on_null.F90 + test_get_device_data_bounds.F90 test_get_device_data_wronly.F90 test_get_device_data_non_contiguous.F90 test_host_mem_pool.F90 diff --git a/tests/test_get_device_data_bounds.F90 b/tests/test_get_device_data_bounds.F90 new file mode 100644 index 00000000..a67a3f9b --- /dev/null +++ b/tests/test_get_device_data_bounds.F90 @@ -0,0 +1,150 @@ +! (C) Copyright 2022- ECMWF. +! (C) Copyright 2022- Meteo-France. +! +! This software is licensed under the terms of the Apache Licence Version 2.0 +! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +! In applying this licence, ECMWF does not waive the privileges and immunities +! granted to it by virtue of its status as an intergovernmental organisation +! nor does it submit to any jurisdiction. + +PROGRAM TEST_GET_DEVICE_DATA_BOUNDS + + USE FIELD_MODULE + USE FIELD_FACTORY_MODULE + USE PARKIND1 + USE FIELD_ABORT_MODULE + IMPLICIT NONE + + CLASS(FIELD_2RB), POINTER :: F_PTR => NULL() + REAL(KIND=JPRB), POINTER :: PTR_CPU(:,:) => NULL() + REAL(KIND=JPRB), POINTER :: PTR_GPU(:,:) => NULL() + REAL(KIND=JPRB), POINTER :: PTR_GPU2(:,:) => NULL() + LOGICAL :: OKAY + INTEGER :: I,J + + CALL FIELD_NEW(F_PTR, LBOUNDS=[1,1], UBOUNDS=[128,3], PERSISTENT=.TRUE.) + CALL F_PTR%GET_HOST_DATA_RDWR(PTR_CPU) + PTR_CPU(:,1) = 42 + PTR_CPU(:,2) = 42 + PTR_CPU(:,3) = 37 + + CALL F_PTR%GET_DEVICE_DATA_RDWR(PTR_GPU, BLK_BOUNDS=[1,2]) + OKAY=.TRUE. + + !$acc serial, present(PTR_GPU), copy(OKAY) + DO I=1,128 + DO J = 1,2 + IF ( PTR_GPU(I,J) /= 42 ) THEN + OKAY = .FALSE. + END IF + PTR_GPU(I,J) = 32 + END DO + END DO + !$acc end serial + + IF (.NOT. OKAY) THEN + CALL FIELD_ABORT("ERROR DATA NOT UPDATED ON DEVICE") + END IF + + CALL F_PTR%SYNC_HOST_RDWR(BLK_BOUNDS=[1,2]) + DO I=1,128 + DO J = 1,2 + IF ( PTR_CPU(I,J) /= 32 ) THEN + OKAY =.FALSE. + END IF + END DO + END DO + + IF (.NOT. OKAY) THEN + CALL FIELD_ABORT("ERROR HOST DATA NOT UPDATED BY SYNC_HOST_RDWR") + END IF + + DO I=1,128 + IF ( PTR_CPU(I,3) /= 37 ) THEN + OKAY =.FALSE. + END IF + END DO + + IF (.NOT. OKAY) THEN + CALL FIELD_ABORT("ERROR HOST 3RD COLUMN OF PTR_CPU SHOULD NOT HAVE BEEN MODIFIED") + END IF + + PTR_CPU(:,1) = 38 + PTR_CPU(:,2) = 38 + PTR_CPU(:,3) = 39 + CALL F_PTR%GET_DEVICE_DATA_RDWR(PTR_GPU, BLK_BOUNDS=[3,3]) + !$acc serial, present(PTR_GPU), copy(OKAY) + DO I=1,128 + IF ( PTR_GPU(I,J) /= 39 ) THEN + OKAY = .FALSE. + END IF + PTR_GPU(I,J) = 40 + END DO + !$acc end serial + + IF (.NOT. OKAY) THEN + CALL FIELD_ABORT("ERROR DEVICE DATA NOT UPDATED BY GET_DEVICE_DATA_RDWR") + END IF + + CALL F_PTR%SYNC_HOST_RDWR(BLK_BOUNDS=[3,3]) + + DO I=1,128 + IF ( PTR_CPU(I,J) /= 40 ) THEN + OKAY =.FALSE. + END IF + END DO + + IF (.NOT. OKAY) THEN + CALL FIELD_ABORT("ERROR HOST DATA NOT UPDATED BY SYNC_HOST_RDWR") + END IF + + DO I=1,128 + DO J = 1,2 + IF ( PTR_CPU(I,J) /= 38 ) THEN + OKAY =.FALSE. + END IF + END DO + END DO + + IF (.NOT. OKAY) THEN + CALL FIELD_ABORT("ERROR HOST 1ST AND 2ND COLUMN OF PTR_CPU SHOULD NOT HAVE BEEN MODIFIED") + END IF + + + PTR_CPU(:,1) = 41 + PTR_CPU(:,2) = 42 + PTR_CPU(:,3) = 43 + + CALL F_PTR%GET_DEVICE_DATA_RDWR(PTR_GPU2) + + !$acc serial, present(PTR_GPU2), copy(OKAY) + DO J=1,3 + DO I=1,128 + IF ( PTR_GPU2(I,J) /= 40+J ) THEN + OKAY = .FALSE. + END IF + PTR_GPU2(I,J) = I*10 + J + END DO + END DO + !$acc end serial + + IF (.NOT. OKAY) THEN + CALL FIELD_ABORT("ERROR DEVICE DATA NOT UPDATED BY GET_DEVICE_DATA_RDWR") + END IF + + CALL F_PTR%SYNC_HOST_RDWR() + DO J=1,3 + DO I=1,128 + IF ( PTR_CPU(I,J) /= I*10+J ) THEN + OKAY = .FALSE. + END IF + END DO + END DO + + IF (.NOT. OKAY) THEN + CALL FIELD_ABORT("ERROR HOST DATA NOT UPDATED BY SYNC_HOST_RDWR") + END IF + + +END PROGRAM TEST_GET_DEVICE_DATA_BOUNDS +