subroutine ESMF_FrameworkInternalInit(lang, configFilenameFromArgNum, &
configFilename, configKey, &
defaultDefaultCalKind, defaultCalKind, &
defaultDefaultLogFilename, defaultLogFilename, &
defaultLogAppendFlag, logAppendFlag, defaultLogKindFlag, logKindFlag, &
mpiCommunicator, ioUnitLBound, ioUnitUBound, &
defaultGlobalResourceControl, globalResourceControl, config, rc)
!
! !ARGUMENTS:
integer, intent(in) :: lang
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
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! Initialize the ESMF framework.
!
! The arguments are:
! \begin{description}
! \item [lang]
! Flag to say whether main program is F90 or C++. Affects things
! related to initialization, such as starting MPI.
! \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 config file for the entire application.
! \item [{[configKey]}]
! Key associated with the the default label map for YAML configs.
! \item [{[defaultDefaultCalKind]}]
! Default value for argument {\tt defaultCalKind}.
! \item [{[defaultCalKind]}]
! Sets the default calendar to be used by ESMF Time Manager.
! If not specified, defaults to {\tt ESMF\_CALKIND\_NOCALENDAR}.
! \item [{[defaultDefaultLogFilename]}]
! Default value for argument {\tt defaultLogFilename}.
! \item [{[defaultLogFilename]}]
! Name of the default log file for warning and error messages.
! If not specified, defaults to {\tt ESMF\_LogFile}.
! \item [{[defaultLogAppendFlag]}]
! Default value for argument {\tt logAppendFlag}.
! \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 to {\tt .true.}.
! \item [{[defaultLogKindFlag]}]
! Default value for argument {\tt logKindFlag}.
! \item [{[logKindFlag]}]
! Sets the default Log Type to be used by ESMF Log Manager.
! If not specified, defaults to "ESMF\_LOGKIND\_MULTI".
! \item [{[mpiCommunicator]}]
! MPI communicator defining the group of processes on which the
! ESMF application is running.
! If not sepcified, 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.
! If not specified, defaults to {\tt ESMF\_LOG\_FORT\_UNIT\_NUMBER}
! \item [{[ioUnitUBound]}]
! Upper bound for Fortran unit numbers used within the ESMF library.
! If not specified, defaults to {\tt ESMF\_LOG\_UPPER}
! \item [{[defaultGlobalResourceControl]}]
! Default value for argument {\tt globalResourceControl}.
! \item [{[globalResourceControl]}]
! Global resource control enabled or disabled. Default {\tt .false.}.
! \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 [{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOPI
logical :: rcpresent ! Return code present
integer :: localrc
logical, save :: already_init = .false. ! Static, maintains state.
logical :: openflag, isPresent
integer :: complianceCheckIsOn
integer :: traceIsOn, profileIsOn, profileToLog
type(ESMF_VM) :: vm
integer :: localPet
character(ESMF_MAXPATHLEN) :: build_detail
character(16) :: build_date, build_time
integer :: detail_loc
character(ESMF_MAXSTR) :: errmsg
integer :: errmsg_l
type(ESMF_Config) :: configInternal
type(ESMF_HConfig) :: hconfig, hconfigNode, hconfigNodePrev
logical :: globalResourceControlSet, logAppendFlagSet
character(160) :: defaultLogFilenameSet, defaultLogFilenameS
character(:), allocatable :: stringAlloc
character(80) :: stringS, stringSU, stringSet
type(ESMF_LogKind_Flag) :: logKindFlagSet
type(ESMF_CalKind_Flag) :: defaultCalKindSet
character(ESMF_MAXSTR) :: configFilenameInternal
logical :: isFlag, validHConfigNode, haveConfig
integer :: i, argCount, configFilenameLength(1)
! Initialize return code
rcpresent = .FALSE.
if(present(rc)) then
rcpresent = .TRUE.
rc = ESMF_RC_NOT_IMPL
endif
if (already_init) then
if (rcpresent) rc = ESMF_SUCCESS
return
endif
! deal with API level defaulting
!
globalResourceControlSet = .false.
if (present(defaultGlobalResourceControl)) &
globalResourceControlSet = defaultGlobalResourceControl
if (present(globalResourceControl)) &
globalResourceControlSet = globalResourceControl
!
defaultLogFilenameSet = "ESMF_LogFile"
if (present(defaultDefaultLogFilename)) &
defaultLogFilenameSet = trim(defaultDefaultLogFilename)
if (present(defaultLogFilename)) &
defaultLogFilenameSet = trim(defaultLogFilename)
!
logAppendFlagSet = .true.
if (present(defaultLogAppendFlag)) &
logAppendFlagSet = defaultLogAppendFlag
if (present(logAppendFlag)) &
logAppendFlagSet = logAppendFlag
!
logKindFlagSet = ESMF_LOGKIND_MULTI
if (present(defaultLogKindFlag)) &
logKindFlagSet = defaultLogKindFlag
if (present(logKindFlag)) &
logKindFlagSet = logKindFlag
!
defaultCalKindSet = ESMF_CALKIND_NOCALENDAR
if (present(defaultDefaultCalKind)) &
defaultCalKindSet = defaultDefaultCalKind
if (present(defaultCalKind)) &
defaultCalKindSet = defaultCalKind
! If non-default Fortran unit numbers are to be used, set them
! prior to log files being created.
if (present (ioUnitLBound) .or. present (ioUnitUBound)) then
call ESMF_UtilIOUnitInit (lower=ioUnitLBound, upper=ioUnitUBound, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
if (rcpresent) rc = localrc
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error setting unit number bounds"
return
end if
end if
! Some compiler RTLs have a problem with flushing the unit used by
! various ESMF Print routines when nothing has been written on the unit.
! Intel 10.1.021 is an example, though the problem is fixed in later
! releases. Doing an inquire up front avoids the problem.
inquire (ESMF_UtilIOStdin, opened=openflag)
inquire (ESMF_UtilIOStdout, opened=openflag)
inquire (ESMF_UtilIOStderr, opened=openflag)
! Initialize the VM. This creates the GlobalVM.
! Note that if VMKernel threading is to be used ESMF_VMInitialize() _must_
! be called before any other mechanism calls MPI_Init. This is because
! MPI_Init() on some systems will spawn helper threads which might have
! signal handlers installed incompatible with VMKernel. Calling
! ESMF_VMInitialize() with an un-initialized MPI will install correct
! signal handlers _before_ possible helper threads are spawned by
! MPI_Init().
! If, however, VMKernel threading is not used, or ESMF_InitializePreMPI()
! has been called, it is fine to come in with a user initialized MPI,
! and thus we support this mode as well!
call ESMF_VMInitialize(mpiCommunicator=mpiCommunicator, rc=localrc)
! error handling without LogErr because it's not initialized yet
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error initializing VM"
return
endif
! deal with Config
haveConfig = .false.
if (present(configFilenameFromArgNum).or.present(configFilename)) &
then
! must initialize a temporary ESMF default log
call ESMF_LogInitialize("ESMF_LogFile", &
logKindFlag=ESMF_LOGKIND_MULTI_ON_ERROR, &
rc=localrc)
if (localrc /= ESMF_SUCCESS) then
call ESMF_LogRc2Msg (localrc, errmsg, errmsg_l)
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error LogInitialize() log file: ", errmsg(:errmsg_l)
return
endif
! get localPet
call ESMF_VMGetGlobal(vm, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_VMGet(vm, localPet=localPet, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (present(configFilenameFromArgNum)) then
! see if a configuration file was indeed specified through the argument
if (localPet==0) then
! arg access is only guaranteed on root pet
call ESMF_UtilGetArgC(count=argCount, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (configFilenameFromArgNum > argCount) then
! argument does not exist -> check into default
if (present(configFilename)) then
haveConfig = .true.
configFilenameInternal = trim(configFilename)
endif
else
! argument does exist -> use it
haveConfig = .true.
call ESMF_UtilGetArg(configFilenameFromArgNum, &
argvalue=configFilenameInternal, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
configFilenameLength(1) = 0
if (haveConfig) then
configFilenameLength(1) = len_trim(configFilenameInternal)
endif
endif
call ESMF_VMBroadcast(vm, bcstData=configFilenameLength, count=1, &
rootPet=0, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
haveConfig = .true.
if (configFilenameLength(1) == 0) haveConfig = .false.
if (haveConfig) then
call ESMF_VMBroadcast(vm, bcstData=configFilenameInternal, &
count=ESMF_MAXSTR, rootPet=0, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
endif
if (.not.haveConfig.and.present(configFilename)) then
haveConfig = .true.
configFilenameInternal = trim(configFilename)
endif
if (haveConfig) then
! have a default Config -> load and use it
! first must initialize a temporary ESMF default log
call ESMF_LogInitialize("ESMF_LogFile", &
logKindFlag=ESMF_LOGKIND_MULTI_ON_ERROR, &
rc=localrc)
if (localrc /= ESMF_SUCCESS) then
call ESMF_LogRc2Msg (localrc, errmsg, errmsg_l)
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error LogInitialize() log file: ", errmsg(:errmsg_l)
return
endif
! create the Config
configInternal = ESMF_ConfigCreate(rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! load config file
call ESMF_ConfigLoadFile(configInternal, trim(configFilenameInternal), &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! access hconfig
call ESMF_ConfigGet(configInternal, hconfig=hconfig, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
isFlag = ESMF_HConfigIsNull(hconfig, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
validHConfigNode = .false. ! not until found
! check for error conditions wrt configKey
if (present(configKey)) then
if (isFlag) then
! traditional config does not support this
call ESMF_LogSetError(ESMF_RC_ARG_INCOMP, &
msg="Cannot set 'configKey' argument for traditional config.", &
ESMF_CONTEXT, rcToReturn=rc)
return ! bail out
endif
! find the hconfigNode holding predefined label map
hconfigNode = ESMF_HConfigCreate(hconfig, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
validHConfigNode = .true.
do i=1, size(configKey)
isFlag = ESMF_HConfigIsMap(hconfigNode, keyString=configKey(i), &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (.not.isFlag) then
! configKey must be a map
validHConfigNode = .false.
call ESMF_HConfigDestroy(hconfigNode, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
exit ! break out of loop
endif
hconfigNodePrev = hconfigNode
hconfigNode = ESMF_HConfigCreateAt(hconfigNodePrev, &
keyString=configKey(i), rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
call ESMF_HConfigDestroy(hconfigNodePrev, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
enddo
endif
! globalResourceControl
if (validHConfigNode) then
isPresent = ESMF_HConfigIsDefined(hconfigNode, &
keyString="globalResourceControl", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (isPresent) then
isPresent = .not.ESMF_HConfigIsNull(hconfigNode, &
keyString="globalResourceControl", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
else
call ESMF_ConfigFindLabel(configInternal, &
label="globalResourceControl:", isPresent=isPresent, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (isPresent) then
if (present(globalResourceControl)) then
! both API and Config want to set -> error
call ESMF_LogSetError(ESMF_RC_ARG_INCOMP, &
msg="Cannot set 'globalResourceControl' from Config and API "//&
"at the same time.", ESMF_CONTEXT, rcToReturn=rc)
return ! bail out
endif
if (validHConfigNode) then
globalResourceControlSet = ESMF_HConfigAsLogical(hconfigNode, &
keyString="globalResourceControl", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else
call ESMF_ConfigGetAttribute(configInternal, &
globalResourceControlSet, label="globalResourceControl:", &
default=.false., rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
endif
! logKindFlag
if (validHConfigNode) then
isPresent = ESMF_HConfigIsDefined(hconfigNode, &
keyString="logKindFlag", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (isPresent) then
isPresent = .not.ESMF_HConfigIsNull(hconfigNode, &
keyString="logKindFlag", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
else
call ESMF_ConfigFindLabel(configInternal, &
label="logKindFlag:", isPresent=isPresent, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (isPresent) then
if (present(logKindFlag)) then
! both API and Config want to set -> error
call ESMF_LogSetError(ESMF_RC_ARG_INCOMP, &
msg="Cannot set 'logKindFlag' from Config and API "//&
"at the same time.", ESMF_CONTEXT, rcToReturn=rc)
return ! bail out
endif
if (validHConfigNode) then
stringAlloc = ESMF_HConfigAsString(hconfigNode, &
keyString="logKindFlag", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
stringSU = ESMF_UtilStringUpperCase(stringAlloc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else
call ESMF_ConfigGetAttribute(configInternal, stringS, &
label="logKindFlag:", default="---invalid---", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
stringSU = ESMF_UtilStringUpperCase(stringS, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (trim(stringSU)=="ESMF_LOGKIND_NONE") then
logKindFlagSet = ESMF_LOGKIND_NONE
else if (trim(stringSU)=="ESMF_LOGKIND_SINGLE") then
logKindFlagSet = ESMF_LOGKIND_SINGLE
else if (trim(stringSU)=="ESMF_LOGKIND_MULTI") then
logKindFlagSet = ESMF_LOGKIND_MULTI
else if (trim(stringSU)=="ESMF_LOGKIND_MULTI_ON_ERROR") then
logKindFlagSet = ESMF_LOGKIND_MULTI_ON_ERROR
endif
endif
! defaultCalKind
if (validHConfigNode) then
isPresent = ESMF_HConfigIsDefined(hconfigNode, &
keyString="defaultCalKind", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (isPresent) then
isPresent = .not.ESMF_HConfigIsNull(hconfigNode, &
keyString="defaultCalKind", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
else
call ESMF_ConfigFindLabel(configInternal, &
label="defaultCalKind:", isPresent=isPresent, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (isPresent) then
if (present(defaultCalKind)) then
! both API and Config want to set -> error
call ESMF_LogSetError(ESMF_RC_ARG_INCOMP, &
msg="Cannot set 'defaultCalKind' from Config and API "//&
"at the same time.", ESMF_CONTEXT, rcToReturn=rc)
return ! bail out
endif
if (validHConfigNode) then
stringAlloc = ESMF_HConfigAsString(hconfigNode, &
keyString="defaultCalKind", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
stringSU = ESMF_UtilStringUpperCase(stringAlloc, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else
call ESMF_ConfigGetAttribute(configInternal, stringS, &
label="defaultCalKind:", default="---invalid---", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
stringSU = ESMF_UtilStringUpperCase(stringS, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (trim(stringSU)=="ESMF_CALKIND_NOCALENDAR") then
defaultCalKindSet = ESMF_CALKIND_NOCALENDAR
else if (trim(stringSU)=="ESMF_CALKIND_360DAY") then
defaultCalKindSet = ESMF_CALKIND_360DAY
else if (trim(stringSU)=="ESMF_CALKIND_CUSTOM") then
defaultCalKindSet = ESMF_CALKIND_CUSTOM
else if (trim(stringSU)=="ESMF_CALKIND_GREGORIAN") then
defaultCalKindSet = ESMF_CALKIND_GREGORIAN
else if (trim(stringSU)=="ESMF_CALKIND_JULIAN") then
defaultCalKindSet = ESMF_CALKIND_JULIAN
else if (trim(stringSU)=="ESMF_CALKIND_JULIANDAY") then
defaultCalKindSet = ESMF_CALKIND_JULIANDAY
else if (trim(stringSU)=="ESMF_CALKIND_MODJULIANDAY") then
defaultCalKindSet = ESMF_CALKIND_MODJULIANDAY
else if (trim(stringSU)=="ESMF_CALKIND_NOLEAP") then
defaultCalKindSet = ESMF_CALKIND_NOLEAP
endif
endif
! defaultLogFilename
if (validHConfigNode) then
isPresent = ESMF_HConfigIsDefined(hconfigNode, &
keyString="defaultLogFilename", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (isPresent) then
isPresent = .not.ESMF_HConfigIsNull(hconfigNode, &
keyString="defaultLogFilename", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
else
call ESMF_ConfigFindLabel(configInternal, &
label="defaultLogFilename:", isPresent=isPresent, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (isPresent) then
if (present(defaultLogFilename)) then
! both API and Config want to set -> error
call ESMF_LogSetError(ESMF_RC_ARG_INCOMP, &
msg="Cannot set 'defaultLogFilename' from Config and API "//&
"at the same time.", ESMF_CONTEXT, rcToReturn=rc)
return ! bail out
endif
if (validHConfigNode) then
stringAlloc = ESMF_HConfigAsString(hconfigNode, &
keyString="defaultLogFilename", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
defaultLogFilenameSet = trim(stringAlloc)
else
call ESMF_ConfigGetAttribute(configInternal, defaultLogFilenameS, &
label="defaultLogFilename:", default="---invalid---", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (trim(defaultLogFilenameS)/="---invalid---") then
defaultLogFilenameSet = trim(defaultLogFilenameS)
endif
endif
endif
! logAppendFlag
if (validHConfigNode) then
isPresent = ESMF_HConfigIsDefined(hconfigNode, &
keyString="logAppendFlag", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (isPresent) then
isPresent = .not.ESMF_HConfigIsNull(hconfigNode, &
keyString="logAppendFlag", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
else
call ESMF_ConfigFindLabel(configInternal, &
label="logAppendFlag:", isPresent=isPresent, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (isPresent) then
if (present(logAppendFlag)) then
! both API and Config want to set -> error
call ESMF_LogSetError(ESMF_RC_ARG_INCOMP, &
msg="Cannot set 'logAppendFlag' from Config and API "//&
"at the same time.", ESMF_CONTEXT, rcToReturn=rc)
return ! bail out
endif
if (validHConfigNode) then
logAppendFlagSet = ESMF_HConfigAsLogical(hconfigNode, &
keyString="logAppendFlag", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else
call ESMF_ConfigGetAttribute(configInternal, &
logAppendFlagSet, label="logAppendFlag:", &
default=.true., rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
endif
endif ! have a default Config
if (present(configFilenameFromArgNum).or.present(configFilename)) &
then
! must shut down temporary Log
call ESMF_LogFinalize(rc=localrc)
if (localrc /= ESMF_SUCCESS) then
call ESMF_LogRc2Msg (localrc, errmsg, errmsg_l)
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error finalizing log file: ", errmsg(:errmsg_l)
return
endif
endif
! set global VM resource control
call ESMF_VMSet(globalResourceControl=globalResourceControlSet, &
rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
! Initialize ESMF default log
call ESMF_LogInitialize(trim(defaultLogFilenameSet), &
logAppendFlag=logAppendFlagSet, logKindFlag=logKindFlagSet, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error initializing the default log/error manager"
return
endif
! Write out warning about performance impact of logging
if ((logKindFlagSet/=ESMF_LOGKIND_NONE) .and. &
(logKindFlagSet/=ESMF_LOGKIND_MULTI_ON_ERROR)) then
call ESMF_LogWrite(&
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error writing into the default log"
return
endif
call ESMF_LogWrite( &
"!!! THE ESMF_LOG IS SET TO OUTPUT ALL LOG MESSAGES !!!", &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error writing into the default log"
return
endif
call ESMF_LogWrite( &
"!!! THIS MAY CAUSE SLOWDOWN IN PERFORMANCE !!!", &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error writing into the default log"
return
endif
call ESMF_LogWrite( &
"!!! FOR PRODUCTION RUNS, USE: !!!", &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error writing into the default log"
return
endif
call ESMF_LogWrite( &
"!!! ESMF_LOGKIND_Multi_On_Error !!!", &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error writing into the default log"
return
endif
call ESMF_LogWrite(&
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error writing into the default log"
return
endif
endif
! Write our version number, build location, and other details to the log
#ifdef ESMF_VERSION_STRING_GIT
call ESMF_LogWrite(&
"Running with ESMF Version : " // ESMF_VERSION_STRING_GIT, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
#else
call ESMF_LogWrite(&
"Running with ESMF Version : " // ESMF_VERSION_STRING, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
#endif
call c_esmc_initget_build_datetime (build_date, build_time, localrc)
call ESMF_LogWrite(&
"ESMF library build date/time: " // trim (build_date) // ' ' // build_time, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
call c_esmc_initget_esmf_dir (build_detail, localrc)
call ESMF_LogWrite(&
"ESMF library build location : " // build_detail, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
call c_esmc_initget_esmf_comm (build_detail, localrc)
call ESMF_LogWrite(&
"ESMF_COMM : " // build_detail, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
#if defined (ESMF_MOAB)
build_detail = 'enabled'
#else
build_detail = 'disabled'
#endif
call ESMF_LogWrite(&
"ESMF_MOAB : " // build_detail, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
#if defined (ESMF_LAPACK)
build_detail = 'enabled'
#else
build_detail = 'disabled'
#endif
call ESMF_LogWrite(&
"ESMF_LAPACK : " // build_detail, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
#if defined (ESMF_NETCDF)
build_detail = 'enabled'
#else
build_detail = 'disabled'
#endif
call ESMF_LogWrite(&
"ESMF_NETCDF : " // build_detail, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
#if defined (ESMF_PNETCDF)
build_detail = 'enabled'
#else
build_detail = 'disabled'
#endif
call ESMF_LogWrite(&
"ESMF_PNETCDF : " // build_detail, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
#if defined (ESMF_PIO)
build_detail = 'enabled'
#else
build_detail = 'disabled'
#endif
call ESMF_LogWrite(&
"ESMF_PIO : " // build_detail, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
#if defined (ESMF_YAMLCPP)
build_detail = 'enabled'
#else
build_detail = 'disabled'
#endif
call ESMF_LogWrite(&
"ESMF_YAMLCPP : " // build_detail, &
ESMF_LOGMSG_INFO, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error writing into the default log"
return
endif
! Ensure that at least the version number makes it into the log
call ESMF_LogFlush(rc=localrc)
if (haveConfig) then
! Ingest ESMF_RUNTIME_* settings from config -> possibly override environment
call ingest_environment_variable("ESMF_RUNTIME_PROFILE")
call ingest_environment_variable("ESMF_RUNTIME_PROFILE_OUTPUT")
call ingest_environment_variable("ESMF_RUNTIME_PROFILE_PETLIST")
call ingest_environment_variable("ESMF_RUNTIME_TRACE")
call ingest_environment_variable("ESMF_RUNTIME_TRACE_CLOCK")
call ingest_environment_variable("ESMF_RUNTIME_TRACE_PETLIST")
call ingest_environment_variable("ESMF_RUNTIME_TRACE_COMPONENT")
call ingest_environment_variable("ESMF_RUNTIME_TRACE_FLUSH")
call ingest_environment_variable("ESMF_RUNTIME_COMPLIANCECHECK")
! optionally destroy the HConfigNode
if (validHConfigNode) then
call ESMF_HConfigDestroy(hconfigNode, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
! optionally destroy the Config
if (.not.present(config)) then
call ESMF_ConfigDestroy(configInternal, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
else
config = configInternal ! return back to user
endif
endif
! if compliance checker is on, we want logs to have high precision timestamps
call c_esmc_getComplianceCheckJSON(complianceCheckIsOn, localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error checking ESMF_RUNTIME_COMPLIANCECHECK env variable"
return
endif
if (complianceCheckIsOn == 1) then
call ESMF_LogSet(highResTimestampFlag=.true., rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error setting default log option: highResTimestampFlag"
return
endif
endif
! check if tracing is on
call c_esmc_getComplianceCheckTrace(traceIsOn, profileIsOn, localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error checking ESMF_RUNTIME_* env variables"
return
endif
if (traceIsOn == 1 .or. profileIsOn == 1) then
profileToLog = 0
if ((logKindFlagSet/=ESMF_LOGKIND_NONE) .and. &
(logKindFlagSet/=ESMF_LOGKIND_MULTI_ON_ERROR)) then
profileToLog = 1
endif
call ESMF_TraceOpen("./traceout", profileToLog=profileToLog, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, ": Error initializing trace stream"
return
endif
endif
! Initialize the default time manager calendar
call ESMF_CalendarInitialize(calkindflag=defaultCalKindSet, rc=localrc)
if (localrc /= ESMF_SUCCESS) then
write (ESMF_UtilIOStderr,*) ESMF_METHOD, &
": Error initializing the default time manager calendar"
return
endif
! in case we need to know what the language was for main, we have it.
! right now we do not make use of it for anything.
if (lang .eq. ESMF_MAIN_C) then
continue
else if (lang .eq. ESMF_MAIN_F90) then
continue
else
continue
endif
already_init = .true.
if (.not.haveConfig.and.present(config)) then
call ESMF_LogSetError(ESMF_RC_ARG_INCOMP, &
msg="Cannot request 'config' without identifying "// &
"a valid config file", &
ESMF_CONTEXT, rcToReturn=rc)
return ! bail out
endif
if (rcpresent) rc = ESMF_SUCCESS
contains
subroutine ingest_environment_variable(env_var_name)
character(*), intent(in) :: env_var_name
if (validHConfigNode) then
isPresent = ESMF_HConfigIsDefined(hconfigNode, &
keyString=env_var_name, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (isPresent) then
isPresent = .not.ESMF_HConfigIsNull(hconfigNode, &
keyString=env_var_name, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
else
call ESMF_ConfigFindLabel(configInternal, &
label="ESMF_RUNTIME_PROFILE:", isPresent=isPresent, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
if (isPresent) then
if (validHConfigNode) then
stringAlloc = ESMF_HConfigAsString(hconfigNode, &
keyString=env_var_name, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
stringSet = trim(stringAlloc)
else
call ESMF_ConfigGetAttribute(configInternal, stringS, &
label="defaultLogFilename:", default="---invalid---", rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
if (trim(stringS)/="---invalid---") then
stringSet = trim(stringS)
endif
endif
call ESMF_VMSetEnv(env_var_name, stringSet, rc=localrc)
if (ESMF_LogFoundError(localrc, ESMF_ERR_PASSTHRU, &
ESMF_CONTEXT, rcToReturn=rc)) return
endif
end subroutine
end subroutine ESMF_FrameworkInternalInit