! $Id$ ! !------------------------------------------------------------------------- !ESMF_SYSTEM_TEST String used by test script to count system tests. !========================================================================= !------------------------------------------------------------------------- ! ! !DESCRIPTION: ! System test ArraySharedDeSSI. ! ! Two Gridded Components defined on the same full petList of the parent. ! ! The first GridComp (comp1) uses the parent PETs directly and runs on all ! parent PETs. The second GridComp (comp2) uses the ESMF_GridCompSetVMMaxPEs() ! method during its SetVM() routine to reduce the number of PETs to the level ! possible to only have a single PET per single system image (SSI). The PETs ! executing comp2 therefore have access to all the PEs held by all the ! original parent PETs. OpenMP threading is used by comp2 to utilize the ! available PEs. ! ! The comp1 Initialize() method creates an Array with 1DE/PET. The ! Array is created specifying the pinflag argument. For ESMF_PIN_DE_TO_SSI ! or ESMF_PIN_DE_TO_SSI_CONTIG the allocation allows DEs to be shared between ! PETs that are executing on the same SSI. The comp1 passes the Array back ! to the parent level via the exportState. The parent level passes the same ! state into comp2 as importState. ! ! The comp1 initializes the data in the Array, each PET accessing its one ! localDe, during the Run() method. Then comp2 compares the data stored in the ! Array to the analytic solution. It does so accessing all the DEs from the ! reduced number of PETs via DE sharing across SSI shared memory. ! !------------------------------------------------------------------------- !\begin{verbatim} program ESMF_ArraySharedDeSSISTest #define ESMF_METHOD "program ESMF_ArraySharedDeSSISTest" #include "ESMF.h" ! ESMF Framework module use ESMF use ESMF_TestMod use user_model1, only : userm1_setvm, userm1_register use user_model2, only : userm2_setvm, userm2_register implicit none ! Local variables integer :: localPet, userrc, localrc, rc=ESMF_SUCCESS type(ESMF_VM) :: vm type(ESMF_State) :: state type(ESMF_GridComp) :: comp1, comp2 type(ESMF_Array) :: array ! cumulative result: count failures; no failures equals "all pass" integer :: result = 0 ! individual test name character(ESMF_MAXSTR) :: testname ! individual test failure message, and final status msg character(ESMF_MAXSTR) :: failMsg, finalMsg !------------------------------------------------------------------------- !------------------------------------------------------------------------- write(testname, *) "System Test ESMF_ArraySharedDeSSISTest" write(failMsg, *) "System Test failure" !------------------------------------------------------------------------- !------------------------------------------------------------------------- print *, "--------------------------------------- " print *, "Start of ", trim(testname) print *, "--------------------------------------- " !------------------------------------------------------------------------- !------------------------------------------------------------------------- ! Create section !------------------------------------------------------------------------- !------------------------------------------------------------------------- ! ! Initialize framework and get back default global VM call ESMF_Initialize(vm=vm, & defaultlogfilename="ArraySharedDeSSISTest.Log", & logkindflag=ESMF_LOGKIND_MULTI, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_LogSet(flush=.true., rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_VMLogSystem(rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_VMLog(vm, prefix="main: ", rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) ! Get number of PETs we are running with call ESMF_VMGet(vm, localPet=localPet, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) ! Create comp1 on all parent PETs comp1 = ESMF_GridCompCreate(name="model comp1", rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) ! Create comp2 on all parent PETs comp2 = ESMF_GridCompCreate(name="model comp2", rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) ! Create a State that can be used to pass information between comp1 and comp2 state = ESMF_StateCreate(rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) !------------------------------------------------------------------------- !------------------------------------------------------------------------- ! SetVM and SetServices section !------------------------------------------------------------------------- !------------------------------------------------------------------------- call ESMF_GridCompSetVM(comp1, userRoutine=userm1_setvm, & userRc=userrc, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_GridCompSetServices(comp1, userRoutine=userm1_register, & userRc=userrc, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_GridCompSetVM(comp2, userRoutine=userm2_setvm, & userRc=userrc, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_GridCompSetServices(comp2, userRoutine=userm2_register, & userRc=userrc, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) !------------------------------------------------------------------------- !------------------------------------------------------------------------- ! Init section !------------------------------------------------------------------------- !------------------------------------------------------------------------- call ESMF_GridCompInitialize(comp1, exportState=state, userRc=userrc,& rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) !------------------------------------------------------------------------- !------------------------------------------------------------------------- ! Run section !------------------------------------------------------------------------- !------------------------------------------------------------------------- ! Comp1 Run -> initialize the data array call ESMF_GridCompRun(comp1, exportState=state, userRc=userrc, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) ! Because DEs are shared across PETs on the same SSI, must call ArraySync() ! before comp2 gets to access the Array. In order to do this here, the ! state must be reconciled in case comp1 was only active on a subset of ! PETs. call ESMF_StateReconcile(state, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_StateGet(state, "MyArray", array, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_ArraySync(array, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) ! Comp2 Run -> validate the data array call ESMF_GridCompRun(comp2, importState=state, userRc=userrc, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) #if 1 ! Call Run Methods a second time to test context switching ! Comp1 Run -> initialize the data array call ESMF_GridCompRun(comp1, exportState=state, userRc=userrc, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) ! Comp2 Run -> validate the data array call ESMF_GridCompRun(comp2, importState=state, userRc=userrc, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) #endif !------------------------------------------------------------------------- !------------------------------------------------------------------------- ! Destroy section !------------------------------------------------------------------------- !------------------------------------------------------------------------- call ESMF_GridCompDestroy(comp1, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_GridCompDestroy(comp2, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) call ESMF_StateDestroy(state, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) & call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) !------------------------------------------------------------------------- !------------------------------------------------------------------------- 10 continue ! Normal ESMF Test output print *, testname, " complete." if (rc .eq. ESMF_SUCCESS) then ! Separate message to console, for quick confirmation of success/failure write(finalMsg, *) "SUCCESS: ",trim(testname)," finished correctly." write(0, *) "" write(0, *) trim(testname) write(0, *) trim(finalMsg) write(0, *) "" endif print *, "------------------------------------------------------------" print *, "------------------------------------------------------------" print *, "Test finished, localPet = ", localPet print *, "------------------------------------------------------------" print *, "------------------------------------------------------------" ! IMPORTANT: ESMF_STest() prints the PASS string and the # of processors ! in the log file that the scripts grep for. call ESMF_STest((rc.eq.ESMF_SUCCESS), testname, failMsg, result, ESMF_SRCLINE) call ESMF_Finalize() end program ESMF_ArraySharedDeSSISTest !\end{verbatim}