Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Focus on Namespace handling for targeted field mirror #328

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 67 additions & 1 deletion src/Infrastructure/Base/interface/ESMF_Info.F90
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ module ESMF_InfoMod
public ESMF_InfoSetDirty
public ESMF_InfoIsSet
public ESMF_InfoIsPresent
public ESMF_InfoLog
public ESMF_InfoPrint
public ESMF_InfoDump
public ESMF_InfoUpdate
Expand Down Expand Up @@ -2495,6 +2496,71 @@ end function ESMF_InfoIsSet

!------------------------------------------------------------------------------

#undef ESMF_METHOD
#define ESMF_METHOD "ESMF_InfoLog()"
!BOP
! !IROUTINE: ESMF_InfoLog - Log contents of an Info object
!
! !INTERFACE:
subroutine ESMF_InfoLog(info, keywordEnforcer, prefix, logMsgFlag, rc)
! !ARGUMENTS:
type(ESMF_Info), intent(in) :: info
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
character(len=*), intent(in), optional :: prefix
type(ESMF_LogMsg_Flag), intent(in), optional :: logMsgFlag
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! Write information about {\tt info} object to the ESMF default Log.
!
! The arguments are:
! \begin{description}
! \item[info]
! {\tt ESMF\_Info} object logged.
! \item [{[prefix]}]
! String to prefix the log message. Default is no prefix.
! \item [{[logMsgFlag]}]
! Type of log message generated. See section \ref{const:logmsgflag} for
! a list of valid message types. Default is {\tt ESMF\_LOGMSG\_INFO}.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOP
!------------------------------------------------------------------------------
integer :: localrc
character(:), allocatable :: output, local_preString

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

!TODO: This should really be implemented on the C++ side where we could
!TODO: correctly deal with line breaks and prepend the prefix string on
!TODO: each line, much like for ESMF_HConfigLog().
!TODO: For now implemented quickly on the Fortran side to make available.

if (present(prefix)) then
local_preString = prefix
else
local_preString = ""
endif

output = ESMF_InfoDump(info, indent=2, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return

call ESMF_LogWrite(local_preString//output, logMsgFlag, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return

! return successfully
if (present(rc)) rc = ESMF_SUCCESS

end subroutine ESMF_InfoLog

!------------------------------------------------------------------------------

#undef ESMF_METHOD
#define ESMF_METHOD "ESMF_InfoPrint()"
!BOP
Expand Down Expand Up @@ -3929,4 +3995,4 @@ subroutine ESMF_InfoWriteJSON(info, filename, keywordEnforcer, rc)
if (present(rc)) rc = ESMF_SUCCESS
end subroutine ESMF_InfoWriteJSON

end module ESMF_InfoMod !=====================================================
end module ESMF_InfoMod !=====================================================
16 changes: 16 additions & 0 deletions src/Superstructure/State/src/ESMF_StateAPI.cppF90
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module ESMF_StateAPIMod
use ESMF_IOUtilMod
use ESMF_UtilMod
use ESMF_UtilStringMod
use ESMF_InfoMod

implicit none

Expand Down Expand Up @@ -1852,6 +1853,21 @@ type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return

#if 0
!TODO: need a way to indicate from calling side that info should be logged
block
type(ESMF_Info) :: info
call ESMF_InfoGetFromBase(stateR%statep%base, info=info, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_InfoLog(info, prefix=prefix, rc=localrc)
if (ESMF_LogFoundError(localrc, &
ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
end block
#endif

if (itemCount > 0) then
allocate(itemNameList(itemCount))
allocate(itemTypeList(itemCount))
Expand Down
50 changes: 32 additions & 18 deletions src/addon/NUOPC/src/NUOPC_Base.F90
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,13 @@ module NUOPC_Base
! !IROUTINE: NUOPC_AddNamespace - Add a nested state with Namespace to a State
! !INTERFACE:
subroutine NUOPC_AddNamespace(state, Namespace, nestedStateName, &
nestedState, rc)
nestedState, vm, rc)
! !ARGUMENTS:
type(ESMF_State), intent(inout) :: state
character(len=*), intent(in) :: Namespace
character(len=*), intent(in), optional :: nestedStateName
type(ESMF_State), intent(out), optional :: nestedState
type(ESMF_VM), intent(in), optional :: vm
integer, intent(out), optional :: rc
! !DESCRIPTION:
! Add a Namespace to {\tt state}. Namespaces are implemented via nested
Expand All @@ -178,6 +179,10 @@ subroutine NUOPC_AddNamespace(state, Namespace, nestedStateName, &
! Name of the nested state. Defaults to {\tt Namespace}.
! \item[{[nestedState]}]
! Optional return of the newly created nested state.
! \item[{[vm]}]
! If present, the nested State created to hold the namespace is created on
! the specified {\tt ESMF\_VM} object. The default is to create the nested
! State on the VM of the current component context.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
Expand All @@ -189,9 +194,10 @@ subroutine NUOPC_AddNamespace(state, Namespace, nestedStateName, &
type(ESMF_State) :: nestedS
character(len=80) :: nestedSName
type(ESMF_StateIntent_Flag) :: stateIntent

logical :: stateIsCreated

if (present(rc)) rc = ESMF_SUCCESS

call ESMF_StateGet(state, stateIntent=stateIntent, rc=localrc)
if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=FILENAME, rcToReturn=rc)) return ! bail out
Expand All @@ -201,31 +207,39 @@ subroutine NUOPC_AddNamespace(state, Namespace, nestedStateName, &
else
nestedSName = trim(Namespace)
endif

nestedS = ESMF_StateCreate(name=nestedSName, stateIntent=stateIntent, &
rc=localrc)
if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=FILENAME, rcToReturn=rc)) return ! bail out

call NUOPC_InitAttributes(nestedS, rc=localrc)
vm=vm, rc=localrc)
if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=FILENAME, rcToReturn=rc)) return ! bail out

call NUOPC_SetAttribute(nestedS, name="Namespace", &
value=trim(Namespace), rc=localrc)
if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=FILENAME, rcToReturn=rc)) return ! bail out

call ESMF_StateAdd(state, (/nestedS/), rc=localrc)
stateIsCreated = ESMF_StateIsCreated(nestedS, rc=rc)
if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=FILENAME, rcToReturn=rc)) return ! bail out

if (stateIsCreated) then

call NUOPC_InitAttributes(nestedS, rc=localrc)
if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=FILENAME, rcToReturn=rc)) return ! bail out

call NUOPC_SetAttribute(nestedS, name="Namespace", &
value=trim(Namespace), rc=localrc)
if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=FILENAME, rcToReturn=rc)) return ! bail out

call ESMF_StateAdd(state, (/nestedS/), rc=localrc)
if (ESMF_LogFoundError(rcToCheck=localrc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=FILENAME, rcToReturn=rc)) return ! bail out

endif

if (present(nestedState)) &
nestedState = nestedS

end subroutine
!---------------------------------------------------------------------
!-----------------------------------------------------------------------------

!-----------------------------------------------------------------------------
!BOP
! !IROUTINE: NUOPC_AddNestedState - Add a nested state to a state with NUOPC attributes
Expand Down
69 changes: 25 additions & 44 deletions src/addon/NUOPC/src/NUOPC_Connector.F90
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ subroutine InitializeIPDv05p1(connector, importState, exportState, clock, rc)
integer :: i, j
character(ESMF_MAXSTR) :: importCplSet, exportCplSet
character(len=240) :: msgString
character(ESMF_MAXSTR) :: importProvider, exportProvider
character(ESMF_MAXSTR) :: stateName, namespace

rc = ESMF_SUCCESS

Expand Down Expand Up @@ -609,25 +609,22 @@ subroutine InitializeIPDv05p1(connector, importState, exportState, clock, rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
elseif (trim(exportXferPolicy)=="transferAllAsNests") then
! check name of provider component
call NUOPC_GetAttribute(importState, name="CompName", &
value=importProvider, rc=rc)
! access importState namespace so it can be transferred to exportState
call NUOPC_GetAttribute(importState, name="Namespace", &
value=namespace, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! create nested state
exportNestedState = ESMF_StateCreate(name=trim(importProvider)//"-NestedState", rc=rc)
! access name of exportState for nestedStateName construction for clarity
call ESMF_StateGet(exportState, name=stateName, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! set FieldTransferPolicy metadata for nested state
call NUOPC_SetAttribute(exportNestedState, "FieldTransferPolicy", "transferAll", rc=rc)
! set namespace on exportState, creating a nestedState on acceptor VM
call NUOPC_AddNamespace(exportState, namespace=trim(namespace), &
nestedStateName=trim(stateName)//"-namespace:"//trim(namespace), &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested state name is appearing in the NUOPC app prototype something like atm-importstate-namespace:ocn and this is aligned with the change in here. So, this is little bit different than the convention that I was using before. Are we plaining to go with this naming convention? If so, I need to couple of adjustment in my real application. Also, I think we need to document this convention in the documentation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss this further next week (on a call, or under your PR). I am thinking your code should only be going off of the Namespace attribute, which is part of the NUOPC standard, and documented. The nested State name itself is a NUOPC implementation detail, and user code should not depend on it (I just made it something meaningful for the purpose of internal NUOPC development and debugging). But we can discuss this in more detail... I may be overlooking something.

nestedState=exportNestedState, vm=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! define namespace and nested state
call NUOPC_AddNamespace(exportState, namespace=trim(importProvider), &
nestedState=exportNestedState, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! top level mirroring into exportState
! mirror importState items into exportNestedState
call doMirror(importState, exportNestedState, acceptorVM=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
Expand Down Expand Up @@ -707,25 +704,20 @@ subroutine InitializeIPDv05p1(connector, importState, exportState, clock, rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
elseif (trim(importXferPolicy)=="transferAllAsNests") then
! check name of provider component
call NUOPC_GetAttribute(exportState, name="CompName", &
value=exportProvider, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! create nested state
importNestedState = ESMF_StateCreate(name=trim(exportProvider)//"-NestedState", rc=rc)
! access exportState namespace so it can be transferred to importState
call NUOPC_GetAttribute(exportState, name="Namespace", &
value=namespace, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! set FieldTransferPolicy metadata for nested state
call NUOPC_SetAttribute(importNestedState, "FieldTransferPolicy", "transferAll", rc=rc)
! access name of importState for nestedStateName construction for clarity
call ESMF_StateGet(importState, name=stateName, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! define namespace and nested state
call NUOPC_AddNamespace(importState, namespace=trim(exportProvider), &
nestedState=importNestedState, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
! top level mirroring into exportState
! set namespace on importState, creating a nestedState on acceptor VM
call NUOPC_AddNamespace(importState, namespace=trim(namespace), &
nestedStateName=trim(stateName)//"-namespace:"//trim(namespace), &
nestedState=importNestedState, vm=vm, rc=rc)
! mirror exportState items into importNestedState
call doMirror(exportState, importNestedState, acceptorVM=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
Expand Down Expand Up @@ -839,13 +831,12 @@ subroutine InitializeIPDv05p1(connector, importState, exportState, clock, rc)
recursive subroutine doMirror(providerState, acceptorState, acceptorVM, rc)
type(ESMF_State) :: providerState
type(ESMF_State) :: acceptorState
type(ESMF_VM), intent(in) :: acceptorVM
type(ESMF_VM), intent(in) :: acceptorVM
integer, intent(out) :: rc

integer :: item, itemCount
character(ESMF_MAXSTR) :: providerTransferOffer, acceptorTransferOffer
character(ESMF_MAXSTR) :: acceptorStateName
character(ESMF_MAXSTR) :: providerCompName
type(ESMF_State) :: providerNestedState
type(ESMF_State) :: acceptorNestedState
character(ESMF_MAXSTR) :: nestedStateName
Expand All @@ -866,26 +857,21 @@ recursive subroutine doMirror(providerState, acceptorState, acceptorVM, rc)
character(ESMF_MAXSTR) :: valueString
type(ESMF_Pointer) :: vmThis
logical :: actualFlag

rc = ESMF_SUCCESS

nullify(providerStandardNameList)
nullify(providerNamespaceList)
nullify(providerFieldList)
nullify(providerCplSetList)
nullify(acceptorStandardNameList)

actualFlag = .true.
call ESMF_VMGetThis(acceptorVM, vmThis)
if (vmThis == ESMF_NULL_POINTER) then
actualFlag = .false. ! local PET is not for an actual member
endif

call NUOPC_GetAttribute(providerState, name="CompName", &
value=providerCompName, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out

call ESMF_StateGet(acceptorState, name=acceptorStateName, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
Expand Down Expand Up @@ -1062,14 +1048,9 @@ recursive subroutine doMirror(providerState, acceptorState, acceptorVM, rc)
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
endif

! Add extra metadata to the field in acceptor side about provider
call NUOPC_SetAttribute(fieldAdv, name="ProviderCompName", &
value=trim(providerCompName), rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=trim(name)//":"//FILENAME)) return ! bail out
end do
endif

if (flipIntent) then
! Need to flip the accetorState intent back (same as providerIntent).
call ESMF_StateSet(acceptorState, stateIntent=providerIntent, rc=rc)
Expand Down
Loading
Loading