API
Index
ThreadPinning.affinitymask2cpuids
ThreadPinning.core
ThreadPinning.cpuids_all
ThreadPinning.cpuids_per_core
ThreadPinning.cpuids_per_node
ThreadPinning.cpuids_per_numa
ThreadPinning.cpuids_per_socket
ThreadPinning.get_affinity_mask
ThreadPinning.get_cpuids_from_affinity_mask
ThreadPinning.getcpuid
ThreadPinning.getcpuid
ThreadPinning.getcpuids
ThreadPinning.getnumanode
ThreadPinning.getnumanode
ThreadPinning.getnumanodes
ThreadPinning.hyperthreading_is_enabled
ThreadPinning.ishyperthread
ThreadPinning.ispinned
ThreadPinning.ncores
ThreadPinning.ncores_per_numa
ThreadPinning.ncores_per_socket
ThreadPinning.ncputhreads
ThreadPinning.ncputhreads_per_core
ThreadPinning.ncputhreads_per_numa
ThreadPinning.ncputhreads_per_socket
ThreadPinning.nnuma
ThreadPinning.node
ThreadPinning.nsockets
ThreadPinning.numa
ThreadPinning.numas
ThreadPinning.pinthread
ThreadPinning.pinthread
ThreadPinning.pinthreads
ThreadPinning.pinthreads_mpi
ThreadPinning.print_affinity_mask
ThreadPinning.print_affinity_masks
ThreadPinning.setaffinity
ThreadPinning.setaffinity
ThreadPinning.socket
ThreadPinning.sockets
ThreadPinning.threadinfo
ThreadPinning.unpinthread
ThreadPinning.unpinthreads
ThreadPinning.with_pinthreads
References - Pinning
ThreadPinning.pinthread
— Methodpinthread(threadid::Integer, cpuid::Integer; kwargs...)
Pin a Julia thread to a specific CPU-thread.
ThreadPinning.pinthread
— Methodpinthread(cpuid::Integer; warn) -> Bool
Pin the calling Julia thread to the given CPU-thread.
ThreadPinning.pinthreads
— Functionpinthreads(cpuids[; nthreads, force=true, warn=first_pin_attempt(), threadpool=:default])
Pin the first min(length(cpuids), nthreads)
Julia threads to an explicit or implicit list of CPU IDs. The latter can be specified in three ways:
- explicitly (e.g.
0:3
or[0,12,4]
), - by passing one of several predefined symbols (e.g.
:cores
or:sockets
), - by providing a logical specification via helper functions (e.g.
node
andsocket
).
See below for more information.
If force=false
the pinthreads
call will only pin threads if this is the first attempt to pin threads with ThreadPinning.jl. Otherwise it will be a no-op. This may be particularly useful for packages that merely want to specify a "default pinning".
The option warn
toggles general warnings, such as unwanted interference with BLAS thread settings.
The keyword argument threadpool
can be used to indicate the pool of threads to be pinned. Supported values are :default
, :interactive
, or :all
. (Requires Julia >= 1.9.)
1) Explicit
Simply provide an AbstractVector{<:Integer}
of CPU IDs. The latter are expected to be the "physical" ids, i.e. as provided by lscpu
, and thus start at zero!
2) Predefined Symbols
:cputhreads
or:compact
: successively pin to all available CPU-threads.:cores
: spread threads across all available cores, only use hyperthreads if necessary.:sockets
: spread threads across sockets (round-robin), only use hyperthreads if necessary. Setcompact=true
to get compact pinning within each socket.:numa
: spread threads across NUMA/memory domains (round-robin), only use hyperthreads if necessary. Setcompact=true
to get compact pinning within each NUMA/memory domain.:random
: pin threads randomly to CPU-threads:current
: pin threads to the CPU-threads they are currently running on:firstn
: pin threads to CPU-threads in "physical" order (as specified by lscpu).:affinitymask
: pin threads to different CPU-threads in accordance with their affinity mask (must be the same for all of them). By default,hyperthreads_last=true
.
3) Logical Specification
The functions node
, socket
, numa
, and core
can be used to to specify CPU IDs of/within a certain domain. Moreover, the functions sockets
and numas
can be used to express a round-robin scatter policy between sockets or NUMA domains, respectively.
Examples (domains):
pinthreads(socket(1, 1:3))
# pin to the first 3 cores in the first socketpinthreads(socket(1, 1:3; compact=true))
# pin to the first 3 CPU-threads in the first socketpinthreads(numa(2, [2,4,6]))
# pin to the second, the fourth, and the sixth cores in the second NUMA/memory domainpinthreads(node(ncores():-1:1))
# pin threads to cores in reversing order (starting at the end of the node)pinthreads(sockets())
# scatter threads between sockets, cores before hyperthreads
Different domains can be concatenated by providing them in a vector or as separate arguments to pinthreads
.
Examples (concatenation):
pinthreads([socket(1, 1:3), numa(2, 4:6)])
pinthreads(socket(1, 1:3), numa(2, 4:6))
ThreadPinning.unpinthread
— Methodunpinthread(threadid)
Unpins the given Julia thread by setting the affinity mask to all unity. Afterwards, the OS is free to move the Julia thread from one CPU thread to another.
ThreadPinning.unpinthreads
— MethodUnpins all Julia threads by setting the affinity mask of all threads to all unity. Afterwards, the OS is free to move any Julia thread from one CPU thread to another.
ThreadPinning.with_pinthreads
— Methodwith_pinthreads(f, args; threadpool, soft, kwargs...)
Runs the function f
with the specified pinning and restores the previous thread affinities afterwards. Typically to be used in combination with do-syntax.
By default (soft=false
), before the thread affinities are restored, the Julia threads will be pinned to the CPU-threads they were running on previously.
Example
julia> getcpuids()
4-element Vector{Int64}:
7
75
63
4
julia> with_pinthreads(:cores) do
getcpuids()
end
4-element Vector{Int64}:
0
1
2
3
julia> getcpuids()
4-element Vector{Int64}:
7
75
63
4
ThreadPinning.pinthreads_mpi
— Methodpinthreads_mpi(symbol, rank, nranks; nthreads_per_rank, compact, kwargs...)
Pin MPI ranks, that is, their respective Julia thread(s), to (subsets of) domains (e.g. sockets or memory domains). Specifically, when calling this function on all MPI ranks, the latter will be distributed in a round-robin fashion among the specified domains such that their Julia threads are pinned to non-overlapping ranges of CPU-threads within the domain.
Valid options for symbol
are :sockets
and :numa
.
If compact=false
(default), physical cores are occupied before hyperthreads. Otherwise, CPU-cores - with potentially multiple CPU-threads - are filled up one after another (compact pinning).
The keyword argument nthreads_per_rank
(default Threads.nthreads()
) can be used to pin only a subset of the available Julia threads per MPI rank.
Note: As per usual for MPI, rank
starts at zero.
Example:
using ThreadPinning
using MPI
comm = MPI.COMM_WORLD
nranks = MPI.Comm_size(comm)
rank = MPI.Comm_rank(comm)
pinthreads_mpi(:sockets, rank, nranks)
ThreadPinning.setaffinity
— Methodsetaffinity(cpuids::AbstractVector{<:Integer})
Set the affinity of the calling Julia thread to the given CPU-threads.
Example:
setaffinity(socket(1))
# set the affinity to the first socketsetaffinity(numa(2))
# set the affinity to the second NUMA domainsetaffinity(socket(1, 1:3))
# set the affinity to the first three cores in the first NUMA domainsetaffinity([1,3,5])
# set the affinity to the CPU-threads with the IDs 1, 3, and 5.
ThreadPinning.setaffinity
— Methodsetaffinity(
threadid::Integer,
cpuids::AbstractVector{<:Integer};
kwargs...
)
Set the affinity of a specific Julia thread to the given CPU-threads.
References - Querying
ThreadPinning.affinitymask2cpuids
— MethodGet the CPU-thread IDs associated with the given affinity mask.
ThreadPinning.core
— Functioncore(i)
core(i, idcs; shuffle, kwargs...)
Represents the CPU ID domain of core i
(logical index, starts at 1). Uses compact ordering by default. Set shuffle=true
to randomize.
Optional second argument: Logical indices to select a subset of the domain.
To be used as input argument for pinthreads
. What it actually returns is an implementation detail!
ThreadPinning.cpuids_all
— MethodReturns a Vector{Int}
which lists all valid CPUIDs. There is no guarantee about the order except that it is the same as in lscpu
.
ThreadPinning.cpuids_per_core
— MethodReturns a Vector{Vector{Int}}
which indicates the CPUIDs associated with the available physical cores
ThreadPinning.cpuids_per_node
— Methodcpuids_per_node(; compact)
Returns a Vector{Int}
which indicates the CPUIDs associated with the available node. Physical cores come first. Set compact=true
to get compact ordering.
ThreadPinning.cpuids_per_numa
— Methodcpuids_per_numa(; compact)
Returns a Vector{Vector{Int}}
which indicates the CPUIDs associated with the available NUMA domains. Within each memory domain, physical cores come first. Set compact=true
to get compact ordering instead.
ThreadPinning.cpuids_per_socket
— Methodcpuids_per_socket(; compact)
Returns a Vector{Vector{Int}}
which indicates the CPUIDs associated with the available CPU sockets. Within each socket, physical cores come first. Set compact=true
to get compact ordering instead.
ThreadPinning.get_affinity_mask
— Functionget_affinity_mask()
get_affinity_mask(tid)
Get the affinity mask of the given Julia Thread
ThreadPinning.get_cpuids_from_affinity_mask
— Functionget_cpuids_from_affinity_mask()
get_cpuids_from_affinity_mask(tid)
Get the IDs of the CPU-threads associated with the affinity mask of the given Julia Thread
ThreadPinning.getcpuid
— Methodgetcpuid(threadid)
Returns the ID of the CPU thread on which the given Julia thread (threadid
) is currently running.
ThreadPinning.getcpuid
— MethodReturns the ID of the CPU thread on which the calling thread is currently running.
See sched_getcpu
for more information.
ThreadPinning.getcpuids
— MethodReturns the IDs of the CPU-threads on which the Julia threads are currently running.
See getcpuid
for more information.
ThreadPinning.getnumanode
— Methodgetnumanode(threadid)
Returns the ID (starting at zero) of the NUMA node corresponding to the CPU thread on which the given Julia thread (threadid
) is currently running.
ThreadPinning.getnumanode
— MethodReturns the ID (starting at zero) of the NUMA node corresponding to the CPU thread on which the calling thread is currently running.
ThreadPinning.getnumanodes
— MethodReturns the ID (starting at zero) of the NUMA nodes corresponding to the CPU threads on which the Julia threads are currently running.
ThreadPinning.hyperthreading_is_enabled
— MethodCheck whether hyperthreading is enabled.
ThreadPinning.ishyperthread
— Methodishyperthread(cpuid)
Check whether the given CPU-thread is a hyperthread (i.e. the second CPU-thread associated with a CPU-core).
ThreadPinning.ispinned
— FunctionReturns true
if the thread is pinned, i.e. if it has an affinity mask that comprises a single CPU-thread.
ThreadPinning.ncores
— MethodNumber of cores (i.e. excluding hyperthreads)
ThreadPinning.ncores_per_numa
— MethodNumber of CPU-cores per NUMA domain
ThreadPinning.ncores_per_socket
— MethodNumber of CPU-cores per socket
ThreadPinning.ncputhreads
— MethodNumber of CPU-threads
ThreadPinning.ncputhreads_per_core
— MethodNumber of CPU-threads per core
ThreadPinning.ncputhreads_per_numa
— MethodNumber of CPU-threads per NUMA domain
ThreadPinning.ncputhreads_per_socket
— MethodNumber of CPU-threads per socket
ThreadPinning.nnuma
— MethodNumber of NUMA nodes
ThreadPinning.node
— Functionnode()
node(idcs; shuffle, kwargs...)
Represents the CPU ID domain of the entire node/system. By default, cores will be used first and hyperthreads will only be used if necessary. Provide compact=true
to get compact ordering instead. Set shuffle=true
to randomize. Set shuffle=true
to randomize.
Optional first argument: Logical indices to select a subset of the domain.
To be used as input argument for pinthreads
. What it actually returns is an implementation detail!
ThreadPinning.nsockets
— MethodNumber of CPU sockets
ThreadPinning.numa
— Functionnuma(i)
numa(i, idcs; shuffle, kwargs...)
Represents the CPU ID domain of NUMA/memory domain i
(logical index, starts at 1). By default, cores will be used first and hyperthreads will only be used if necessary. Provide compact=true
to get compact ordering instead. Set shuffle=true
to randomize.
Optional second argument: Logical indices to select a subset of the domain.
To be used as input argument for pinthreads
. What it actually returns is an implementation detail!
ThreadPinning.numas
— Functionnumas()
numas(idcs; shuffle, kwargs...)
Represents the CPU IDs of the system as obtained by a round-robin scattering between NUMA/memory domain. By default, within each memory domain, cores will be used first and hyperthreads will only be used if necessary. Provide compact=true
to get compact ordering within each memory domain. Set shuffle=true
to randomize.
Optional first argument: Logical indices to select a subset of the domain.
To be used as input argument for pinthreads
. What it actually returns is an implementation detail!
ThreadPinning.print_affinity_mask
— Functionprint_affinity_mask()
print_affinity_mask(tid; io, kwargs...)
Print the affinity mask of a Julia thread.
ThreadPinning.print_affinity_masks
— Methodprint_affinity_masks(; threadpool, io, kwargs...)
Print the affinity masks of all Julia threads.
ThreadPinning.socket
— Functionsocket(i)
socket(i, idcs; shuffle, kwargs...)
Represents the CPU ID domain of socket i
(logical index, starts at 1). By default, cores will be used first and hyperthreads will only be used if necessary. Provide compact=true
to get compact ordering instead. Set shuffle=true
to randomize.
Optional second argument: Logical indices to select a subset of the domain.
To be used as input argument for pinthreads
. What it actually returns is an implementation detail!
ThreadPinning.sockets
— Functionsockets()
sockets(idcs; shuffle, kwargs...)
Represents the CPU IDs of the system as obtained by a round-robin scattering between sockets. By default, within each socket, cores will be used first and hyperthreads will only be used if necessary. Provide compact=true
to get compact ordering within each socket. Set shuffle=true
to randomize.
Optional first argument: Logical indices to select a subset of the domain.
To be used as input argument for pinthreads
. What it actually returns is an implementation detail!
ThreadPinning.threadinfo
— Functionthreadinfo()
threadinfo(
io;
blas,
hints,
color,
masks,
groupby,
threadpool,
slurm,
kwargs...
)
Print information about Julia threads, e.g. on which CPU-threads (i.e. cores if hyperthreading is disabled) they are running.
Keyword arguments:
color
(default:true
): Toggle between colored and black-and-white output.blocksize
(default:32
): Wrap to a new line afterblocksize
many CPU-threads.hyperthreading
(default:true
): Iftrue
, we (try to) highlight CPU-threads associated with hyperthreading in thecolor=true
output.blas
(default:false
): Show information about BLAS threads as well.slurm
(default:false
): Only show the part of the system that is covered by the active SLURM session.hints
(default:false
): Give some hints about how to improve the threading related settings.groupby
(default::sockets
): Options are:sockets
,:numa
,:cores
, or:none
.masks
(default:false
): Show the affinity masks of all Julia threads.threadpool
(default::default
): Only consider Julia threads in the given thread pool. Supported values are:default
,:interactive
, and:all
. Only works for Julia >= 1.9.