Files
wifi-densepose/crates/rvf/rvf-wasm/README.md
ruv d803bfe2b1 Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
2026-02-28 14:39:40 -05:00

133 lines
5.0 KiB
Markdown

# rvf-wasm
WASM microkernel and control plane for running RuVector Format operations in the browser and at the edge.
## Overview
`rvf-wasm` compiles the core RVF runtime to WebAssembly for use in browsers, Cloudflare Workers, and other WASM environments:
- **Compact binary** -- optimized with `opt-level = "z"` and LTO
- **No-std compatible** -- runs with a lightweight `dlmalloc` allocator
- **Browser-ready** -- works with `wasm-bindgen` or standalone instantiation
- **Full control plane** -- create, query, modify, and export `.rvf` stores entirely in-memory
## Build
```bash
cargo build --target wasm32-unknown-unknown --release -p rvf-wasm
```
## API
### Tile Compute (14 exports)
Low-level distance computation, quantization, and HNSW navigation for the Cognitum tile architecture:
| Export | Description |
|--------|-------------|
| `rvf_init` | Initialize tile with configuration |
| `rvf_load_query` | Load query vector into scratch |
| `rvf_load_block` | Load vector block into SIMD scratch |
| `rvf_distances` | Compute distances (L2, IP, cosine, hamming) |
| `rvf_topk_merge` | Merge distances into top-K heap |
| `rvf_topk_read` | Read sorted top-K results |
| `rvf_load_sq_params` | Load scalar quantization parameters |
| `rvf_dequant_i8` | Dequantize int8 to fp16 |
| `rvf_load_pq_codebook` | Load PQ codebook for asymmetric distance |
| `rvf_pq_distances` | Compute PQ distances |
| `rvf_load_neighbors` | Load HNSW neighbor list |
| `rvf_greedy_step` | HNSW greedy search step |
| `rvf_verify_header` | Verify segment header magic/version |
| `rvf_crc32c` | Compute CRC32C checksum |
### Control Plane (10 exports)
In-memory store operations for creating and querying `.rvf` data without filesystem access:
| Export | Description |
|--------|-------------|
| `rvf_store_create(dim, metric) -> handle` | Create in-memory store |
| `rvf_store_open(buf_ptr, buf_len) -> handle` | Parse `.rvf` bytes into queryable store |
| `rvf_store_ingest(handle, vecs, ids, count)` | Add vectors |
| `rvf_store_query(handle, query, k, metric, out)` | k-NN search |
| `rvf_store_delete(handle, ids, count)` | Soft-delete by ID |
| `rvf_store_count(handle)` | Live vector count |
| `rvf_store_dimension(handle)` | Get dimensionality |
| `rvf_store_status(handle, out)` | Write 20-byte status |
| `rvf_store_export(handle, out, len)` | Serialize to `.rvf` bytes |
| `rvf_store_close(handle)` | Free store |
### Segment Inspection (4 exports)
Parse and inspect `.rvf` file structure from raw bytes:
| Export | Description |
|--------|-------------|
| `rvf_parse_header(buf, len, out)` | Parse a 64-byte segment header |
| `rvf_segment_count(buf, len)` | Count segments in buffer |
| `rvf_segment_info(buf, len, idx, out)` | Get segment details by index |
| `rvf_verify_checksum(buf, len)` | Verify CRC32C integrity |
### Witness Chain Verification (2 exports)
Verify SHAKE-256 witness chains from WITNESS_SEG payloads:
| Export | Description |
|--------|-------------|
| `rvf_witness_verify(chain_ptr, chain_len) -> i32` | Verify full chain integrity; returns entry count or negative error (-2 = truncated, -3 = hash mismatch) |
| `rvf_witness_count(chain_len) -> i32` | Count entries without full verification (chain_len / 73) |
These exports enable browser-side verification of acceptance test artifacts and audit trails without any backend. See [ADR-037](../../docs/adr/ADR-037-publishable-rvf-acceptance-test.md).
### Memory Management (2 exports)
| Export | Description |
|--------|-------------|
| `rvf_alloc(size) -> ptr` | Allocate memory for JS interop |
| `rvf_free(ptr, size)` | Free allocated memory |
## Usage from JavaScript
```javascript
const wasm = await WebAssembly.instantiate(wasmBytes);
const { rvf_store_create, rvf_store_ingest, rvf_store_query,
rvf_store_export, rvf_store_close, rvf_alloc, rvf_free } = wasm.instance.exports;
// Create a 4-dimensional store with L2 metric
const handle = rvf_store_create(4, 0);
// Allocate and copy vectors into WASM memory
const vecs = new Float32Array([1,0,0,0, 0,1,0,0, 0,0,1,0]);
const ids = new BigUint64Array([0n, 1n, 2n]);
const vecPtr = rvf_alloc(vecs.byteLength);
const idPtr = rvf_alloc(ids.byteLength);
new Uint8Array(wasm.instance.exports.memory.buffer, vecPtr, vecs.byteLength)
.set(new Uint8Array(vecs.buffer));
new Uint8Array(wasm.instance.exports.memory.buffer, idPtr, ids.byteLength)
.set(new Uint8Array(ids.buffer));
// Ingest
rvf_store_ingest(handle, vecPtr, idPtr, 3);
rvf_free(vecPtr, vecs.byteLength);
rvf_free(idPtr, ids.byteLength);
// Query
const queryVec = new Float32Array([1,0,0,0]);
const qPtr = rvf_alloc(16);
new Uint8Array(wasm.instance.exports.memory.buffer, qPtr, 16)
.set(new Uint8Array(queryVec.buffer));
const outPtr = rvf_alloc(12 * 3); // 3 results * (8 bytes id + 4 bytes dist)
const count = rvf_store_query(handle, qPtr, 3, 0, outPtr);
// Export to .rvf bytes
const exportBuf = rvf_alloc(65536);
const written = rvf_store_export(handle, exportBuf, 65536);
const rvfBytes = new Uint8Array(wasm.instance.exports.memory.buffer, exportBuf, written);
rvf_store_close(handle);
```
## License
MIT OR Apache-2.0