subroutine ESMF_CplCompSetVMMaxPEs(cplcomp, keywordEnforcer, &
maxPeCountPerPet, prefIntraProcess, prefIntraSsi, prefInterSsi, &
pthreadMinStackSize, forceChildPthreads, rc)
!
! !ARGUMENTS:
type(ESMF_CplComp), intent(inout) :: cplcomp
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
integer, intent(in), optional :: maxPeCountPerPet
integer, intent(in), optional :: prefIntraProcess
integer, intent(in), optional :: prefIntraSsi
integer, intent(in), optional :: prefInterSsi
integer, intent(in), optional :: pthreadMinStackSize
logical, intent(in), optional :: forceChildPthreads
integer, intent(out), optional :: rc
!
! !DESCRIPTION:
! Set characteristics of the {\tt ESMF\_VM} for this {\tt ESMF\_CplComp}.
! Attempts to associate up to {\tt maxPeCountPerPet} PEs with each PET. Only
! PEs that are located on the same single system image (SSI) can be associated
! with the same PET. Within this constraint the call tries to get as close as
! possible to the number specified by {\tt maxPeCountPerPet}.
!
! The other constraint to this call is that the number of PEs is preserved.
! This means that the child Component in the end is associated with as many
! PEs as the parent Component provided to the child. The number of child PETs
! however is adjusted according to the above rule.
!
! The typical use of {\tt ESMF\_CplCompSetVMMaxPEs()} is to allocate
! multiple PEs per PET in a Component for user-level threading, e.g. OpenMP.
!
! The arguments are:
! \begin{description}
! \item[cplcomp]
! {\tt ESMF\_CplComp} to set the {\tt ESMF\_VM} for.
! \item[{[maxPeCountPerPet]}]
! Maximum number of PEs on each PET.
! Default for each SSI is the local number of PEs.
! \item[{[prefIntraProcess]}]
! Communication preference within a single process.
! {\em Currently options not documented. Use default.}
! \item[{[prefIntraSsi]}]
! Communication preference within a single system image (SSI).
! {\em Currently options not documented. Use default.}
! \item[{[prefInterSsi]}]
! Communication preference between different single system images (SSIs).
! {\em Currently options not documented. Use default.}
! \item[{[pthreadMinStackSize]}]
! Minimum stack size in byte of any child PET executing as Pthread. By default
! single threaded child PETs do {\em not} execute as Pthread, and their stack
! size is unaffected by this argument. However, for multi-threaded child PETs,
! or if {\tt forceChildPthreads} is {\tt .true.}, child PETs execute
! as Pthreads with their own private stack.
!
! For cases where OpenMP threads
! are used by the user code, each thread allocates its own private stack. For
! all threads {\em other} than the master, the stack size is set via the
! typical {\tt OMP\_STACKSIZE} environment variable mechanism. The PET itself,
! however, becomes the {\em master} of the OpenMP thread team, and is not
! affected by {\tt OMP\_STACKSIZE}. It is the master's stack that can be
! sized via the {\tt pthreadMinStackSize} argument, and a large enough size
! is often critical.
!
! When {\tt pthreadMinStackSize}
! is absent, the default is to use the system default
! set by the {\tt limit} or {\tt ulimit} command. However, the stack of a
! Pthread cannot be unlimited, and a shell {\em stacksize} setting of
! {\em unlimited}, or any setting below the ESMF implemented minimum,
! will result in setting the stack size to 20MiB (the ESMF minimum).
! Depending on how much private data is used by the user code under
! the master thread, the default might be too small, and
! {\tt pthreadMinStackSize} must be used to allocate sufficient stack space.
! \item[{[forceChildPthreads]}]
! For {\tt .true.}, force each child PET to execute in its own Pthread.
! By default, {\tt .false.}, single PETs spawned from a parent PET
! execute in the same thread (or MPI process) as the parent PET. Multiple
! child PETs spawned by the same parent PET always execute as their own
! Pthreads.
! \item[{[rc]}]
! Return code; equals {\tt ESMF\_SUCCESS} if there are no errors.
! \end{description}
!
!EOP
!------------------------------------------------------------------------------
integer :: localrc ! local error localrc
! initialize return code; assume routine not implemented
if (present(rc)) rc = ESMF_RC_NOT_IMPL
localrc = ESMF_RC_NOT_IMPL
ESMF_INIT_CHECK_DEEP(ESMF_CplCompGetInit,cplcomp,rc)
! call Comp method
call ESMF_CompSetVMMaxPEs(cplcomp%compp, maxPeCountPerPet, &
prefIntraProcess, prefIntraSsi, prefInterSsi, pthreadMinStackSize, &
forceChildPthreads=forceChildPthreads, 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_CplCompSetVMMaxPEs