ghosttest.f90

来自「CCSM Research Tools: Community Atmospher」· F90 代码 · 共 534 行

F90
534
字号
!------------------------------------------------------------------------!         NASA/GSFC, Data Assimilation Office, Code 910.3, GEOS/DAS!------------------------------------------------------------------------!BOP! !ROUTINE: GhostTest --- Unit tester for the decomposition utilities!! !INTERFACE:      PROGRAM GhostTest! !USES:      USE  precision      USE  decompmodule, ONLY: DecompType, DecompFree, DecompRegular1D,  &     &              DecompRegular2D, DecompRegular3D, DecompCreate,      &     &              DecompLocalToGlobal      USE  ghostmodule, ONLY: GhostType, GhostFree, GhostCreate,         &     &              GhostCopy, GhostInfo      USE  parutilitiesmodule, ONLY: CommGlobal, GID, GSize,             &     &              ParPatternType, ParPatternCreate, ParPatternFree,    &     &              ParInit, ParExit, ParBeginTransfer, ParEndTransfer#include "debug.h"#include "misc.h"      IMPLICIT NONE#include "gpt.inc"! !DESCRIPTION:!!    This main program tests the functionality of the GhostModule!    It performs the following tests:!!    \begin{enumerate}!      \item 1D ghost region of a 1D decomposition!      \item 2D ghost region of a 2D decomposition!      \item 3D ghost region of a 3D decomposition!      \item irregular ghost region of an irregular decomposition!    \end{enumerate}!!    Validation check: !!      mpirun -np 7 GhostTest!!    Should yield a single message (if -DDEBUG_ON is *not* defined):!!      Passed all tests!!    Be patient, it tests many complex cases, so it could take a while!! !REVISION HISTORY:!   01.02.07   Sawyer     Creation!   01.05.01   Sawyer     Minor changes for CCM framework!!EOP!-------------------------------------------------------------------------!BOC!! !LOCAL VARIABLES:      TYPE (DecompType)     :: Decomp      TYPE (GhostType)      :: Ghost      TYPE (ParPatternType) :: Pattern, Pattern2d, Pattern3d      INTEGER   Nactual, GhostWidth, Nx, Ny      PARAMETER (Nactual = 100, GhostWidth = 4, Nx = 72, Ny = 46 )! For the Observation decomposition      INTEGER   BlockLen, I, J, K, Local, Global, Pe      INTEGER   PEsInX, PEsInY, PEsInZ, IamInX, IamInY, IamInZ      INTEGER   Xstart, Xend, Ystart, Yend, Zstart, Zend, Ytrue, Ztrue      LOGICAL :: Passed      REAL (r8), ALLOCATABLE :: Rtmp(:), Rtmp2d(:,:), Rtmp3d(:,:,:)      INTEGER, ALLOCATABLE :: itmp(:), ilocal(:), Dist(:), Tags(:),      &     &                        Xdist(:), Ydist(:), Zdist(:), Perm(:)!! GhostModule is communication-free, but in this test a communication! pattern is constructed for different ghost regions.  This makes it! an SPMD code.!      CALL ParInit()      Passed = .TRUE.!! Initialize timing library.  2nd arg 0 means disable, 1 means enable!#if defined(TIMING)      call t_setoptionf (usrsys, 1)      call t_initializef ()#endif!! Test 1 : Test GhostRegular1D!          using a block-wise distribution.!#if defined(TIMING)      call t_startf('1D Ghosting Total')#endif      ALLOCATE( Xdist( GSize ) )!! Decomposition for Observations:  Block distribution with remainder! on last PE.  Should be OK if #obs >> #PEs!      Global = Nactual*Gsize      BlockLen = Global      DO I = 1, GSize-1        Xdist( I ) = BlockLen / 2        BlockLen  = BlockLen - Xdist(I)      ENDDO      Xdist( GSize ) = BlockLen      CALL DecompRegular1D ( GSize, Xdist, Decomp )!! Now define a ghost region (i.e., a subset of the entire domain)!      Xstart = 1      IF (GID .GT. 0) Xstart = SUM( Xdist(1:GID) ) + 1      Xend = Global      IF (GID .LT. Gsize-1) Xend   = Xstart + Xdist(GID+1) - 1      DEALLOCATE( Xdist )!! Define ghost region with GhostWidth overlap (and wrap-around)!      CALL GhostCreate( Decomp, Gid, Global,                             &     &               Xstart-GhostWidth, Xend+GhostWidth, .TRUE., Ghost )! Allocate the ghosted region itself      ALLOCATE( Rtmp( Xstart-GhostWidth:Xend+GhostWidth ) ) !! Put the correct global tag into entry of the array, but zero out ghost region!      Rtmp = 0.0      DO I=Xstart, Xend        Rtmp(I) = I      ENDDO!! Now create a communication pattern which interrelates all the ! ghosted vectors!#if defined(TIMING)      call t_startf('1D PatternCreate')#endif      CALL ParPatternCreate( CommGlobal, Ghost, Pattern )#if defined(TIMING)      call t_stopf('1D PatternCreate')#endif!! Do a test with the communication pattern!#if defined(TIMING)      call t_startf('1D Ghost Transfer')#endif      CALL ParBeginTransfer( Pattern, Rtmp, Rtmp )      CALL ParEndTransfer( Pattern, Rtmp, Rtmp )#if defined(TIMING)      call t_stopf('1D Ghost Transfer')#endif      DO I=Xstart-GhostWidth, Xend+GhostWidth        IF ( Rtmp(I) .NE. MODULO(I-1,Global)+1 ) THEN          print *, "Error on PE", GID, "Rtmp(",I,")=",Rtmp(I)          Passed = .FALSE.        ENDIF      ENDDO!! Free the communication pattern!      DEALLOCATE( Rtmp )      CALL ParPatternFree( CommGlobal, Pattern )      CALL GhostFree( Ghost )      CALL DecompFree( Decomp )#if defined(TIMING)      call t_stopf('1D Ghosting Total')#endif!! Test 2 : Test DecompRegular2D!#if defined(TIMING)      call t_startf('2D Ghosting Total')#endif      IF ( Gsize .GT. 1 ) THEN        PEsInX = 2        DO WHILE ( MOD(Gsize,PEsInX) .NE. 0 )          PEsInX = PEsInX + 1        ENDDO      ELSE          PEsInX = 1      ENDIF!! In the worst case PEsInX = Gsize, PEsInY=1!      PEsInY = Gsize / PEsInX      IamInY = GID / PEsInX      IamInX = MOD( GID, PEsInX )      ALLOCATE( Xdist( PEsInX ) )      ALLOCATE( Ydist( PEsInY ) )!      BlockLen = Nactual      DO I = 1, PEsInX-1        Xdist( I ) = BlockLen / 2        BlockLen  = BlockLen - Xdist(I)      ENDDO      Xdist( PEsInX ) = BlockLen      DO J = 1, PEsInY-1        Ydist( J ) = Nactual / PEsInY      ENDDO      Ydist( PEsInY ) = Nactual - (PEsInY-1)*(Nactual/PEsInY)      CALL DecompRegular2D( PEsInX, PEsInY, Xdist, Ydist, Decomp )      Xstart = 1      IF (IamInX .GT. 0) Xstart = SUM( Xdist(1:IamInX) ) + 1      Xend = Nactual      IF (IamInX .LT. PEsInX-1) Xend   = Xstart + Xdist(IamInX+1) - 1      Ystart = 1      IF (IamInY .GT. 0) Ystart = SUM( Ydist(1:IamInY) ) + 1      Yend = Nactual      IF (IamInY .LT. PEsInY-1) Yend   = Ystart + Ydist(IamInY+1) - 1      DEALLOCATE( Ydist )      DEALLOCATE( Xdist )!! Now define a ghost region (i.e., a subset of the entire domain)!      CALL GhostCreate( Decomp, Gid,                                     &     &              Nactual, Xstart-GhostWidth, Xend+GhostWidth,.TRUE.,  &     &              Nactual, Ystart-GhostWidth, Yend+GhostWidth,.FALSE., &     &              Ghost)!! Allocated the corresponding ghosted array: Note that some ghost regions! will not be used (there is no wrap around)!      ALLOCATE( Rtmp2d(Xstart-GhostWidth:Xend+GhostWidth,                &     &                 Ystart-GhostWidth:Yend+GhostWidth) )!! Put the correct global tag into entry of the array, but zero out ghost region!      Rtmp2d = 0.0      DO J=Ystart, Yend        DO I=Xstart, Xend          Rtmp2d(I,J) = (J-1)*Nactual + I        ENDDO      ENDDO#if defined(TIMING)      call t_startf('2D PatternCreate')#endif      CALL ParPatternCreate( CommGlobal, Ghost, Pattern2d )#if defined(TIMING)      call t_stopf('2D PatternCreate')#endif!! Do a test with the communication pattern!#if defined(TIMING)      call t_startf('2D Ghost Transfer')#endif      CALL BeginTransfer( Pattern2d, Rtmp2d, Rtmp2d )      CALL EndTransfer( Pattern2d, Rtmp2d, Rtmp2d )#if defined(TIMING)      call t_stopf('2D Ghost Transfer')#endif      DO J=Ystart, Yend        Ytrue = MODULO(J-1,Nactual)        DO I=Xstart-GhostWidth, Xend+GhostWidth          Global = Ytrue*Nactual + MODULO(I-1,Nactual) + 1          IF ( Rtmp2D(I,J) .NE. Global ) THEN            print *, "Error on PE", GID, "Rtmp2d(",I,J,")=",Rtmp2d(I,J)            Passed = .FALSE.          ENDIF        ENDDO      ENDDO!! Free the communication pattern!      CALL ParPatternFree( CommGlobal, Pattern2d )      DEALLOCATE( Rtmp2D )      CALL GhostFree( Ghost )      CALL DecompFree( Decomp )#if defined(TIMING)      call t_stopf('2D Ghosting Total')#endif!! Test 3 : Test DecompRegular3D!#if defined(TIMING)      call t_startf('3D Ghosting Total')#endif!! In the case of a prime: PEsInZ = Gsize, PEsInY=1, PEsInX=1!      IF ( Gsize .GT. 1 ) THEN        PEsInZ = 2        DO WHILE ( MOD(Gsize,PEsInZ) .NE. 0 )          PEsInZ = PEsInZ + 1        ENDDO      ELSE        PEsInZ = 1      ENDIF      Pe = Gsize / PEsInZ      IF ( Pe .GT. 1 ) THEN        PEsInY = 2        DO WHILE ( MOD(Pe,PEsInY) .NE. 0 )          PEsInY = PEsInY + 1        ENDDO      ELSE        PEsInY = 1      ENDIF!      PEsInX = Pe / PEsInY!      IamInX = MOD( GID, PEsInX )      IamInY = MOD( GID/PEsInX, PEsInY )      IamInZ = GID / Pe      ALLOCATE( Xdist( PEsInX ) )      ALLOCATE( Ydist( PEsInY ) )      ALLOCATE( Zdist( PEsInZ ) )!      BlockLen = Nactual      DO I = 1, PEsInX-1        Xdist( I ) = BlockLen / 2        BlockLen  = BlockLen - Xdist(I)      ENDDO      Xdist( PEsInX ) = BlockLen      DO J = 1, PEsInY-1        Ydist( J ) = Nactual / PEsInY      ENDDO      Ydist( PEsInY ) = Nactual - (PEsInY-1)*(Nactual/PEsInY)      BlockLen = Nactual      DO K = PEsInZ,2,-1        Zdist( K ) = BlockLen / 2        BlockLen  = BlockLen - Zdist(K)      ENDDO      Zdist( 1 ) = BlockLen      CALL DecompRegular3D( PEsInX, PEsInY, PEsInZ,                      &     &                      Xdist, Ydist, Zdist, Decomp )      Xstart = 1      IF (IamInX .GT. 0) Xstart = SUM( Xdist(1:IamInX) ) + 1      Xend = Nactual      IF (IamInX .LT. PEsInX-1) Xend   = Xstart + Xdist(IamInX+1) - 1      Ystart = 1      IF (IamInY .GT. 0) Ystart = SUM( Ydist(1:IamInY) ) + 1      Yend = Nactual      IF (IamInY .LT. PEsInY-1) Yend   = Ystart + Ydist(IamInY+1) - 1      Zstart = 1      IF (IamInZ .GT. 0) Zstart = SUM( Zdist(1:IamInZ) ) + 1      Zend = Nactual      IF (IamInZ .LT. PEsInZ-1) Zend   = Zstart + Zdist(IamInZ+1) - 1      DEALLOCATE( Zdist )      DEALLOCATE( Ydist )      DEALLOCATE( Xdist )#if defined(DEBUG_GHOSTTEST)      print *, GID, "Xstart", Xstart, "Xend", Xend, "Ystart", Ystart,    &     &         "Yend", Yend, "Zstart", Zstart, "Zend", Zend,             &     &         "IamInX", IamInX, "IamInY", IamInY, "IamInZ", IamInZ#endif!! Now define a ghost region (i.e., a subset of the entire domain)!      CALL GhostCreate( Decomp, Gid,                                     &     &              Nactual, Xstart-GhostWidth, Xend+GhostWidth,.FALSE., &     &              Nactual, Ystart-GhostWidth, Yend+GhostWidth,.FALSE., &     &              Nactual, Zstart-GhostWidth, Zend+GhostWidth,.TRUE.,  &     &              Ghost)!! Allocated the corresponding ghosted array: Note that some ghost regions! will not be used (there is no wrap around)!      ALLOCATE( Rtmp3d(Xstart-GhostWidth:Xend+GhostWidth,                &     &                 Ystart-GhostWidth:Yend+GhostWidth,                &     &                 Zstart-GhostWidth:Zend+GhostWidth) )!! Put the correct global tag into entry of the array, but zero out ghost region!      Rtmp3d = 0.0      DO K=Zstart, Zend        DO J=Ystart, Yend          DO I=Xstart, Xend            Rtmp3d(I,J,K) = (K-1)*Nactual*Nactual + (J-1)*Nactual + I          ENDDO        ENDDO      ENDDO#if defined(TIMING)      call t_startf('3D PatternCreate')#endif      CALL ParPatternCreate( CommGlobal, Ghost, Pattern3d )#if defined(TIMING)      call t_stopf('3D PatternCreate')#endif!! Do a test with the communication pattern!#if defined(TIMING)      call t_startf('3D Ghost Transfer')#endif      CALL BeginTransfer( Pattern3d, Rtmp3d, Rtmp3d )      CALL EndTransfer( Pattern3d, Rtmp3d, Rtmp3d )#if defined(TIMING)      call t_stopf('3D Ghost Transfer')#endif      DO K=Zstart-GhostWidth, Zend+GhostWidth        Ztrue = MODULO(K-1,Nactual)        DO J=Ystart, Yend          Ytrue = MODULO(J-1,Nactual)          DO I=Xstart, Xend            Global = (Ztrue*Nactual+Ytrue)*Nactual+MODULO(I-1,Nactual)+1            IF ( Rtmp3D(I,J,K) .NE. Global ) THEN              print *, "Error on",GID,"Rtmp3d(",I,J,K,")=",Rtmp3d(I,J,K)              Passed = .FALSE.            ENDIF          ENDDO        ENDDO      ENDDO!! Free the communication pattern!      CALL ParPatternFree( CommGlobal, Pattern3d )      CALL GhostFree( Ghost )      CALL DecompFree( Decomp )#if defined(TIMING)      call t_stopf('3D Ghosting Total')#endif#if 0!! Test 4 : Test Irregular Decomposition!      ALLOCATE( Tags( Nactual ) )      ALLOCATE( Dist( Nactual ) )      ALLOCATE( Rtmp( Nactual ) )      ALLOCATE( Perm( GSize ) )!! A random PE assignment is by far the hardest test for the library!      CALL RANDOM_NUMBER( HARVEST = Rtmp )      Dist = INT( GSize*Rtmp - 0.5 )!! This is the simple version of an irregular decomposition!      CALL DecompCreate( GSize, Dist, Nactual, Decomp )!! Define the Ghost region through an arbitrary set of unique tags!       CALL RANDOM_NUMBER( HARVEST = Rtmp )      global = 0      DO I=1, Nactual        IF ( Rtmp(I) .GE. 0.3333 .AND. Rtmp(I) .LT. 0.6667 ) THEN          global = global + 1          Tags( global ) = I        ENDIF      ENDDO!      CALL RANDOM_NUMBER( HARVEST = Rtmp )      Dist = INT( GSize*Rtmp - 0.5 )!! This is the esoteric version of an irregular decomposition!      CALL GhostCreate( Decomp, Gid, Global, Tags, Ghost )      DEALLOCATE( Perm )      DEALLOCATE( Rtmp )      DEALLOCATE( Dist )      DEALLOCATE( Tags )      CALL DecompFree( Decomp )      CALL ParPatternCreate( CommGlobal, Ghost, Pattern )      CALL GhostFree( Ghost )!! Do a test with the communication pattern!!! Free the communication pattern!      CALL ParPatternFree( CommGlobal, Pattern )#endif!! That's all folks!      call t_prf(GID)      IF ( Passed ) THEN        PRINT *, "Passed GhostTest"      ELSE        PRINT *, "Failed GhostTest"      ENDIF      CALL ParExit()!EOC!-------------------------------------------------------------------------      END PROGRAM GhostTest

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?