ESMF_StateReconcileIsNoop Subroutine

private subroutine ESMF_StateReconcileIsNoop(state, vm, isNoop, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_State), intent(inout) :: state
type(ESMF_VM), intent(in) :: vm
logical, intent(out) :: isNoop
integer, intent(out) :: rc

Calls

proc~~esmf_statereconcileisnoop~~CallsGraph proc~esmf_statereconcileisnoop ESMF_StateReconcileIsNoop esmf_arrayget esmf_arrayget proc~esmf_statereconcileisnoop->esmf_arrayget esmf_fieldbundleget esmf_fieldbundleget proc~esmf_statereconcileisnoop->esmf_fieldbundleget esmf_fieldget esmf_fieldget proc~esmf_statereconcileisnoop->esmf_fieldget esmf_stateget esmf_stateget proc~esmf_statereconcileisnoop->esmf_stateget interface~esmf_arraybundleget ESMF_ArrayBundleGet proc~esmf_statereconcileisnoop->interface~esmf_arraybundleget interface~esmf_routehandleget ESMF_RouteHandleGet proc~esmf_statereconcileisnoop->interface~esmf_routehandleget interface~esmf_vmallreduce ESMF_VMAllReduce proc~esmf_statereconcileisnoop->interface~esmf_vmallreduce proc~esmf_logfounderror ESMF_LogFoundError proc~esmf_statereconcileisnoop->proc~esmf_logfounderror proc~esmf_traceregionenter ESMF_TraceRegionEnter proc~esmf_statereconcileisnoop->proc~esmf_traceregionenter proc~esmf_traceregionexit ESMF_TraceRegionExit proc~esmf_statereconcileisnoop->proc~esmf_traceregionexit proc~esmf_vmgetthis ESMF_VMGetThis proc~esmf_statereconcileisnoop->proc~esmf_vmgetthis proc~esmf_vmgetvmid ESMF_VMGetVMId proc~esmf_statereconcileisnoop->proc~esmf_vmgetvmid proc~esmf_vmidcompare ESMF_VMIdCompare proc~esmf_statereconcileisnoop->proc~esmf_vmidcompare

Called by

proc~~esmf_statereconcileisnoop~~CalledByGraph proc~esmf_statereconcileisnoop ESMF_StateReconcileIsNoop proc~esmf_statereconcile ESMF_StateReconcile proc~esmf_statereconcile->proc~esmf_statereconcileisnoop

Source Code

    subroutine ESMF_StateReconcileIsNoop(state, vm, isNoop, rc)
!
! !ARGUMENTS:
      type (ESMF_State), intent(inout) :: state
      type (ESMF_VM),    intent(in)    :: vm
      logical,           intent(out)   :: isNoop
      integer,           intent(out)   :: rc
!
! !DESCRIPTION:
!
!   Determine whether there is a need for reconciliation of {\tt state} across
!   the PETs of {\tt vm}.
!
!   The arguments are:
!   \begin{description}
!   \item[state]
!     {\tt ESMF\_State} to be reconciled.
!   \item[vm]
!     The current {\tt ESMF\_VM} (virtual machine).
!   \item[isNoop]
!     Return {\tt .true.} if no reconcile is needed, {\tt .false.} otherwise.
!   \item[{[rc]}]
!     Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!EOPI
    integer                 :: localrc
    type(ESMF_VMId)         :: vmId
    logical                 :: isNoopLoc
    integer                 :: isNoopLocInt(1), isNoopInt(1)

    logical, parameter      :: profile = .false.

    localrc = ESMF_RC_NOT_IMPL

    isNoop = .false.  ! assume reconcile is needed

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

    if (profile) then
      call ESMF_TraceRegionEnter("StateReconcileIsNoopLoc", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    endif

    call StateReconcileIsNoopLoc(state, isNoopLoc=isNoopLoc, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
      rcToReturn=rc)) return

    if (profile) then
      call ESMF_TraceRegionExit("StateReconcileIsNoopLoc", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    endif

    isNoopLocInt(1) = 0
    if (isNoopLoc) isNoopLocInt(1) = 1

    if (profile) then
      call ESMF_TraceRegionEnter("ESMF_VMAllReduce", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    endif

    ! 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 (profile) then
      call ESMF_TraceRegionExit("ESMF_VMAllReduce", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return
    endif

    isNoop = (isNoopInt(1)==1)  ! globally consistent result

    ! return successfully
    rc = ESMF_SUCCESS

  contains

    recursive subroutine StateReconcileIsNoopLoc(stateR, isNoopLoc, rc)
      type(ESMF_State), intent(in)    :: stateR
      logical,          intent(out)   :: isNoopLoc
      integer,          intent(out)   :: rc
      ! - local variables
      integer                     :: localrc
      integer                     :: itemCount, item, fieldCount, arrayCount, i
      character(ESMF_MAXSTR), allocatable     :: itemNameList(:)
      type(ESMF_StateItem_Flag), allocatable  :: itemTypeList(:)
      type(ESMF_State)            :: nestedState
      type(ESMF_Field)            :: field
      type(ESMF_FieldBundle)      :: fieldbundle
      type(ESMF_Array)            :: array
      type(ESMF_ArrayBundle)      :: arraybundle
      type(ESMF_RouteHandle)      :: routehandle
      type(ESMF_VM)               :: vmItem
      type(ESMF_VMId)             :: vmIdItem
      type(ESMF_Pointer)          :: thisItem
      logical                     :: isFlag

      localrc = ESMF_RC_NOT_IMPL

      isNoopLoc = .true.

      ! query
      call ESMF_StateGet(stateR, itemCount=itemCount, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
        rcToReturn=rc)) return

      if (itemCount > 0) then
        allocate(itemNameList(itemCount))
        allocate(itemTypeList(itemCount))
        call ESMF_StateGet(stateR, itemNameList=itemNameList, &
          itemtypeList=itemtypeList, rc=localrc)
        if (ESMF_LogFoundError(localrc, &
          ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT, rcToReturn=rc)) return

        do item=1, itemCount
          ! access the VM of the item, using appropriate API
          if ((itemtypeList(item) == ESMF_STATEITEM_STATE)) then
            call ESMF_StateGet(stateR, itemName=itemNameList(item), &
              nestedState=nestedState, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
            call ESMF_StateGet(nestedState, vm=vmItem, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
          else if (itemtypeList(item) == ESMF_STATEITEM_FIELD) then
            call ESMF_StateGet(stateR, itemName=itemNameList(item), &
              field=field, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
            call ESMF_FieldGet(field, vm=vmItem, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
          else if (itemtypeList(item) == ESMF_STATEITEM_FIELDBUNDLE) then
            call ESMF_StateGet(stateR, itemName=itemNameList(item), &
              fieldbundle=fieldbundle, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
            call ESMF_FieldBundleGet(fieldbundle, vm=vmItem, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
          else if (itemtypeList(item) == ESMF_STATEITEM_ARRAY) then
            call ESMF_StateGet(stateR, itemName=itemNameList(item), &
              array=array, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
            call ESMF_ArrayGet(array, vm=vmItem, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
          else if (itemtypeList(item) == ESMF_STATEITEM_ARRAYBUNDLE) then
            call ESMF_StateGet(stateR, itemName=itemNameList(item), &
              arraybundle=arraybundle, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
            call ESMF_ArrayBundleGet(arraybundle, vm=vmItem, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
          else if (itemtypeList(item) == ESMF_STATEITEM_ROUTEHANDLE) then
            call ESMF_StateGet(stateR, itemName=itemNameList(item), &
              routehandle=routehandle, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
            call ESMF_RouteHandleGet(routehandle, vm=vmItem, rc=localrc)
            if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, &
              rcToReturn=rc)) return
          endif

#if 0
call ESMF_LogWrite("processing "//trim(itemNameList(item)), ESMF_LOGMSG_DEBUG, rc=localrc)
#endif

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

          if (thisItem == ESMF_NULL_POINTER) isNoopLoc = .false.  ! found proxy

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

          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 0
block
  character(160) :: msgStr
  call ESMF_VMIdLog(vmIdItem, prefix="vmIdItem: ", rc=localrc)
  write(msgStr,*) "isNoopLoc: ", isNoopLoc
  call ESMF_LogWrite(msgStr, ESMF_LOGMSG_DEBUG, rc=localrc)
end block
#endif
          if (.not.isNoopLoc) exit  ! exit for .false.

          vmId = vmIdItem  ! more likely to hit pointer comparison this way

        enddo

        deallocate(itemNameList)
        deallocate(itemTypeList)
      endif

    end subroutine StateReconcileIsNoopLoc

  end subroutine ESMF_StateReconcileIsNoop