Rust API Guide#
The package is orbite and the crate is orbite. Generate the full type
documentation with:
cargo doc --locked --no-deps --open
Add --features rdma,cuda in an environment with the
build prerequisites. The docs.rs profile includes CUDA, io_uring,
GDS and metrics on Linux through runtime-loaded SDKs; it deliberately excludes
rdma/rdma-adaptive, whose generated bindings need system verbs headers.
CI builds that profile with --cfg docsrs and no verbs headers. Use the full
local feature build for RDMA rustdoc.
Current public surface#
This is the current public surface for 0.1.0-beta.1.
This is an inventory, not a freeze: breaking changes are allowed before 0.1.0, including between betas. Hardware qualification is separate. Rust is the primary API.
The following names and their public methods/fields are inventoried here; private
transport owners, native function tables and test shims are not public APIs.
Full signatures come from rustdoc for the chosen feature set. TENT
compatibility surfaces are out of scope.
Area |
Public surface |
|---|---|
Construction |
|
Requests and outcomes |
|
Registered backing |
|
Peer and file authority |
|
Async work |
|
Notifications |
|
Selection |
|
QoS |
|
Credits and accounting |
|
CPU providers |
|
Linux topology |
|
|
|
Unstable |
|
|
|
|
|
Storage features |
|
|
|
Offline diagnostics |
|
API decisions#
All public enums and every public struct with public fields are
#[non_exhaustive]. TransferOp is the sole exhaustive enum: its binary
READ/WRITE contract is intentional. CI enforces Clippy’s exhaustive_structs
and exhaustive_enums lints with that single exception. Opaque structs with private fields already
require their constructors. Match enums with a wildcard and destructure field
records with ..; construct configuration through defaults and field assignment:
use orbite::{EngineConfig, RuntimeQueueConfig};
let mut queue = RuntimeQueueConfig::default();
queue.max_dispatch_owners = 8;
let mut config = EngineConfig::default();
config.runtime_queue = Some(queue);
Notification::new, NicEntry::new, MemEntry::new, CreditAmount::new and
ReceiverCreditUpdateV1::new construct input records without struct literals.
Their public fields remain mutable. QP pools use QpPool::default() followed by
a unique name and any count/link overrides.
Boundary |
API decision |
|---|---|
Primary Rust helpers |
|
Binding internals |
Backing |
Names |
|
Adaptive core |
The callable |
Documentation |
Missing docs are not a beta publication blocker: adding documentation is non-breaking. The release-readiness audit found 668 all-feature Linux diagnostics. Before |
Native binding types |
The deliberate cudarc stream coupling and raw owner-backed alternative below remain. Signatures may change between betas; installed GPU profiles remain unqualified. |
Transfer requests#
TransferRequest::new(transport, local_address, remote_address, length) starts
with Priority::High, the engine’s default QoS contract and remote staging off.
Override them with .with_qos(policy), .with_priority(priority) and
.with_remote_staging(true); an explicit QoS policy supplies its own priority.
Use Transport::Unspec for transport selection.
Public enums other than TransferOp are non-exhaustive, so matches outside
the crate need a wildcard arm.
Both ranges must lie inside one applicable registration, and TransferOp
selects READ or WRITE. Submission resolves and retains every backing allocation
before any transfer effect. Priority orders RDMA payloads on each worker; TCP and
NVLink accept every priority as advisory, and requests within a batch keep their
order.
Engine and registration#
TransferEngine::new(EngineConfig) starts a source control service (loopback by
default) and owns requester and source admission. Configuration is immutable per
engine. engine.config() borrows its effective settings.
Transport::Fabric and the provider config/stats exports are removed. All
remaining Rust discriminants are unchanged; Transport stays non-exhaustive.
CUDA fabric allocations, MNNVL and EGM are unaffected.
Configuration loading#
use orbite::{EngineConfig, TransferEngine};
fn open_engine() -> orbite::Result<TransferEngine> {
TransferEngine::new(EngineConfig::from_env()?)
}
EngineConfig::from_json(text) and from_file(path) take explicit input and
ignore the environment. from_env() reads only ORBITE_CONF, containing either
inline JSON or a regular UTF-8 file path; absent means typed defaults. Engine
construction never rereads it. Reuse a snapshot after changing or deleting its
input file. No loader mutates the process environment.
The root uses the typed EngineConfig field names. Transport fields may instead
be grouped under transports; a field cannot appear in both places. Provider
records use their typed field names and defaults. An optional provider object
opts in; null disables it. hp_tcp.enable and shm.enable remain explicit.
The RDMA record adds gpu_direct_registration: "auto" (default), "dmabuf"
or "peermem"; it is compiled once and affects CUDA Direct registrations only.
See route selection and lifetime.
Duration fields have an _us suffix and take integer microseconds; fields already
naming a unit, such as connect_timeout_ms, retain that unit. Other sizes are
bytes except explicitly named KiB settings. MNNVL fabric_domain uses the
32-hex-digit SourceEpoch representation or null. Selector rules and QoS contracts
live under selector and qos; receiver budgets under receiver_credit.
{
"bind_addr": "127.0.0.1:0",
"handler_timeout_us": 5000000,
"transports": {"tcp": true, "shm": {"enable": false}},
"selector": {"policy": [{"name": "host", "segment_type": "memory", "transports": ["tcp"]}]}
}
Unknown keys, duplicate keys, wrong types, malformed roots and out-of-range
values fail before an engine starts. Documents are bounded to 1 MiB and files
must be regular files. Removed metadata keys and legacy aliases are unknown
fields. Legacy environment variables have no effect; provider-runtime variables
such as CUDA_VISIBLE_DEVICES remain the provider’s responsibility. Native fields require
their build feature. Typed Rust construction stays the primary interface.
API |
Contract |
|---|---|
|
Move host bytes into a registered range |
|
Register a range of an existing |
|
Preflight a set of host ranges, then publish them together |
|
Register CUDA allocations ( |
|
Drop a registration reference; admitted users keep their backing |
|
Resolve a contained registered range without adopting a raw pointer |
Permission distinguishes local-only, remote READ, remote WRITE and remote
READ/WRITE; repeated registration of a range keeps its first permission. With
RDMA host Direct policy, registration also prepares MRs on every usable context
before the range becomes visible, so it can fail when native resources are
exhausted; see the
publication contract.
Admission and QoS configuration#
Setting |
Purpose |
Guide |
|---|---|---|
|
FIFO/EDF dispatch window for all data submissions |
|
|
Global/tenant/intent contracts; |
|
|
Sender credit gating; |
|
|
Receiver-side issuer; |
|
|
Ordered transport selection rules ( |
EffectiveQosPolicy::fields(), effective_priority() and usage() explain a
resolved policy and sample its budget.
Memory type and location#
RegisteredMemory::memory_type() returns MemoryType::Cpu or Cuda from the
retained backing, without locks or driver calls. RegisteredMemory::location()
returns RangeLocation { address, length, location } clipped to that
registration, and HostMemory::location(offset, length) /
CudaMemory::location(offset, length) check the owner subrange first. These
queries neither wait for producer readiness nor grant payload access.
MemoryLocation::Cuda { device, context } displays as cuda:N; the context
number is diagnostic, not a usable handle. MemoryLocation::Cpu(Some(N))
displays cpu:N and Cpu(None) displays *. Ordinary, external and portable
pinned host memory have unknown NUMA placement, and pinned DRAM stays CPU memory.
External CUDA adoption makes one cuPointerGetAttributes call (type, managed
status, context, device), resolves the device with cuDeviceGet and checks the
whole range with cuMemGetAddressRange in that context. Unknown attributes,
managed or host pointers and native errors fail adoption and never select CPU
access. This covers the owner-backed part of TENT’s Platform getMemoryType,
getPointerDeviceId and getLocation; there is no general pointer classifier,
CPU page-residency scan or device-plugin ABI. See
qualification.
RDMA bandwidth and load#
With rdma, RdmaConfig::scheduling configures SchedulingParams for
bandwidth-aware selection (on by default; smart_selection = false uses
round-robin in the first tier); see
selection.
TransferEngine::nic_load_stats() returns initialized NICs without discovery:
rate estimates in bytes per second, link_speed_gbps in Gbit/s,
inflight_bytes (grant admission), posted_bytes (native payload debt) and
cumulative completed bytes, busy time and sample counts. Priority settings
(deadline_bw_arbitration, priority_promotion_timeout,
priority_promotion_per_entry, shared_quota_shm_path,
slot_rotation_interval) are described in
request priority.
Reports#
submit_and_wait returns a BatchReport with completed request and byte counts,
failure details, notification status and local drain status. The completed prefix
is not a transaction. RemoteEffect::Unknown means an attempted WRITE may have
changed peer bytes, and never authorizes replay. TransferFailure.affected_requests
counts the consecutive tasks that share a failure from request_index; only later
requests were never attempted. A multirail or remote-staged request counts only
after all its slices or chunks complete, but earlier slices may already have
changed bytes. For asynchronous ownership see async batches.
For explicit progress, call engine.progress_batch(batch.id()?)?. A status
query observes the published result. EngineConfig::enable_progress_worker
enables event-driven turns and deferred free. Use
Batch::submit_with_notification_targets to track deliveries independently
of the payload result. See explicit progress
for backoff, queue wakes, bounded retries and owner retirement.
Native providers#
The CUDA feature accepts compatible cudarc 0.19 releases. Rust 1.85 builds
use 0.19.0 in the checked-in lockfile. Consumers resolving a fresh lockfile
on 1.85 can select it with cargo update -p cudarc --precise 0.19.0.
Consumers using cudarc 0.19.8 share one registry package with OrbiTE on
Rust 1.88 or newer, as required by that release’s libloading dependency.
OrbitKV deliberately passes its Arc<cudarc::driver::CudaStream> as the
lifetime owner for local copies. Code that names that type follows cudarc’s
semver. The underlying unsafe LocalCopyEngine::bind accepts a
*mut std::ffi::c_void and an Arc<dyn Send + Sync>. A caller with its own
CUDA binding can supply its raw stream and owner directly. The same contract
applies to ProducerEvent::from_raw, so a future C adapter can retain its
own handles. Local copy ownership
transport::rdma::RdmaConfig selects discovery and pins, host Direct or staged
memory, progress mode (Polling by default, or EventDriven) and native budgets.
The cuda module owns device and pinned-host allocations and synchronized copies;
device transfers use staging or explicit GPUDirect RDMA. Unsafe
CudaMemory::record_producer_stream and HostMemory::record_producer_stream
hand already-queued producer work to transfers; read the
producer contract before using them.
Close and drain#
close_source and close_requester fence one direction; whole-engine close
fences both, drains accepted work and closes shared native resources. A timeout
never completes pending native work, and Error::Unquiesced keeps the real
resources and charges when cleanup could not be proved. With cuda,
flush_nvlink_cache(timeout) closes the cached imports present when it starts
while admission stays open; see
the cache contract.
Runnable examples: TCP, external allocation and async batches.
The Python API uses the same Rust owners through the optional wheel boundary; Rust consumers do not compile or load Python.