ESMF_ArrayBundleSMMStoreNF Subroutine

private subroutine ESMF_ArrayBundleSMMStoreNF(srcArrayBundle, dstArrayBundle, routehandle, keywordEnforcer, ignoreUnmatchedIndicesFlag, srcTermProcessing, rc)

Arguments

Type IntentOptional Attributes Name
type(ESMF_ArrayBundle), intent(in) :: srcArrayBundle
type(ESMF_ArrayBundle), intent(inout) :: dstArrayBundle
type(ESMF_RouteHandle), intent(inout) :: routehandle
type(ESMF_KeywordEnforcer), optional :: keywordEnforcer
logical, intent(in), optional :: ignoreUnmatchedIndicesFlag(:)
integer, intent(inout), optional :: srcTermProcessing(:)
integer, intent(out), optional :: rc

Source Code

  subroutine ESMF_ArrayBundleSMMStoreNF(srcArrayBundle, dstArrayBundle, &
    routehandle, keywordEnforcer, ignoreUnmatchedIndicesFlag, srcTermProcessing, rc)
!
! !ARGUMENTS:
    type(ESMF_ArrayBundle),  intent(in)              :: srcArrayBundle
    type(ESMF_ArrayBundle),  intent(inout)           :: dstArrayBundle
    type(ESMF_RouteHandle),  intent(inout)           :: routehandle
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
    logical,                 intent(in),    optional :: ignoreUnmatchedIndicesFlag(:)
    integer,                 intent(inout), optional :: srcTermProcessing(:)
    integer,                 intent(out),   optional :: rc
!
! !STATUS:
! \begin{itemize}
! \item\apiStatusCompatibleVersion{5.2.0r}
! \item\apiStatusModifiedSinceVersion{5.2.0r}
! \begin{description}
! \item[7.1.0r] Added argument {\tt srcTermProcessing}.
!              The new argument gives the user access to the tuning parameter
!              affecting the sparse matrix execution and bit-wise 
!              reproducibility.
! \item[8.1.0] Added argument {\tt ignoreUnmatchedIndicesFlag} to support cases
!    where the sparse matrix includes terms with source or destination sequence
!    indices not present in the source or destination array.
! \end{description}
! \end{itemize}
!
! !DESCRIPTION:
!   Store an ArrayBundle sparse matrix multiplication operation from
!   {\tt srcArrayBundle} to {\tt dstArrayBundle}. The sparse matrix
!   multiplication between ArrayBundles is defined as the sequence of
!   individual Array sparse matrix multiplications over all source and
!   destination Array pairs in sequence. The method requires that
!   {\tt srcArrayBundle} and {\tt dstArrayBundle} reference an identical
!   number of {\tt ESMF\_Array} objects.
!
!   The effect of this method on ArrayBundles that contain aliased members is
!   undefined.
!
!   PETs that specify non-zero matrix coefficients must use
!   the <type><kind> overloaded interface and provide the {\tt factorList} and
!   {\tt factorIndexList} arguments. Providing {\tt factorList} and
!   {\tt factorIndexList} arguments with {\tt size(factorList) = (/0/)} and
!   {\tt size(factorIndexList) = (/2,0/)} or {\tt (/4,0/)} indicates that a 
!   PET does not provide matrix elements. Alternatively, PETs that do not 
!   provide matrix elements may also call into the overloaded interface
!   {\em without} {\tt factorList} and {\tt factorIndexList} arguments.
!   
!   See the description of method {\tt ESMF\_ArraySMMStore()} for
!   the definition of the Array based operation.
!
!   The routine returns an {\tt ESMF\_RouteHandle} that can be used to call 
!   {\tt ESMF\_ArrayBundleSMM()} on any pair of ArrayBundles that matches 
!   {\tt srcArrayBundle} and {\tt dstArrayBundle} in {\em type}, {\em kind},
!   and memory layout of the {\em distributed} dimensions. However, the size, 
!   number, and index order of {\em undistributed} dimensions may be different.
!   See section \ref{RH:Reusability} for a more detailed discussion of
!   RouteHandle reusability.
!  
!   This call is {\em collective} across the current VM.
!
!   \begin{description}
!   \item [srcArrayBundle]
!     {\tt ESMF\_ArrayBundle} with source data.
!   \item [dstArrayBundle]
!     {\tt ESMF\_ArrayBundle} with destination data. The data in these Arrays
!     may be destroyed by this call.
!   \item [routehandle]
!     Handle to the precomputed Route.
!
!   \item [{[ignoreUnmatchedIndicesFlag]}] 
!     If set to {.false.}, the {\em default}, source and destination side must
!     cover all of the squence indices defined in the sparse matrix. An error
!     will be returned if a sequence index in the sparse matrix does not match
!     on either the source or destination side.
!     If set to {.true.}, mismatching sequence indices are silently ignored.
!     The size of this array argument must either be 1 or equal the number of
!     Arrays in the {\tt srcArrayBundle} and {\tt dstArrayBundle} arguments. In
!     the latter case, the handling of unmatched indices is specified for each
!     Array pair separately. If only one element is specified, it is
!     used for {\em all} Array pairs.
!
!   \item [{[srcTermProcessing]}]
!       Source term summing options for route handle creation. See
!       {\tt ESMF\_ArraySMMStore} documentation for a full parameter description.
!       Two forms may be provided. If a single element list is provided, this
!       integer value is applied across all bundle members. Otherwise, the list must
!       contain as many elements as there are bundle members. For the special case
!       of accessing the auto-tuned parameter (providing a negative integer value),
!       the list length must equal the bundle member count.
!   \item [{[rc]}]
!     Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!   \end{description}
!
!EOP
!------------------------------------------------------------------------------
    integer                         :: localrc              ! local return code
    type(ESMF_Logical), pointer     :: opt_ignoreUnmatched(:)
    type(ESMF_Logical), target      :: def_ignoreUnmatched(1)
    integer                         :: len_ignoreUnmatched
    type(ESMF_InterArray)           :: srcTermProcessingArg ! helper variable

    ! initialize return code; assume routine not implemented
    localrc = ESMF_RC_NOT_IMPL
    if (present(rc)) rc = ESMF_RC_NOT_IMPL
    
    ! Check init status of arguments
    ESMF_INIT_CHECK_DEEP_SHORT(ESMF_ArrayBundleGetInit, srcArrayBundle, rc)
    ESMF_INIT_CHECK_DEEP_SHORT(ESMF_ArrayBundleGetInit, dstArrayBundle, rc)
    
    ! Deal with ignoreUnmatchedIndicesFlag
    def_ignoreUnmatched(1) = .false.
    if (present(ignoreUnmatchedIndicesFlag)) then
      if (size(ignoreUnmatchedIndicesFlag)==0) then
        call ESMF_LogSetError(rcToCheck=ESMF_RC_ARG_SIZE, &
          msg="Size of 'ignoreUnmatchedIndicesFlag' argument must not be zero.",&
          ESMF_CONTEXT, rcToReturn=rc)
        return ! bail out
      endif
      allocate(opt_ignoreUnmatched(size(ignoreUnmatchedIndicesFlag)))
      opt_ignoreUnmatched(:) = ignoreUnmatchedIndicesFlag(:)
    else
      opt_ignoreUnmatched => def_ignoreUnmatched
    endif
    len_ignoreUnmatched = size(opt_ignoreUnmatched)

    ! Wrap srcTermProcessing argument
    srcTermProcessingArg = &
      ESMF_InterArrayCreate(srcTermProcessing, rc=localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return

    ! Call into the C++ interface, which will sort out optional arguments
    call c_ESMC_ArrayBundleSMMStoreNF(srcArrayBundle, dstArrayBundle, &
      routehandle, opt_ignoreUnmatched(1), len_ignoreUnmatched, &
      srcTermProcessingArg, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return
    
    ! Garbage collection
    if (present(ignoreUnmatchedIndicesFlag)) then
      deallocate(opt_ignoreUnmatched)
    endif

    ! Mark routehandle object as being created
    call ESMF_RouteHandleSetInitCreated(routehandle, localrc)
    if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
      ESMF_CONTEXT, rcToReturn=rc)) return
    
    ! return successfully
    if (present(rc)) rc = ESMF_SUCCESS

  end subroutine ESMF_ArrayBundleSMMStoreNF