ESMF_StateReconcile_driver Subroutine

private subroutine ESMF_StateReconcile_driver(state, vm, attreconflag, rc)

Arguments

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

Source Code

    subroutine ESMF_StateReconcile_driver (state, vm, attreconflag, rc)
!
! !ARGUMENTS:
      type (ESMF_State), intent(inout) :: state
      type (ESMF_VM),    intent(in)    :: vm
      type(ESMF_AttReconcileFlag), intent(in)  :: attreconflag
      integer,           intent(out)   :: rc
!
! !DESCRIPTION:
!
!     The arguments are:
!     \begin{description}
!     \item[state]
!       {\tt ESMF\_State} to collect information from.
!     \item[vm]
!       The current {\tt ESMF\_VM} (virtual machine).  All PETs in this
!       {\tt ESMF\_VM} will exchange information about objects which might
!       only be known to one or more PETs, and ensure all PETs in this VM
!       have a consistent view of the object list in this {\tt ESMF\_State}.
!     \item[{[attreconflag]}]
!       Flag to tell if Attribute reconciliation is to be done as well as data reconciliation
!     \item[{[rc]}]
!       Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!     \end{description}
!EOPI
    integer :: localrc
    integer :: memstat
    integer :: mypet, npets

    integer, pointer :: nitems_buf(:)
    type (ESMF_StateItemWrap), pointer :: siwrap(:)

    integer,         pointer :: ids_send(:)
    type(ESMF_VMId), pointer :: vmids_send(:)
    integer, allocatable, target :: vmintids_send(:)

    type(ESMF_ReconcileIDInfo), allocatable :: id_info(:)

    logical, pointer :: recvd_needs_matrix(:,:)

    type(ESMF_CharPtr), allocatable :: items_recv(:)
    character, pointer :: buffer_recv(:)

    integer :: i

    logical, parameter :: debug = .false.
    logical, parameter :: meminfo = .false.
    logical, parameter :: trace = .false.
    logical, parameter :: profile = .false.

    character(160)  :: prefixStr
    type(ESMF_VMId), allocatable, target :: vmIdMap(:)
    type(ESMF_VMId), pointer :: vmIdMap_ptr(:)

    character(len=ESMF_MAXSTR) :: logmsg

    type(ESMF_InfoCache) :: info_cache
    type(ESMF_InfoDescribe) :: idesc

    ! -------------------------------------------------------------------------
    localrc = ESMF_RC_NOT_IMPL
    nullify(vmIdMap_ptr)

    if (meminfo) call ESMF_VMLogMemInfo ("entering ESMF_StateReconcile_driver")

    call ESMF_VMGet(vm, localPet=mypet, petCount=npets, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return

    if (debug) then
      do, i=0, npets-1
        if (i == mypet) then
          call ESMF_StatePrint (state)
          call ESMF_UtilIOUnitFlush (6)
        end if
        call ESMF_VMBarrier (vm)
      end do
    end if

    ! -------------------------------------------------------------------------
    ! 0.) Interchange item counts between PETs.  Set up counts/displacements
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("0.) Interchange item counts", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 0 - Initialize item counts and siwrappers')
    end if
    siwrap     => null ()
    nitems_buf => null ()
    call ESMF_ReconcileInitialize (state, vm,  &
        siwrap=siwrap, nitems_all=nitems_buf, rc=localrc)
    if (debug)  &
        localrc = ESMF_ReconcileAllRC (vm, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("0.) Interchange item counts", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 0.) Interchange item counts")

    ! -------------------------------------------------------------------------
    ! 1.) Each PET constructs its send arrays containing local Id
    ! and VMId info for each object contained in the State.
    ! Note that element zero is reserved for the State itself.
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("1.) Construct send arrays", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 1.0 - Build send arrays')
    end if
    ids_send   => null ()
    vmids_send => null ()
    if (profile) then
      call ESMF_TraceRegionEnter("ESMF_ReconcileGetStateIDInfo", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    call ESMF_ReconcileGetStateIDInfo (state, siwrap,  &
          id=  ids_send,  &
        vmid=vmids_send,  &
        rc=localrc)
    if (debug)  &
        localrc = ESMF_ReconcileAllRC (vm, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    if (profile) then
      call ESMF_TraceRegionExit("ESMF_ReconcileGetStateIDInfo", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif

    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 1.1 - Translate VM identifiers to integers')
    end if

    ! Translate VmId objects to an integer representation to minimize memory
    ! usage. This is also beneficial for performance.
    if (profile) then
      call ESMF_TraceRegionEnter("ESMF_VMTranslateVMId", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    call ESMF_VMTranslateVMId(vm, vmIds=vmids_send, ids=vmintids_send, &
      vmIdMap=vmIdMap, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT,  &
      rcToReturn=rc)) return
    if (profile) then
      call ESMF_TraceRegionExit("ESMF_VMTranslateVMId", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif

    ! VM integer ids should always start with 1
    if (profile) then
      call ESMF_TraceRegionEnter("Check vmIntIds", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    do i=lbound(vmintids_send,1),ubound(vmintids_send,1)
      if (vmintids_send(i) <= 0) then
        if (ESMF_LogFoundError(ESMF_FAILURE, msg="A <= zero VM integer id was encountered", &
          ESMF_CONTEXT, rcToReturn=rc)) return
      end if
    enddo
    if (profile) then
      call ESMF_TraceRegionExit("Check vmIntIds", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif

    vmIdMap_ptr => vmIdMap

#if 0
    ! Log a JSON State representation -----------------------------------------

    call idesc%Initialize(createInfo=.true., addObjectInfo=.true., vmIdMap=vmIdMap_ptr, &
      vmIdMapGeomExc=.true., rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return
    call idesc%Update(state, "", rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return
    call ESMF_LogWrite("InfoDescribe AFTER VMId collection=", rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return
    call ESMF_LogWrite("state_json_after_vmid="//ESMF_InfoDump(idesc%info), rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return
    call idesc%Destroy(rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return
#endif

    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 1.2 - Update Field metadata for unique geometries')
    end if

    ! Update Field metadata for unique geometries. This will traverse the state
    ! hierarchy adding reconcile-specific attributes that will find unique
    ! geometry objects and maintain sufficient information to re-establish
    ! references once the objects have been communicated and deserialized.
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("info_cache for unique geometries", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif

    call info_cache%Initialize(localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return

    call info_cache%UpdateFields(state, vmIdMap_ptr, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return

    call info_cache%Destroy(localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return

    if (profile) then
      call ESMF_TraceRegionExit("info_cache for unique geometries", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif

    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("1.) Construct send arrays", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 1.) Construct send arrays")

    ! -------------------------------------------------------------------------
    ! 2.) All PETs send their items Ids and VMIds to all the other PETs,
    ! then create local directories of which PETs have which ids/VMIds.
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("2.) Send arrays exchange", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 2 - Exchange Ids/VMIds')
    end if
    allocate (id_info(0:npets-1), stat=memstat)
    if (ESMF_LogFoundAllocError(memstat, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    call ESMF_ReconcileExchgIDInfo (vm,  &
        nitems_buf=nitems_buf,  &
        id=ids_send,  &
        vmid=vmintids_send,  &
        id_info=id_info, &
        rc=localrc)
    if (debug)  &
        localrc = ESMF_ReconcileAllRC (vm, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("2.) Send arrays exchange", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 2.) Send arrays exchange")

! At this point, each PET knows what items can be found on all of
! the other PETs.  The id_info array has global PET info in it.

    ! -------------------------------------------------------------------------
    ! 3.) Construct needs list.  Receiving PETs compare IDs and VMIds
    ! in their send ID/VMId array with what was received from the
    ! currently-being-processed sending PET.  Note that multiple PETs
    ! can 'offer' an item.
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("3.) Construct needs list", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 3 - Compare and create needs arrays')
    end if
    call ESMF_ReconcileCompareNeeds (vm,  &
          id=  ids_send,  &
        vmid=vmintids_send,  &
        id_info=id_info,  &
        rc=localrc)
    if (debug)  &
        localrc = ESMF_ReconcileAllRC (vm, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("3.) Construct needs list", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 3.) Construct needs list")

    ! -------------------------------------------------------------------------
    ! 4.) Communicate needs back to the offering PETs.
    ! Send to each offering PET a buffer containing 'needed' array
    ! specifying which items are needed.  The array is the same size as,
    ! and corresponds to, the ID and VMId arrays that were previously
    ! offered.
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("4.) Communicate needs back", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 4 - Exchange needs')
    end if
    recvd_needs_matrix => null ()
    call ESMF_ReconcileExchgNeeds (vm,  &
        id_info=id_info,  &
        recv_needs=recvd_needs_matrix,  &
        rc=localrc)
    if (debug)  &
        localrc = ESMF_ReconcileAllRC (vm, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("4.) Communicate needs back", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 4.) Communicate needs back")

    ! -------------------------------------------------------------------------
    ! 5.) Serialize needed objects
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("5.) Serialize needed objects", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 5 - Serialize needs', ask=.false.)
    end if
    call ESMF_ReconcileSerialize (state, vm, siwrap, &
        needs_list=recvd_needs_matrix, &
        attreconflag=attreconflag,  &
        id_info=id_info,  &
        rc=localrc)
    if (debug)  &
        localrc = ESMF_ReconcileAllRC (vm, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    deallocate (recvd_needs_matrix, stat=memstat)
    if (ESMF_LogFoundDeallocError(memstat, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("5.) Serialize needed objects", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 5.) Serialize needed objects")

    ! -------------------------------------------------------------------------
    ! 6.) Send/receive serialized objects to whoever needed them
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("6.) Send/receive serialized objects", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 6 - Exchange serialized objects')
    end if
    allocate (items_recv(0:npets-1), stat=memstat)
    if (ESMF_LogFoundAllocError(memstat, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    buffer_recv => null ()
    call ESMF_ReconcileExchgItems (vm,  &
        id_info=id_info,  &
        recv_items=items_recv,  &  ! %cptr aliased to portions of buffer_recv
        recv_buffer=buffer_recv,  &
        rc=localrc)
    if (debug)  &
        localrc = ESMF_ReconcileAllRC (vm, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("6.) Send/receive serialized objects", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 6.) Send/receive serialized objects")

    ! -------------------------------------------------------------------------
    ! 7.) Deserialize received objects and create proxies (recurse on
    !     nested States as needed)
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("7.) Deserialize received objects and create proxies", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 7 - Deserialize needs')
    end if
    do, i=0, npets-1
      if (debug) then
        write (*, '(a,i0,a,i0,a,l1)')  &
            '   PET ', mypet, ': Deserializing from PET ', i,  &
            ', associated (items_recv(i)%cptr) =', associated (items_recv(i)%cptr)
      end if
      if (associated (items_recv(i)%cptr)) then
        if (debug) then
          print *, '    items_recv(', lbound (items_recv(i)%cptr),  &
              ':', ubound (items_recv(i)%cptr), ')'
            end if
        call ESMF_ReconcileDeserialize (state, vm, &
            obj_buffer=items_recv(i)%cptr, &
            attreconflag=attreconflag, &
            rc=localrc)
      else
        localrc = ESMF_SUCCESS
      end if
      if (debug)  &
          localrc = ESMF_ReconcileAllRC (vm, localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT,  &
          rcToReturn=rc)) return
    end do
    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': *** Step 7 - Complete')
    end if

! Clean up

    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
          ': At clean up.', ask=.false.)
      call ESMF_VMBarrier (vm)
    end if

    if (associated (buffer_recv)) then
      deallocate (buffer_recv, stat=memstat)
      if (ESMF_LogFoundDeallocError (memstat, ESMF_ERR_PASSTHRU,  &
          ESMF_CONTEXT,  &
          rcToReturn=rc)) return
    end if

    if (associated (ids_send)) then
      deallocate (ids_send, vmids_send, stat=memstat)
      if (ESMF_LogFoundDeallocError(memstat, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT,  &
          rcToReturn=rc)) return
    end if

    do, i=0, ubound (id_info, 1)
      if (associated (id_info(i)%id)) then
        deallocate (id_info(i)%id, id_info(i)%vmid, id_info(i)%needed,  &
            stat=memstat)
        if (ESMF_LogFoundDeallocError(memstat, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT,  &
            rcToReturn=rc)) return
      end if
      if (associated (id_info(i)%item_buffer)) then
        deallocate (id_info(i)%item_buffer,  &
            stat=memstat)
        if (ESMF_LogFoundDeallocError(memstat, ESMF_ERR_PASSTHRU, &
            ESMF_CONTEXT,  &
            rcToReturn=rc)) return
      end if
    end do

    call ESMF_VMIdDestroy(vmIdMap, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, ESMF_CONTEXT, rcToReturn=rc)) return

    deallocate (vmIdMap, stat=memstat)
    if (ESMF_LogFoundDeallocError(memstat, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return

    deallocate (id_info, stat=memstat)
    if (ESMF_LogFoundDeallocError(memstat, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return

    if (associated (siwrap)) then
      deallocate (siwrap, stat=memstat)
      if (ESMF_LogFoundDeallocError(memstat, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT,  &
          rcToReturn=rc)) return
    end if

    deallocate (nitems_buf, stat=memstat)
    if (ESMF_LogFoundDeallocError(memstat, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return

    call ESMF_ReconcileZappedProxies (state, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("7.) Deserialize received objects and create proxies", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 7.) Deserialize received objects and create proxies")

    ! -------------------------------------------------------------------------
    ! 8.) Attributes on the State itself
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionEnter("8.) Attributes on the State itself", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (attreconflag == ESMF_ATTRECONCILE_ON) then
      if (trace) then
        call ESMF_ReconcileDebugPrint (ESMF_METHOD //  &
            ': *** Step 8 - Exchange Base Attributes', ask=.false.)
        call ESMF_VMBarrier (vm)
      end if
      call ESMF_ReconcileExchgAttributes (state, vm, rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
          ESMF_CONTEXT,  &
          rcToReturn=rc)) return
    end if
    state%statep%reconcileneededflag = .false.
    ! -------------------------------------------------------------------------
    if (profile) then
      call ESMF_TraceRegionExit("8.) Attributes on the State itself", rc=localrc)
      if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
        ESMF_CONTEXT,  &
        rcToReturn=rc)) return
    endif
    ! -------------------------------------------------------------------------
    if (meminfo) call ESMF_VMLogMemInfo ("after 8.) Attributes on the State itself")

    if (trace) then
      call ESMF_ReconcileDebugPrint (ESMF_METHOD // ': Complete!')
      call ESMF_VMBarrier (vm)
    end if
    rc = ESMF_SUCCESS

    if (meminfo) call ESMF_VMLogMemInfo ("exiting ESMF_StateReconcile_driver")

  end subroutine ESMF_StateReconcile_driver