subroutine ESMF_GridCompSetVMMaxThreads(gridcomp, keywordEnforcer, &
maxPetCountPerVas, prefIntraProcess, prefIntraSsi, prefInterSsi, &
pthreadMinStackSize, forceChildPthreads, rc)
!
! !ARGUMENTS:
type(ESMF_GridComp), intent(inout) :: gridcomp
type(ESMF_KeywordEnforcer), optional:: keywordEnforcer ! must use keywords below
integer, intent(in), optional :: maxPetCountPerVas
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\_GridComp}.
! Attempts to provide {\tt maxPetCountPerVas} threaded PETs in each
! virtual address space (VAS). Only as many threaded PETs as there are PEs
! located on the single system image (SSI) can be associated with the VAS.
! Within this constraint the call tries to get as close as possible to the
! number specified by {\tt maxPetCountPerVas}.
!
! The other constraint to this call is that the number of PETs is preserved.
! This means that the child Component in the end is associated with as many
! PETs as the parent Component provided to the child. The threading level of
! the child PETs however is adjusted according to the above rule.
!
! The typical use of {\tt ESMF\_GridCompSetVMMaxThreads()} is to run a
! Component multi-threaded with groups of PETs executing within a common
! virtual address space.
!
! The arguments are:
! \begin{description}
! \item[gridcomp]
! {\tt ESMF\_GridComp} to set the {\tt ESMF\_VM} for.
! \item[{[maxPetCountPerVas]}]
! Maximum number of threaded PETs in each virtual address space (VAS).
! 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 status
! 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_GridCompGetInit,gridcomp,rc)
! call Comp method
call ESMF_CompSetVMMaxThreads(gridcomp%compp, maxPetCountPerVas, &
prefIntraProcess, prefIntraSsi, prefInterSsi, pthreadMinStackSize, &
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_GridCompSetVMMaxThreads