Skip to content

Commit e070805

Browse files
committed
move preprocessor logic to choose if cosine preprocessor is needed to CreateIndexComponents:
pass bool is_normalized get distnce function according to original metric get pp according to is_normalized && metric == VecSimMetric_Cosine, and remove this logic from the indexes factories. add dataSize member to AbstractIndexInitParams add VecSimType_INT8 type introduce VecSimParams_GetDataSize: returns datasize introduce and implement GetNormalizeFunc<int8_t> thtat returns int8_normalizeVector int8_normalizeVector computes the norm and stores it at the emd of argument vector.
1 parent 5e16397 commit e070805

File tree

14 files changed

+99
-51
lines changed

14 files changed

+99
-51
lines changed

src/VecSim/index_factories/brute_force_factory.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ inline VecSimIndex *NewIndex_ChooseMultiOrSingle(const BFParams *params,
3333
static AbstractIndexInitParams NewAbstractInitParams(const VecSimParams *params) {
3434

3535
const BFParams *bfParams = &params->algoParams.bfParams;
36+
size_t dataSize = VecSimParams_GetDataSize(bfParams->type, bfParams->dim, bfParams->metric);
3637
AbstractIndexInitParams abstractInitParams = {.allocator =
3738
VecSimAllocator::newVecsimAllocator(),
3839
.dim = bfParams->dim,
3940
.vecType = bfParams->type,
41+
.dataSize = dataSize,
4042
.metric = bfParams->metric,
4143
.blockSize = bfParams->blockSize,
4244
.multi = bfParams->multi,
@@ -52,30 +54,23 @@ VecSimIndex *NewIndex(const VecSimParams *params, bool is_normalized) {
5254

5355
VecSimIndex *NewIndex(const BFParams *bfparams, const AbstractIndexInitParams &abstractInitParams,
5456
bool is_normalized) {
55-
// If the index metric is Cosine, and is_normalized == true, we will skip normalizing vectors
56-
// and query blobs.
57-
VecSimMetric metric;
58-
if (is_normalized && bfparams->metric == VecSimMetric_Cosine) {
59-
metric = VecSimMetric_IP;
60-
} else {
61-
metric = bfparams->metric;
62-
}
57+
6358
if (bfparams->type == VecSimType_FLOAT32) {
6459
IndexComponents<float, float> indexComponents = CreateIndexComponents<float, float>(
65-
abstractInitParams.allocator, metric, bfparams->dim);
60+
abstractInitParams.allocator, bfparams->metric, bfparams->dim, is_normalized);
6661
return NewIndex_ChooseMultiOrSingle<float>(bfparams, abstractInitParams, indexComponents);
6762
} else if (bfparams->type == VecSimType_FLOAT64) {
6863
IndexComponents<double, double> indexComponents = CreateIndexComponents<double, double>(
69-
abstractInitParams.allocator, metric, bfparams->dim);
64+
abstractInitParams.allocator, bfparams->metric, bfparams->dim, is_normalized);
7065
return NewIndex_ChooseMultiOrSingle<double>(bfparams, abstractInitParams, indexComponents);
7166
} else if (bfparams->type == VecSimType_BFLOAT16) {
7267
IndexComponents<bfloat16, float> indexComponents = CreateIndexComponents<bfloat16, float>(
73-
abstractInitParams.allocator, metric, bfparams->dim);
68+
abstractInitParams.allocator, bfparams->metric, bfparams->dim, is_normalized);
7469
return NewIndex_ChooseMultiOrSingle<bfloat16, float>(bfparams, abstractInitParams,
7570
indexComponents);
7671
} else if (bfparams->type == VecSimType_FLOAT16) {
7772
IndexComponents<float16, float> indexComponents = CreateIndexComponents<float16, float>(
78-
abstractInitParams.allocator, metric, bfparams->dim);
73+
abstractInitParams.allocator, bfparams->metric, bfparams->dim, is_normalized);
7974
return NewIndex_ChooseMultiOrSingle<float16, float>(bfparams, abstractInitParams,
8075
indexComponents);
8176
}

src/VecSim/index_factories/components/components_factory.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,24 @@
1414

1515
template <typename DataType, typename DistType>
1616
IndexComponents<DataType, DistType>
17-
CreateIndexComponents(std::shared_ptr<VecSimAllocator> allocator, VecSimMetric metric, size_t dim) {
17+
CreateIndexComponents(std::shared_ptr<VecSimAllocator> allocator, VecSimMetric metric, size_t dim,
18+
bool is_normalized) {
1819
unsigned char alignment = 0;
1920
spaces::dist_func_t<DistType> distFunc =
2021
spaces::GetDistFunc<DataType, DistType>(metric, dim, &alignment);
2122
// Currently we have only one distance calculator implementation
2223
auto indexCalculator = new (allocator) DistanceCalculatorCommon<DistType>(allocator, distFunc);
2324

24-
PreprocessorsContainerParams ppParams = {.metric = metric, .dim = dim, .alignment = alignment};
25+
// If the index metric is Cosine, and is_normalized == true, we will skip normalizing vectors
26+
// and query blobs.
27+
VecSimMetric pp_metric;
28+
if (is_normalized && metric == VecSimMetric_Cosine) {
29+
pp_metric = VecSimMetric_IP;
30+
} else {
31+
pp_metric = metric;
32+
}
33+
PreprocessorsContainerParams ppParams = {
34+
.metric = pp_metric, .dim = dim, .alignment = alignment};
2535
auto preprocessors = CreatePreprocessorsContainer<DataType>(allocator, ppParams);
2636

2737
return {indexCalculator, preprocessors};

src/VecSim/index_factories/hnsw_factory.cpp

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,14 @@ NewIndex_ChooseMultiOrSingle(const HNSWParams *params,
3333

3434
static AbstractIndexInitParams NewAbstractInitParams(const VecSimParams *params) {
3535
const HNSWParams *hnswParams = &params->algoParams.hnswParams;
36+
37+
size_t dataSize =
38+
VecSimParams_GetDataSize(hnswParams->type, hnswParams->dim, hnswParams->metric);
3639
AbstractIndexInitParams abstractInitParams = {.allocator =
3740
VecSimAllocator::newVecsimAllocator(),
3841
.dim = hnswParams->dim,
3942
.vecType = hnswParams->type,
43+
.dataSize = dataSize,
4044
.metric = hnswParams->metric,
4145
.blockSize = hnswParams->blockSize,
4246
.multi = hnswParams->multi,
@@ -48,34 +52,25 @@ VecSimIndex *NewIndex(const VecSimParams *params, bool is_normalized) {
4852
const HNSWParams *hnswParams = &params->algoParams.hnswParams;
4953
AbstractIndexInitParams abstractInitParams = NewAbstractInitParams(params);
5054

51-
// If the index metric is Cosine, and is_normalized == true, we will skip normalizing vectors
52-
// and query blobs.
53-
VecSimMetric metric;
54-
if (is_normalized && hnswParams->metric == VecSimMetric_Cosine) {
55-
metric = VecSimMetric_IP;
56-
} else {
57-
metric = hnswParams->metric;
58-
}
59-
6055
if (hnswParams->type == VecSimType_FLOAT32) {
6156
IndexComponents<float, float> indexComponents = CreateIndexComponents<float, float>(
62-
abstractInitParams.allocator, metric, hnswParams->dim);
57+
abstractInitParams.allocator, hnswParams->metric, hnswParams->dim, is_normalized);
6358
return NewIndex_ChooseMultiOrSingle<float>(hnswParams, abstractInitParams, indexComponents);
6459

6560
} else if (hnswParams->type == VecSimType_FLOAT64) {
6661
IndexComponents<double, double> indexComponents = CreateIndexComponents<double, double>(
67-
abstractInitParams.allocator, metric, hnswParams->dim);
62+
abstractInitParams.allocator, hnswParams->metric, hnswParams->dim, is_normalized);
6863
return NewIndex_ChooseMultiOrSingle<double>(hnswParams, abstractInitParams,
6964
indexComponents);
7065

7166
} else if (hnswParams->type == VecSimType_BFLOAT16) {
7267
IndexComponents<bfloat16, float> indexComponents = CreateIndexComponents<bfloat16, float>(
73-
abstractInitParams.allocator, metric, hnswParams->dim);
68+
abstractInitParams.allocator, hnswParams->metric, hnswParams->dim, is_normalized);
7469
return NewIndex_ChooseMultiOrSingle<bfloat16, float>(hnswParams, abstractInitParams,
7570
indexComponents);
7671
} else if (hnswParams->type == VecSimType_FLOAT16) {
7772
IndexComponents<float16, float> indexComponents = CreateIndexComponents<float16, float>(
78-
abstractInitParams.allocator, metric, hnswParams->dim);
73+
abstractInitParams.allocator, hnswParams->metric, hnswParams->dim, is_normalized);
7974
return NewIndex_ChooseMultiOrSingle<float16, float>(hnswParams, abstractInitParams,
8075
indexComponents);
8176
}
@@ -203,32 +198,25 @@ VecSimIndex *NewIndex(const std::string &location, bool is_normalized) {
203198
VecSimParams vecsimParams = {.algo = VecSimAlgo_HNSWLIB,
204199
.algoParams = {.hnswParams = HNSWParams{params}}};
205200

206-
VecSimMetric metric;
207-
if (is_normalized && params.metric == VecSimMetric_Cosine) {
208-
metric = VecSimMetric_IP;
209-
} else {
210-
metric = params.metric;
211-
}
212-
213201
AbstractIndexInitParams abstractInitParams = NewAbstractInitParams(&vecsimParams);
214202
if (params.type == VecSimType_FLOAT32) {
215203
IndexComponents<float, float> indexComponents = CreateIndexComponents<float, float>(
216-
abstractInitParams.allocator, metric, abstractInitParams.dim);
204+
abstractInitParams.allocator, params.metric, abstractInitParams.dim, is_normalized);
217205
return NewIndex_ChooseMultiOrSingle<float>(input, &params, abstractInitParams,
218206
indexComponents, version);
219207
} else if (params.type == VecSimType_FLOAT64) {
220208
IndexComponents<double, double> indexComponents = CreateIndexComponents<double, double>(
221-
abstractInitParams.allocator, metric, abstractInitParams.dim);
209+
abstractInitParams.allocator, params.metric, abstractInitParams.dim, is_normalized);
222210
return NewIndex_ChooseMultiOrSingle<double>(input, &params, abstractInitParams,
223211
indexComponents, version);
224212
} else if (params.type == VecSimType_BFLOAT16) {
225213
IndexComponents<bfloat16, float> indexComponents = CreateIndexComponents<bfloat16, float>(
226-
abstractInitParams.allocator, metric, abstractInitParams.dim);
214+
abstractInitParams.allocator, params.metric, abstractInitParams.dim, is_normalized);
227215
return NewIndex_ChooseMultiOrSingle<bfloat16, float>(input, &params, abstractInitParams,
228216
indexComponents, version);
229217
} else if (params.type == VecSimType_FLOAT16) {
230218
IndexComponents<float16, float> indexComponents = CreateIndexComponents<float16, float>(
231-
abstractInitParams.allocator, metric, abstractInitParams.dim);
219+
abstractInitParams.allocator, params.metric, abstractInitParams.dim, is_normalized);
232220
return NewIndex_ChooseMultiOrSingle<float16, float>(input, &params, abstractInitParams,
233221
indexComponents, version);
234222
} else {

src/VecSim/index_factories/tiered_factory.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@ inline VecSimIndex *NewIndex(const TieredIndexParams *params) {
3434
.blockSize = params->primaryIndexParams->algoParams.hnswParams.blockSize};
3535

3636
std::shared_ptr<VecSimAllocator> flat_allocator = VecSimAllocator::newVecsimAllocator();
37+
size_t dataSize = VecSimParams_GetDataSize(bf_params.type, bf_params.dim, bf_params.metric);
38+
3739
AbstractIndexInitParams abstractInitParams = {.allocator = flat_allocator,
3840
.dim = bf_params.dim,
3941
.vecType = bf_params.type,
42+
.dataSize = dataSize,
4043
.metric = bf_params.metric,
4144
.blockSize = bf_params.blockSize,
4245
.multi = bf_params.multi,

src/VecSim/spaces/normalize/compute_norm.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@
66

77
#pragma once
88

9-
#include "VecSim/types/bfloat16.h"
10-
#include "VecSim/types/float16.h"
119
#include <cmath>
12-
#include <vector>
13-
14-
using bfloat16 = vecsim_types::bfloat16;
15-
using float16 = vecsim_types::float16;
1610

1711
namespace spaces {
1812

@@ -21,12 +15,11 @@ static inline float IntegralType_ComputeNorm(const DataType *vec, const size_t d
2115
int sum = 0;
2216

2317
for (size_t i = 0; i < dim; i++) {
24-
int val = static_cast<int>(vec[i]);
25-
sum += val * val;
18+
// No need to cast to int because c++ integer promotion ensures vec[i] is promoted to int
19+
// before multiplication.
20+
sum += vec[i] * vec[i];
2621
}
27-
float norm = sqrt(sum);
22+
return sqrt(sum);
2823
}
2924

30-
31-
3225
} // namespace spaces

src/VecSim/spaces/normalize/normalize_naive.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "VecSim/types/bfloat16.h"
1010
#include "VecSim/types/float16.h"
11+
#include "compute_norm.h"
1112
#include <cmath>
1213
#include <vector>
1314

@@ -73,4 +74,13 @@ static inline void float16_normalizeVector(void *vec, const size_t dim) {
7374
}
7475
}
7576

77+
static inline void int8_normalizeVector(void *vec, const size_t dim) {
78+
int8_t *input_vector = (int8_t *)vec;
79+
80+
float norm = IntegralType_ComputeNorm<int8_t>(input_vector, dim);
81+
82+
// Store norm at the end of the vector.
83+
*(float *)(input_vector + dim) = norm;
84+
}
85+
7686
} // namespace spaces

src/VecSim/spaces/spaces.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,10 @@ normalizeVector_f<vecsim_types::float16> GetNormalizeFunc<vecsim_types::float16>
9494
return float16_normalizeVector;
9595
}
9696

97+
/** The returned function computes the norm and stores it at the end of the given vector */
98+
template <>
99+
normalizeVector_f<int8_t> GetNormalizeFunc<int8_t>(void) {
100+
return int8_normalizeVector;
101+
}
102+
97103
} // namespace spaces

src/VecSim/utils/vec_utils.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const char *VecSimCommonStrings::FLOAT32_STRING = "FLOAT32";
2727
const char *VecSimCommonStrings::FLOAT64_STRING = "FLOAT64";
2828
const char *VecSimCommonStrings::BFLOAT16_STRING = "BFLOAT16";
2929
const char *VecSimCommonStrings::FLOAT16_STRING = "FLOAT16";
30+
const char *VecSimCommonStrings::INT8_STRING = "INT8";
3031
const char *VecSimCommonStrings::INT32_STRING = "INT32";
3132
const char *VecSimCommonStrings::INT64_STRING = "INT64";
3233

@@ -147,6 +148,8 @@ const char *VecSimType_ToString(VecSimType vecsimType) {
147148
return VecSimCommonStrings::BFLOAT16_STRING;
148149
case VecSimType_FLOAT16:
149150
return VecSimCommonStrings::FLOAT16_STRING;
151+
case VecSimType_INT8:
152+
return VecSimCommonStrings::INT8_STRING;
150153
case VecSimType_INT32:
151154
return VecSimCommonStrings::INT32_STRING;
152155
case VecSimType_INT64:
@@ -195,10 +198,20 @@ size_t VecSimType_sizeof(VecSimType type) {
195198
return sizeof(bfloat16);
196199
case VecSimType_FLOAT16:
197200
return sizeof(float16);
201+
case VecSimType_INT8:
202+
return sizeof(int8_t);
198203
case VecSimType_INT32:
199204
return sizeof(int32_t);
200205
case VecSimType_INT64:
201206
return sizeof(int64_t);
202207
}
203208
return 0;
204209
}
210+
211+
size_t VecSimParams_GetDataSize(VecSimType type, size_t dim, VecSimMetric metric) {
212+
size_t dataSize = VecSimType_sizeof(type) * dim;
213+
if (type == VecSimType_INT8 && metric == VecSimMetric_Cosine) {
214+
dataSize += sizeof(float); // For the norm
215+
}
216+
return dataSize;
217+
}

src/VecSim/utils/vec_utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct VecSimCommonStrings {
2727
static const char *FLOAT64_STRING;
2828
static const char *BFLOAT16_STRING;
2929
static const char *FLOAT16_STRING;
30+
static const char *INT8_STRING;
3031
static const char *INT32_STRING;
3132
static const char *INT64_STRING;
3233

@@ -90,3 +91,6 @@ const char *VecSimMetric_ToString(VecSimMetric vecsimMetric);
9091
const char *VecSimSearchMode_ToString(VecSearchMode vecsimSearchMode);
9192

9293
size_t VecSimType_sizeof(VecSimType vecsimType);
94+
95+
/** Returns the size in bytes of a stored or query vector */
96+
size_t VecSimParams_GetDataSize(VecSimType type, size_t dim, VecSimMetric metric);

src/VecSim/vec_sim_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ typedef enum {
3636
VecSimType_FLOAT64,
3737
VecSimType_BFLOAT16,
3838
VecSimType_FLOAT16,
39+
VecSimType_INT8,
3940
VecSimType_INT32,
4041
VecSimType_INT64
4142
} VecSimType;

0 commit comments

Comments
 (0)