Table of Contents

Class TensorEngine.Threading

Namespace
NumSharp
Assembly
NumSharp.dll

Process-wide threading configuration — one named, environment-variable-backed knob per threading domain (NumSharp's own kernels, and the native BLAS / OpenMP runtimes NumPy and the rest of the ecosystem thread through: OpenBLAS, MKL, BLIS, NumExpr, vecLib). It is the single surface for reading and setting them, and it is extensible per module: a module registers (or upgrades) its own knob via Register(string, string, Func<int?>, Action<int?>) — that is how NumSharp.Interop.OpenBLAS attaches a native applier to the OpenBlas knob so a change reaches the loaded library, and how any future backend adds its own.

public static class TensorEngine.Threading
Inheritance
TensorEngine.Threading
Inherited Members

Remarks

Two invariants govern every knob.

1. Source of truth. A variable already present in the environment when the knob is first observed is authoritative: its value seeds the knob (IsEnvSourced becomes true) and is pushed to the knob's applier. A module-supplied default never overwrites it (see TrySetDefault(string, int?)). An explicit SetThreads(string, int?) / SetAll(int) is a deliberate in-process override and does take effect.

2. Writes only apply to the process. Every write this class performs targets Process — the caller's persistent (User / Machine) environment is never modified.

Reaching a native runtime. Core is 100 % managed and can only write the managed process-env table. A native library reads a variable through its own C runtime's getenv, which a managed write does NOT reach (documented on OpenBlasEngine); and most native BLAS read their *_NUM_THREADS variable once, at load. So for the native knobs the Core write is a best-effort managed-table update for diagnostics and child processes; the value only takes hold in the running library when a module has registered an applier that pushes it there (through the CRT and the runtime's own set-thread-count call).

Fields

Blis

BLIS (BLIS_NUM_THREADS).

public const string Blis = "BLIS"

Field Value

string

Mkl

Intel MKL (MKL_NUM_THREADS).

public const string Mkl = "MKL"

Field Value

string

NumExpr

NumExpr (NUMEXPR_NUM_THREADS).

public const string NumExpr = "NumExpr"

Field Value

string

NumSharp

NumSharp's own multithreaded kernels — the knob whose value is MaxThreads. Enabling/disabling those kernels is the companion NUMSHARP_MULTITHREADING / multithreading(bool, int) switch on Enabled — a bool, not a thread count, so it is not a knob here.

public const string NumSharp = "NumSharp"

Field Value

string

OpenBlas

OpenBLAS (OPENBLAS_NUM_THREADS). Core only touches the managed env table; referencing NumSharp.Interop.OpenBLAS upgrades this knob with a native applier.

public const string OpenBlas = "OpenBLAS"

Field Value

string

OpenMp

OpenMP (OMP_NUM_THREADS) — the threading layer inside OpenBLAS / MKL / BLIS.

public const string OpenMp = "OpenMP"

Field Value

string

VecLib

Apple Accelerate / vecLib (VECLIB_MAXIMUM_THREADS).

public const string VecLib = "vecLib"

Field Value

string

Properties

Variables

A snapshot of every registered knob.

public static IReadOnlyList<TensorEngine.Threading.Variable> Variables { get; }

Property Value

IReadOnlyList<TensorEngine.Threading.Variable>

Methods

Get(string)

The registered knob named name.

public static TensorEngine.Threading.Variable Get(string name)

Parameters

name string

Returns

TensorEngine.Threading.Variable

Exceptions

ArgumentException

No knob of that name is registered.

GetThreads(string)

The current thread count of name (null when unset / auto).

public static int? GetThreads(string name)

Parameters

name string

Returns

int?

Register(string, string, Func<int?>, Action<int?>)

Registers a threading knob, or upgrades an existing one of the same name (this is the per-module extension point — a module attaches its reader / applier to a knob Core already declared). A non-null argument replaces that facet; a null one leaves it unchanged.

public static TensorEngine.Threading.Variable Register(string name, string envVar = null, Func<int?> reader = null, Action<int?> applier = null)

Parameters

name string

Logical knob name (one of the constants above, or a module's own).

envVar string

Backing environment variable, or null for a value with no env backing.

reader Func<int?>

Live value source. When set, Threads returns reader() — used to bind a knob to live state (e.g. the managed MaxThreads, or a native openblas_get_num_threads()) instead of the cached value.

applier Action<int?>

Invoked after every value change (and once, at registration, with a source-of-truth env value) to push the count where it takes effect — a managed field, a native set_num_threads, the CRT env, etc.

Returns

TensorEngine.Threading.Variable

The registered (or upgraded) knob.

SetAll(int)

Sets every registered knob to threads — a deliberate override of all (e.g. pin the whole process to one thread). Process-scoped writes, per knob.

public static void SetAll(int threads)

Parameters

threads int

SetThreads(string, int?)

Sets name to threads — a deliberate in-process override. Writes the backing env var (process scope only), records the value, and runs the applier. Passing null clears the env var / requests auto.

public static void SetThreads(string name, int? threads)

Parameters

name string
threads int?

TryGet(string, out Variable)

The knob named name, if one is registered.

public static bool TryGet(string name, out TensorEngine.Threading.Variable variable)

Parameters

name string
variable TensorEngine.Threading.Variable

Returns

bool

TrySetDefault(string, int?)

Applies threads as a DEFAULT — honouring the source-of-truth rule: does nothing (returns false) if the knob was seeded from the environment or has already been set explicitly; otherwise behaves like SetThreads(string, int?) and returns true. Modules use this to suggest a value without overriding what the user configured.

public static bool TrySetDefault(string name, int? threads)

Parameters

name string
threads int?

Returns

bool