Skip to content

Commit ec1cce5

Browse files
committed
First implementation of the improved runtime Vamana API
1 parent dc6aa10 commit ec1cce5

File tree

11 files changed

+1368
-73
lines changed

11 files changed

+1368
-73
lines changed

bindings/cpp/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,19 @@ set(SVS_RUNTIME_HEADERS
2020
include/IndexSVSImplDefs.h
2121
include/IndexSVSFlatImpl.h
2222
include/IndexSVSVamanaImpl.h
23+
include/training.h
24+
include/vamana_index.h
25+
include/dynamic_vamana_index.h
2326
)
2427

2528
set(SVS_RUNTIME_SOURCES
2629
src/IndexSVSImplUtils.h
30+
src/svs_runtime_utils.h
31+
src/dynamic_vamana_index_impl.h
2732
src/IndexSVSFlatImpl.cpp
2833
src/IndexSVSVamanaImpl.cpp
34+
src/training.cpp
35+
src/dynamic_vamana_index.cpp
2936
)
3037

3138
option(SVS_RUNTIME_ENABLE_LVQ_LEANVEC "Enable compilation of SVS runtime with LVQ and LeanVec support" ON)

bindings/cpp/include/IndexSVSImplDefs.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,19 @@ namespace svs {
3131
namespace runtime {
3232
enum class MetricType { L2, INNER_PRODUCT };
3333

34+
enum class StorageKind {
35+
FP32, FP16, SQI8,
36+
LVQ4x0, LVQ4x4, LVQ4x8,
37+
LeanVec4x4, LeanVec4x8, LeanVec8x8,
38+
};
39+
3440
enum class ErrorCode {
3541
SUCCESS = 0,
3642
UNKNOWN_ERROR = 1,
3743
INVALID_ARGUMENT = 2,
3844
NOT_IMPLEMENTED = 3,
39-
NOT_INITIALIZED = 4
45+
NOT_INITIALIZED = 4,
46+
RUNTIME_ERROR = 5
4047
};
4148

4249
struct Status {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2025 Intel Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
#include "IndexSVSImplDefs.h"
19+
#include "vamana_index.h"
20+
#include "training.h"
21+
22+
#include <cstddef>
23+
#include <istream>
24+
#include <ostream>
25+
26+
namespace svs {
27+
namespace runtime {
28+
29+
// Abstract interface for Dynamic Vamana-based indexes.
30+
struct SVS_RUNTIME_API DynamicVamanaIndex : public VamanaIndex {
31+
32+
virtual Status add(size_t n, const size_t* labels, const float* x) noexcept = 0;
33+
virtual Status remove_selected(size_t* num_removed, const IDFilter& selector) noexcept = 0;
34+
virtual Status remove(size_t n, const size_t* labels) noexcept = 0;
35+
36+
virtual Status reset() noexcept = 0;
37+
38+
// Static constructors and destructors
39+
static Status build(
40+
DynamicVamanaIndex** index,
41+
size_t dim,
42+
MetricType metric,
43+
StorageKind storage_kind,
44+
const VamanaIndex::BuildParams& params,
45+
const VamanaIndex::SearchParams& default_search_params = {10, 10, 0, 0}
46+
) noexcept;
47+
48+
static Status destroy(DynamicVamanaIndex* index) noexcept;
49+
50+
virtual Status save(std::ostream& out) const noexcept = 0;
51+
static Status load(DynamicVamanaIndex** index, std::istream& in, MetricType metric, StorageKind storage_kind) noexcept;
52+
};
53+
54+
struct SVS_RUNTIME_API DynamicVamanaIndexLeanVec : public DynamicVamanaIndex {
55+
// Specialization to build LeanVec-based Vamana index with specified leanvec dims
56+
static Status build(
57+
DynamicVamanaIndex** index,
58+
size_t dim,
59+
MetricType metric,
60+
StorageKind storage_kind,
61+
size_t leanvec_dims,
62+
const VamanaIndex::BuildParams& params,
63+
const VamanaIndex::SearchParams& default_search_params = {10, 10, 0, 0}
64+
) noexcept;
65+
66+
// Specialization to build LeanVec-based Vamana index with provided training data
67+
static Status build(
68+
DynamicVamanaIndex** index,
69+
size_t dim,
70+
MetricType metric,
71+
StorageKind storage_kind,
72+
const LeanVecTrainingData* training_data,
73+
const VamanaIndex::BuildParams& params,
74+
const VamanaIndex::SearchParams& default_search_params = {10, 10, 0, 0}
75+
) noexcept;
76+
};
77+
78+
} // namespace runtime
79+
} // namespace svs

bindings/cpp/include/training.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2025 Intel Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
#include "IndexSVSImplDefs.h"
19+
20+
#include <cstddef>
21+
#include <istream>
22+
#include <ostream>
23+
24+
namespace svs {
25+
namespace runtime {
26+
struct SVS_RUNTIME_API LeanVecTrainingData {
27+
virtual ~LeanVecTrainingData() = 0;
28+
Status build(
29+
LeanVecTrainingData** training_data,
30+
size_t dim,
31+
size_t n,
32+
const float* x,
33+
size_t leanvec_dims
34+
) noexcept;
35+
36+
static Status destroy(LeanVecTrainingData* training_data) noexcept;
37+
38+
virtual Status save(std::ostream& out) const noexcept;
39+
static Status load(LeanVecTrainingData** training_data, std::istream& in) noexcept;
40+
};
41+
} // namespace runtime
42+
} // namespace svs

bindings/cpp/include/vamana_index.h

Lines changed: 6 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,16 @@
1818
#include "IndexSVSImplDefs.h"
1919

2020
#include <cstddef>
21-
#include <istream>
22-
#include <memory>
23-
#include <numeric>
24-
#include <ostream>
25-
#include <vector>
2621

2722
namespace svs {
2823
namespace runtime {
2924

3025
// Abstract interface for Vamana-based indexes.
26+
// NOTE VamanaIndex is not implemented directly, only DynamicVamanaIndex is implemented.
3127
struct SVS_RUNTIME_API VamanaIndex {
32-
enum StorageKind {
33-
FP32, FP16, SQI8,
34-
LVQ4x0, LVQ4x4, LVQ4x8,
35-
LeanVec4x4, LeanVec4x8, LeanVec8x8,
36-
};
28+
virtual ~VamanaIndex() = 0;
3729

38-
// TODO:
39-
// 1. Should StorageKind, metric, be a part of BuildParams?
40-
// 2. Does it make sense to have "Common" BuildParams{dim, metric} struct for other index algos (Flat, IVF)?
41-
// Or dim, metric, storage kind should be passed separately to the build() method?
42-
// What about storage kind in Flat, IVF?
4330
struct BuildParams {
44-
size_t dim;
4531
size_t graph_max_degree;
4632
size_t prune_to = 0;
4733
float alpha = 0;
@@ -51,21 +37,12 @@ struct SVS_RUNTIME_API VamanaIndex {
5137
};
5238

5339
struct SearchParams {
54-
size_t search_window_size = 0;
55-
size_t search_buffer_capacity = 0;
40+
size_t search_window_size = 10;
41+
size_t search_buffer_capacity = 10;
42+
size_t prefetch_lookahead = 0;
43+
size_t prefetch_step = 0;
5644
};
5745

58-
// Unused for now:
59-
virtual size_t size() const noexcept = 0;
60-
virtual size_t dimensions() const noexcept = 0;
61-
virtual MetricType metric_type() const noexcept = 0;
62-
virtual StorageKind get_storage_kind() const noexcept = 0;
63-
64-
virtual Status add(size_t n, const size_t* labels, const float* x) noexcept = 0;
65-
virtual Status remove_selected(size_t* num_removed, const IDFilter& selector) noexcept = 0;
66-
// Further method for deletion can be added later:
67-
// virtual Status remove(size_t n, const size_t* labels) noexcept = 0;
68-
6946
virtual Status search(
7047
size_t n,
7148
const float* x,
@@ -84,48 +61,6 @@ struct SVS_RUNTIME_API VamanaIndex {
8461
const SearchParams* params = nullptr,
8562
IDFilter* filter = nullptr
8663
) const noexcept = 0;
87-
88-
virtual Status reset() noexcept = 0;
89-
// TODO: Does it make sense to rename it to "save()"?
90-
virtual Status serialize(std::ostream& out) const noexcept = 0;
91-
92-
// Static constructors and destructors
93-
static Status build(
94-
VamanaIndex** index,
95-
MetricType metric,
96-
StorageKind storage_kind,
97-
const VamanaIndex::BuildParams& params,
98-
const VamanaIndex::SearchParams& default_search_params = {10,10}
99-
) noexcept;
100-
101-
static Status destroy(VamanaIndex* index) noexcept;
102-
// TODO: Does it make sense to rename it to "load()"?
103-
// TODO: is it possible to get metric and storage kind from the stream instead of passing them explicitly?
104-
static Status deserialize(VamanaIndex** index, std::istream& in, MetricType metric, VamanaIndex::StorageKind storage_kind) noexcept;
105-
};
106-
107-
struct SVS_RUNTIME_API VamanaIndexLeanVecFactory {
108-
static Status train(
109-
VamanaIndexLeanVecFactory** factory,
110-
size_t d,
111-
size_t n,
112-
const float* x,
113-
size_t leanvec_dims
114-
) noexcept;
115-
116-
static Status destroy(VamanaIndexLeanVecFactory* factory) noexcept;
117-
118-
virtual Status serialize(std::ostream& out) const noexcept;
119-
static Status deserialize(VamanaIndexLeanVecFactory** factory, std::istream& in) noexcept;
120-
121-
virtual Status buildIndex(
122-
VamanaIndex** index,
123-
size_t dim,
124-
MetricType metric,
125-
const VamanaIndex::BuildParams& params,
126-
const VamanaIndex::SearchParams& default_search_params = {}
127-
) noexcept;
12864
};
129-
13065
} // namespace runtime
13166
} // namespace svs

0 commit comments

Comments
 (0)