subroutine ESMF_Initialize(keywordEnforcer, configFilenameFromArgNum, &
configFilename, configKey, &
defaultDefaultCalKind, defaultCalKind, &
defaultDefaultLogFilename, defaultLogFilename, &
defaultLogAppendFlag, logAppendFlag, defaultLogKindFlag, logKindFlag, &
mpiCommunicator, ioUnitLBound, ioUnitUBound, &
defaultGlobalResourceControl, globalResourceControl, config, vm, rc)
!
! !ARGUMENTS:
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
integer, intent(in), optional :: configFilenameFromArgNum
character(len=*), intent(in), optional :: configFilename
character(len=*), intent(in), optional :: configKey(:)
type(ESMF_CalKind_Flag), intent(in), optional :: defaultDefaultCalKind
type(ESMF_CalKind_Flag), intent(in), optional :: defaultCalKind
character(len=*), intent(in), optional :: defaultDefaultLogFilename
character(len=*), intent(in), optional :: defaultLogFilename
logical, intent(in), optional :: defaultLogAppendFlag
logical, intent(in), optional :: logAppendFlag
type(ESMF_LogKind_Flag), intent(in), optional :: defaultLogKindFlag
type(ESMF_LogKind_Flag), intent(in), optional :: logKindFlag
integer, intent(in), optional :: mpiCommunicator
integer, intent(in), optional :: ioUnitLBound
integer, intent(in), optional :: ioUnitUBound
logical, intent(in), optional :: defaultGlobalResourceControl
logical, intent(in), optional :: globalResourceControl
type(ESMF_Config), intent(out), optional :: config
type(ESMF_VM), intent(out), optional :: vm
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 logAppendFlag} to allow specifying that the
! existing log files will be overwritten.
! \item[8.2.0] Added argument {\tt globalResourceControl} to support ESMF-aware
! threading and resource control on the global VM level.\newline
! Added argument {\tt config} to return default handle to the
! defaultConfig.\newline
! Renamed argument {\tt defaultConfigFilename} to
! {\tt configFilename}, in order to clarify that provided settings
! in the Config file are {\em not} defaults, but final
! overrides.\newline
! Introduce {\tt default} prefixed arguments:
! {\tt defaultDefaultLogFilename},
! {\tt defaultLogAppendFlag}, {\tt defaultLogKindFlag},
! {\tt defaultGlobalResourceControl}. These arguments allow
! specification of defaults for the associated settings. This
! default can be overridden via the associated argument, without
! the extra {\tt default} prefix, either specified in the call, or
! within the specified Config file.
! \item[8.5.0] Added argument {\tt configKey} to support custom location of the
! map of predefined initialization options for YAML
! configurations.\newline
! Added argument {\tt configFilenameFromArgNum} to support config
! file specification via the command line.
! \item[8.6.0] Added {\tt defaultDefaultCalKind} argument to allow specifiation
! of a default for {\tt defaultCalKind}.
! \end{description}
! \end{itemize}
!
! !DESCRIPTION:
! This method must be called once on each PET before
! any other ESMF methods are used. The method contains a
! barrier before returning, ensuring that all processes
! made it successfully through initialization.
!
! Typically {\tt ESMF\_Initialize()} will call {\tt MPI\_Init()}
! internally unless MPI has been initialized by the user code before
! initializing the framework. If the MPI initialization is left to
! {\tt ESMF\_Initialize()} it inherits all of the MPI implementation
! dependent limitations of what may or may not be done before
! {\tt MPI\_Init()}. For instance, it is unsafe for some MPI
! implementations, such as MPICH1, to do I/O before the MPI environment
! is initialized. Please consult the documentation of your MPI
! implementation for details.
!
! Note that when using MPICH1 as the MPI library, ESMF needs to use
! the application command line arguments for {\tt MPI\_Init()}. However,
! ESMF acquires these arguments internally and the user does not need
! to worry about providing them. Also, note that ESMF does not alter
! the command line arguments, so that if the user obtains them they will
! be as specified on the command line (including those which MPICH1 would
! normally strip out).
!
! {\tt ESMF\_Initialize()} supports running ESMF inside a user MPI program.
! Details of this feature are discussed under the VM example
! \ref{vm_inside_user_mpi}. It is not necessary that all MPI ranks are
! handed to ESMF. Section \ref{vm_nesting_esmf} shows how an MPI
! communicator can be used to execute ESMF on a subset of MPI ranks.
! {\tt ESMF\_Initialize()} supports running multiple concurrent
! instances of ESMF under the same user MPI program. This feature is
! discussed under \ref{vm_multi_instance_esmf}.
!
! In order to use any of the advanced resource management functions that
! ESMF provides via the {\tt ESMF\_*CompSetVM*()} methods, the MPI
! environment must be thread-safe. {\tt ESMF\_Initialize()} handles this
! automatically if it is in charge of initializing MPI. However, if the
! user code initializes MPI before calling into {\tt ESMF\_Initialize()},
! it must do so via {\tt MPI\_Init\_thread()}, specifying
! {\tt MPI\_THREAD\_SERIALIZED} or above for the required level of thread
! support.
!
! In cases where {\tt ESMF\_*CompSetVM*()} methods are used to move
! processing elements (PEs), i.e. CPU cores, between persistent execution
! threads (PETs), ESMF uses POSIX signals between PETs. In order to do so
! safely, the proper signal handlers must be installed {\em before} MPI is
! initialized. {\tt ESMF\_Initialize()} handles this automatically if it is
! in charge of initializing MPI. If, however, MPI is explicitly initialized
! by user code, then to ensure correct signal handling it is necessary to
! call {\tt ESMF\_InitializePreMPI()} from the user code prior to the MPI
! initialization.
!
! By default, {\tt ESMF\_Initialize()} opens multiple error log files,
! one per processor. This is very useful for debugging purpose. However,
! when running the application on a large number of tasks, opening a
! large number of log files and writing log messages from all the tasks
! can become a performance bottleneck. Therefore, it is recommended
! for production runs to set {\tt logKindFlag} to ESMF\_LOGKIND\_NONE, or
! {\tt ESMF\_LOGKIND\_Multi\_On\_Error}. The latter only creates log files
! when an error occurs.
!
! When integrating ESMF with applications where Fortran unit number conflicts
! exist, the optional {\tt ioUnitLBound} and {\tt ioUnitUBound} arguments may be
! used to specify an alternate unit number range. See section \ref{fio:unitnumbers}
! for more information on how ESMF uses Fortran unit numbers.
!
! Before exiting the application the user must call {\tt ESMF\_Finalize()}
! to release resources and clean up ESMF gracefully. See the
! {\tt ESMF\_Finalize()} documentation about details relating to the MPI
! environment.
!
! The arguments are:
! \begin{description}
! \item [{[configFilenameFromArgNum]}]
! Index of the command line argument specifying the config file
! name. If the specified command line argument does not exist, or
! {\tt configFilenameFromArgNum} was not specified, the
! {\tt configFilename} argument, if provided, is used by default.
! \item [{[configFilename]}]
! Name of the configuration file for the entire application.
! If this argument is specified, the configuration file must exist.
! Its content is read during {\tt ESMF\_Initialize()}, and
! returned in optional argument {\tt config} if present.
!
! The traditional {\tt ESMF\_Config} format and the YAML format
! are supported. The latter is identified by file suffix {\tt .yaml}
! and {\tt .yml}, including all lower/upper case letter combinations
! that map to either suffix.
!
! In the case of the traditional {\tt ESMF\_Config} format, the
! predefined labels of initialization options discussed below are
! expected on the top level of the configuration. The expected
! termination character for this case is a single colon following
! each label.
!
! For the YAML case, the predefined initialization option labels are
! expected as the keys of a map. If the optional argument
! {\tt configKey} is specified, it is used to locate this map. The
! map is expected as the terminal value of a succession of mappings:
! \begin{verbatim}
! configKey(1) :
! configKey(2) :
! ...
! configKey(size(configKey)) :
! {map of specified init options}
! \end{verbatim}
! By default, in the absence of argument {\tt configKey}, the top
! level itself is searched for a mapping of predefined labels,
! analogous to the traditional case.
!
! If any of the following predefined labels are found in the specified
! configuration file (as per the above defined rules), their
! {\em values} are used to set the associated {\tt ESMF\_Initialize()}
! argument, overriding any defaults.
! If the same argument is also specified in the
! {\tt ESMF\_Initialize()} call directly, an error is returned,
! and ESMF is not initialized.
! The supported config labels are:
! \begin{itemize}
! \item {\tt defaultCalKind}
! \item {\tt defaultLogFilename}
! \item {\tt logAppendFlag}
! \item {\tt logKindFlag}
! \item {\tt globalResourceControl}
! \end{itemize}
!
! ESMF allows the user to affect certain details about the execution
! of an application through a number of run-time environment variables.
! The following list of variables are checked within the specified
! configuration file. If a matching label is found, the respective
! value is set, potentially overriding the value defined within the
! user environment for the same variable.
! \begin{itemize}
! \item {\tt ESMF\_RUNTIME\_PROFILE}
! \item {\tt ESMF\_RUNTIME\_PROFILE\_OUTPUT}
! \item {\tt ESMF\_RUNTIME\_PROFILE\_PETLIST}
! \item {\tt ESMF\_RUNTIME\_TRACE}
! \item {\tt ESMF\_RUNTIME\_TRACE\_CLOCK}
! \item {\tt ESMF\_RUNTIME\_TRACE\_PETLIST}
! \item {\tt ESMF\_RUNTIME\_TRACE\_COMPONENT}
! \item {\tt ESMF\_RUNTIME\_TRACE\_FLUSH}
! \item {\tt ESMF\_RUNTIME\_COMPLIANCECHECK}
! \end{itemize}
! \item [{[configKey]}]
! If present, use {\tt configKey} to find the map of predefined
! initialization options that are used during ESMF initialization.
! The default is to search the top level of the configuration for the
! labels directly.
! The {\tt configKey} option is only supported for YAML configurations.
! An error is returned if {\tt configKey} is specified for the
! traditional {\tt ESMF\_Config} case.
! \item [{[defaultDefaultCalKind]}]
! Default value for argument {\tt defaultCalKind}, the calendar
! used by ESMF Time Manger by default.
! If not specified, defaults to {\tt ESMF\_CALKIND\_NOCALENDAR}.
! \item [{[defaultCalKind]}]
! Sets the default calendar to be used by ESMF Time Manager.
! See section \ref{const:calkindflag} for a list of valid options.
! If not specified,
! defaults according to {\tt defaultDefaultCalKind}.
! \item [{[defaultDefaultLogFilename]}]
! Default value for argument {\tt defaultLogFilename}, the name of
! the default log file for warning and error messages.
! If not specified, the default is {\tt ESMF\_LogFile}.
! \item [{[defaultLogFilename]}]
! Name of the default log file for warning and error messages.
! If not specified,
! defaults according to {\tt defaultDefaultLogFilename}.
! \item [{[defaultLogAppendFlag]}]
! Default value for argument {\tt logAppendFlag}, indicating the
! overwrite behavior in case the default log file already exists.
! If not specified, the default is {\tt .true.}.
! \item [{[logAppendFlag]}]
! If the default log file already exists, a value of {\tt .false.}
! will set the file position to the beginning of the file. A value
! of {\tt .true.} sets the position to the end of the file.
! If not specified,
! defaults according to {\tt defaultLogAppendFlag}.
! \item [{[defaultLogKindFlag]}]
! Default value for argument {\tt logKindFlag}, setting the LogKind
! of the default ESMF log.
! If not specified, the default is {\tt ESMF\_LOGKIND\_MULTI}.
! \item [{[logKindFlag]}]
! Sets the LogKind of the default ESMF log. See section
! \ref{const:logkindflag} for a list of valid options.
! If not specified,
! defaults according to {\tt defaultLogKindFlag}.
! \item [{[mpiCommunicator]}]
! MPI communicator defining the group of processes on which the
! ESMF application is running.
! See section \ref{vm_nesting_esmf} and \ref{vm_multi_instance_esmf}
! for details.
! If not specified, defaults to {\tt MPI\_COMM\_WORLD}.
! \item [{[ioUnitLBound]}]
! Lower bound for Fortran unit numbers used within the ESMF library.
! Fortran units are primarily used for log files. Legal unit numbers
! are positive integers. A value higher than 10 is recommended
! in order to avoid the compiler-specific
! reservations which are typically found on the first few units.
! If not specified, defaults to {\tt ESMF\_LOG\_FORT\_UNIT\_NUMBER},
! which is distributed with a value of 50.
! \item [{[ioUnitUBound]}]
! Upper bound for Fortran unit numbers used within the ESMF library.
! Must be set to a value at least 5 units higher than {\tt ioUnitLBound}.
! If not specified, defaults to {\tt ESMF\_LOG\_UPPER}, which is
! distributed with a value of 99.
! \item [{[defaultGlobalResourceControl]}]
! Default value for argument {\tt globalResourceControl}, indicating
! whether PETs of the global VM are pinned to PEs and the OpenMP
! threading level is reset.
! If not specified, the default is {\tt .false.}.
! \item [{[globalResourceControl]}]
! For {\tt .true.}, each global PET is pinned to the corresponding
! PE (i.e. CPU core) in order. Further, if OpenMP support is enabled
! for the ESMF installation (during build time), the
! {\tt OMP\_NUM\_THREADS} is set to {\tt 1} on every PET, regardless
! of the setting in the launching environment. The {\tt .true.}
! setting is recommended for applications that utilize the ESMF-aware
! threading and resource control features.
! For {\tt .false.}, global PETs are {\em not} pinned by ESMF, and
! {\tt OMP\_NUM\_THREADS} is {\em not} modified.
! If not specified,
! defaults according to {\tt defaultGlobalResourceControl}.
! \item [{[config]}]
! Returns the default {\tt ESMF\_Config} if the
! {\tt configFilename} argument was provided. Otherwise the
! presence of this argument triggers an error.
! \item [{[vm]}]
! Returns the global {\tt ESMF\_VM} that was created
! during initialization.
! \item [{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
!
! \end{description}
!EOP
integer :: localrc ! local return code
type(ESMF_VM) :: localvm
! assume failure until success
if (present(rc)) rc = ESMF_RC_NOT_IMPL
! initialize the framework
call ESMF_FrameworkInternalInit(lang=ESMF_MAIN_F90, &
configFilenameFromArgNum=configFilenameFromArgNum, &
configFilename=configFilename, configKey=configKey, &
defaultDefaultCalKind=defaultDefaultCalKind, &
defaultCalKind=defaultCalKind, &
defaultDefaultLogFilename=defaultDefaultLogFilename, &
defaultLogFilename=defaultLogFilename, &
defaultLogAppendFlag=defaultLogAppendFlag, &
logAppendFlag=logAppendFlag, &
defaultLogKindFlag=defaultLogKindFlag, logKindFlag=logKindFlag, &
mpiCommunicator=mpiCommunicator, &
ioUnitLBound=ioUnitLBound, ioUnitUBound=ioUnitUBound, &
defaultGlobalResourceControl=defaultGlobalResourceControl, &
globalResourceControl=globalResourceControl, &
config=config, rc=localrc)
! on failure LogErr is not initialized -> explicit print on error
if (localrc .ne. ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error initializing framework"
return
endif
! on success LogErr is assumed to be functioning
! obtain global VM
call ESMF_VMGetGlobal(localvm, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (present(vm)) vm=localvm
! block on all PETs
call ESMF_VMBarrier(localvm, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (present(rc)) rc = ESMF_SUCCESS
end subroutine ESMF_Initialize