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