C · Executors

Executors

#include <uform/types.h>#include <uform/train.h> 4.0.0-rc.1 · 3ee5e534

An executor owns what a call runs on but a model does not: host threads or device streams, activation scratch, and the pinned buffer staging passes through.

  • uform_executor_for_ram creates an executor of host threads across the compute domains local to the memory domains of its uform_ram_options_t, 7/8 of their cores when threads is zero.
  • uform_executor_on_pool lends UForm a ForkUnion fu_pool_t another library spawned, so UForm, USearch and UStore in one process share one set of threads; the pool must outlive the executor.
  • uform_executor_for_vram opens one stream on every device of its uform_vram_options_t, named by their position in uform_gpu_devices, beside host threads for the decoding the devices cannot do.
  • uform_executor_drain waits until no call holds the executor, then applies the uform_mood_t its threads keep until the next call: parked sleeps in the kernel, spinning keeps polling.
  • uform_executor_free waits the same way, releases what the executor owns and returns what it borrowed.

One executor serves any number of models of its residency, and a call pairing a model with an executor of another residency reports uform_status_device_k. A NULL executor runs the call on the calling thread, final when it returns. cpu_class and gpu_class in the options pin the class a call dispatches as, and uform_status_unsupported_k answers a class the machine cannot run.

§ Classes and Devices

Dispatch picks one tuned variant per CPU or GPU family, named by uform_cpu_class_t and uform_gpu_class_t, whose enumerators and ordinals are USearch’s. uform_ram_options_t::cpu_class and uform_vram_options_t::gpu_class pin one, and the unknown zero derives the hardware’s own:

  • A CPU pin dispatches as if the CPU were of that class, taking every rung whose features it holds, and a class the CPU cannot run reports uform_status_unsupported_k.
  • A GPU pin dispatches every named device as that class, and a device that cannot run it reports uform_status_unsupported_k.
  • Unpinned devices of one VRAM executor must share a class, or the call reports uform_status_config_mismatch_k.

uform_gpu_devices lists every GPU the process can drive, NVIDIA devices first, then AMD, each as a uform_gpu_device_t of its vendor, vendor ordinal, class, compute units, memory and name. A device’s position in that listing is the ordinal uform_vram_options_t::devices names it by, and a machine without GPUs lists none and succeeds. uform_cpu_class_name and uform_gpu_class_name spell a class, like intel-haswell or nvidia-hopper, and the _from_name verbs read one back.

API

Types

uform_cpu_class_tThe CPU families UForm ships tuned variants for - dispatch reports its pick in this vocabulary, and callers may pin one.
types.h:442 ↗
enum uform_cpu_class_t

The enumerators and their ordinals are USearch's.

Values

uform_cpu_class_unknown_k0
uform_cpu_class_serial_kThe portable floor: no SIMD assumptions.
uform_cpu_class_intel_haswell_kHaswell-class x86: AVX2 & FMA, the 256-bit floor.
uform_cpu_class_intel_sierra_kSierra Forest-class x86 - the E-core Xeons: AVX-VNNI and its successors without AVX-512.
uform_cpu_class_intel_skylake_kSkylake-class x86: the AVX-512 foundation tier.
uform_cpu_class_intel_icelake_kIcelake-class x86: AVX-512 VNNI & VPOPCNT.
uform_cpu_class_amd_genoa_kGenoa-class x86 - Zen 4 and newer: native bf16 dot products over AVX-512.
uform_cpu_class_intel_sapphire_kSapphire Rapids-class x86: the Genoa bundle plus AVX-512 FP16 and the AMX-BF16 & AMX-INT8 tiles.
uform_cpu_class_intel_granite_kGranite Rapids-class x86: the Sapphire Rapids bundle plus the AMX-FP16 tiles.
uform_cpu_class_intel_diamond_kDiamond Rapids-class x86: the Granite Rapids bundle plus AVX10.2's FP8 conversions.
uform_cpu_class_aws_g2_kGraviton2-class Arm - Neoverse N1, the bare NEON floor; phones predating Armv8.6 land here too.
uform_cpu_class_apple_m2_kArmv8.6+ NEON: dot products, bf16 & f16 fused multiplies - Apple M2, Cortex-A710 & X2 class silicon.
uform_cpu_class_apple_m4_kApple M4-class Arm: the Armv8.6 NEON bundle plus the SME outer-product tiles.
uform_cpu_class_aws_g5_kGraviton5-class Arm - Neoverse V3, Armv9.2; reserved, as its kits equal apple_m2's.
uform_cpu_class_nvidia_vera_kVera-class Arm - NVIDIA's Armv9.2-generation cores with FP8 dot products.
uform_cpu_class_alibaba_c930_kAlibaba C930-class RISC-V - T-Head's XuanTie core, RVA23 vectors.
uform_cpu_class_wasm32_v128_kWebAssembly every engine loads: 32-bit, single-threaded, the fixed-width simd128 tier.
uform_cpu_class_wasm64_extended_kWebAssembly with relaxed SIMD, shared memory for real thread pools, and 64-bit addressing.
uform_cpu_class_monoversioned_kThe one class of a monoversioned build: every capability its floor implies or its preset vouches for, as the kernel libraries compiled them.

Spellings

char const * uform_cpu_class_name(uform_cpu_class_t cpu_class);
uform_cpu_class_t uform_cpu_class_from_name(uform_bytes_view_t name);
uform_gpu_class_tThe GPU families UForm ships tuned variants for, the device twin of uform_cpu_class_t: one class per generation of kernel kits.
types.h:507 ↗
enum uform_gpu_class_t

The enumerators and their ordinals are USearch's.

Values

uform_gpu_class_unknown_k0
uform_gpu_class_nvidia_ampere_kAmpere-class NVIDIA and every GPU without a class of its own - A100, A10 & RTX 30.
uform_gpu_class_nvidia_ada_kAda-class NVIDIA - L4, L40S & RTX 40: the fp8 conversions.
uform_gpu_class_nvidia_hopper_kHopper-class NVIDIA - H100 & H200.
uform_gpu_class_nvidia_blackwell_kBlackwell-class NVIDIA - B200, B300 & GB300.
uform_gpu_class_nvidia_blackwellrtx_kConsumer Blackwell NVIDIA - RTX 50, RTX PRO 6000 & DGX Spark.
uform_gpu_class_nvidia_rubin_kRubin-class NVIDIA - the Vera-Rubin platform's device half.
uform_gpu_class_amd_cdna3_kCDNA3 AMD - MI300X & MI325X: gfx942, FNUZ fp8.
uform_gpu_class_amd_cdna4_kCDNA4 AMD - MI350X & MI355X: gfx950, OCP fp8.
uform_gpu_class_amd_cdna5_kCDNA5 AMD - MI400: gfx1250.
uform_gpu_class_apple_metal7_kApple7-family GPUs and every Apple GPU without a class of its own - M1 & M2.
uform_gpu_class_apple_metal9_kApple9-family GPUs - M3 & M4.
uform_gpu_class_apple_metal10_kApple10-family GPUs - M5.

Spellings

char const * uform_gpu_class_name(uform_gpu_class_t gpu_class);
uform_gpu_class_t uform_gpu_class_from_name(uform_bytes_view_t name);
uform_gpu_vendor_tThe GPU vendors one binary drives at once.
types.h:548 ↗
enum uform_gpu_vendor_t

Values

uform_gpu_vendor_unknown_k0
uform_gpu_vendor_nvidia_kNVIDIA, through the CUDA driver.
uform_gpu_vendor_amd_kAMD, through the HIP runtime.
uform_gpu_vendor_apple_kApple, through Metal.
uform_gpu_device_tOne GPU as UForm numbers it: its position in uform_gpu_devices is the UForm device ordinal every VRAM call names.
types.h:563 ↗
struct uform_gpu_device_t

Fields

vendoruform_gpu_vendor_tThe vendor whose runtime drives the device.
vendor_ordinaluint32_tThe device's ordinal in its vendor's runtime, as nvidia-smi or rocm-smi list it.
gpu_classuform_gpu_class_tThe class whose kernels run on it.
compute_unitsuint32_tStreaming multiprocessors or compute units.
memory_bytesuint64_tDevice memory in bytes.
namecharThe vendor's own name for the device, NUL-terminated and truncated to fit.
uform_ram_options_tThe host memory domains a RAM-resident model and executor place their bytes in - one NUMA node each.
types.h:611 ↗
struct uform_ram_options_t

Fields

memory_domainsint32_t const *NUMA node IDs, borrowed for the duration of the call; NULL derives every node the process may allocate on.
memory_domains_countsize_tNumber of entries in memory_domains; zero derives.
cpu_classuform_cpu_class_tThe class to dispatch as if the CPU were of it, admitting every rung whose features it holds; uform_cpu_class_unknown_k derives the CPU's own.
uform_vram_options_tThe devices a VRAM-resident model, trainer and executor place their bytes in.
types.h:627 ↗
struct uform_vram_options_t

Fields

devicesint32_t const *UForm device ordinals, positions in the listing uform_gpu_devices reports, borrowed for the duration of the call; NULL derives one free device.
devices_countsize_tNumber of entries in devices; zero derives.
gpu_classuform_gpu_class_tThe class every named device dispatches as; uform_gpu_class_unknown_k derives the devices' own, which must agree, or the call reports uform_status_config_mismatch_k.
uform_executor_tEverything a call needs to run but a model does not own: the host threads or device streams that advance the work, the activation scratch, and the pinned bounce buffer staging passes through.
types.h:665 ↗
typedef struct uform_executor_handle_t * uform_executor_t;

One executor serves any number of models of its residency, so several models share one machine's cores or devices instead of each claiming a private set; a mismatch reports uform_status_device_k. Scratch grows to the largest batch asked of it, is rewound per call, and is kept between calls.

Calls on one executor run in submission order. Every executor tracks its deferred calls in a fixed table sized at creation, so submitting never allocates.

The library stages only to change layout on the side that computes, or to make pageable memory DMA-able:

CaseAction
Device inputs on the executor's deviceread in place
Pinned or managed host inputsa direct asynchronous upload
Pageable host inputsthe pinned bounce buffer, then an upload
Encoded media needing a host decoderdecoded on the executor's host threads, then uploaded
Outputs in an arena on the executor's devicethe kernel writes them directly
uform_mesh_options_tWhere this process sits among the processes training one model, and how they meet.
train.h:373 ↗
struct uform_mesh_options_t

Fields

host_domain_indexsize_tThis process's index among host_domain_count.
host_domain_countsize_tProcesses in the run, one per host; zero derives one, a run with no peers.
gpus_per_multimem_domainsize_tGPUs one NVLink multicast domain spans, a fabric property no local probe sees; zero derives the host.
directoryuform_bytes_view_tThe path of the directory every host sees, where processes exchange their facts; required with peers.
jobuform_bytes_view_tThe run's unique name, naming one directory inside directory; required with peers.
timeout_secondsdoubleSeconds any wait for a peer lasts before the call fails; zero derives 120.
uform_mesh_tOne process's place among the processes of a run: the topology every process agreed on at bootstrap, and the InfiniBand domain joining its NVLink domains.
train.h:406 ↗
typedef struct uform_mesh_handle_t * uform_mesh_t;

The process-wide half of a run's transport, made once and borrowed by every trainer, so no consumer wires its own adapters. The NVLink multicast domain is not here: its size is the sum of what its consumers reserve, so each trainer makes its own over the mesh's devices. Bootstrap is a one-time rendezvous through files in directory; after it, processes talk only over NVLink and InfiniBand.

uform_multimem_tier_tHow a mesh's NVLink domains reduce.
train.h:434 ↗
enum uform_multimem_tier_t

Values

uform_multimem_tier_switch_reduced_k0The NVLink switch reduces through multicast memory.
uform_multimem_tier_peer_read_k1Every member reads its peers in a fixed order, where multicast is absent; bit-identical results.

Spellings

char const * uform_multimem_tier_name(uform_multimem_tier_t tier);
uform_multimem_tier_t uform_multimem_tier_from_name(
    uform_bytes_view_t name);
uform_mesh_description_tWhat a mesh reports about itself.
train.h:445 ↗
struct uform_mesh_description_t

Fields

gpus_per_host_domainsize_tGPUs one process drives.
gpus_per_multimem_domainsize_tGPUs one NVLink domain spans.
gpus_per_colocated_domainsize_tGPUs in the whole run.
host_domain_indexsize_tThis process's index among the run's processes.
first_gpu_indexsize_tThe run-wide index of this process's first GPU, where its share of a sharded dataset begins.
multimem_tieruform_multimem_tier_tHow its NVLink domains reduce.
gpu_classuform_gpu_class_tThe class every GPU of the run dispatches as: the executor's pin, or the devices' own.

Functions

uform_gpu_devicesLists every GPU this process can drive, NVIDIA devices first, then AMD, so the position of a device is the UForm ordinal uform_vram_options_t names it by.
types.h:607 ↗
void uform_gpu_devices(uform_gpu_devices_t *arguments);

A vendor this build does not compile, or whose runtime is absent, lists no devices, so the call succeeds with a zero count on a machine without GPUs.

Parameters

outcomeuform_outcome_t *Output for the outcome, final when the call returns.
devicesuform_gpu_device_t *Output for up to devices_capacity devices, in UForm ordinal order; may be NULL.
devices_capacitysize_tEntries devices holds.
devices_countsize_t *Output for every device this process can drive, which may exceed devices_capacity.
uform_executor_for_ramSpawns host threads for RAM-resident models, interleaved across the compute domains local to the named memory domains.
types.h:688 ↗
void uform_executor_for_ram(uform_executor_for_ram_t *arguments);

Parameters

executoruform_executor_t *Output for the new executor.
outcomeuform_outcome_t *Output for the outcome, final once its status leaves uform_status_deferred_k.
ramuform_ram_options_tThe memory domains of the models it will drive; copied, not borrowed.
threadssize_tThreads to spawn; zero takes 7/8 of the cores those domains carry.
deferred_limitsize_tDeferred calls it tracks at once, sizing its deferred table; zero takes a default.
uform_executor_on_poolCreates a RAM executor over a borrowed ForkUnion pool, so UForm, USearch and UStore in one process share one set of threads while each keeps its own scratch.
types.h:712 ↗
void uform_executor_on_pool(uform_executor_on_pool_t *arguments);

Parameters

executoruform_executor_t *Output for the new executor.
outcomeuform_outcome_t *Output for the outcome, final once its status leaves uform_status_deferred_k.
ramuform_ram_options_tThe memory domains of the models it will drive; copied, not borrowed.
poolvoid *The ForkUnion fu_pool_t to borrow; it must outlive the executor, and keeps its lender's mood.
deferred_limitsize_tDeferred calls it tracks at once, sizing its deferred table; zero takes a default.
uform_executor_for_vramOpens one submission stream on every named device, all of them driven by whichever host thread submits; borrowing the caller's streams reports uform_status_unsupported_k for now.
types.h:752 ↗
void uform_executor_for_vram(uform_executor_for_vram_t *arguments);

Text and JPEG images never leave the device; the rest of decoding - container demux, PNG and WebP, audio, and every modality on AMD - runs on host threads the executor spawns beside its streams, 7/8 of the cores local to the memory domains ram names, dispatching as its cpu_class . A GPU executor never changes process-wide device flags.

Parameters

executoruform_executor_t *Output for the new executor.
outcomeuform_outcome_t *Output for the outcome, final once its status leaves uform_status_deferred_k.
vramuform_vram_options_tThe devices of the models it will drive; copied, not borrowed.
ramuform_ram_options_tThe memory domains and the CPU class of its host decoders; copied, not borrowed.
streamsvoid *const *The optional borrowed CUDA streams, one per device in vram order; NULL creates its own.
scratch_limitsize_tThe optional ceiling on scratch bytes per device; zero lets scratch grow as batches ask.
deferred_limitsize_tDeferred calls it tracks at once, sizing its deferred table; zero takes a default.
uform_executor_drainWaits for every call submitted before the drain began, so later submissions can't hold it up, then sets the mood the executor adopts whenever it next goes idle.
types.h:781 ↗
void uform_executor_drain(uform_executor_drain_t *arguments);

Reports only executor-level failures.

Parameters

executoruform_executor_tThe executor whose submitted calls are awaited.
outcomeuform_outcome_t *Output for an executor-level failure, such as a device fault; never one of a drained call.
mooduform_mood_tWhat the executor does whenever it next goes idle; the last drain wins.
uform_executor_freeDrains every call, releases the scratch and the streams it owns, returns borrowed streams and pools, and frees the executor; NULL is safe, and it cannot fail, so takes no outcome.
types.h:785 ↗
void uform_executor_free(uform_executor_t executor);
uform_capabilities_compiledThe hardware capabilities this binary was compiled with, as a comma-separated static string.
types.h:942 ↗
char const * uform_capabilities_compiled(void);
uform_capabilities_availableThe hardware capabilities the current machine offers at runtime, as a comma-separated static string.
types.h:946 ↗
char const * uform_capabilities_available(void);
uform_mesh_bootstrapJoins this process to the run's mesh; every process of the run calls it with the same count, multicast extent, directory, job and GPU class, or the call reports uform_status_config_mismatch_k.
train.h:431 ↗
void uform_mesh_bootstrap(uform_mesh_bootstrap_t *arguments);

Parameters

meshuform_mesh_t *Output for the new mesh, written once every process has joined.
executoruform_executor_tA VRAM executor whose devices are this process's members of the mesh.
outcomeuform_outcome_t *Output for the outcome, final once its status leaves uform_status_deferred_k.
completionuform_completion_tWhether the call blocks or returns once queued; zero blocks.
optionsuform_mesh_options_tWhere this process sits and how the processes meet.
uform_mesh_describeReports a mesh's shape and this process's place in it.
train.h:484 ↗
void uform_mesh_describe(uform_mesh_describe_t *arguments);

Parameters

meshuform_mesh_tThe mesh to be described.
outcomeuform_outcome_t *Output for the outcome, final once its status leaves uform_status_deferred_k.
descriptionuform_mesh_description_t *Output, filled whole.
uform_mesh_freeLeaves the mesh; NULL is safe, and it cannot fail, so takes no outcome.
train.h:488 ↗
void uform_mesh_free(uform_mesh_t mesh);

Every trainer borrowing it must be freed first.