Skip to content

[C API] Expose leanvec ood - #358

Draft
ethanglaser wants to merge 10 commits into
dev/c-apifrom
dev/eglaser-leanvec-ood-capi
Draft

[C API] Expose leanvec ood#358
ethanglaser wants to merge 10 commits into
dev/c-apifrom
dev/eglaser-leanvec-ood-capi

Conversation

@ethanglaser

Copy link
Copy Markdown
Member

No description provided.

ethanglaser and others added 9 commits June 16, 2026 14:21
This pull request enhances the flexibility and predictability of blocked
data structures by introducing explicit control over the number of
elements per block (`blocksize_elements`) in addition to the existing
byte-based blocking (`blocksize_bytes`). It also improves test coverage
to verify the new behavior and edge cases.

**Blocking parameter improvements:**

* Added an optional `blocksize_elements` field to the
`BlockingParameters` struct, allowing users to specify the number of
elements per block directly. If set, this takes precedence over
`blocksize_bytes` when determining block size.
(`include/svs/core/data/simple.h`)

**Testing and validation:**

* Added test to demonstrate the pitfalls of relying solely on
`blocksize_bytes` for memory prediction.
* Extended unit tests to cover scenarios where `blocksize_elements` is
set, including checks for correct block size selection and memory
consumption predictions.
(`tests/svs/core/data/block.cpp`)
Latest macos github actions image was bumped and no longer supports
specified clang versions. This is because we take latest:
https://github.com/intel/ScalableVectorSearch/blob/main/.github/workflows/build-macos.yaml#L35
and as far as I can tell there is not an easy way to track this via
dependabot. Alternative would be to pin it to a version but then it
could sit idle and forgotten.
This pull request refactors the `Blocked` class template to inherit from
its allocator type instead of storing it as a member, and updates the
associated test to use a struct-based allocator. This change simplifies
allocator handling and improves compatibility with standard allocator
patterns.

**Core class refactoring:**

* `Blocked` now inherits from its allocator type (`Alloc`) instead of
storing an `Alloc allocator_` member, which simplifies construction,
copying, and access to the allocator. The `get_allocator()` method now
returns `*this` (as an allocator), and constructors have been updated
accordingly.

**Test improvements:**

* The test for `Blocked` with an allocator has been updated to use a
struct-based allocator (`I`), which provides a `value_type` and integer
value for testing propagation and compatibility with the new
inheritance-based implementation.
## Summary

Adds `get_memory_usage()` returning the total number of bytes a Vamana
index has **allocated** — graph storage + vector data + metadata — so an
integrator can accurately report and bound SVS memory consumption.

Both the static `VamanaIndex` and the dynamic `MutableVamanaIndex` are
covered, and the method is plumbed through the orchestrator layers
(`VamanaInterface` virtual → `VamanaImpl` override → `Vamana` /
`DynamicVamana`) so it is callable on `svs::Vamana` and
`svs::DynamicVamana`.

## Why

Integrators (e.g. memory-bounded module hosts) need to account for
memory SVS allocates via `mmap`/blocked allocators, which bypass the
host's `malloc` accounting. The existing `blocksize_bytes()` reports
only the initial block size and is neither an upper nor lower bound on
the real footprint. `get_memory_usage()` reports the true allocated
total across all blocks plus metadata.

## What

Accounting is **capacity-based** (the bytes the containers have
reserved, not just live elements) so that block over-allocation is
reflected:

| Component | Source |
|---|---|
| `graph_bytes` | `graph_.get_data().capacity() * element_size()` |
| `data_bytes` | `data_.capacity() * data_.element_size()` |
| `metadata_bytes` (dynamic only) | slot-status vector + entry-point
list + estimate of the external/internal ID translation maps |

A `VamanaMemoryUsage { graph_bytes, data_bytes, metadata_bytes, total()
}` struct and `get_memory_breakdown()` expose the per-component split;
`get_memory_usage()` returns `get_memory_breakdown().total()`.

Notes:
- A `detail::dataset_allocated_bytes()` helper uses capacity-based
accounting when the dataset exposes `capacity()` (flat/blocked
`SimpleData`), and falls back to live element count otherwise (e.g.
`SQDataset`). No public accessors or signatures were changed.
- The ID-translation map byte size is not directly queryable; it is
estimated from the entry count (accurate to within a few percent), with
a comment noting the approximation.

## Tests

New unit tests at both the core-index and orchestrator levels for the
static and dynamic indices:
- `tests/svs/index/vamana/index.cpp`,
`tests/svs/index/vamana/dynamic_index.cpp`
- `tests/svs/orchestrators/vamana.cpp`,
`tests/svs/orchestrators/dynamic_vamana.cpp`

Assertions: usage `> 0` for a built index, breakdown components sum to
the total, and `graph_bytes`/`data_bytes` are non-zero. `[managers]` and
the touched index tags pass with no regressions.
Bumps the pinned LTO prebuilt SVS library
(`bindings/cpp/CMakeLists.txt`) from
`svs-shared-library-lto-nightly-2026-05-21-1429` to
`svs-shared-library-lto-nightly-2026-07-21-127`, which includes
`get_memory_usage()` / `get_memory_breakdown()` (#345).

## Why

The `Build and unit tests for C++ runtime bindings (with static library,
ON)` job links the runtime bindings against this prebuilt lib. The
previously-pinned nightly predated #345, so it failed:

```
bindings/cpp/src/dynamic_vamana_index_impl.h:73: error: no member named 'get_memory_breakdown' in 'svs::DynamicVamana'
```

The new nightly was built from `main` (post-#345, via the private-repo
submodule bump intel-innersource#338) and ships the method — verified
the tarball's headers contain `get_memory_breakdown`. This should turn
that CI job green.

Follows the pattern of #311 (Update SVS_URL in binaries).
@ethanglaser ethanglaser changed the title Dev/eglaser leanvec ood capi Expose leanvec ood in C API Jul 28, 2026
@ethanglaser ethanglaser changed the title Expose leanvec ood in C API [C API] Expose leanvec ood Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants