Skip to content

Commit

Permalink
Switch to doing HConfig equality on C++ side.
Browse files Browse the repository at this point in the history
  • Loading branch information
oehmke committed Dec 23, 2023
1 parent c8a4059 commit cb589e1
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/Infrastructure/HConfig/include/ESMCI_HConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ namespace ESMCI {
static HConfig create(int *rc=NULL);
template <typename T> static HConfig create(T content, int *rc=NULL);
template <typename T> static HConfig create(T *content, int count, int *rc=NULL);
static bool equal(HConfig *hconfig1, HConfig *hconfig2);
static int destroy(HConfig *hconfig);

template <typename T> inline static YAML::Node find(T self, HConfig *key);
Expand Down
23 changes: 23 additions & 0 deletions src/Infrastructure/HConfig/interface/ESMCI_HConfig_F.C
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,29 @@ extern "C" {
if (rc!=NULL) *rc = ESMF_SUCCESS;
}

// Check for equality
// Since this is used as equality operator above there isn't a place to pass a return code, so just
// pass false for an error instead (as done with equality operators elsewhere in ESMF)
void FTN_X(c_esmc_hconfigequal)(ESMCI::HConfig *hconfig1, ESMCI::HConfig *hconfig2, ESMC_Logical *isEqual){
#undef ESMC_METHOD
#define ESMC_METHOD "c_esmc_hconfigequal()"

// Init return
*isEqual = ESMF_FALSE;

// Test for NULL pointers
if (hconfig1 == NULL) return;
if (hconfig2 == NULL) return;

// call into C++
bool equal=ESMCI::HConfig::equal(hconfig1, hconfig2);

// Comnvert to ESMF Logical
if (equal) *isEqual=ESMF_TRUE;
else *isEqual = ESMF_FALSE;
}


void FTN_X(c_esmc_hconfigdestroy)(ESMCI::HConfig *ptr, int *rc){
#undef ESMC_METHOD
#define ESMC_METHOD "c_esmc_hconfigdestroy()"
Expand Down
32 changes: 25 additions & 7 deletions src/Infrastructure/HConfig/interface/ESMF_HConfig.F90
Original file line number Diff line number Diff line change
Expand Up @@ -614,9 +614,8 @@ function ESMF_HConfigEQ(HConfig1, HConfig2)
!-------------------------------------------------------------------------------

ESMF_INIT_TYPE init1, init2
integer :: localrc1, localrc2
logical :: lval1, lval2

type(ESMF_Logical) :: isEqual

! Use the following logic, rather than "ESMF-INIT-CHECK-DEEP", to gain
! init checks on both args, and in the case where both are uninitialized,
! to distinguish equality based on uninitialized type (uncreated,
Expand All @@ -629,7 +628,16 @@ function ESMF_HConfigEQ(HConfig1, HConfig2)
! TODO: this line must remain split in two for SunOS f90 8.3 127000-03
if (init1 .eq. ESMF_INIT_CREATED .and. &
init2 .eq. ESMF_INIT_CREATED) then
ESMF_HConfigEQ = all(HConfig1%shallowMemory .eq. HConfig2%shallowMemory)

! Call into the C++ interface to determine equality
call c_ESMC_HConfigEqual(HConfig1, HConfig2, isEqual)

! Translate from ESMF logical to Fortran logical
ESMF_HConfigEQ= .false.
if (isEqual == ESMF_TRUE) then
ESMF_HConfigEQ= .true.
endif

else
ESMF_HConfigEQ = .false.
endif
Expand Down Expand Up @@ -662,8 +670,7 @@ function ESMF_HConfigIterEQ(HConfig1, HConfig2)
!-------------------------------------------------------------------------------

ESMF_INIT_TYPE init1, init2
integer :: localrc1, localrc2
logical :: lval1, lval2
type(ESMF_Logical) :: isEqual

! Use the following logic, rather than "ESMF-INIT-CHECK-DEEP", to gain
! init checks on both args, and in the case where both are uninitialized,
Expand All @@ -677,7 +684,18 @@ function ESMF_HConfigIterEQ(HConfig1, HConfig2)
! TODO: this line must remain split in two for SunOS f90 8.3 127000-03
if (init1 .eq. ESMF_INIT_CREATED .and. &
init2 .eq. ESMF_INIT_CREATED) then
ESMF_HConfigIterEQ = all(HConfig1%shallowMemory .eq. HConfig2%shallowMemory)

! Call into the C++ interface to determine equality
! For now use HConfig equality since HConfig iterators and HConfig are
! stored in the same class
call c_ESMC_HConfigEqual(HConfig1, HConfig2, isEqual)

! Translate from ESMF logical to Fortran logical
ESMF_HConfigIterEQ= .false.
if (isEqual == ESMF_TRUE) then
ESMF_HConfigIterEQ= .true.
endif

else
ESMF_HConfigIterEQ = .false.
endif
Expand Down
63 changes: 63 additions & 0 deletions src/Infrastructure/HConfig/src/ESMCI_HConfig.C
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,69 @@ HConfig HConfig::create(
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
#undef ESMC_METHOD
#define ESMC_METHOD "ESMCI::HConfig::equal()"
//BOP
// !IROUTINE: ESMCI::HConfig::equal - check if two hconfigs are equal
//
// !INTERFACE:
bool HConfig::equal(
//
// !RETURN VALUE:
// bool
//
// !ARGUMENTS:
HConfig *hconfig1,
HConfig *hconfig2) {
//
//
// !DESCRIPTION:
//
//EOP
//-----------------------------------------------------------------------------

#ifdef ESMF_YAMLCPP

// Check for error condiiton of NULL inputs, since this is used as an equality operator above there isn't
// really a route to pass an error code, so return false instead (which seems to be the way this is handled
// in other equality operators in the framework).
if (hconfig1 == NULL) return false;
if (hconfig2 == NULL) return false;

// TODO: Move this into an equality operator for HConfig and call that here instead

// See if the docs are equal
if (hconfig1->doc == hconfig2->doc) {

// They are both NULL, so this is an iterator
if (hconfig1->doc == NULL) {

// See if they are the same type
if (hconfig1->type == hconfig2->type) {

// Compare iterators to determine final equality
if (hconfig1->iter == hconfig2->iter) return true;
else return false;

} else {
return false; // Not the same type so not the same
}

} else { // Not NULL, so they aren't iterators, but have the same docs, so the same
return true;
}

} else { // Not the same docs, so not the same
return false;
}

#endif

}
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
#undef ESMC_METHOD
#define ESMC_METHOD "ESMCI::HConfig::destroy()"
Expand Down

0 comments on commit cb589e1

Please sign in to comment.