Mojo · Executors

Executors

from usearch import DenseIndexOn, DenseIndexDeferredOn, DenseVerbs, … 3.0.0-rc.1 · 4c3e5023

One executor serves any number of indexes, and its residency must match the one their handles were built for. Executor(library) owns nothing and runs every call handed it on the calling thread, whatever the handle’s residency. There is a constructor per C one, each taking every argument its own hardware has:

var threads = Executor.for_ram(library, RamOptions.on(domains), threads=8)  # zero takes 7/8 of the cores
var shared = Executor.on_pool(library, fork_union_pool)                       # borrows a fu_pool_t
var streams = Executor.for_vram(library, VramOptions.on(devices))             # one host thread, a stream per device
var rings = Executor.for_nvme(library, threads=4)                             # one submission ring per thread
threads.drain(Mood.SPINNING)                                                # waits out the holding call, then keeps spinning

One call holds an executor at a time, while index handles stay freely concurrent, so threads that genuinely overlap take one executor apiece. A second call finding the executor held finishes at once with Status.CONTENDED, and nothing queues. A deferred call on a caller-exclusive pool runs on the pool’s thread 0, so polling alone finishes it, and its progress handler and predicate run on the pool’s threads; a single thread or a VRAM executor runs it at submission.

§ Receivers & Deferred Calls

The receiver chooses where a verb runs and how it completes, and the verb stays the same. The index runs it on the calling thread, index.on(executor) blocks on an executor, and index.deferred(executor) submits it there and answers a Deferred:

index.search(queries, 10, arena)                               # the calling thread
index.on(executor).search(queries, 10, arena)                  # blocking, holding the executor until it returns
var call = index.deferred(executor).search(queries, 10, arena)  # Deferred[...], final once waited

DenseIndexOn and DenseIndexDeferredOn offer the same verbs with the same arguments. The blocking verbs are written once, in the DenseVerbs trait both the index and DenseIndexOn conform to. Constructors address no index yet, so no receiver offers them; the ones whose C structure names an executor take one.

A Deferred owns its outcome and outputs until the call is final, and borrows the index, the executor, the arena and every input it was handed, which Mojo keeps alive for as long as the Deferred is.

var call = index.deferred(executor).search(queries, 10, arena)
if call.status() == Status.DEFERRED:
    pass  # other work
print(call.wait().query_keys(0)[0])  # the matches, read in place from your arena

Mojo has no runtime of its own to await on, so wait is the whole interface: it blocks in usearch_outcome_wait until the call is final, then answers the result or raises the failure, as many times as it is asked. The result is the very Matches a blocking search answers, borrowing the same arena, and status reads the outcome without blocking. A failure this binding catches before the call crosses is final at once, and arrives through the same status and wait. Mojo destroys a value at its last use, and destroying an unfinished Deferred waits for it. Calls depending on each other are ordered by waiting on the first before submitting the second.

API

StructDenseIndexOnAn index bound to the executor its verbs block on, as index.on(executor) answers it. Binding-only.3
struct DenseIndexOn[origin: ImmOrigin]

Parameters

originImmOrigincomptimeThe index and the executor, which this receiver borrows.

Fields

indexPointer[DenseIndex, origin]The index every verb addresses.
executorAddressThe usearch_executor_t every verb runs on.

Conforms to

Copyable, Deinitable, DenseVerbs, ImplicitlyCopyable, Movable
__init__Binds an index to an executor.
def __init__(out self, index: Pointer[DenseIndex, origin], executor: Int)

Parameters

indexPointer[DenseIndex, origin]The index every verb addresses.
executorIntThe usearch_executor_t every verb runs on.
cursorOpens a walk over every entry as stored, its pulls on the bound executor. Calls usearch_dense_cursor_init.
def cursor(self) -> DenseCursor[origin]
def cursor[starts_origin: ImmOrigin, //](
    self,
    starts: Span[Key, starts_origin]
) -> DenseCursor[origin]

Opens a walk from starts, its pulls on the bound executor. Calls usearch_dense_cursor_init.

Parameters

starts_originImmOrigincomptimeThe start keys' origin, inferred from the argument.
startsSpan[Key, starts_origin]The keys to walk from, the walk yielding their entries first.

Returns

The cursor, which borrows the index and the executor and cannot outlive them.

Raises

Error if the residency has no cursor, as VRAM does not.
search_streamOpens a resumable nearest-neighbor stream for one query, its pulls on the bound executor. Calls usearch_dense_search_stream_init.
def search_stream[query_origin: ImmOrigin, //](
    self,
    query: RowsView[query_origin],
    config: DenseSearchStreamInitConfig = DenseSearchStreamInitConfig(expansion_factor=Int(0))
) -> DenseSearchStream[origin_of(origin, query_origin)]

Parameters

query_originImmOrigincomptimeThe query row's origin, inferred from the argument.
queryRowsView[query_origin]The single query row; a view of more rows has its first row read.
configDenseSearchStreamInitConfigThe breadth of the candidates the walk explores.

Returns

A stream yielding matches lazily, which borrows the index, the executor and the query.

Raises

Error with UNSUPPORTED while no residency implements the stream.
StructDenseIndexDeferredOnAn index bound to the executor its verbs are submitted to, as index.deferred(executor) answers it: every verb answers a Deferred at once. Binding-only.18
struct DenseIndexDeferredOn[origin: ImmOrigin]

The verbs and their arguments are those of DenseVerbs, the arena borrowed as theirs is; only the blocking receivers add the cursor and the search stream, whose every pull blocks.

Parameters

originImmOrigincomptimeThe index and the executor, which this receiver borrows.

Fields

indexPointer[DenseIndex, origin]The index every verb addresses.
executorAddressThe usearch_executor_t every verb is submitted to.

Conforms to

Copyable, Deinitable, ImplicitlyCopyable, Movable
__init__Binds an index to an executor.
def __init__(out self, index: Pointer[DenseIndex, origin], executor: Int)

Parameters

indexPointer[DenseIndex, origin]The index every verb addresses.
executorIntThe usearch_executor_t every verb is submitted to.
reserveSubmits DenseVerbs.reserve. Calls usearch_dense_reserve.
def reserve(self, capacity: Int) -> Deferred[_DenseReserveCall, origin]
clearSubmits DenseVerbs.clear. Calls usearch_dense_clear.
def clear(self) -> Deferred[_DenseClearCall, origin]
describeSubmits DenseVerbs.describe. Calls usearch_dense_describe.
def describe(self) -> Deferred[_DenseDescribeCall, origin]
insertSubmits DenseVerbs.insert; the keys, rows and telemetry slot stay borrowed until final. Calls usearch_dense_insert.
def insert[keys_origin: ImmOrigin, vectors_origin: ImmOrigin, stats_origin: MutOrigin, //](
    self,
    keys: Span[Key, keys_origin],
    vectors: RowsView[vectors_origin],
    config: DenseInsertConfig[stats_origin] = DenseInsertConfig(expansion_factor=Int(0), stats=Optional())
) -> Deferred[_DenseInsertCall, origin_of(keys_origin, origin, stats_origin, vectors_origin)]
refineSubmits DenseVerbs.refine. Calls usearch_dense_refine.
def refine[stats_origin: MutOrigin, //](
    self,
    config: DenseRefineConfig[stats_origin] = DenseRefineConfig(expansion_factor=Int(0), stats=Optional())
) -> Deferred[_DenseRefineCall, origin_of(origin, stats_origin)]
healthSubmits DenseVerbs.health. Calls usearch_dense_health.
def health(self) -> Deferred[_DenseHealthCall, origin]
absorbSubmits DenseVerbs.absorb; the donors are owned by the call. Calls usearch_dense_absorb.
def absorb(self, var donors: List[DenseIndex]) -> Deferred[_DenseAbsorbCall, origin]
splitSubmits DenseVerbs.split; the receivers stay borrowed until final. Calls usearch_dense_split.
def split(
    self,
    receivers: List[DenseIndex],
    seed: UInt64 = UInt64(0)
) -> Deferred[_DenseSplitCall, origin_of(origin, receivers)]
sampleSubmits DenseVerbs.sample; the shown keys, focus and arena stay borrowed until final. Calls usearch_dense_sample.
def sample[shown_origin: ImmOrigin, coordinates_origin: ImmOrigin, focus_origin: ImmOrigin, //](
    self,
    wanted: Int,
    mut arena: Arena,
    config: DenseSampleConfig[shown_origin, coordinates_origin, focus_origin] = DenseSampleConfig(shown=Span(), shown_coordinates=Span(), focus=Span(), seed=UInt64(0))
) -> Deferred[_DenseSampleCall[origin_of(arena)], origin_of(coordinates_origin, focus_origin, origin, shown_origin)]
countSubmits DenseVerbs.count. Calls usearch_dense_count.
def count(self, key: Key) -> Deferred[_DenseCountCall, origin]
getSubmits DenseVerbs.get; the arena stays borrowed until final. Calls usearch_dense_get.
def get[dtype: DType](
    self,
    key: Key,
    mut arena: Arena,
    scalar: ScalarKind = ScalarKind.of[dtype]()
) -> Deferred[_DenseGetCall[dtype, origin_of(arena)], origin]
saveSubmits DenseVerbs.save; the path stays borrowed until final. Calls usearch_dense_save.
def save[path_origin: ImmOrigin, //](
    self,
    path: StringSpan[path_origin]
) -> Deferred[_DenseSaveCall, origin_of(origin, path_origin)]
save_bufferSubmits DenseVerbs.save_buffer; the arena stays borrowed until final. Calls usearch_dense_save_buffer.
def save_buffer(self, mut arena: Arena) -> Deferred[_DenseSaveBufferCall[origin_of(arena)], origin]
multiplySubmits DenseVerbs.multiply; the rows, telemetry slot and arena stay borrowed until final. Calls usearch_dense_multiply.
def multiply[left_origin: ImmOrigin, stats_origin: MutOrigin, //](
    self,
    left: RowsView[left_origin],
    mut arena: Arena,
    config: DenseMultiplyConfig[stats_origin] = DenseMultiplyConfig(wanted=Int(0), expansion_factor=Int(0), stats=Optional())
) -> Deferred[_DenseMultiplyCall[origin_of(arena)], origin_of(left_origin, origin, stats_origin)]
attendSubmits DenseVerbs.attend; the queries, carry, telemetry slot and arena stay borrowed until final, and the lookup state must outlive the call too. Calls usearch_dense_attend.
def attend[queries_origin: ImmOrigin, carry_origin: MutOrigin, stats_origin: MutOrigin, //, dtype: DType](
    self,
    queries: RowsView[queries_origin],
    value_lookup: def(Int, Pointer[Key, ImmUntrackedOrigin], UInt, ScalarKind, UInt, Pointer[Int, MutAnyOrigin]) abi("C") thin -> None,
    value_lookup_state: Int,
    mut arena: Arena,
    config: DenseAttendConfig[carry_origin, stats_origin] = DenseAttendConfig(head_count=Int(0), carry=Span(), expansion_factor=Int(0), score_scale=Float32("0"), stats=Optional())
) -> Deferred[_DenseAttendCall[dtype, origin_of(arena)], origin_of(carry_origin, origin, queries_origin, stats_origin)]
maxsimSubmits DenseVerbs.maxsim; the queries, telemetry slot and arena stay borrowed until final. Calls usearch_dense_maxsim.
def maxsim[queries_origin: ImmOrigin, stats_origin: MutOrigin, //](
    self,
    queries: RowsView[queries_origin],
    rows_per_query: Int,
    wanted: Int,
    mut arena: Arena,
    config: DenseMaxsimConfig[stats_origin] = DenseMaxsimConfig(expansion_factor=Int(0), stats=Optional())
) -> Deferred[_DenseMaxsimCall[origin_of(arena)], origin_of(origin, queries_origin, stats_origin)]
TraitDenseVerbsThe verbs every blocking receiver offers - the index on the calling thread, and index.on(executor) on an executor - each written once over the receiver's _route.17
trait DenseVerbs
reserveReserves capacity for a number of incoming vectors ahead of insertion. Calls usearch_dense_reserve.
def reserve(self, capacity: Int)

Parameters

capacityIntThe desired total capacity, including the current size.

Raises

Error if the reservation cannot be satisfied, or contradicts a frozen geometry.
clearErases every entry, keeping the reserved capacity and the frozen geometry. Calls usearch_dense_clear.
def clear(self)

Never invoked concurrently with any other verb on the same handle.

Raises

Error with READ_ONLY if the handle serves its checkpoint in place.
describeReports the frozen metadata and the current counters in one call. Calls usearch_dense_describe.
def describe(self) -> DenseIndexDescription

Returns

The description.

Raises

Error if the engine refuses the query.
insertAdds a run of vectors under their keys - the native batch operation. Calls usearch_dense_insert.
def insert[keys_origin: ImmOrigin, vectors_origin: ImmOrigin, stats_origin: MutOrigin, //](
    self,
    keys: Span[Key, keys_origin],
    vectors: RowsView[vectors_origin],
    config: DenseInsertConfig[stats_origin] = DenseInsertConfig(expansion_factor=Int(0), stats=Optional())
)

A batch is all-or-nothing, because this binding installs no progress handler: every fallible step runs before the first entry identity is claimed, so a rejected batch leaves the index untouched and publishes no entry.

Parameters

keys_originImmOrigincomptimeThe key run's origin, inferred from the argument.
vectors_originImmOrigincomptimeThe row storage's origin, inferred with it.
stats_originMutOrigincomptimeThe lent telemetry slot's origin, inferred with it.
keysSpan[Key, keys_origin]One key per row of vectors; keys need not be unique.
vectorsRowsView[vectors_origin]The rows to insert, converted on ingest to the stored type.
configDenseInsertConfig[stats_origin]The breadth of the candidates and the telemetry slot.

Raises

Error if the shapes disagree or the handle is read-only.
refineRe-selects every entry's neighbors against the finished graph. Calls usearch_dense_refine.
def refine[stats_origin: MutOrigin, //](
    self,
    config: DenseRefineConfig[stats_origin] = DenseRefineConfig(expansion_factor=Int(0), stats=Optional())
) -> DenseRefineReport

A build step rather than a repair: a cheap insertion pass followed by one refinement reaches a better graph, in less total time, than a single expensive insertion pass - so a wide expansion factor belongs here rather than in insert. Searches may run throughout; insertions may not.

Parameters

stats_originMutOrigincomptimeThe lent telemetry slot's origin, inferred from the argument.
configDenseRefineConfig[stats_origin]The breadth of the candidates the re-selection walk explores, and the telemetry slot.

Returns

The entries re-selected and changed, the islands healed, and the closing audit; zero changed means the graph has settled.

Raises

Error with READ_ONLY if the handle serves its checkpoint in place.
healthAudits how much of the graph a search reaches from its landmarks. Calls usearch_dense_health.
def health(self) -> DenseReachability

Read-only, so concurrent insertions merely leave fresh entries unaudited.

Returns

The audit; entries it misses stay unfound until a refine re-links them.

Raises

Error if the engine refuses the audit.
absorbAbsorbs every donor into this index, keeping their graphs rather than re-inserting their vectors. Calls usearch_dense_absorb.
def absorb(self, var donors: List[DenseIndex]) -> DenseRefineReport

Each donor the engine consumes is emptied here, so dropping the list releases only the donors a stopped absorb left standing.

Parameters

donorsList[DenseIndex]varThe handles to absorb, consumed by the call.

Returns

What the closing refine did to the graph.

Raises

Error with CONFIG_MISMATCH for a donor of another residency, scalar, metric or geometry, or with READ_ONLY if the handle serves its checkpoint in place.
splitSplits this index into the receivers, the inverse of absorb: graph-local parts keeping their edges, one per receiver, leaving this index empty but live. Calls usearch_dense_split.
def split(self, receivers: List[DenseIndex], seed: UInt64 = UInt64(0)) -> DenseRefineReport

Parameters

receiversList[DenseIndex]Two or more empty handles of this index's residency, scalar, class, metric, geometry and shard count, each receiving one part.
seedUInt64Picks the part roots; equal seeds over an unchanged index split equally.

Returns

What the receivers' closing refines did to their graphs.

Raises

Error with CONFIG_MISMATCH for a mismatched or non-empty receiver, in which case nothing moves, or with READ_ONLY if the handle serves its checkpoint in place.
sampleDraws up to wanted keys around config.focus, or across the whole index, each hanging from a shown or earlier draw and placed in three dimensions beside the shown ones. Calls usearch_dense_sample.
def sample[shown_origin: ImmOrigin, coordinates_origin: ImmOrigin, focus_origin: ImmOrigin, //](
    self,
    wanted: Int,
    mut arena: Arena,
    config: DenseSampleConfig[shown_origin, coordinates_origin, focus_origin] = DenseSampleConfig(shown=Span(), shown_coordinates=Span(), focus=Span(), seed=UInt64(0))
) -> DenseDraws[origin_of(arena)]

A larger wanted draws a superset, so a view grows one connected sample as it zooms. Only RAM samples yet.

Parameters

shown_originImmOrigincomptimeThe shown keys' origin, inferred from the config.
coordinates_originImmOrigincomptimeTheir coordinates' origin, inferred with it.
focus_originImmOrigincomptimeThe focus keys' origin, inferred with it.
wantedIntThe upper bound on draws.
arenaArenamutThe arena to rewind and refill, which the result borrows; a failed call leaves it valid.
configDenseSampleConfig[shown_origin, coordinates_origin, focus_origin]The shown keys and their coordinates, the focus and the seed.

Returns

The draws, read in place from the arena.

Raises

Error with SHAPE_MISMATCH unless there are three coordinates per shown key, or UNSUPPORTED off RAM.
countHow many entries the index stores under one key. Calls usearch_dense_count.
def count(self, key: Key) -> Int

Parameters

keyKeyThe key whose entries are counted.

Returns

The number of entries sharing the key; zero means the index holds none.

Raises

Error if the engine refuses the query.
getExports every vector stored under one key into a lent arena, one row per entry, in insertion order. Calls usearch_dense_get.
def get[dtype: DType](
    self,
    key: Key,
    mut arena: Arena,
    scalar: ScalarKind = ScalarKind.of[dtype]()
) -> DenseVectors[dtype, origin_of(arena)]

Parameters

dtypeDTypecomptimeThe element type the rows are read as, which scalar must store whole.
keyKeyThe key whose entries are exported.
arenaArenamutThe arena to rewind and refill, which the result borrows; a failed call leaves it valid.
scalarScalarKindThe scalar type to export as, converted from storage where it differs; the kind dtype stores by default.

Returns

The rows, read in place from the arena; none when the key is absent.

Raises

Error with SHAPE_MISMATCH if dtype cannot hold scalar, or if the engine refuses the export.
saveWrites a checkpoint, the path extension picking the layout. Calls usearch_dense_save.
def save[path_origin: ImmOrigin, //](self, path: StringSpan[path_origin])

A .safegraphs path is one monolith; a .safegraphs.json path is a manifest naming one monolith per shard. Demands a mutation-free window; concurrent readers keep searching throughout. A failed save leaves a file without its header, which every reader rejects, and that leftover is the caller's to remove.

Parameters

path_originImmOrigincomptimeThe path bytes' origin, inferred from the argument.
pathStringSpan[path_origin]Destination path, whose extension picks the layout.

Raises

Error if the destination cannot be written.
save_bufferSerializes the index as one monolith into a lent arena - the same bytes the path-taking sibling writes. Calls usearch_dense_save_buffer.
def save_buffer(self, mut arena: Arena) -> Monolith[origin_of(arena)]

Parameters

arenaArenamutThe arena to rewind and refill, which the result borrows; a failed call leaves it valid.

Returns

The monolith, read in place from the arena.

Raises

Error if the engine refuses the write.
multiplyApproximate sparse product of a run of rows against the indexed vectors, into a lent arena. Calls usearch_dense_multiply.
def multiply[left_origin: ImmOrigin, stats_origin: MutOrigin, //](
    self,
    left: RowsView[left_origin],
    mut arena: Arena,
    config: DenseMultiplyConfig[stats_origin] = DenseMultiplyConfig(wanted=Int(0), expansion_factor=Int(0), stats=Optional())
) -> DenseProducts[origin_of(arena)]

Reports every pair the traversal scored instead of only the nearest, in traversal order rather than sorted, and with no duplicates. Cost is roughly rows x expansion x connectivity x dimensions, sublinear in the indexed entries, which is the whole point of reading a product off a graph. Runs on DenseMetric.INNER alone.

Parameters

left_originImmOrigincomptimeThe left-hand rows' origin, inferred from the argument.
stats_originMutOrigincomptimeThe lent telemetry slot's origin, inferred with it.
leftRowsView[left_origin]The left-hand rows.
arenaArenamutThe arena to rewind and refill, which the result borrows; a failed call leaves it valid.
configDenseMultiplyConfig[stats_origin]The pairs kept per row, the breadth of the candidates, and the telemetry slot.

Returns

The ragged pairs and their offsets, read in place from the arena.

Raises

Error with CONFIG_MISMATCH if the graph was frozen under a distance kind.
attendSoftmax attention of a run of query heads over every indexed key their graph walks score, written in a lent arena. Calls usearch_dense_attend.
def attend[queries_origin: ImmOrigin, carry_origin: MutOrigin, stats_origin: MutOrigin, //, dtype: DType](
    self,
    queries: RowsView[queries_origin],
    value_lookup: def(Int, Pointer[Key, ImmUntrackedOrigin], UInt, ScalarKind, UInt, Pointer[Int, MutAnyOrigin]) abi("C") thin -> None,
    value_lookup_state: Int,
    mut arena: Arena,
    config: DenseAttendConfig[carry_origin, stats_origin] = DenseAttendConfig(head_count=Int(0), carry=Span(), expansion_factor=Int(0), score_scale=Float32("0"), stats=Optional())
) -> DenseVectors[dtype, origin_of(arena)]

Every key a walk scores folds into each head's running maximum, partition, and weighted value sum, as Flash Attention folds key tiles, with no top-k cut: the long tail the walk scores is what brings the result toward exact dense attention. The outputs come back already divided by the partition.

Row t · head_count + h of queries, the outputs, and carry is head h of token t. One index holds one layer's one key-value head, so the head_count query heads of grouped-query attention share its keys and one walk per token.

The index stores no values: value_lookup resolves the keys of every scored batch to their value rows, so only keys a walk scores are ever resolved. carry is the softmax's m and l, one DenseSoftmaxState per query row, lent by the caller: supplying it folds this branch into another over the same queries, such as the recent window kept out of the index, by partial-softmax rescaling.

Parameters

queries_originImmOrigincomptimeThe query rows' origin, inferred from the argument.
carry_originMutOrigincomptimeThe softmax states' origin, inferred with it where any are supplied.
stats_originMutOrigincomptimeThe lent telemetry slot's origin, inferred with it.
dtypeDTypecomptimeThe element type the attended rows land as, which must name a scalar kind.
queriesRowsView[queries_origin]The query rows, head_count per token.
value_lookupdef(Int, Pointer[Key, ImmUntrackedOrigin], UInt, ScalarKind, UInt, Pointer[Int, MutAnyOrigin]) abi("C") thin -> NoneResolves every scored batch of keys to their value rows - a host function on RAM, and a device one on VRAM.
value_lookup_stateIntThe opaque state forwarded into every value_lookup call.
arenaArenamutThe arena to rewind and refill, which the result borrows; a failed call leaves it valid.
configDenseAttendConfig[carry_origin, stats_origin]The heads per token, the carry, the breadth of the candidates, the logit scale, and the telemetry slot.

Returns

One attended row per query row, as wide as the keys, read in place from the arena.

Raises

Error with SHAPE_MISMATCH if dtype names no scalar kind, head_count does not divide the rows, the carry holds fewer states than there are rows, or a lookup yields a null row; with CONFIG_MISMATCH if the graph was frozen under a distance kind.
maxsimLate-interaction scoring: every query row takes its best match within a key, and those maxima sum to that key's score, written in a lent arena. Calls usearch_dense_maxsim.
def maxsim[queries_origin: ImmOrigin, stats_origin: MutOrigin, //](
    self,
    queries: RowsView[queries_origin],
    rows_per_query: Int,
    wanted: Int,
    mut arena: Arena,
    config: DenseMaxsimConfig[stats_origin] = DenseMaxsimConfig(expansion_factor=Int(0), stats=Optional())
) -> DenseProducts[origin_of(arena)]

This is what values_per_key above one exists for. A document is one key holding its token rows, and the walk stays over individual tokens under a plain inner product. Approximate in the usual direction: a key can score below its exact value but never above it.

Parameters

queries_originImmOrigincomptimeThe query rows' origin, inferred from the argument.
stats_originMutOrigincomptimeThe lent telemetry slot's origin, inferred with it.
queriesRowsView[queries_origin]The token rows of every query, laid end to end.
rows_per_queryIntRows in every query; uniform, so ColBERT's padding applies as is.
wantedIntKeys per query - the "k" over documents rather than rows; zero keeps every key scored.
arenaArenamutThe arena to rewind and refill, which the result borrows; a failed call leaves it valid.
configDenseMaxsimConfig[stats_origin]The breadth of the candidates and the telemetry slot.

Returns

Every query's keys, summed maxima largest first, read in place from the arena.

Raises

Error with SHAPE_MISMATCH if rows_per_query does not divide the rows; with CONFIG_MISMATCH if the graph was frozen under a distance kind.
StructMoodWhat an executor does with its threads or streams once it goes idle - usearch_mood_t.
struct Mood

Fields

codec_intThe raw usearch_mood_t value the ABI exchanges.

Values

PARKEDMood(Int32(1))Idle threads sleep; the next call pays a wake-up.
SPINNINGMood(Int32(2))Idle threads stay hot, trading power for the next call's latency.

Conforms to

Copyable, Deinitable, Equatable, ImplicitlyCopyable, Movable, RegisterPassable, TrivialRegisterPassable
StructExecutorThe threads or streams a verb runs on, freed once it and every VRAM arena it made go out of scope.6
struct Executor

Executor(library) owns nothing: every verb handed it runs on the calling thread - single-threaded on RAM, on the handle's device and default stream on VRAM. The spawning constructors fix a kind that must match the residency of every handle they drive. Calls on one executor start in submission order, so threads that genuinely overlap take one apiece.

Fields

libraryLibraryThe loaded engine, held so its symbol table outlives every call made through the handle.
addressAddressThe opaque usearch_executor_t every verb hands back to the engine; NULL_ADDRESS runs inline.
residencyResidencyWhere the arenas it makes live; the caller-thread executor makes host pages.

Conforms to

Deinitable, Movable
__init__The caller-thread executor, which every verb accepts whatever the handle's residency.
def __init__(out self, library: Library)
def __init__(out self, *, library: Library, address: Int, residency: Residency)

Adopts a handle that is already spawned, which is how the factories hand one back.

Parameters

libraryLibraryThe loaded engine, kept so the shared object stays mapped.
addressIntA usearch_executor_t whose lifetime this executor takes over.
residencyResidencyThe residency of the handles it drives, which places the arenas it makes.
for_ramSpawns host workers for RAM-resident indexes. Calls usearch_executor_for_ram.
def for_ram[ram_origin: ImmOrigin, //](
    library: Library,
    ram: RamOptions[ram_origin] = RamOptions(),
    threads: Int = Int(0),
    deferred_limit: Int = Int(0)
) -> Self

Passing the very options the indexes were built with is what makes compute and memory domains agree, leaving no second place to name hardware.

Parameters

ram_originImmOrigincomptimeThe options' borrowed node-id array, inferred from the argument.
libraryLibraryThe loaded engine, kept so the shared object stays mapped.
ramRamOptions[ram_origin]The same options the indexes were initialized with; copied, not borrowed.
threadsIntWorker threads; zero takes 7/8 of the cores those domains carry.
deferred_limitIntDeferred calls it tracks at once, sizing its deferred table; zero takes a default.

Returns

An executor that may drive RAM-resident handles and no others.

Raises

Error if the domains cannot be resolved or the OS refuses the threads.
on_poolSchedules onto a borrowed ForkUnion pool, so several libraries share one set of threads. Calls usearch_executor_on_pool.
def on_pool[ram_origin: ImmOrigin, //](
    library: Library,
    pool: Int,
    ram: RamOptions[ram_origin] = RamOptions(),
    deferred_limit: Int = Int(0)
) -> Self

Parameters

ram_originImmOrigincomptimeThe options' borrowed node-id array, inferred from the argument.
libraryLibraryThe loaded engine, kept so the shared object stays mapped.
poolIntA live ForkUnion fu_pool_t, which must outlive the executor.
ramRamOptions[ram_origin]The same options the indexes were initialized with; copied, not borrowed.
deferred_limitIntDeferred calls it tracks at once, sizing its deferred table; zero takes a default.

Returns

An executor that may drive RAM-resident handles and no others.

Raises

Error if the pool or the domains are refused.
for_nvmeSpawns host workers for NVMe-resident indexes, one submission ring apiece. Calls usearch_executor_for_nvme.
def for_nvme[nvme_origin: ImmOrigin, //](
    library: Library,
    nvme: NvmeOptions[nvme_origin] = NvmeOptions(),
    threads: Int = Int(0),
    deferred_limit: Int = Int(0)
) -> Self

One ring per thread is what keeps submission lock-free: a thread owns its queue outright, so an external-memory walk never coordinates with a sibling to issue a read.

Parameters

nvme_originImmOrigincomptimeThe options' borrowed path array, inferred from the argument.
libraryLibraryThe loaded engine, kept so the shared object stays mapped.
nvmeNvmeOptions[nvme_origin]The same options the indexes were initialized with; copied, not borrowed.
threadsIntWorker threads; zero derives from the devices' queue capabilities.
deferred_limitIntDeferred calls it tracks at once, sizing its deferred table; zero takes a default.

Returns

An executor that may drive NVMe-resident handles and no others.

Raises

Error if a path cannot be opened or the OS refuses the threads.
for_vramOpens one submission stream on every named device, all driven by the calling thread. Calls usearch_executor_for_vram.
def for_vram[vram_origin: ImmOrigin, //](
    library: Library,
    vram: VramOptions[vram_origin] = VramOptions(),
    streams: Int = Int(0),
    scratch_limit: Int = Int(0),
    deferred_limit: Int = Int(0)
) -> Self

One stream per device is the whole design: a single host thread keeps every device fed, and adding host threads would buy nothing, which is why this constructor takes no thread count.

Parameters

vram_originImmOrigincomptimeThe options' borrowed ordinal array, inferred from the argument.
libraryLibraryThe loaded engine, kept so the shared object stays mapped.
vramVramOptions[vram_origin]The same options the indexes were initialized with; copied, not borrowed.
streamsIntBorrowed CUDA streams, one per device in vram order; NULL_ADDRESS creates its own.
scratch_limitIntCeiling on scratch bytes per device; zero lets scratch grow as geometry asks.
deferred_limitIntDeferred calls it tracks at once, sizing its deferred table; zero takes a default.

Returns

An executor that may drive VRAM-resident handles and no others.

Raises

Error if a device cannot be selected or its memory cannot be claimed.
drainWaits for every call submitted before the drain, then adopts mood whenever it next idles. Calls usearch_executor_drain.
def drain(self, mood: Mood = Mood.PARKED)

An executor without threads of its own holds a deferred call until its wait, the next drain or blocking call, or the free of a handle it names, so this runs every call it still holds.

Parameters

moodMoodWhat the threads or streams do once idle; the last drain wins.

Raises

Error for a failure of the executor itself, such as a lost device - never one of a drained call, which reports through its own outcome.
StructDeferredA call submitted to an executor, which owns its outcome and outputs until it is final. Binding-only.4
struct Deferred[C: Call, origin: ImmOrigin]

status reads DEFERRED until then, without blocking, and wait blocks until the call is final and answers its result or raises its failure, as many times as it is asked. The result is the view a blocking call answers, borrowing the same arena. Dropping an unfinished one waits the same way, so nothing the engine still writes is ever freed under it. The origins keep the index, the executor, the arena and every borrowed input alive for as long as this is.

An executor without threads of its own holds a deferred call until its wait, its executor's next drain or blocking call, or the free of a handle it names, so a wait - or the last use of the Deferred, which Mojo destroys at once - runs it there.

Parameters

CCallcomptimeThe verb's crossing, which names the result.
originImmOrigincomptimeThe union of everything the call borrows.

Fields

libraryLibraryThe loaded engine, held so the wait can still reach usearch_outcome_wait.
slotsOwnedPointer[CallSlots[C.Outputs]]The outcome and scalar outputs the engine writes, on the heap since they outlive the verb.
callOptional[C]What the call lends the engine, until a wait concludes it.
answerOptional[C.Result]The result, once a wait found the call succeeded.
failureOptional[Error]The failure, once a wait found the call failed.
generationIntThe stamp served answered at submission, so a result waited on late still reads as stale.

Conforms to

Deinitable, Movable
__init__Submits call deferred, on executor, against index.
def __init__(out self, library: Library, var call: C, index: Int, executor: Int)

Parameters

libraryLibraryThe loaded engine the call crosses into.
callCvarThe verb's crossing, owned until the call is final.
indexIntThe handle the call names, or NULL_ADDRESS for one that names none.
executorIntThe executor the call is submitted to.
__deinit__Waits until the call is final, then frees what it lent. Calls usearch_outcome_wait.
def __deinit__(deinit self)
statusDEFERRED until the call is final, then its final status; never blocks. Calls usearch_outcome_status.
def status(self) -> Status

Returns

The status the outcome holds.
waitBlocks until the call is final, then answers its result or raises its failure, every time it is asked. Calls usearch_outcome_wait.
def wait(mut self) -> ref[self] C.Result

Returns

The result, owned by this Deferred and borrowed for as long as it is.

Raises

Error carrying the call's failure, whether the engine or the binding refused it.