Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .install/install_cmake.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ MODE=$1 # whether to install using sudo or not

if [[ $OS_TYPE = 'Darwin' ]]
then
brew install cmake
if ! command -v cmake &> /dev/null; then
brew install cmake
else
echo "cmake already installed"
fi
else
if [[ $processor = 'x86_64' ]]
then
Expand Down
2 changes: 1 addition & 1 deletion cmake/cpu_features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ option(CMAKE_POSITION_INDEPENDENT_CODE "" ON)
FetchContent_Declare(
cpu_features
GIT_REPOSITORY https://github.com/google/cpu_features.git
GIT_TAG v0.9.0
GIT_TAG v0.10.1
)
FetchContent_MakeAvailable(cpu_features)
17 changes: 8 additions & 9 deletions src/VecSim/algorithms/brute_force/brute_force.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,11 @@ BruteForceIndex<DataType, DistType>::topKQuery(const void *queryBlob, size_t k,
return rl;
}

DataType normalized_blob[this->dim]; // This will be use only if metric == VecSimMetric_Cosine.
auto normalized_blob = this->getAllocator()->allocate_unique(this->dim * sizeof(DataType));
if (this->metric == VecSimMetric_Cosine) {
memcpy(normalized_blob, queryBlob, this->dim * sizeof(DataType));
normalizeVector(normalized_blob, this->dim);

queryBlob = normalized_blob;
memcpy(normalized_blob.get(), queryBlob, this->dim * sizeof(DataType));
normalizeVector(static_cast<DataType *>(normalized_blob.get()), this->dim);
queryBlob = normalized_blob.get();
}

DistType upperBound = std::numeric_limits<DistType>::lowest();
Expand Down Expand Up @@ -296,11 +295,11 @@ BruteForceIndex<DataType, DistType>::rangeQuery(const void *queryBlob, double ra
void *timeoutCtx = queryParams ? queryParams->timeoutCtx : nullptr;
this->last_mode = RANGE_QUERY;

DataType normalized_blob[this->dim]; // This will be use only if metric == VecSimMetric_Cosine.
auto normalized_blob = this->getAllocator()->allocate_unique(this->dim * sizeof(DataType));
if (this->metric == VecSimMetric_Cosine) {
memcpy(normalized_blob, queryBlob, this->dim * sizeof(DataType));
normalizeVector(normalized_blob, this->dim);
queryBlob = normalized_blob;
memcpy(normalized_blob.get(), queryBlob, this->dim * sizeof(DataType));
normalizeVector(static_cast<DataType *>(normalized_blob.get()), this->dim);
queryBlob = normalized_blob.get();
}

// Compute scores in every block and save results that are within the range.
Expand Down
8 changes: 4 additions & 4 deletions src/VecSim/algorithms/brute_force/brute_force_multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ class BruteForceIndex_Multi : public BruteForceIndex<DataType, DistType> {
template <typename DataType, typename DistType>
int BruteForceIndex_Multi<DataType, DistType>::addVector(const void *vector_data, labelType label) {

DataType normalized_blob[this->dim]; // This will be use only if metric == VecSimMetric_Cosine.
auto normalized_blob = this->getAllocator()->allocate_unique(this->dim * sizeof(DataType));
if (this->metric == VecSimMetric_Cosine) {
memcpy(normalized_blob, vector_data, this->dim * sizeof(DataType));
normalizeVector(normalized_blob, this->dim);
vector_data = normalized_blob;
memcpy(normalized_blob.get(), vector_data, this->dim * sizeof(DataType));
normalizeVector(static_cast<DataType *>(normalized_blob.get()), this->dim);
vector_data = normalized_blob.get();
}

return this->appendVector(vector_data, label);
Expand Down
8 changes: 4 additions & 4 deletions src/VecSim/algorithms/brute_force/brute_force_single.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ template <typename DataType, typename DistType>
int BruteForceIndex_Single<DataType, DistType>::addVector(const void *vector_data,
labelType label) {

DataType normalized_blob[this->dim]; // This will be use only if metric == VecSimMetric_Cosine
auto normalized_blob = this->getAllocator()->allocate_unique(this->dim * sizeof(DataType));
if (this->metric == VecSimMetric_Cosine) {
memcpy(normalized_blob, vector_data, this->dim * sizeof(DataType));
normalizeVector(normalized_blob, this->dim);
vector_data = normalized_blob;
memcpy(normalized_blob.get(), vector_data, this->dim * sizeof(DataType));
normalizeVector(static_cast<DataType *>(normalized_blob.get()), this->dim);
vector_data = normalized_blob.get();
}

auto optionalID = this->labelToIdLookup.find(label);
Expand Down
32 changes: 18 additions & 14 deletions src/VecSim/algorithms/hnsw/hnsw.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,9 @@ idType HNSWIndex<DataType, DistType>::mutuallyConnectNewElement(
neighbors_bitmap[neighbor_neighbors[j]] = true;
}

idType removed_links[sz_link_list_other + 1];
auto removed_links_alloc =
this->getAllocator()->allocate_unique((sz_link_list_other + 1) * sizeof(idType));
auto removed_links = static_cast<idType *>(removed_links_alloc.get());
size_t removed_links_num;
removeExtraLinks(ll_other, candidates, Mcurmax, neighbor_neighbors, neighbors_bitmap,
removed_links, &removed_links_num);
Expand Down Expand Up @@ -755,7 +757,9 @@ void HNSWIndex<DataType, DistType>::repairConnectionsForDeletion(

size_t Mcurmax = level ? maxM_ : maxM0_;
size_t removed_links_num;
idType removed_links[neighbour_neighbours_count];
auto removed_links_alloc =
this->getAllocator()->allocate_unique(neighbour_neighbours_count * sizeof(idType));
idType *removed_links = static_cast<idType *>(removed_links_alloc.get());
removeExtraLinks(neighbour_neighbours_list, candidates, Mcurmax, neighbour_neighbours,
neighbour_orig_neighbours_set, removed_links, &removed_links_num);

Expand Down Expand Up @@ -1166,11 +1170,11 @@ int HNSWIndex<DataType, DistType>::appendVector(const void *vector_data, const l

idType cur_c;

DataType normalized_blob[this->dim]; // This will be use only if metric == VecSimMetric_Cosine
auto normalized_blob = this->getAllocator()->allocate_unique(this->dim * sizeof(DataType));
if (this->metric == VecSimMetric_Cosine) {
memcpy(normalized_blob, vector_data, this->dim * sizeof(DataType));
normalizeVector(normalized_blob, this->dim);
vector_data = normalized_blob;
memcpy(normalized_blob.get(), vector_data, this->dim * sizeof(DataType));
normalizeVector(static_cast<DataType *>(normalized_blob.get()), this->dim);
vector_data = normalized_blob.get();
}

{
Expand Down Expand Up @@ -1392,11 +1396,11 @@ VecSimQueryResult_List HNSWIndex<DataType, DistType>::topKQuery(const void *quer

void *timeoutCtx = nullptr;

DataType normalized_blob[this->dim]; // This will be use only if metric == VecSimMetric_Cosine.
auto normalized_blob = this->getAllocator()->allocate_unique(this->dim * sizeof(DataType));
if (this->metric == VecSimMetric_Cosine) {
memcpy(normalized_blob, query_data, this->dim * sizeof(DataType));
normalizeVector(normalized_blob, this->dim);
query_data = normalized_blob;
memcpy(normalized_blob.get(), query_data, this->dim * sizeof(DataType));
normalizeVector(static_cast<DataType *>(normalized_blob.get()), this->dim);
query_data = normalized_blob.get();
}
// Get original efRuntime and store it.
size_t ef = ef_;
Expand Down Expand Up @@ -1509,11 +1513,11 @@ VecSimQueryResult_List HNSWIndex<DataType, DistType>::rangeQuery(const void *que
}
void *timeoutCtx = nullptr;

DataType normalized_blob[this->dim]; // This will be use only if metric == VecSimMetric_Cosine
auto normalized_blob = this->getAllocator()->allocate_unique(this->dim * sizeof(DataType));
if (this->metric == VecSimMetric_Cosine) {
memcpy(normalized_blob, query_data, this->dim * sizeof(DataType));
normalizeVector(normalized_blob, this->dim);
query_data = normalized_blob;
memcpy(normalized_blob.get(), query_data, this->dim * sizeof(DataType));
normalizeVector(static_cast<DataType *>(normalized_blob.get()), this->dim);
query_data = normalized_blob.get();
}

double epsilon = epsilon_;
Expand Down
5 changes: 5 additions & 0 deletions src/VecSim/memory/vecsim_malloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ void *VecSimAllocator::callocate(size_t size) {
return NULL;
}

std::unique_ptr<void, VecSimAllocator::Deleter> VecSimAllocator::allocate_unique(size_t size) {
void *ptr = this->allocate(size);
return {ptr, Deleter(*this)};
}

void *VecSimAllocator::operator new(size_t size) { return vecsim_malloc(size); }

void *VecSimAllocator::operator new[](size_t size) { return vecsim_malloc(size); }
Expand Down
13 changes: 12 additions & 1 deletion src/VecSim/memory/vecsim_malloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ struct VecSimAllocator {
static size_t allocation_header_size;
static VecSimMemoryFunctions memFunctions;

// Forward declaration of the deleter for the unique_ptr.
struct Deleter;
VecSimAllocator() : allocated(std::make_shared<uint64_t>(sizeof(VecSimAllocator))) {}

public:
Expand All @@ -34,6 +36,9 @@ struct VecSimAllocator {
void *reallocate(void *p, size_t size);
void free_allocation(void *p);

// Allocations for scope-life-time memory.
std::unique_ptr<void, Deleter> allocate_unique(size_t size);

void *operator new(size_t size);
void *operator new[](size_t size);
void operator delete(void *p, size_t size);
Expand All @@ -51,8 +56,14 @@ struct VecSimAllocator {
static void setMemoryFunctions(VecSimMemoryFunctions memFunctions);

private:
// Retrive the original requested allocation size. Required for remalloc.
// Retrieve the original requested allocation size. Required for remalloc.
inline size_t getPointerAllocationSize(void *p) { return *(((size_t *)p) - 1); }

struct Deleter {
VecSimAllocator &allocator;
explicit constexpr Deleter(VecSimAllocator &allocator) : allocator(allocator) {}
void operator()(void *ptr) const { allocator.free_allocation(ptr); }
};
};

/**
Expand Down
6 changes: 5 additions & 1 deletion src/VecSim/spaces/IP_space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "VecSim/spaces/functions/NEON.h"
#include "VecSim/spaces/functions/SVE.h"
#include "VecSim/spaces/functions/SVE2.h"

#include <cassert>
namespace spaces {
dist_func_t<float> IP_FP32_GetDistFunc(size_t dim, const Arch_Optimization arch_opt) {

Expand Down Expand Up @@ -78,6 +78,8 @@ dist_func_t<float> IP_FP32_GetDistFunc(size_t dim, const Arch_Optimization arch_
ret_dist_func = Choose_FP32_IP_implementation_NEON(dim);
break;
#endif
case ARCH_OPT_SIZE:
assert(false && "ARCH_OPT_SIZE is not a valid optimization type");
#endif // CPU_FEATURES_ARCH_X86_64
case ARCH_OPT_NONE:
break;
Expand Down Expand Up @@ -161,6 +163,8 @@ dist_func_t<double> IP_FP64_GetDistFunc(size_t dim, const Arch_Optimization arch
ret_dist_func = Choose_FP64_IP_implementation_NEON(dim);
break;
#endif
case ARCH_OPT_SIZE:
assert(false && "ARCH_OPT_SIZE is not a valid optimization type");
#endif // CPU_FEATURES_ARCH_AARCH64
case ARCH_OPT_NONE:
break;
Expand Down
5 changes: 5 additions & 0 deletions src/VecSim/spaces/L2_space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "VecSim/spaces/functions/NEON.h"
#include "VecSim/spaces/functions/SVE.h"
#include "VecSim/spaces/functions/SVE2.h"
#include <cassert>

namespace spaces {

Expand Down Expand Up @@ -81,6 +82,8 @@ dist_func_t<float> L2_FP32_GetDistFunc(size_t dim, const Arch_Optimization arch_
ret_dist_func = Choose_FP32_L2_implementation_NEON(dim);
break;
#endif
case ARCH_OPT_SIZE:
assert(false && "ARCH_OPT_SIZE is not a valid optimization type");
#endif
case ARCH_OPT_NONE:
break;
Expand Down Expand Up @@ -162,6 +165,8 @@ dist_func_t<double> L2_FP64_GetDistFunc(size_t dim, const Arch_Optimization arch
ret_dist_func = Choose_FP64_L2_implementation_NEON(dim);
break;
#endif
case ARCH_OPT_SIZE:
assert(false && "ARCH_OPT_SIZE is not a valid optimization type");
#endif // __aarch64__
case ARCH_OPT_NONE:
break;
Expand Down
1 change: 1 addition & 0 deletions src/VecSim/spaces/space_aux.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ enum Arch_Optimization {
ARCH_OPT_NEON,
ARCH_OPT_SVE,
ARCH_OPT_SVE2,
ARCH_OPT_SIZE,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ARCH_OPT_SIZE,
ARCH_OPT_EDGE,

or something like that, so it will be clearer that we are using the optimization in the test

#endif
};

Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_spaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ static dist_func_t<double> IP_dist_funcs_2ExtResiduals[] = {

#ifdef CPU_FEATURES_ARCH_AARCH64
static dist_func_t<float> *build_arm_funcs_array_fp32(size_t dim, bool is_ip) {
static dist_func_t<float> funcs[ARCH_OPT_SVE2] = {nullptr};
static dist_func_t<float> funcs[ARCH_OPT_SIZE] = {nullptr};
cpu_features::Aarch64Features features = cpu_features::GetAarch64Info().features;
// Always add baseline implementation
funcs[ARCH_OPT_NONE] = is_ip ? FP32_InnerProduct : FP32_L2Sqr;
Expand Down Expand Up @@ -196,7 +196,7 @@ static dist_func_t<float> *build_arm_funcs_array_fp32(size_t dim, bool is_ip) {
}

static dist_func_t<double> *build_arm_funcs_array_fp64(size_t dim, bool is_ip) {
static dist_func_t<double> funcs[ARCH_OPT_SVE2] = {nullptr};
static dist_func_t<double> funcs[ARCH_OPT_SIZE] = {nullptr};
cpu_features::Aarch64Features features = cpu_features::GetAarch64Info().features;
// Always add baseline implementation
funcs[ARCH_OPT_NONE] = is_ip ? FP64_InnerProduct : FP64_L2Sqr;
Expand Down
Loading