Skip to content

Commit

Permalink
First ESMF_StateReconcileIsNoop() implementation complete.
Browse files Browse the repository at this point in the history
  • Loading branch information
theurich committed Sep 24, 2024
1 parent b582b0c commit 4fb8294
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/Infrastructure/VM/include/ESMCI_VM.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class VMId {
namespace ESMCI {

// ESMCI::VMId methods:
bool VMIdCompare(const VMId *vmID1, const VMId *vmID2);
bool VMIdCompare(const VMId *vmID1, const VMId *vmID2, bool keyOnly=false);
bool VMIdLessThan(const VMId *vmID1, const VMId *vmID2);
int VMIdCopy(VMId *vmIDdst, VMId *vmIDsrc);
} // namespace ESMCI
Expand Down
7 changes: 5 additions & 2 deletions src/Infrastructure/VM/interface/ESMCI_VM_F.C
Original file line number Diff line number Diff line change
Expand Up @@ -1660,7 +1660,7 @@ extern "C" {
}

void FTN_X(c_esmc_vmidcompare)(ESMCI::VMId **vmid1, ESMCI::VMId **vmid2,
ESMC_Logical *result, int *rc){
ESMC_Logical *keyOnly, ESMC_Logical *result, int *rc){
#undef ESMC_METHOD
#define ESMC_METHOD "c_esmc_vmidcompare()"
// Initialize return code; assume routine not implemented
Expand All @@ -1669,7 +1669,10 @@ extern "C" {
ESMCI_NULL_CHECK_PRC(vmid1, rc)
ESMCI_NULL_CHECK_PRC(vmid2, rc)
ESMCI_NULL_CHECK_PRC(result, rc)
bool resultBool = ESMCI::VMIdCompare(*vmid1, *vmid2);
bool keyOnlyOpt = false; // default
if (ESMC_NOT_PRESENT_FILTER(keyOnly) != ESMC_NULL_POINTER)
if (*keyOnly == ESMF_TRUE) keyOnlyOpt = true;
bool resultBool = ESMCI::VMIdCompare(*vmid1, *vmid2, keyOnlyOpt);
*result = resultBool ? ESMF_TRUE : ESMF_FALSE;
// return successfully
if (rc!=NULL) *rc = ESMF_SUCCESS;
Expand Down
15 changes: 12 additions & 3 deletions src/Infrastructure/VM/interface/ESMF_VM.F90
Original file line number Diff line number Diff line change
Expand Up @@ -10353,14 +10353,15 @@ end subroutine ESMF_VMPlanMinThreads
! !IROUTINE: ESMF_VMIdCompare - Compare two ESMF_VMId objects

! !INTERFACE:
function ESMF_VMIdCompare(vmId1, vmId2, rc)
function ESMF_VMIdCompare(vmId1, vmId2, keyOnly, rc)
!
! !RETURN VALUE:
logical :: ESMF_VMIdCompare
!
! !ARGUMENTS:
type(ESMF_VMId), intent(in) :: vmId1
type(ESMF_VMId), intent(in) :: vmId2
logical, intent(in), optional :: keyOnly
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
Expand All @@ -10372,21 +10373,29 @@ function ESMF_VMIdCompare(vmId1, vmId2, rc)
! ESMF_VMId object 1
! \item[vmId2]
! ESMF_VMId object 2
! \item[{[keyOnly]}]
! For {\tt .true.} only compare the vmKey parts. Default is
! {\tt .false.}.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
!------------------------------------------------------------------------------
integer :: localrc ! local return code
type(ESMF_Logical) :: tf
type(ESMF_Logical) :: tf, keyOnlyOpt

! initialize return code; assume routine not implemented
localrc = ESMF_RC_NOT_IMPL
if (present(rc)) rc = ESMF_RC_NOT_IMPL

keyOnlyOpt = ESMF_FALSE
if (present(keyOnly)) then
if (keyOnly) keyOnlyOpt = ESMF_TRUE
endif

! Call into the C++ interface
call c_ESMC_VMIdCompare(vmId1, vmId2, tf, localrc)
call c_ESMC_VMIdCompare(vmId1, vmId2, keyOnly, tf, localrc)
ESMF_VMIdCompare = tf == ESMF_TRUE
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
Expand Down
12 changes: 8 additions & 4 deletions src/Infrastructure/VM/src/ESMCI_VM.C
Original file line number Diff line number Diff line change
Expand Up @@ -729,11 +729,13 @@ bool VMIdCompare(
// !ARGUMENTS:
//
const VMId *vmID1,
const VMId *vmID2
const VMId *vmID2,
bool keyOnly
){
//
// !DESCRIPTION:
// Compare two {\tt ESMC\_VMId} objects.
// Compare two {\tt ESMC\_VMId} objects. If {\tt keyOnly==true} only compare
// vmKey part.
//
//EOPI
//-----------------------------------------------------------------------------
Expand All @@ -742,8 +744,10 @@ bool VMIdCompare(
"- Invalid vmIDs", ESMC_CONTEXT, NULL);
return false; // bail out
}
if (vmID1->localID != vmID2->localID){
return false;
if (!keyOnly){
if (vmID1->localID != vmID2->localID){
return false;
}
}
return VMKeyCompare(vmID1->vmKey, vmID2->vmKey);
}
Expand Down
47 changes: 36 additions & 11 deletions src/Superstructure/StateReconcile/src/ESMF_StateReconcile.F90
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ subroutine ESMF_StateReconcile(state, vm, rc)
rcToReturn=rc)) return
endif

if (isNoop) then
call ESMF_LogWrite("returning early with isNoop=.true.", ESMF_LOGMSG_DEBUG, rc=localrc)
! successful early return because of NOOP condition
if (present(rc)) rc = ESMF_SUCCESS
return
endif

! Each PET broadcasts the object ID lists and compares them to what
! they get back. Missing objects are sent so they can be recreated
! on the PETs without those objects as "proxy" objects. Eventually
Expand Down Expand Up @@ -322,6 +329,7 @@ subroutine ESMF_StateReconcileIsNoop(state, vm, isNoop, rc)
integer :: localrc
type(ESMF_VMId) :: vmId
logical :: isNoopLoc
integer :: isNoopLocInt(1), isNoopInt(1)

localrc = ESMF_RC_NOT_IMPL

Expand All @@ -331,15 +339,21 @@ subroutine ESMF_StateReconcileIsNoop(state, vm, isNoop, rc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
rcToReturn=rc)) return

call ESMF_VMIdLog(vmId, prefix="ESMF_StateReconcileIsNoop(): ", &
rc=localrc)
call StateReconcileIsNoopLoc(state, isNoopLoc=isNoopLoc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
rcToReturn=rc)) return

call StateReconcileIsNoopLoc(state, isNoopLoc=isNoopLoc, rc=localrc)
isNoopLocInt(1) = 0
if (isNoopLoc) isNoopLocInt(1) = 1

! logical AND reduction, only 1 if all incoming 1
call ESMF_VMAllReduce(vm, isNoopLocInt, isNoopInt, 1, ESMF_REDUCE_MIN, &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
rcToReturn=rc)) return

if (isNoopInt(1)==1) isNoop = .true. ! found that Reconcile is a NOOP

! return successfully
rc = ESMF_SUCCESS

Expand All @@ -362,10 +376,11 @@ recursive subroutine StateReconcileIsNoopLoc(stateR, isNoopLoc, rc)
type(ESMF_RouteHandle) :: routehandle
type(ESMF_VM) :: vmItem
type(ESMF_VMId) :: vmIdItem
type(ESMF_Pointer) :: thisItem

localrc = ESMF_RC_NOT_IMPL

isNoopLoc = .false. ! assume reconcile needed until found otherwise
isNoopLoc = .true.

! query
call ESMF_StateGet(stateR, itemCount=itemCount, rc=localrc)
Expand Down Expand Up @@ -454,14 +469,24 @@ recursive subroutine StateReconcileIsNoopLoc(stateR, isNoopLoc, rc)
ESMF_CONTEXT, rcToReturn=rc)) return
endif

call ESMF_VMGetVMId(vmItem, vmId=vmIdItem, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
rcToReturn=rc)) return
call ESMF_VMGetThis(vmItem, thisItem, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
rcToReturn=rc)) return

call ESMF_VMIdLog(vmIdItem, prefix="vmIdItem: ", &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
rcToReturn=rc)) return
if (thisItem == ESMF_NULL_POINTER) isNoopLoc = .false. ! found proxy

if (.not.isNoopLoc) exit ! exit for .false. already recurse or proxy

call ESMF_VMGetVMId(vmItem, vmId=vmIdItem, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
rcToReturn=rc)) return

isNoopLoc = ESMF_VMIdCompare(vmIdItem, vmId, keyOnly=.true., &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
rcToReturn=rc)) return

if (.not.isNoopLoc) exit ! exit for .false.

enddo

Expand Down

0 comments on commit 4fb8294

Please sign in to comment.