! $Id$ ! ! Earth System Modeling Framework ! Copyright (c) 2002-2023, University Corporation for Atmospheric Research, ! Massachusetts Institute of Technology, Geophysical Fluid Dynamics ! Laboratory, University of Michigan, National Centers for Environmental ! Prediction, Los Alamos National Laboratory, Argonne National Laboratory, ! NASA Goddard Space Flight Center. ! Licensed under the University of Illinois-NCSA License. ! !============================================================================== ! #define ESMF_FILENAME "ESMF_FieldRedist.F90" ! ! ESMF Field Communications Redist module module ESMF_FieldRedistMod ! !============================================================================== ! ! !------------------------------------------------------------------------------ ! INCLUDES #include "ESMF.h" !------------------------------------------------------------------------------ ! !BOPI ! !MODULE: ESMF_FieldRedistMod - FieldRedist routines for Field objects ! ! !DESCRIPTION: ! The code in this file implements the {\tt ESMF\_FieldRedist} subroutine. ! !EOPI !------------------------------------------------------------------------------ ! !USES: use ESMF_UtilTypesMod use ESMF_InitMacrosMod use ESMF_LogErrMod use ESMF_VMMod use ESMF_FieldMod use ESMF_FieldGetMod use ESMF_ArrayMod use ESMF_RHandleMod implicit none private !------------------------------------------------------------------------------ ! !PRIVATE TYPES: ! <none> !------------------------------------------------------------------------------ ! !PUBLIC TYPES: ! <none> !------------------------------------------------------------------------------ ! ! !PUBLIC MEMBER FUNCTIONS: public ESMF_FieldRedistStore public ESMF_FieldRedist public ESMF_FieldRedistRelease ! !------------------------------------------------------------------------------ ! The following line turns the CVS identifier string into a printable variable. character(*), parameter, private :: version = & '$Id$' !------------------------------------------------------------------------------ interface ESMF_FieldRedistStore module procedure ESMF_FieldRedistStoreI4 module procedure ESMF_FieldRedistStoreI8 module procedure ESMF_FieldRedistStoreR4 module procedure ESMF_FieldRedistStoreR8 module procedure ESMF_FieldRedistStoreNF end interface !------------------------------------------------------------------------------ contains !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldRedist()" !BOP ! !IROUTINE: ESMF_FieldRedist - Execute a Field redistribution ! ! !INTERFACE: subroutine ESMF_FieldRedist(srcField, dstField, routehandle, keywordEnforcer, & checkflag, rc) ! ! !ARGUMENTS: type(ESMF_Field), intent(in),optional :: srcField type(ESMF_Field), intent(inout),optional :: dstField type(ESMF_RouteHandle), intent(inout) :: routehandle type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below logical, intent(in), optional :: checkflag integer, intent(out), optional :: rc ! ! ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \end{itemize} ! ! !DESCRIPTION: ! Execute a precomputed Field redistribution from {\tt srcField} to ! {\tt dstField}. ! Both {\tt srcField} and {\tt dstField} must match the respective Fields ! used during {\tt ESMF\_FieldRedistStore()} in {\em type}, {\em kind}, and ! memory layout of the {\em gridded} dimensions. However, the size, number, ! and index order of {\em ungridded} dimensions may be different. See section ! \ref{RH:Reusability} for a more detailed discussion of RouteHandle ! reusability. ! ! The {\tt srcField} and {\tt dstField} arguments are optional in support of ! the situation where {\tt srcField} and/or {\tt dstField} are not defined on ! all PETs. The {\tt srcField} and {\tt dstField} must be specified on those ! PETs that hold source or destination DEs, respectively, but may be omitted ! on all other PETs. PETs that hold neither source nor destination DEs may ! omit both arguments. ! ! It is erroneous to specify the identical Field object for {\tt srcField} and ! {\tt dstField} arguments. ! ! See {\tt ESMF\_FieldRedistStore()} on how to precompute ! {\tt routehandle}. ! ! This call is {\em collective} across the current VM. ! ! For examples and associated documentation regarding this method see Section ! \ref{sec:field:usage:redist_1dptr}. ! ! \begin{description} ! \item [{[srcField]}] ! {\tt ESMF\_Field} with source data. ! \item [{[dstField]}] ! {\tt ESMF\_Field} with destination data. ! \item [routehandle] ! Handle to the precomputed Route. ! \item [{[checkflag]}] ! If set to {\tt .TRUE.} the input Field pair will be checked for ! consistency with the precomputed operation provided by {\tt routehandle}. ! If set to {\tt .FALSE.} {\em (default)} only a very basic input check ! will be performed, leaving many inconsistencies undetected. Set ! {\tt checkflag} to {\tt .FALSE.} to achieve highest performance. ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !------------------------------------------------------------------------------ integer :: localrc ! local return code ! local variables to buffer optional arguments type(ESMF_Array) :: l_srcArray ! helper variable type(ESMF_Array) :: l_dstArray ! 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, deal with optional Field args ESMF_INIT_CHECK_DEEP(ESMF_RouteHandleGetInit, routehandle, rc) ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, srcField, rc) ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, dstField, rc) if (present(srcField)) then call ESMF_FieldGet(srcField, array=l_srcArray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return else call ESMF_ArraySetThisNull(l_srcArray, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif if (present(dstField)) then call ESMF_FieldGet(dstField, array=l_dstArray, rc=localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return else call ESMF_ArraySetThisNull(l_dstArray, localrc) if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return endif ! perform Field redist through internal array call ESMF_ArrayRedist(srcArray=l_srcArray, dstArray=l_dstArray, & routehandle=routehandle, checkflag=checkflag, 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_FieldRedist !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldRedistRelease()" !BOP ! !IROUTINE: ESMF_FieldRedistRelease - Release resources associated with Field redistribution ! ! !INTERFACE: subroutine ESMF_FieldRedistRelease(routehandle, keywordEnforcer, noGarbage, rc) ! ! !ARGUMENTS: type(ESMF_RouteHandle), intent(inout) :: routehandle type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below logical, intent(in), optional :: noGarbage integer, intent(out), optional :: rc ! ! ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \item\apiStatusModifiedSinceVersion{5.2.0r} ! \begin{description} ! \item[8.0.0] Added argument {\tt noGarbage}. ! The argument provides a mechanism to override the default garbage collection ! mechanism when destroying an ESMF object. ! \end{description} ! \end{itemize} ! ! !DESCRIPTION: ! Release resources associated with a Field redistribution. After this call ! {\tt routehandle} becomes invalid. ! ! \begin{description} ! \item [routehandle] ! Handle to the precomputed Route. ! \item[{[noGarbage]}] ! If set to {\tt .TRUE.} the object will be fully destroyed and removed ! from the ESMF garbage collection system. Note however that under this ! condition ESMF cannot protect against accessing the destroyed object ! through dangling aliases -- a situation which may lead to hard to debug ! application crashes. ! ! It is generally recommended to leave the {\tt noGarbage} argument ! set to {\tt .FALSE.} (the default), and to take advantage of the ESMF ! garbage collection system which will prevent problems with dangling ! aliases or incorrect sequences of destroy calls. However this level of ! support requires that a small remnant of the object is kept in memory ! past the destroy call. This can lead to an unexpected increase in memory ! consumption over the course of execution in applications that use ! temporary ESMF objects. For situations where the repeated creation and ! destruction of temporary objects leads to memory issues, it is ! recommended to call with {\tt noGarbage} set to {\tt .TRUE.}, fully ! removing the entire temporary object from memory. ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !------------------------------------------------------------------------------ integer :: localrc ! local return code ! 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(ESMF_RouteHandleGetInit, routehandle, rc) ! Call into the RouteHandle code call ESMF_RouteHandleRelease(routehandle, noGarbage=noGarbage, & 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_FieldRedistRelease !---------------------------------------------------------------------------- !BOP ! !IROUTINE: ESMF_FieldRedistStore - Precompute Field redistribution with a local factor argument ! ! !INTERFACE: ! ! Private name; call using ESMF_FieldRedistStore() ! subroutine ESMF_FieldRedistStore<type><kind>(srcField, dstField, & ! routehandle, factor, keywordEnforcer, srcToDstTransposeMap, & ! ignoreUnmatchedIndices, rc) ! ! !ARGUMENTS: ! type(ESMF_Field), intent(in) :: srcField ! type(ESMF_Field), intent(inout) :: dstField ! type(ESMF_RouteHandle), intent(inout) :: routehandle ! <type>(ESMF_KIND_<kind>), intent(in) :: factor ! type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below ! integer, intent(in), optional :: srcToDstTransposeMap(:) ! logical, intent(in), optional :: ignoreUnmatchedIndices ! integer, intent(out), optional :: rc ! ! ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \item\apiStatusModifiedSinceVersion{5.2.0r} ! \begin{description} ! \item[7.0.0] Added argument {\tt ignoreUnmatchedIndices} to support sparse ! matrices that contain elements with indices that do not have a ! match within the source or destination Array. ! \end{description} ! \end{itemize} ! ! !DESCRIPTION: ! \label{FieldRedistStoreTK} ! {\tt ESMF\_FieldRedistStore()} is a collective method across all PETs of the ! current Component. The interface of the method is overloaded, allowing ! -- in principle -- each PET to call into {\tt ESMF\_FieldRedistStore()} ! through a different entry point. Restrictions apply as to which combinations ! are sensible. All other combinations result in ESMF run time errors. The ! complete semantics of the {\tt ESMF\_FieldRedistStore()} method, as provided ! through the separate entry points shown in \ref{FieldRedistStoreTK} and ! \ref{FieldRedistStoreNF}, is described in the following paragraphs as a whole. ! ! Store a Field redistribution operation from {\tt srcField} to {\tt dstField}. ! Interface \ref{FieldRedistStoreTK} allows PETs to specify a {\tt factor} ! argument. PETs not specifying a {\tt factor} argument call into interface ! \ref{FieldRedistStoreNF}. If multiple PETs specify the {\tt factor} argument, ! its type and kind, as well as its value must match across all PETs. If none ! of the PETs specify a {\tt factor} argument the default will be a factor of ! 1. The resulting factor is applied to all of the source data during ! redistribution, allowing scaling of the data, e.g. for unit transformation. ! ! Both {\tt srcField} and {\tt dstField} are interpreted as sequentialized ! vectors. The sequence is defined by the order of DistGrid dimensions and the ! order of tiles within the DistGrid or by user-supplied arbitrary sequence ! indices. See section \ref{Array:SparseMatMul} for details on the definition ! of {\em sequence indices}. ! ! Source Field, destination Field, and the factor may be of different ! <type><kind>. Further, source and destination Fields may differ in shape, ! however, the number of elements must match. ! ! The default redistribution operation, when {\tt srcToDstTransposeMap} is not ! specified, corresponds to the identity mapping: each element of the ! sequentialized source Field is copied to the sequentialized ! destination Field element in order. ! ! \begin{sloppypar} ! If the {\tt srcToDstTransposeMap} argument is provided it must be identical ! across all PETs. The {\tt srcToDstTransposeMap} allows source and destination ! Field dimensions to be transposed during the redistribution. To support this ! option, the number of source and destination Field dimensions must be equal ! and the size of the associated dimensions must match. ! See section \ref{Array:Redist:TransposeMode} for more details about the ! use of the {\tt srcToDstTransposeMap} argument. ! \end{sloppypar} ! ! It is erroneous to specify the identical Field object for {\tt srcField} and ! {\tt dstField} arguments. ! ! The routine returns an {\tt ESMF\_RouteHandle} that can be used to call ! {\tt ESMF\_FieldRedist()} on any pair of Fields that matches ! {\tt srcField} and {\tt dstField} in {\em type}, {\em kind}, and ! memory layout of the {\em gridded} dimensions. However, the size, number, ! and index order of {\em ungridded} dimensions may be different. See section ! \ref{RH:Reusability} for a more detailed discussion of RouteHandle ! reusability. ! ! This method is overloaded for:\newline ! {\tt ESMF\_TYPEKIND\_I4}, {\tt ESMF\_TYPEKIND\_I8},\newline ! {\tt ESMF\_TYPEKIND\_R4}, {\tt ESMF\_TYPEKIND\_R8}. ! \newline ! ! This call is {\em collective} across the current VM. ! ! For examples and associated documentation regarding this method see Section ! \ref{sec:field:usage:redist_1dptr}. ! ! The arguments are: ! \begin{description} ! \item [srcField] ! {\tt ESMF\_Field} with source data. ! \item [dstField] ! {\tt ESMF\_Field} with destination data. The data in this Field may be ! destroyed by this call. ! \item [routehandle] ! Handle to the precomputed Route. ! \item [factor] ! Factor by which to multiply data. Default is 1. See full method ! description above for details on the interplay with other PETs. ! \item [{[srcToDstTransposeMap]}] ! A list with as many entries as there are dimensions in {\tt srcField}, or ! {\tt tileCount} times this many entries. ! Each entry maps the corresponding {\tt srcField} dimension against the ! specified {\tt dstField} dimension. Mixing distributed and ! undistributed dimensions is supported. ! Negative entries reverse the order of elements along the specified ! dimension when going from source to destination. ! When providing $rank \times tileCount$ elements in ! {\tt srcToDstTransposeMap}, each block of size {\tt rank} is associated ! with the corresponding tile (in order), and interpreted as the ! tile-specific transpose map. ! \item [{[ignoreUnmatchedIndices]}] ! A logical flag that affects the behavior for when not all elements match ! between the {\tt srcField} and {\tt dstField} side. The default setting ! is {\tt .false.}, indicating that it is an error when such a situation is ! encountered. Setting {\tt ignoreUnmatchedIndices} to {\tt .true.} ignores ! unmatched indices. ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !---------------------------------------------------------------------------- #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldRedistStoreI4" !BOPI ! !IROUTINE: ESMF_FieldRedistStore - Precompute Field redistribution ! ! !INTERFACE: ! Private name; call using ESMF_FieldRedistStore() subroutine ESMF_FieldRedistStoreI4(srcField, dstField, & routehandle, factor, keywordEnforcer, srcToDstTransposeMap, & ignoreUnmatchedIndices, rc) ! input arguments type(ESMF_Field), intent(in) :: srcField type(ESMF_Field), intent(inout) :: dstField type(ESMF_RouteHandle), intent(inout) :: routehandle integer(ESMF_KIND_I4), intent(in) :: factor type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: srcToDstTransposeMap(:) logical, intent(in), optional :: ignoreUnmatchedIndices integer, intent(out), optional :: rc !EOPI ! local variables as temporary input/output arguments ! internal local variables integer :: localrc type(ESMF_Array) :: srcArray, dstArray ! Initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if(present(rc)) rc = ESMF_RC_NOT_IMPL ! check variable: focus on field and farray ! rely on ArrayRedist to check the sanity of other variables ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, srcField, rc) ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, dstField, rc) ! Retrieve source and destination arrays. call ESMF_FieldGet(srcField, array=srcArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_FieldGet(dstField, array=dstArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! perform redist through array ! For performance consideration: ! Rely on ArrayRedist to perform sanity checking of the other parameters call ESMF_ArrayRedistStore(srcArray, dstArray, routehandle, factor, & srcToDstTransposeMap=srcToDstTransposeMap, & ignoreUnmatchedIndices=ignoreUnmatchedIndices, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_FieldRedistStoreI4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldRedistStoreI8" !BOPI ! !IROUTINE: ESMF_FieldRedistStore - Precompute Field redistribution ! ! !INTERFACE: ! Private name; call using ESMF_FieldRedistStore() subroutine ESMF_FieldRedistStoreI8(srcField, dstField, & routehandle, factor, keywordEnforcer, ignoreUnmatchedIndices, & srcToDstTransposeMap, rc) ! input arguments type(ESMF_Field), intent(in) :: srcField type(ESMF_Field), intent(inout) :: dstField type(ESMF_RouteHandle), intent(inout) :: routehandle integer(ESMF_KIND_I8), intent(in) :: factor type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: srcToDstTransposeMap(:) logical, intent(in), optional :: ignoreUnmatchedIndices integer, intent(out), optional :: rc !EOPI ! local variables as temporary input/output arguments ! internal local variables integer :: localrc type(ESMF_Array) :: srcArray, dstArray ! Initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if(present(rc)) rc = ESMF_RC_NOT_IMPL ! check variable: focus on field and farray ! rely on ArrayRedist to check the sanity of other variables ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, srcField, rc) ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, dstField, rc) ! Retrieve source and destination arrays. call ESMF_FieldGet(srcField, array=srcArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_FieldGet(dstField, array=dstArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! perform redist through array ! For performance consideration: ! Rely on ArrayRedist to perform sanity checking of the other parameters call ESMF_ArrayRedistStore(srcArray, dstArray, routehandle, factor, & srcToDstTransposeMap=srcToDstTransposeMap, & ignoreUnmatchedIndices=ignoreUnmatchedIndices, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_FieldRedistStoreI8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldRedistStoreR4" !BOPI ! !IROUTINE: ESMF_FieldRedistStore - Precompute Field redistribution ! ! !INTERFACE: ! Private name; call using ESMF_FieldRedistStore() subroutine ESMF_FieldRedistStoreR4(srcField, dstField, & routehandle, factor, keywordEnforcer, srcToDstTransposeMap, & ignoreUnmatchedIndices, rc) ! input arguments type(ESMF_Field), intent(in) :: srcField type(ESMF_Field), intent(inout) :: dstField type(ESMF_RouteHandle), intent(inout) :: routehandle real(ESMF_KIND_R4), intent(in) :: factor type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: srcToDstTransposeMap(:) logical, intent(in), optional :: ignoreUnmatchedIndices integer, intent(out), optional :: rc !EOPI ! local variables as temporary input/output arguments ! internal local variables integer :: localrc type(ESMF_Array) :: srcArray, dstArray ! Initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if(present(rc)) rc = ESMF_RC_NOT_IMPL ! check variable: focus on field and farray ! rely on ArrayRedist to check the sanity of other variables ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, srcField, rc) ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, dstField, rc) ! Retrieve source and destination arrays. call ESMF_FieldGet(srcField, array=srcArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_FieldGet(dstField, array=dstArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! perform redist through array ! For performance consideration: ! Rely on ArrayRedist to perform sanity checking of the other parameters call ESMF_ArrayRedistStore(srcArray, dstArray, routehandle, factor, & srcToDstTransposeMap=srcToDstTransposeMap, & ignoreUnmatchedIndices=ignoreUnmatchedIndices, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_FieldRedistStoreR4 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldRedistStoreR8" !BOPI ! !IROUTINE: ESMF_FieldRedistStore - Precompute Field redistribution ! ! !INTERFACE: ! Private name; call using ESMF_FieldRedistStore() subroutine ESMF_FieldRedistStoreR8(srcField, dstField, & routehandle, factor, keywordEnforcer, srcToDstTransposeMap, & ignoreUnmatchedIndices, rc) ! input arguments type(ESMF_Field), intent(in) :: srcField type(ESMF_Field), intent(inout) :: dstField type(ESMF_RouteHandle), intent(inout) :: routehandle real(ESMF_KIND_R8), intent(in) :: factor type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: srcToDstTransposeMap(:) logical, intent(in), optional :: ignoreUnmatchedIndices integer, intent(out), optional :: rc !EOPI ! local variables as temporary input/output arguments ! internal local variables integer :: localrc type(ESMF_Array) :: srcArray, dstArray ! Initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if(present(rc)) rc = ESMF_RC_NOT_IMPL ! check variable: focus on field and farray ! rely on ArrayRedist to check the sanity of other variables ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, srcField, rc) ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, dstField, rc) ! Retrieve source and destination arrays. call ESMF_FieldGet(srcField, array=srcArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_FieldGet(dstField, array=dstArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! perform redist through array ! For performance consideration: ! Rely on ArrayRedist to perform sanity checking of the other parameters call ESMF_ArrayRedistStore(srcArray, dstArray, routehandle, factor, & srcToDstTransposeMap=srcToDstTransposeMap, & ignoreUnmatchedIndices=ignoreUnmatchedIndices, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_FieldRedistStoreR8 !------------------------------------------------------------------------------ #undef ESMF_METHOD #define ESMF_METHOD "ESMF_FieldRedistStoreNF" !---------------------------------------------------------------------------- !BOP ! !IROUTINE: ESMF_FieldRedistStore - Precompute Field redistribution without a local factor argument ! ! !INTERFACE: ! ! Private name; call using ESMF_FieldRedistStore() subroutine ESMF_FieldRedistStoreNF(srcField, dstField, & routehandle, keywordEnforcer, srcToDstTransposeMap, & ignoreUnmatchedIndices, rc) ! ! !ARGUMENTS: type(ESMF_Field), intent(in) :: srcField type(ESMF_Field), intent(inout) :: dstField type(ESMF_RouteHandle), intent(inout) :: routehandle type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below integer, intent(in), optional :: srcToDstTransposeMap(:) logical, intent(in), optional :: ignoreUnmatchedIndices integer, intent(out), optional :: rc ! ! !STATUS: ! \begin{itemize} ! \item\apiStatusCompatibleVersion{5.2.0r} ! \end{itemize} ! ! !DESCRIPTION: ! ! \label{FieldRedistStoreNF} ! {\tt ESMF\_FieldRedistStore()} is a collective method across all PETs of the ! current Component. The interface of the method is overloaded, allowing ! -- in principle -- each PET to call into {\tt ESMF\_FieldRedistStore()} ! through a different entry point. Restrictions apply as to which combinations ! are sensible. All other combinations result in ESMF run time errors. The ! complete semantics of the {\tt ESMF\_FieldRedistStore()} method, as provided ! through the separate entry points shown in \ref{FieldRedistStoreTK} and ! \ref{FieldRedistStoreNF}, is described in the following paragraphs as a whole. ! ! Store a Field redistribution operation from {\tt srcField} to {\tt dstField}. ! Interface \ref{FieldRedistStoreTK} allows PETs to specify a {\tt factor} ! argument. PETs not specifying a {\tt factor} argument call into interface ! \ref{FieldRedistStoreNF}. If multiple PETs specify the {\tt factor} argument, ! its type and kind, as well as its value must match across all PETs. If none ! of the PETs specify a {\tt factor} argument the default will be a factor of ! 1. The resulting factor is applied to all of the source data during ! redistribution, allowing scaling of the data, e.g. for unit transformation. ! ! Both {\tt srcField} and {\tt dstField} are interpreted as sequentialized ! vectors. The sequence is defined by the order of DistGrid dimensions and the ! order of tiles within the DistGrid or by user-supplied arbitrary sequence ! indices. See section \ref{Array:SparseMatMul} for details on the definition ! of {\em sequence indices}. ! ! Source Field, destination Field, and the factor may be of different ! <type><kind>. Further, source and destination Fields may differ in shape, ! however, the number of elements must match. ! ! The default redistribution operation, when {\tt srcToDstTransposeMap} is not ! specified, corresponds to the identity mapping: each element of the ! sequentialized source Field is copied to the sequentialized ! destination Field element in order. ! ! \begin{sloppypar} ! If the {\tt srcToDstTransposeMap} argument is provided it must be identical ! across all PETs. The {\tt srcToDstTransposeMap} allows source and destination ! Field dimensions to be transposed during the redistribution. To support this ! option, the number of source and destination Field dimensions must be equal ! and the size of the associated dimensions must match. ! See section \ref{Array:Redist:TransposeMode} for more details about the ! use of the {\tt srcToDstTransposeMap} argument. ! \end{sloppypar} ! ! It is erroneous to specify the identical Field object for {\tt srcField} and ! {\tt dstField} arguments. ! ! The routine returns an {\tt ESMF\_RouteHandle} that can be used to call ! {\tt ESMF\_FieldRedist()} on any pair of Fields that matches ! {\tt srcField} and {\tt dstField} in {\em type}, {\em kind}, and ! memory layout of the {\em gridded} dimensions. However, the size, number, ! and index order of {\em ungridded} 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. ! ! For examples and associated documentation regarding this method see Section ! \ref{sec:field:usage:redist_1dptr}. ! ! The arguments are: ! \begin{description} ! \item [srcField] ! {\tt ESMF\_Field} with source data. ! \item [dstField] ! {\tt ESMF\_Field} with destination data. The data in this Field may be ! destroyed by this call. ! \item [routehandle] ! Handle to the precomputed Route. ! \item [{[srcToDstTransposeMap]}] ! A list with as many entries as there are dimensions in {\tt srcField}, or ! {\tt tileCount} times this many entries. ! Each entry maps the corresponding {\tt srcField} dimension against the ! specified {\tt dstField} dimension. Mixing distributed and ! undistributed dimensions is supported. ! Negative entries reverse the order of elements along the specified ! dimension when going from source to destination. ! When providing $rank \times tileCount$ elements in ! {\tt srcToDstTransposeMap}, each block of size {\tt rank} is associated ! with the corresponding tile (in order), and interpreted as the ! tile-specific transpose map. ! \item [{[ignoreUnmatchedIndices]}] ! A logical flag that affects the behavior for when not all elements match ! between the {\tt srcField} and {\tt dstField} side. The default setting ! is {\tt .false.}, indicating that it is an error when such a situation is ! encountered. Setting {\tt ignoreUnmatchedIndices} to {\tt .true.} ignores ! unmatched indices. ! \item [{[rc]}] ! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors. ! \end{description} ! !EOP !---------------------------------------------------------------------------- ! local variables as temporary input/output arguments ! internal local variables integer :: localrc type(ESMF_Array) :: srcArray, dstArray ! Initialize return code; assume routine not implemented localrc = ESMF_RC_NOT_IMPL if(present(rc)) rc = ESMF_RC_NOT_IMPL ! check variable: focus on field and farray ! rely on ArrayRedist to check the sanity of other variables ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, srcField, rc) ESMF_INIT_CHECK_DEEP(ESMF_FieldGetInit, dstField, rc) #define PROGRESSLOG_on #ifdef PROGRESSLOG_on call ESMF_LogWrite("ESMF_FieldRedistStoreNF(): Just entered routine.", ESMF_LOGMSG_INFO) #endif ! Retrieve source and destination arrays. call ESMF_FieldGet(srcField, array=srcArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return call ESMF_FieldGet(dstField, array=dstArray, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return ! perform redist through array ! For performance consideration: ! Rely on ArrayRedist to perform sanity checking of the other parameters call ESMF_ArrayRedistStore(srcArray, dstArray, routehandle, & srcToDstTransposeMap=srcToDstTransposeMap, & ignoreUnmatchedIndices=ignoreUnmatchedIndices, rc=localrc) if (ESMF_LogFoundError(localrc, & ESMF_ERR_PASSTHRU, & ESMF_CONTEXT, rcToReturn=rc)) return #ifdef PROGRESSLOG_on call ESMF_LogWrite("ESMF_FieldRedistStoreNF(): Leaving routine.", ESMF_LOGMSG_INFO) #endif if (present(rc)) rc = ESMF_SUCCESS end subroutine ESMF_FieldRedistStoreNF end module