program MapperSimpleTwoConcurrentComps
#include "ESMF_Conf.inc"
#include "ESMF.h"
#define ESMF_METHOD "MapperSimpleTwoConcurrentComps"
! ESMF Framework module
use ESMF
use ESMF_TestMod
use user_model1, only : userm1_setvm, userm1_register
use user_model2, only : userm2_setvm, userm2_register
use user_coupler, only : usercpl_setvm, usercpl_register
use comp_utils
use mpi
implicit none
! Dynamic Integer array type
type DIArray
integer, dimension(:), allocatable :: arr
end type
abstract interface
subroutine iuser_setvm(comp, rc)
use ESMF
type(ESMF_GridComp) :: comp
integer, intent(out) :: rc
end subroutine iuser_setvm
subroutine iuser_register(comp, rc)
use ESMF
type(ESMF_GridComp) :: comp
integer, intent(out) :: rc
end subroutine iuser_register
end interface
type UModelFP
procedure(iuser_setvm), pointer, nopass :: puser_setvm
procedure(iuser_register), pointer, nopass :: puser_register
end type
integer, parameter :: NUM_UMODELS = 2
type(UModelFP) :: umodel_func_ptrs(NUM_UMODELS)
! Local variables
! assert(NUM_COMPS > 0)
integer, parameter :: NUM_COMPS = 8
integer, parameter :: NUM_COMPS_PLUS_CPL = NUM_COMPS+1
integer :: pet_id, npets, rc, localrc, userrc
integer :: npets_comps(NUM_COMPS)
integer :: npets_cpl
integer :: petlist_start_comps(NUM_COMPS)
integer :: petlist_start_cpl
integer :: petlist_end_comps(NUM_COMPS)
integer :: petlist_end_cpl
integer :: i, j, k
type(DIArray) :: petlist_comps(NUM_COMPS)
integer, dimension(:), allocatable :: petlist_cpl
character(len=ESMF_MAXSTR) :: comp_names(NUM_COMPS)
character(len=ESMF_MAXSTR) :: cplname
character(len=ESMF_MAXSTR) :: comp_phase_names(NUM_COMPS)
type(ESMF_VM):: vm
type(ESMF_State) :: cexps(NUM_COMPS), cimps(NUM_COMPS)
type(ESMF_GridComp) :: comps(NUM_COMPS)
real(ESMF_KIND_R8) :: comp_starts(NUM_COMPS), comp_ends(NUM_COMPS)
double precision :: run_loop_start, run_loop_end
double precision :: run_loop_wtime
double precision :: comp_wtimes(NUM_COMPS)
type(ESMF_CplComp) :: cpl
! instantiate a clock, a calendar, and timesteps
!type(ESMF_Clock) :: clock_comps(1), clock_comps(2), clock_cpl
integer, parameter :: CPL_IDX = 1
integer, parameter :: GCOMP_SIDX = 2
type(ESMF_Clock) :: clocks(NUM_COMPS_PLUS_CPL)
type(ESMF_Calendar) :: gregorianCalendar
type(ESMF_TimeInterval) :: timeSteps(NUM_COMPS_PLUS_CPL)
type(ESMF_Time) :: startTime
type(ESMF_Time) :: stopTime
type(ESMF_Mapper) :: mapper
type(ESMF_Time) :: dbg_time
integer(ESMF_KIND_I8) :: dbg_stime
! cumulative result: count failures; no failures equals "all pass"
integer :: testresult = 0
integer :: result = 0
character(ESMF_MAXSTR) :: tmpstr
! individual test name
character(ESMF_MAXSTR) :: testname
! individual test failure message, and final status msg
character(ESMF_MAXSTR) :: failMsg, finalMsg
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
print *, "Start of System Test MapperSimpleTwoConcurrentComps."
localrc = ESMF_SUCCESS
rc = ESMF_SUCCESS
! Set the model function ptrs
umodel_func_ptrs(1)%puser_setvm => userm1_setvm
umodel_func_ptrs(1)%puser_register => userm1_register
umodel_func_ptrs(2)%puser_setvm => userm2_setvm
umodel_func_ptrs(2)%puser_register => userm2_register
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Create section
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
!
print *, "ESMF_Initialize ..."
! Initialize framework and get back default global VM
call ESMF_Initialize(vm=vm, defaultlogfilename="ConcurrentCompSTest.Log", &
logkindflag=ESMF_LOGKIND_MULTI, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
print *, "ESMF_VMGet ..."
! Get number of PETs we are running with
call ESMF_VMGet(vm, petCount=npets, localPET=pet_id, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
! Check for correct number of PETs
if ( npets < NUM_COMPS ) then
write(failMsg,'(A50,I6,A10)') "This system test does not run on fewer than ", NUM_COMPS, " PETs"
call ESMF_LogSetError(ESMF_RC_ARG_BAD,&
msg=failMsg,&
ESMF_CONTEXT, rcToReturn=rc)
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
endif
print *, "Allocating PETs among components ..."
j = 0
do i=1,NUM_COMPS-1
npets_comps(i) = npets/NUM_COMPS
petlist_start_comps(i) = j
petlist_end_comps(i) = petlist_start_comps(i) + npets_comps(i) - 1
j = j + npets_comps(i)
end do
npets_comps(NUM_COMPS) = npets - (NUM_COMPS - 1) * (npets/NUM_COMPS)
petlist_start_comps(NUM_COMPS) = j
petlist_end_comps(NUM_COMPS) = petlist_start_comps(NUM_COMPS) +&
npets_comps(NUM_COMPS) - 1
npets_cpl = npets
petlist_start_cpl = 0
petlist_end_cpl = petlist_start_cpl + npets_cpl - 1;
do i=1,NUM_COMPS
allocate(petlist_comps(i)%arr(npets_comps(i)))
end do
allocate(petlist_cpl(npets_cpl))
do k=1,NUM_COMPS
j = petlist_start_comps(k)
do i=1,npets_comps(k)
petlist_comps(k)%arr(i) = j
j = j + 1
end do
end do
j = petlist_start_cpl
do i=1,npets_cpl
petlist_cpl(i) = j
j = j + 1
end do
print *, "Creating N model components..."
! Create the N model components and coupler
do i=1,NUM_COMPS
write(tmpstr, '(A12,I6)') "user model ", i
comp_names(i) = trim(tmpstr)
comps(i) = ESMF_GridCompCreate(name=comp_names(i), petList=petlist_comps(i)%arr, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
print *, "Created component ", trim(comp_names(i)), "rc =", rc
end do
cplname = "user one-way coupler"
cpl = ESMF_CplCompCreate(name=cplname, petList=petlist_cpl, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
print *, "Created component ", trim(cplname), ", rc =", rc
do i=1,NUM_COMPS
deallocate(petlist_comps(i)%arr)
end do
deallocate(petlist_cpl)
!print *, "Comp Creates finished"
print *, "Creating mapper...."
!mapper = ESMF_MapperCreate(vm, configFile="./runseq.txt", rc=localrc)
mapper = ESMF_MapperCreate(vm, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Register section
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
print *, "Registering components ..."
do i=1,NUM_COMPS
call ESMF_GridCompSetVM(comps(i),&
userRoutine=umodel_func_ptrs(mod(i-1,NUM_UMODELS)+1)%puser_setvm,&
userRc=userrc, rc=localrc)
print *, "Comp1 SetVM finished, rc= ", localrc, userrc
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(comps(i),&
userRoutine=umodel_func_ptrs(mod(i-1,NUM_UMODELS)+1)%puser_register,&
userRc=userrc, rc=localrc)
print *, "Comp1 SetServices finished, rc= ", localrc, userrc
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)
end do
call ESMF_CplCompSetVM(cpl, userRoutine=usercpl_setvm, &
userRc=userrc, rc=localrc)
print *, "Cpl SetVM finished, rc= ", localrc, userrc
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_CplCompSetServices(cpl, userRoutine=usercpl_register, &
userRc=userrc, rc=localrc)
print *, "Cpl SetServices finished, rc= ", localrc, userrc
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)
! Set mapper constraints
!call ESMF_MapperSetConstraints(mapper, rc=localrc)
!if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
! ESMF_CONTEXT, rcToReturn=rc)) &
! call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Create and initialize clocks for comps(1) and comps(2).
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! initialize calendar to be Gregorian type
gregorianCalendar = ESMF_CalendarCreate(ESMF_CALKIND_GREGORIAN, &
name="Gregorian", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
! initialize time interval to 4 hours
call ESMF_TimeIntervalSet(timeSteps(CPL_IDX), h=4, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
do i=1,NUM_COMPS
call ESMF_TimeIntervalSet(timeSteps(GCOMP_SIDX+i-1), h=4, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
end do
! initialize start time to 5/01/2003
call ESMF_TimeSet(startTime, yy=2003, mm=5, dd=1, &
calendar=gregorianCalendar, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
! initialize stop time to 5/06/2003
call ESMF_TimeSet(stopTime, yy=2003, mm=5, dd=6, &
calendar=gregorianCalendar, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
! initialize the clock for comps(1) with the above values
clocks(CPL_IDX) = ESMF_ClockCreate(timeSteps(CPL_IDX), startTime, stopTime=stopTime, &
name="Cpl Clock 1", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
do i=1,NUM_COMPS
write(tmpstr,"(A15,I6)") "Gcomp Clock", i
clocks(GCOMP_SIDX+i-1) = ESMF_ClockCreate(timeSteps(GCOMP_SIDX+i-1), startTime, stopTime=stopTime, &
name=tmpstr, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
end do
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Init section
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
do i=1,NUM_COMPS,2
write(tmpstr,"(A20,I6)") "export comps", i
cexps(i) = ESMF_StateCreate(name=tmpstr, &
stateintent=ESMF_STATEINTENT_EXPORT, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
call ESMF_GridCompInitialize(comps(i), exportState=cexps(i),&
clock=clocks(GCOMP_SIDX+i-1), &
userRC=userrc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
!print *, "Comp 1 Initialize finished, rc =", rc
if((i+1) <= NUM_COMPS) then
write(tmpstr,"(A20,I6)") "import comps", i+1
cimps(i+1) = ESMF_StateCreate(name=tmpstr, &
stateintent=ESMF_STATEINTENT_IMPORT, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
call ESMF_GridCompInitialize(comps(i+1), importState=cimps(i+1),&
clock=clocks(GCOMP_SIDX+i), &
userRC=userrc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
!print *, "Comp 2 Initialize finished, rc =", rc
end if
end do
! note that the coupler's import is comps(1)'s export
do i=1,NUM_COMPS,2
if((i+1) <= NUM_COMPS) then
call ESMF_CplCompInitialize(cpl, importState=cexps(i), &
exportState=cimps(i+1), clock=clocks(CPL_IDX), userRC=userrc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
end if
end do
!print *, "Coupler Initialize finished, rc =", rc
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Run section
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
do i=1,NUM_COMPS
write(comp_phase_names(i),"(A15,I6)") "comp phase run", i
end do
do while (.not. ESMF_ClockIsStopTime(clocks(CPL_IDX), rc=localrc))
print *, "PET ", pet_id, " starting time step..."
run_loop_start = MPI_Wtime()
! Uncomment the following call to ESMF_GridCompWait() to sequentialize
! comps(1) and comps(2). The following ESMF_GridCompWait() call will block
! all PETs until comps(2) has returned. Consequently comps(1) will not be
! run until comps(2) has returned.
!call ESMF_GridCompWait(comps(2), syncflag=ESMF_SYNC_BLOCKING, rc=localrc)
!print *, "Comp 2 Wait returned, rc =", localrc
!if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
! ESMF_CONTEXT, rcToReturn=rc)) &
! call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
! Run the first component:
! After the first time thru the loop this will be running concurrently
! with the second component since comps(1) and comps(2) are defined on
! exclusive sets of PETs
do i=1,NUM_COMPS,2
!print *, "I am calling into GridCompRun(comps(1))"
comp_starts(i) = MPI_Wtime()
!call ESMF_GridCompRun(comps(1), exportState=cexps(1), clock=clocks(GCOMP_SIDX), &
! userRc=userrc, rc=localrc)
call ESMF_GridCompRun(comps(i), clock=clocks(GCOMP_SIDX+i-1), &
userRc=userrc, rc=localrc)
print *, "Comp ", i, " Run returned, 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)
comp_ends(i) = MPI_Wtime()
end do
! Uncomment the following calls to ESMF_GridCompWait() to sequentialize
! comps(1), comps(2) and the coupler. The following ESMF_GridCompWait() calls
! will block all PETs until comps(1) and comps(2) have returned. Consequently
! the coupler component will not be run until comps(1) and comps(2) have
! returned.
!call ESMF_GridCompWait(comps(1), syncflag=ESMF_SYNC_BLOCKING, rc=localrc)
!print *, "Comp 1 Wait returned, rc =", localrc
!if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
! ESMF_CONTEXT, rcToReturn=rc)) &
! call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
!call ESMF_GridCompWait(comps(2), syncflag=ESMF_SYNC_BLOCKING, rc=localrc)
!print *, "Comp 2 Wait returned, rc =", localrc
!if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
! ESMF_CONTEXT, rcToReturn=rc)) &
! call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
! Run the coupler:
! The coupler will run in "per-PET sequential" mode because it runs on
! the union of all PETs. Depending on the per-PET runtime of comps(1) and
! comps(2) some PETs may start/finish executing the coupler at different
! times. There is no intrinsic inter PET synchronization in calling
! component methods via CompI/R/F(). However, collective communication
! calls contained in the user written coupler methods will indirectly
! lead to inter PET synchronization of the coupler component.
!print *, "I am calling into CplCompRun(cpl)"
!call ESMF_CplCompRun(cpl, importState=cexps(1), &
! exportState=cimps(2), clock=clocks(CPL_IDX), userRc=userrc, rc=localrc)
call ESMF_CplCompRun(cpl,&
clock=clocks(CPL_IDX), userRc=userrc, rc=localrc)
!print *, "Coupler Run returned, 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)
! Uncomment the following call to ESMF_GridCompWait() to sequentialize
! comps(1) and comps(2). The following ESMF_GridCompWait() call will block
! all PETs until comps(1) has returned. Consequently comps(2) will not be
! run until comps(2) has returned.
!call ESMF_GridCompWait(comps(1), syncflag=ESMF_SYNC_BLOCKING, rc=localrc)
!print *, "Comp 1 Wait returned, rc =", localrc
!if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
! ESMF_CONTEXT, rcToReturn=rc)) &
! call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
! Run the second component:
! Since comps(1) and comps(2) are defined on exclusive sets of PETs those PET
! that are part of comps(1) will not block in the following call but proceed
! to the next loop increment, executing comps(1) concurrently with comps(2).
do i=2,NUM_COMPS,2
!print *, "I am calling into GridCompRun(comps(2))"
comp_starts(i) = MPI_Wtime()
!call ESMF_GridCompRun(comps(2), importState=cimps(2), clock=clocks(GCOMP_SIDX+1), &
! userRc=userrc, rc=localrc)
call ESMF_GridCompRun(comps(i), clock=clocks(GCOMP_SIDX+i-1), &
userRc=userrc, rc=localrc)
print *, "Comp ", i, " Run returned, 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)
comp_ends(2) = MPI_Wtime()
end do
run_loop_end = MPI_Wtime() - run_loop_start
do i=1,NUM_COMPS
call MPI_Allreduce(comp_ends(i), comp_wtimes(i),&
1, MPI_DOUBLE_PRECISION,&
MPI_MAX, MPI_COMM_WORLD, rc)
end do
call MPI_Allreduce(run_loop_end, run_loop_wtime, 1, MPI_DOUBLE_PRECISION,&
MPI_MAX, MPI_COMM_WORLD, rc)
do i=1,NUM_COMPS
print *, "comps(", i, ") = ", comp_wtimes(i), "s"
end do
print *, "run loop = ", run_loop_wtime, "s"
print *, "Setting comp infos..."
do i=1,NUM_COMPS
! Contact mapper
call ESMF_MapperSetCompInfo(mapper,&
len_trim(comp_names(i)), comp_names(i),&
len_trim(comp_phase_names(i)), comp_phase_names(i),&
petlist_start_comps(i), petlist_end_comps(i),&
comp_starts(i), comp_ends(i),&
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=localrc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
end do
print *, "Optimizing PET layouts using mapper..."
! Optimize using the mapper
call ESMF_MapperOptimize(mapper, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=localrc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
print *, "Retrieving optimized PET layouts from mapper..."
do i=1,NUM_COMPS
! Contact mapper
call ESMF_MapperGetCompInfo(mapper,&
len_trim(comp_names(i)), comp_names(i),&
len_trim(comp_phase_names(i)), comp_phase_names(i),&
startPet=petlist_start_comps(i), endPet=petlist_end_comps(i),&
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=localrc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
end do
print *, "Recreating components..."
do i=1,NUM_COMPS
! Recreate the components using info from mapper
call user_comp_recreate(comps(i),&
umodel_func_ptrs(mod(i-1,NUM_UMODELS) + 1)%puser_setvm,&
umodel_func_ptrs(mod(i-1,NUM_UMODELS) + 1)%puser_register,&
petlist_start_comps(i), petlist_end_comps(i), mapper, localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=localrc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
end do
do i=1,NUM_COMPS
call ESMF_ClockAdvance(clocks(GCOMP_SIDX+i-1), rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
!call ESMF_ClockPrint(clock_comps(1), rc=localrc)
end do
call ESMF_ClockAdvance(clocks(CPL_IDX), rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
!call ESMF_ClockPrint(clock_cpl, rc=localrc)
print *, "... time step finished on PET ", pet_id, "."
enddo
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Finalize section
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Print result
do i=1,NUM_COMPS,2
call ESMF_GridCompFinalize(comps(i), exportState=cexps(i), clock=clocks(GCOMP_SIDX+i-1), &
userRc=userrc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
!print *, "Comp 1 Finalize finished, rc =", rc
end do
do i=2,NUM_COMPS,2
call ESMF_GridCompFinalize(comps(i), importState=cimps(i), clock=clocks(GCOMP_SIDX+i-1), &
userRc=userrc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
!print *, "Comp 2 Finalize finished, rc =", rc
end do
call ESMF_CplCompFinalize(cpl, importState=cexps(1), &
exportState=cimps(2), clock=clocks(CPL_IDX), userRc=userrc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
if (ESMF_LogFoundError(userrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT)
!print *, "Coupler Finalize finished, rc =", rc
!print *, "Comp Finalize returned"
!
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Destroy section
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
! Clean up
do i=1,NUM_COMPS,2
call ESMF_StateDestroy(cexps(i), rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
end do
do i=2,NUM_COMPS,2
call ESMF_StateDestroy(cimps(i), rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
end do
do i=1,NUM_COMPS
call ESMF_ClockDestroy(clocks(GCOMP_SIDX+i-1), rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
end do
call ESMF_ClockDestroy(clocks(CPL_IDX), rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
call ESMF_CalendarDestroy(gregorianCalendar, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
do i=1,NUM_COMPS
call ESMF_GridCompDestroy(comps(i), rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
end do
call ESMF_CplCompDestroy(cpl, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
call ESMF_MapperDestroy(mapper, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) &
call ESMF_Finalize(rc=localrc, endflag=ESMF_END_ABORT)
!print *, "All Destroy routines done"
!-------------------------------------------------------------------------
!-------------------------------------------------------------------------
print *, "System Test MapperSimpleTwoConcurrentComps complete."
rc = localrc
! Normal ESMF Test output
write(failMsg, *) "System Test failure"
write(testname, *) "System Test MapperSimpleTwoConcurrentComps: Array Concurrent Components"
if (rc .eq. ESMF_SUCCESS) then
write(finalMsg, *) "SUCCESS: Concurrent Component test finished correctly."
else
write(finalMsg, *) "System Test did not succeed. Error code ", rc
endif
write(0, *) ""
write(0, *) trim(testname)
write(0, *) trim(finalMsg)
write(0, *) ""
! IMPORTANT: ESMF_STest() prints the PASS string and the # of processors
! into the Log file that the scripts grep for.
call ESMF_STest((rc.eq.ESMF_SUCCESS), testname, failMsg, result, &
__FILE__, &
__LINE__)
call ESMF_Finalize()
end program MapperSimpleTwoConcurrentComps