From d006416ca75cbdb74a9230231d55d6c7a9300c39 Mon Sep 17 00:00:00 2001 From: Max Buckley Date: Mon, 26 Jan 2026 22:01:29 +0100 Subject: [PATCH] Fix all compiler warnings with strict warning flags Enable strict compiler warnings and fix all issues found: Library headers: - Convert C-style casts to C++ casts (static_cast, reinterpret_cast, const_cast) - Fix const correctness in distance functions and data pointers - Mark unused parameters with /*name*/ syntax - Add missing override keywords on virtual functions - Fix shadow variable warnings - Fix sign comparison warnings (int vs size_t) - Add HNSWLIB_MAYBE_UNUSED macro for conditionally-used SIMD functions - Fix member initializer order in visited_list_pool.h Examples and tests: - Fix sign comparison warnings in loops - Mark unused lambda parameters - Fix shadow variables - Add missing override keywords Build infrastructure: - Update CMakeLists.txt with proper warning flags for GCC/Clang/MSVC - Add HNSWLIB_WERROR option to treat warnings as errors Co-Authored-By: Claude Opus 4.5 --- CMakeLists.txt | 106 ++++++------ examples/cpp/example_mt_filter.cpp | 8 +- examples/cpp/example_mt_replace_deleted.cpp | 8 +- examples/cpp/example_mt_search.cpp | 8 +- examples/cpp/example_search.cpp | 8 +- hnswlib/bruteforce.h | 20 +-- hnswlib/hnswalg.h | 168 ++++++++++---------- hnswlib/hnswlib.h | 21 ++- hnswlib/space_ip.h | 50 +++--- hnswlib/space_l2.h | 60 +++---- hnswlib/stop_condition.h | 27 ++-- hnswlib/visited_list_pool.h | 18 +-- tests/cpp/epsilon_search_test.cpp | 10 +- tests/cpp/multiThreadLoad_test.cpp | 14 +- tests/cpp/multiThread_replace_test.cpp | 4 +- tests/cpp/multivector_search_test.cpp | 16 +- tests/cpp/searchKnnWithFilter_test.cpp | 6 +- tests/cpp/sift_1b.cpp | 37 +++-- tests/cpp/updates_test.cpp | 12 +- 19 files changed, 307 insertions(+), 294 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be0d40f0..1ded4702 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,75 +31,81 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) else() option(HNSWLIB_EXAMPLES "Build examples and tests." OFF) endif() + +# Option to treat warnings as errors (useful for CI) +option(HNSWLIB_WERROR "Treat warnings as errors" OFF) + if(HNSWLIB_EXAMPLES) - set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD 14) + + # Common warning flags for GCC/Clang + set(HNSWLIB_WARNING_FLAGS + -Wall + -Wextra + -Wno-unknown-pragmas + ) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - SET( CMAKE_CXX_FLAGS "-Ofast -std=c++11 -DHAVE_CXX0X -openmp -fpic -ftree-vectorize" ) + set(CMAKE_CXX_FLAGS "-O3 -DHAVE_CXX0X -fpic -ftree-vectorize") check_cxx_compiler_flag("-march=native" COMPILER_SUPPORT_NATIVE_FLAG) if(COMPILER_SUPPORT_NATIVE_FLAG) - SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native" ) - message("set -march=native flag") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") + message(STATUS "set -march=native flag") else() check_cxx_compiler_flag("-mcpu=apple-m1" COMPILER_SUPPORT_M1_FLAG) if(COMPILER_SUPPORT_M1_FLAG) - SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=apple-m1" ) - message("set -mcpu=apple-m1 flag") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=apple-m1") + message(STATUS "set -mcpu=apple-m1 flag") endif() endif() + # Add OpenMP if available + find_package(OpenMP QUIET) + if(OpenMP_CXX_FOUND) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + endif() elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - SET( CMAKE_CXX_FLAGS "-Ofast -lrt -std=c++11 -DHAVE_CXX0X -march=native -fpic -w -fopenmp -ftree-vectorize -ftree-vectorizer-verbose=0" ) + set(CMAKE_CXX_FLAGS "-O3 -lrt -DHAVE_CXX0X -march=native -fpic -fopenmp -ftree-vectorize") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - SET( CMAKE_CXX_FLAGS "/O2 -DHAVE_CXX0X /W1 /openmp /EHsc" ) + set(CMAKE_CXX_FLAGS "/O2 -DHAVE_CXX0X /W3 /openmp /EHsc") + set(HNSWLIB_WARNING_FLAGS /W3) endif() - # examples - add_executable(example_search examples/cpp/example_search.cpp) - target_link_libraries(example_search hnswlib) - - add_executable(example_epsilon_search examples/cpp/example_epsilon_search.cpp) - target_link_libraries(example_epsilon_search hnswlib) - - add_executable(example_multivector_search examples/cpp/example_multivector_search.cpp) - target_link_libraries(example_multivector_search hnswlib) - - add_executable(example_filter examples/cpp/example_filter.cpp) - target_link_libraries(example_filter hnswlib) - - add_executable(example_replace_deleted examples/cpp/example_replace_deleted.cpp) - target_link_libraries(example_replace_deleted hnswlib) - - add_executable(example_mt_search examples/cpp/example_mt_search.cpp) - target_link_libraries(example_mt_search hnswlib) + # Add warning-as-error flag if requested + if(HNSWLIB_WERROR) + if(MSVC) + list(APPEND HNSWLIB_WARNING_FLAGS /WX) + else() + list(APPEND HNSWLIB_WARNING_FLAGS -Werror) + endif() + endif() - add_executable(example_mt_filter examples/cpp/example_mt_filter.cpp) - target_link_libraries(example_mt_filter hnswlib) + # Helper function to add warning flags to targets + function(hnswlib_add_executable target_name) + add_executable(${target_name} ${ARGN}) + target_link_libraries(${target_name} hnswlib) + target_compile_options(${target_name} PRIVATE ${HNSWLIB_WARNING_FLAGS}) + endfunction() - add_executable(example_mt_replace_deleted examples/cpp/example_mt_replace_deleted.cpp) - target_link_libraries(example_mt_replace_deleted hnswlib) + # examples + hnswlib_add_executable(example_search examples/cpp/example_search.cpp) + hnswlib_add_executable(example_epsilon_search examples/cpp/example_epsilon_search.cpp) + hnswlib_add_executable(example_multivector_search examples/cpp/example_multivector_search.cpp) + hnswlib_add_executable(example_filter examples/cpp/example_filter.cpp) + hnswlib_add_executable(example_replace_deleted examples/cpp/example_replace_deleted.cpp) + hnswlib_add_executable(example_mt_search examples/cpp/example_mt_search.cpp) + hnswlib_add_executable(example_mt_filter examples/cpp/example_mt_filter.cpp) + hnswlib_add_executable(example_mt_replace_deleted examples/cpp/example_mt_replace_deleted.cpp) # tests - add_executable(multivector_search_test tests/cpp/multivector_search_test.cpp) - target_link_libraries(multivector_search_test hnswlib) - - add_executable(epsilon_search_test tests/cpp/epsilon_search_test.cpp) - target_link_libraries(epsilon_search_test hnswlib) - - add_executable(test_updates tests/cpp/updates_test.cpp) - target_link_libraries(test_updates hnswlib) - - add_executable(searchKnnCloserFirst_test tests/cpp/searchKnnCloserFirst_test.cpp) - target_link_libraries(searchKnnCloserFirst_test hnswlib) - - add_executable(searchKnnWithFilter_test tests/cpp/searchKnnWithFilter_test.cpp) - target_link_libraries(searchKnnWithFilter_test hnswlib) - - add_executable(multiThreadLoad_test tests/cpp/multiThreadLoad_test.cpp) - target_link_libraries(multiThreadLoad_test hnswlib) - - add_executable(multiThread_replace_test tests/cpp/multiThread_replace_test.cpp) - target_link_libraries(multiThread_replace_test hnswlib) + hnswlib_add_executable(multivector_search_test tests/cpp/multivector_search_test.cpp) + hnswlib_add_executable(epsilon_search_test tests/cpp/epsilon_search_test.cpp) + hnswlib_add_executable(test_updates tests/cpp/updates_test.cpp) + hnswlib_add_executable(searchKnnCloserFirst_test tests/cpp/searchKnnCloserFirst_test.cpp) + hnswlib_add_executable(searchKnnWithFilter_test tests/cpp/searchKnnWithFilter_test.cpp) + hnswlib_add_executable(multiThreadLoad_test tests/cpp/multiThreadLoad_test.cpp) + hnswlib_add_executable(multiThread_replace_test tests/cpp/multiThread_replace_test.cpp) add_executable(main tests/cpp/main.cpp tests/cpp/sift_1b.cpp) target_link_libraries(main hnswlib) + target_compile_options(main PRIVATE ${HNSWLIB_WARNING_FLAGS}) endif() diff --git a/examples/cpp/example_mt_filter.cpp b/examples/cpp/example_mt_filter.cpp index b39de4c3..9c01c8d7 100644 --- a/examples/cpp/example_mt_filter.cpp +++ b/examples/cpp/example_mt_filter.cpp @@ -95,7 +95,7 @@ int main() { } // Add data to index - ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t threadId) { + ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t /*threadId*/) { alg_hnsw->addPoint((void*)(data + dim * row), row); }); @@ -104,13 +104,13 @@ int main() { // Query the elements for themselves with filter and check returned labels int k = 10; - std::vector neighbors(max_elements * k); - ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t threadId) { + std::vector neighbors(static_cast(max_elements * k)); + ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t /*threadId*/) { std::priority_queue> result = alg_hnsw->searchKnn(data + dim * row, k, &pickIdsDivisibleByTwo); for (int i = 0; i < k; i++) { hnswlib::labeltype label = result.top().second; result.pop(); - neighbors[row * k + i] = label; + neighbors[row * static_cast(k) + static_cast(i)] = label; } }); diff --git a/examples/cpp/example_mt_replace_deleted.cpp b/examples/cpp/example_mt_replace_deleted.cpp index 40a94ce7..b98ee885 100644 --- a/examples/cpp/example_mt_replace_deleted.cpp +++ b/examples/cpp/example_mt_replace_deleted.cpp @@ -83,13 +83,13 @@ int main() { } // Add data to index - ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t threadId) { + ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t /*threadId*/) { alg_hnsw->addPoint((void*)(data + dim * row), row); }); // Mark first half of elements as deleted int num_deleted = max_elements / 2; - ParallelFor(0, num_deleted, num_threads, [&](size_t row, size_t threadId) { + ParallelFor(0, num_deleted, num_threads, [&](size_t row, size_t /*threadId*/) { alg_hnsw->markDelete(row); }); @@ -102,8 +102,8 @@ int main() { // Replace deleted data with new elements // Maximum number of elements is reached therefore we cannot add new items, // but we can replace the deleted ones by using replace_deleted=true - ParallelFor(0, num_deleted, num_threads, [&](size_t row, size_t threadId) { - hnswlib::labeltype label = max_elements + row; + ParallelFor(0, num_deleted, num_threads, [&](size_t row, size_t /*threadId*/) { + hnswlib::labeltype label = static_cast(max_elements) + row; alg_hnsw->addPoint((void*)(add_data + dim * row), label, true); }); diff --git a/examples/cpp/example_mt_search.cpp b/examples/cpp/example_mt_search.cpp index e315b9ff..531e9de6 100644 --- a/examples/cpp/example_mt_search.cpp +++ b/examples/cpp/example_mt_search.cpp @@ -82,13 +82,13 @@ int main() { } // Add data to index - ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t threadId) { + ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t /*threadId*/) { alg_hnsw->addPoint((void*)(data + dim * row), row); }); // Query the elements for themselves and measure recall std::vector neighbors(max_elements); - ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t threadId) { + ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t /*threadId*/) { std::priority_queue> result = alg_hnsw->searchKnn(data + dim * row, 1); hnswlib::labeltype label = result.top().second; neighbors[row] = label; @@ -96,9 +96,9 @@ int main() { float correct = 0; for (int i = 0; i < max_elements; i++) { hnswlib::labeltype label = neighbors[i]; - if (label == i) correct++; + if (label == static_cast(i)) correct++; } - float recall = correct / max_elements; + float recall = correct / static_cast(max_elements); std::cout << "Recall: " << recall << "\n"; delete[] data; diff --git a/examples/cpp/example_search.cpp b/examples/cpp/example_search.cpp index 2c28738f..60a9e155 100644 --- a/examples/cpp/example_search.cpp +++ b/examples/cpp/example_search.cpp @@ -31,9 +31,9 @@ int main() { for (int i = 0; i < max_elements; i++) { std::priority_queue> result = alg_hnsw->searchKnn(data + i * dim, 1); hnswlib::labeltype label = result.top().second; - if (label == i) correct++; + if (label == static_cast(i)) correct++; } - float recall = correct / max_elements; + float recall = correct / static_cast(max_elements); std::cout << "Recall: " << recall << "\n"; // Serialize index @@ -47,9 +47,9 @@ int main() { for (int i = 0; i < max_elements; i++) { std::priority_queue> result = alg_hnsw->searchKnn(data + i * dim, 1); hnswlib::labeltype label = result.top().second; - if (label == i) correct++; + if (label == static_cast(i)) correct++; } - recall = (float)correct / max_elements; + recall = correct / static_cast(max_elements); std::cout << "Recall of deserialized index: " << recall << "\n"; delete[] data; diff --git a/hnswlib/bruteforce.h b/hnswlib/bruteforce.h index 8727cc8a..e5620059 100644 --- a/hnswlib/bruteforce.h +++ b/hnswlib/bruteforce.h @@ -22,7 +22,7 @@ class BruteforceSearch : public AlgorithmInterface { std::unordered_map dict_external_to_internal; - BruteforceSearch(SpaceInterface *s) + BruteforceSearch(SpaceInterface * /*s*/) : data_(nullptr), maxelements_(0), cur_element_count(0), @@ -49,7 +49,7 @@ class BruteforceSearch : public AlgorithmInterface { fstdistfunc_ = s->get_dist_func(); dist_func_param_ = s->get_dist_func_param(); size_per_element_ = data_size_ + sizeof(labeltype); - data_ = (char *) malloc(maxElements * size_per_element_); + data_ = static_cast(malloc(maxElements * size_per_element_)); if (data_ == nullptr) throw std::runtime_error("Not enough memory: BruteforceSearch failed to allocate data"); cur_element_count = 0; @@ -61,8 +61,8 @@ class BruteforceSearch : public AlgorithmInterface { } - void addPoint(const void *datapoint, labeltype label, bool replace_deleted = false) { - int idx; + void addPoint(const void *datapoint, labeltype label, bool /*replace_deleted*/ = false) { + size_t idx; { std::unique_lock lock(index_lock); @@ -94,7 +94,7 @@ class BruteforceSearch : public AlgorithmInterface { dict_external_to_internal.erase(found); size_t cur_c = found->second; - labeltype label = *((labeltype*)(data_ + size_per_element_ * (cur_element_count-1) + data_size_)); + labeltype label = *reinterpret_cast(data_ + size_per_element_ * (cur_element_count-1) + data_size_); dict_external_to_internal[label] = cur_c; memcpy(data_ + size_per_element_ * cur_c, data_ + size_per_element_ * (cur_element_count-1), @@ -108,18 +108,18 @@ class BruteforceSearch : public AlgorithmInterface { assert(k <= cur_element_count); std::priority_queue> topResults; if (cur_element_count == 0) return topResults; - for (int i = 0; i < k; i++) { + for (size_t i = 0; i < k; i++) { dist_t dist = fstdistfunc_(query_data, data_ + size_per_element_ * i, dist_func_param_); - labeltype label = *((labeltype*) (data_ + size_per_element_ * i + data_size_)); + labeltype label = *reinterpret_cast(data_ + size_per_element_ * i + data_size_); if ((!isIdAllowed) || (*isIdAllowed)(label)) { topResults.emplace(dist, label); } } dist_t lastdist = topResults.empty() ? std::numeric_limits::max() : topResults.top().first; - for (int i = k; i < cur_element_count; i++) { + for (size_t i = k; i < cur_element_count; i++) { dist_t dist = fstdistfunc_(query_data, data_ + size_per_element_ * i, dist_func_param_); if (dist <= lastdist) { - labeltype label = *((labeltype *) (data_ + size_per_element_ * i + data_size_)); + labeltype label = *reinterpret_cast(data_ + size_per_element_ * i + data_size_); if ((!isIdAllowed) || (*isIdAllowed)(label)) { topResults.emplace(dist, label); } @@ -161,7 +161,7 @@ class BruteforceSearch : public AlgorithmInterface { fstdistfunc_ = s->get_dist_func(); dist_func_param_ = s->get_dist_func_param(); size_per_element_ = data_size_ + sizeof(labeltype); - data_ = (char *) malloc(maxelements_ * size_per_element_); + data_ = static_cast(malloc(maxelements_ * size_per_element_)); if (data_ == nullptr) throw std::runtime_error("Not enough memory: loadIndex failed to allocate data"); diff --git a/hnswlib/hnswalg.h b/hnswlib/hnswalg.h index e269ae69..cea39fe1 100644 --- a/hnswlib/hnswalg.h +++ b/hnswlib/hnswalg.h @@ -71,14 +71,14 @@ class HierarchicalNSW : public AlgorithmInterface { std::unordered_set deleted_elements; // contains internal ids of deleted elements - HierarchicalNSW(SpaceInterface *s) { + HierarchicalNSW(SpaceInterface* /*s*/) { } HierarchicalNSW( SpaceInterface *s, const std::string &location, - bool nmslib = false, + bool /*nmslib*/ = false, size_t max_elements = 0, bool allow_replace_deleted = false) : allow_replace_deleted_(allow_replace_deleted) { @@ -123,7 +123,7 @@ class HierarchicalNSW : public AlgorithmInterface { label_offset_ = size_links_level0_ + data_size_; offsetLevel0_ = 0; - data_level0_memory_ = (char *) malloc(max_elements_ * size_data_per_element_); + data_level0_memory_ = static_cast(malloc(max_elements_ * size_data_per_element_)); if (data_level0_memory_ == nullptr) throw std::runtime_error("Not enough memory"); @@ -132,14 +132,14 @@ class HierarchicalNSW : public AlgorithmInterface { visited_list_pool_ = std::unique_ptr(new VisitedListPool(1, max_elements)); // initializations for special treatment of the first node - enterpoint_node_ = -1; + enterpoint_node_ = static_cast(-1); maxlevel_ = -1; - linkLists_ = (char **) malloc(sizeof(void *) * max_elements_); + linkLists_ = static_cast(malloc(sizeof(void*) * max_elements_)); if (linkLists_ == nullptr) throw std::runtime_error("Not enough memory: HierarchicalNSW failed to allocate linklists"); size_links_per_element_ = maxM_ * sizeof(tableint) + sizeof(linklistsizeint); - mult_ = 1 / log(1.0 * M_); + mult_ = 1.0 / log(static_cast(M_)); revSize_ = 1.0 / mult_; } @@ -195,7 +195,7 @@ class HierarchicalNSW : public AlgorithmInterface { inline labeltype *getExternalLabeLp(tableint internal_id) const { - return (labeltype *) (data_level0_memory_ + internal_id * size_data_per_element_ + label_offset_); + return reinterpret_cast(data_level0_memory_ + internal_id * size_data_per_element_ + label_offset_); } @@ -207,7 +207,7 @@ class HierarchicalNSW : public AlgorithmInterface { int getRandomLevel(double reverse_size) { std::uniform_real_distribution distribution(0.0, 1.0); double r = -log(distribution(level_generator_)) * reverse_size; - return (int) r; + return static_cast(r); } size_t getMaxElements() { @@ -256,16 +256,16 @@ class HierarchicalNSW : public AlgorithmInterface { int *data; // = (int *)(linkList0_ + curNodeNum * size_links_per_element0_); if (layer == 0) { - data = (int*)get_linklist0(curNodeNum); + data = reinterpret_cast(get_linklist0(curNodeNum)); } else { - data = (int*)get_linklist(curNodeNum, layer); + data = reinterpret_cast(get_linklist(curNodeNum, layer)); // data = (int *) (linkLists_[curNodeNum] + (layer - 1) * size_links_per_element_); } - size_t size = getListCount((linklistsizeint*)data); - tableint *datal = (tableint *) (data + 1); + size_t size = getListCount(reinterpret_cast(data)); + tableint *datal = reinterpret_cast(data + 1); #ifdef USE_SSE - _mm_prefetch((char *) (visited_array + *(data + 1)), _MM_HINT_T0); - _mm_prefetch((char *) (visited_array + *(data + 1) + 64), _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(visited_array + *(data + 1)), _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(visited_array + *(data + 1) + 64), _MM_HINT_T0); _mm_prefetch(getDataByInternalId(*datal), _MM_HINT_T0); _mm_prefetch(getDataByInternalId(*(datal + 1)), _MM_HINT_T0); #endif @@ -274,7 +274,7 @@ class HierarchicalNSW : public AlgorithmInterface { tableint candidate_id = *(datal + j); // if (candidate_id == 0) continue; #ifdef USE_SSE - _mm_prefetch((char *) (visited_array + *(datal + j + 1)), _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(visited_array + *(datal + j + 1)), _MM_HINT_T0); _mm_prefetch(getDataByInternalId(*(datal + j + 1)), _MM_HINT_T0); #endif if (visited_array[candidate_id] == visited_array_tag) continue; @@ -359,8 +359,8 @@ class HierarchicalNSW : public AlgorithmInterface { candidate_set.pop(); tableint current_node_id = current_node_pair.second; - int *data = (int *) get_linklist0(current_node_id); - size_t size = getListCount((linklistsizeint*)data); + int *data = reinterpret_cast(get_linklist0(current_node_id)); + size_t size = getListCount(reinterpret_cast(data)); // bool cur_node_deleted = isMarkedDeleted(current_node_id); if (collect_metrics) { metric_hops++; @@ -368,24 +368,24 @@ class HierarchicalNSW : public AlgorithmInterface { } #ifdef USE_SSE - _mm_prefetch((char *) (visited_array + *(data + 1)), _MM_HINT_T0); - _mm_prefetch((char *) (visited_array + *(data + 1) + 64), _MM_HINT_T0); - _mm_prefetch(data_level0_memory_ + (*(data + 1)) * size_data_per_element_ + offsetData_, _MM_HINT_T0); - _mm_prefetch((char *) (data + 2), _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(visited_array + *(data + 1)), _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(visited_array + *(data + 1) + 64), _MM_HINT_T0); + _mm_prefetch(data_level0_memory_ + static_cast(*(data + 1)) * size_data_per_element_ + offsetData_, _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(data + 2), _MM_HINT_T0); #endif for (size_t j = 1; j <= size; j++) { - int candidate_id = *(data + j); + tableint candidate_id = static_cast(*(data + j)); // if (candidate_id == 0) continue; #ifdef USE_SSE - _mm_prefetch((char *) (visited_array + *(data + j + 1)), _MM_HINT_T0); - _mm_prefetch(data_level0_memory_ + (*(data + j + 1)) * size_data_per_element_ + offsetData_, + _mm_prefetch(reinterpret_cast(visited_array + *(data + j + 1)), _MM_HINT_T0); + _mm_prefetch(data_level0_memory_ + static_cast(*(data + j + 1)) * size_data_per_element_ + offsetData_, _MM_HINT_T0); //////////// #endif if (!(visited_array[candidate_id] == visited_array_tag)) { visited_array[candidate_id] = visited_array_tag; - char *currObj1 = (getDataByInternalId(candidate_id)); + char *currObj1 = getDataByInternalId(candidate_id); dist_t dist = fstdistfunc_(data_point, currObj1, dist_func_param_); bool flag_consider_candidate; @@ -484,17 +484,17 @@ class HierarchicalNSW : public AlgorithmInterface { linklistsizeint *get_linklist0(tableint internal_id) const { - return (linklistsizeint *) (data_level0_memory_ + internal_id * size_data_per_element_ + offsetLevel0_); + return reinterpret_cast(data_level0_memory_ + internal_id * size_data_per_element_ + offsetLevel0_); } - linklistsizeint *get_linklist0(tableint internal_id, char *data_level0_memory_) const { - return (linklistsizeint *) (data_level0_memory_ + internal_id * size_data_per_element_ + offsetLevel0_); + linklistsizeint *get_linklist0(tableint internal_id, char *data_level0_mem) const { + return reinterpret_cast(data_level0_mem + internal_id * size_data_per_element_ + offsetLevel0_); } linklistsizeint *get_linklist(tableint internal_id, int level) const { - return (linklistsizeint *) (linkLists_[internal_id] + (level - 1) * size_links_per_element_); + return reinterpret_cast(linkLists_[internal_id] + static_cast(level - 1) * size_links_per_element_); } @@ -504,7 +504,7 @@ class HierarchicalNSW : public AlgorithmInterface { tableint mutuallyConnectNewElement( - const void *data_point, + const void* /*data_point*/, tableint cur_c, std::priority_queue, std::vector>, CompareByFirst> &top_candidates, int level, @@ -539,8 +539,8 @@ class HierarchicalNSW : public AlgorithmInterface { if (*ll_cur && !isUpdate) { throw std::runtime_error("The newly inserted element should have blank link list"); } - setListCount(ll_cur, selectedNeighbors.size()); - tableint *data = (tableint *) (ll_cur + 1); + setListCount(ll_cur, static_cast(selectedNeighbors.size())); + tableint *data = reinterpret_cast(ll_cur + 1); for (size_t idx = 0; idx < selectedNeighbors.size(); idx++) { if (data[idx] && !isUpdate) throw std::runtime_error("Possible memory corruption"); @@ -569,7 +569,7 @@ class HierarchicalNSW : public AlgorithmInterface { if (level > element_levels_[selectedNeighbors[idx]]) throw std::runtime_error("Trying to make a link on a non-existent level"); - tableint *data = (tableint *) (ll_other + 1); + tableint *data = reinterpret_cast(ll_other + 1); bool is_cur_c_present = false; if (isUpdate) { @@ -585,7 +585,7 @@ class HierarchicalNSW : public AlgorithmInterface { if (!is_cur_c_present) { if (sz_link_list_other < Mcurmax) { data[sz_link_list_other] = cur_c; - setListCount(ll_other, sz_link_list_other + 1); + setListCount(ll_other, static_cast(sz_link_list_other + 1)); } else { // finding the "weakest" element to replace it with the new one dist_t d_max = fstdistfunc_(getDataByInternalId(cur_c), getDataByInternalId(selectedNeighbors[idx]), @@ -602,14 +602,14 @@ class HierarchicalNSW : public AlgorithmInterface { getNeighborsByHeuristic2(candidates, Mcurmax); - int indx = 0; + size_t indx = 0; while (candidates.size() > 0) { data[indx] = candidates.top().second; candidates.pop(); indx++; } - setListCount(ll_other, indx); + setListCount(ll_other, static_cast(indx)); // Nearest K: /*int indx = -1; for (int j = 0; j < sz_link_list_other; j++) { @@ -641,13 +641,13 @@ class HierarchicalNSW : public AlgorithmInterface { std::vector(new_max_elements).swap(link_list_locks_); // Reallocate base layer - char * data_level0_memory_new = (char *) realloc(data_level0_memory_, new_max_elements * size_data_per_element_); + char * data_level0_memory_new = static_cast(realloc(data_level0_memory_, new_max_elements * size_data_per_element_)); if (data_level0_memory_new == nullptr) throw std::runtime_error("Not enough memory: resizeIndex failed to allocate base layer"); data_level0_memory_ = data_level0_memory_new; // Reallocate all other layers - char ** linkLists_new = (char **) realloc(linkLists_, sizeof(void *) * new_max_elements); + char ** linkLists_new = static_cast(realloc(linkLists_, sizeof(void*) * new_max_elements)); if (linkLists_new == nullptr) throw std::runtime_error("Not enough memory: resizeIndex failed to allocate other layers"); linkLists_ = linkLists_new; @@ -774,7 +774,7 @@ class HierarchicalNSW : public AlgorithmInterface { input.seekg(pos, input.beg); - data_level0_memory_ = (char *) malloc(max_elements * size_data_per_element_); + data_level0_memory_ = static_cast(malloc(max_elements * size_data_per_element_)); if (data_level0_memory_ == nullptr) throw std::runtime_error("Not enough memory: loadIndex failed to allocate level0"); input.read(data_level0_memory_, cur_element_count * size_data_per_element_); @@ -787,7 +787,7 @@ class HierarchicalNSW : public AlgorithmInterface { visited_list_pool_.reset(new VisitedListPool(1, max_elements)); - linkLists_ = (char **) malloc(sizeof(void *) * max_elements); + linkLists_ = static_cast(malloc(sizeof(void*) * max_elements)); if (linkLists_ == nullptr) throw std::runtime_error("Not enough memory: loadIndex failed to allocate linklists"); element_levels_ = std::vector(max_elements); @@ -802,7 +802,7 @@ class HierarchicalNSW : public AlgorithmInterface { linkLists_[i] = nullptr; } else { element_levels_[i] = linkListSize / size_links_per_element_; - linkLists_[i] = (char *) malloc(linkListSize); + linkLists_[i] = static_cast(malloc(linkListSize)); if (linkLists_[i] == nullptr) throw std::runtime_error("Not enough memory: loadIndex failed to allocate linklist"); input.read(linkLists_[i], linkListSize); @@ -836,9 +836,9 @@ class HierarchicalNSW : public AlgorithmInterface { lock_table.unlock(); char* data_ptrv = getDataByInternalId(internalId); - size_t dim = *((size_t *) dist_func_param_); + size_t dim = *static_cast(dist_func_param_); std::vector data; - data_t* data_ptr = (data_t*) data_ptrv; + data_t* data_ptr = reinterpret_cast(data_ptrv); for (size_t i = 0; i < dim; i++) { data.push_back(*data_ptr); data_ptr += 1; @@ -873,7 +873,7 @@ class HierarchicalNSW : public AlgorithmInterface { void markDeletedInternal(tableint internalId) { assert(internalId < cur_element_count); if (!isMarkedDeleted(internalId)) { - unsigned char *ll_cur = ((unsigned char *)get_linklist0(internalId))+2; + unsigned char *ll_cur = reinterpret_cast(get_linklist0(internalId)) + 2; *ll_cur |= DELETE_MARK; num_deleted_ += 1; if (allow_replace_deleted_) { @@ -915,8 +915,8 @@ class HierarchicalNSW : public AlgorithmInterface { void unmarkDeletedInternal(tableint internalId) { assert(internalId < cur_element_count); if (isMarkedDeleted(internalId)) { - unsigned char *ll_cur = ((unsigned char *)get_linklist0(internalId)) + 2; - *ll_cur &= ~DELETE_MARK; + unsigned char *ll_cur = reinterpret_cast(get_linklist0(internalId)) + 2; + *ll_cur &= static_cast(~DELETE_MARK); num_deleted_ -= 1; if (allow_replace_deleted_) { std::unique_lock lock_deleted_elements(deleted_elements_lock); @@ -932,18 +932,18 @@ class HierarchicalNSW : public AlgorithmInterface { * Checks the first 16 bits of the memory to see if the element is marked deleted. */ bool isMarkedDeleted(tableint internalId) const { - unsigned char *ll_cur = ((unsigned char*)get_linklist0(internalId)) + 2; + unsigned char *ll_cur = reinterpret_cast(get_linklist0(internalId)) + 2; return *ll_cur & DELETE_MARK; } unsigned short int getListCount(linklistsizeint * ptr) const { - return *((unsigned short int *)ptr); + return *reinterpret_cast(ptr); } void setListCount(linklistsizeint * ptr, unsigned short int size) const { - *((unsigned short int*)(ptr))=*((unsigned short int *)&size); + *reinterpret_cast(ptr) = size; } @@ -1057,8 +1057,8 @@ class HierarchicalNSW : public AlgorithmInterface { linklistsizeint *ll_cur; ll_cur = get_linklist_at_level(neigh, layer); size_t candSize = candidates.size(); - setListCount(ll_cur, candSize); - tableint *data = (tableint *) (ll_cur + 1); + setListCount(ll_cur, static_cast(candSize)); + tableint *data = reinterpret_cast(ll_cur + 1); for (size_t idx = 0; idx < candSize; idx++) { data[idx] = candidates.top().second; candidates.pop(); @@ -1084,11 +1084,11 @@ class HierarchicalNSW : public AlgorithmInterface { bool changed = true; while (changed) { changed = false; - unsigned int *data; + linklistsizeint *data; std::unique_lock lock(link_list_locks_[currObj]); data = get_linklist_at_level(currObj, level); int size = getListCount(data); - tableint *datal = (tableint *) (data + 1); + tableint *datal = reinterpret_cast(data + 1); #ifdef USE_SSE _mm_prefetch(getDataByInternalId(*datal), _MM_HINT_T0); #endif @@ -1141,10 +1141,10 @@ class HierarchicalNSW : public AlgorithmInterface { std::vector getConnectionsWithLock(tableint internalId, int level) { std::unique_lock lock(link_list_locks_[internalId]); - unsigned int *data = get_linklist_at_level(internalId, level); - int size = getListCount(data); + linklistsizeint *data = get_linklist_at_level(internalId, level); + size_t size = static_cast(getListCount(data)); std::vector result(size); - tableint *ll = (tableint *) (data + 1); + tableint *ll = reinterpret_cast(data + 1); memcpy(result.data(), ll, size * sizeof(tableint)); return result; } @@ -1204,28 +1204,28 @@ class HierarchicalNSW : public AlgorithmInterface { memcpy(getDataByInternalId(cur_c), data_point, data_size_); if (curlevel) { - linkLists_[cur_c] = (char *) malloc(size_links_per_element_ * curlevel + 1); + linkLists_[cur_c] = static_cast(malloc(size_links_per_element_ * static_cast(curlevel) + 1)); if (linkLists_[cur_c] == nullptr) throw std::runtime_error("Not enough memory: addPoint failed to allocate linklist"); - memset(linkLists_[cur_c], 0, size_links_per_element_ * curlevel + 1); + memset(linkLists_[cur_c], 0, size_links_per_element_ * static_cast(curlevel) + 1); } - if ((signed)currObj != -1) { + if (currObj != static_cast(-1)) { if (curlevel < maxlevelcopy) { dist_t curdist = fstdistfunc_(data_point, getDataByInternalId(currObj), dist_func_param_); - for (int level = maxlevelcopy; level > curlevel; level--) { + for (int lv = maxlevelcopy; lv > curlevel; lv--) { bool changed = true; while (changed) { changed = false; - unsigned int *data; + linklistsizeint *data; std::unique_lock lock(link_list_locks_[currObj]); - data = get_linklist(currObj, level); + data = get_linklist(currObj, lv); int size = getListCount(data); - tableint *datal = (tableint *) (data + 1); + tableint *datal = reinterpret_cast(data + 1); for (int i = 0; i < size; i++) { tableint cand = datal[i]; - if (cand < 0 || cand > max_elements_) + if (cand > max_elements_) throw std::runtime_error("cand error"); dist_t d = fstdistfunc_(data_point, getDataByInternalId(cand), dist_func_param_); if (d < curdist) { @@ -1239,18 +1239,18 @@ class HierarchicalNSW : public AlgorithmInterface { } bool epDeleted = isMarkedDeleted(enterpoint_copy); - for (int level = std::min(curlevel, maxlevelcopy); level >= 0; level--) { - if (level > maxlevelcopy || level < 0) // possible? + for (int lv = std::min(curlevel, maxlevelcopy); lv >= 0; lv--) { + if (lv > maxlevelcopy || lv < 0) // possible? throw std::runtime_error("Level error"); std::priority_queue, std::vector>, CompareByFirst> top_candidates = searchBaseLayer( - currObj, data_point, level); + currObj, data_point, lv); if (epDeleted) { top_candidates.emplace(fstdistfunc_(data_point, getDataByInternalId(enterpoint_copy), dist_func_param_), enterpoint_copy); if (top_candidates.size() > ef_construction_) top_candidates.pop(); } - currObj = mutuallyConnectNewElement(data_point, cur_c, top_candidates, level, false); + currObj = mutuallyConnectNewElement(data_point, cur_c, top_candidates, lv, false); } } else { // Do nothing for the first element @@ -1279,17 +1279,17 @@ class HierarchicalNSW : public AlgorithmInterface { bool changed = true; while (changed) { changed = false; - unsigned int *data; + linklistsizeint *data; - data = (unsigned int *) get_linklist(currObj, level); + data = get_linklist(currObj, level); int size = getListCount(data); metric_hops++; metric_distance_computations+=size; - tableint *datal = (tableint *) (data + 1); + tableint *datal = reinterpret_cast(data + 1); for (int i = 0; i < size; i++) { tableint cand = datal[i]; - if (cand < 0 || cand > max_elements_) + if (cand > max_elements_) throw std::runtime_error("cand error"); dist_t d = fstdistfunc_(query_data, getDataByInternalId(cand), dist_func_param_); @@ -1339,17 +1339,17 @@ class HierarchicalNSW : public AlgorithmInterface { bool changed = true; while (changed) { changed = false; - unsigned int *data; + linklistsizeint *data; - data = (unsigned int *) get_linklist(currObj, level); + data = get_linklist(currObj, level); int size = getListCount(data); metric_hops++; metric_distance_computations+=size; - tableint *datal = (tableint *) (data + 1); + tableint *datal = reinterpret_cast(data + 1); for (int i = 0; i < size; i++) { tableint cand = datal[i]; - if (cand < 0 || cand > max_elements_) + if (cand > max_elements_) throw std::runtime_error("cand error"); dist_t d = fstdistfunc_(query_data, getDataByInternalId(cand), dist_func_param_); @@ -1379,27 +1379,27 @@ class HierarchicalNSW : public AlgorithmInterface { void checkIntegrity() { - int connections_checked = 0; - std::vector inbound_connections_num(cur_element_count, 0); - for (int i = 0; i < cur_element_count; i++) { + size_t connections_checked = 0; + std::vector inbound_connections_num(cur_element_count, 0); + for (size_t i = 0; i < cur_element_count; i++) { for (int l = 0; l <= element_levels_[i]; l++) { - linklistsizeint *ll_cur = get_linklist_at_level(i, l); + linklistsizeint *ll_cur = get_linklist_at_level(static_cast(i), l); int size = getListCount(ll_cur); - tableint *data = (tableint *) (ll_cur + 1); + tableint *data = reinterpret_cast(ll_cur + 1); std::unordered_set s; for (int j = 0; j < size; j++) { assert(data[j] < cur_element_count); - assert(data[j] != i); + assert(data[j] != static_cast(i)); inbound_connections_num[data[j]]++; s.insert(data[j]); connections_checked++; } - assert(s.size() == size); + assert(s.size() == static_cast(size)); } } if (cur_element_count > 1) { int min1 = inbound_connections_num[0], max1 = inbound_connections_num[0]; - for (int i=0; i < cur_element_count; i++) { + for (size_t i = 0; i < cur_element_count; i++) { assert(inbound_connections_num[i] > 0); min1 = std::min(inbound_connections_num[i], min1); max1 = std::max(inbound_connections_num[i], max1); diff --git a/hnswlib/hnswlib.h b/hnswlib/hnswlib.h index 7ccfbba5..95903104 100644 --- a/hnswlib/hnswlib.h +++ b/hnswlib/hnswlib.h @@ -40,7 +40,7 @@ static void cpuid(int32_t cpuInfo[4], int32_t eax, int32_t ecx) { static uint64_t xgetbv(unsigned int index) { uint32_t eax, edx; __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index)); - return ((uint64_t)edx << 32) | eax; + return (static_cast(edx) << 32) | eax; } #endif @@ -59,6 +59,14 @@ static uint64_t xgetbv(unsigned int index) { // Adapted from https://github.com/Mysticial/FeatureDetector #define _XCR_XFEATURE_ENABLED_MASK 0 +// These functions may be unused when SIMD is disabled or specific instruction sets are not available +#if defined(__GNUC__) || defined(__clang__) +#define HNSWLIB_MAYBE_UNUSED __attribute__((unused)) +#else +#define HNSWLIB_MAYBE_UNUSED +#endif + +HNSWLIB_MAYBE_UNUSED static bool AVXCapable() { int cpuInfo[4]; @@ -69,7 +77,7 @@ static bool AVXCapable() { bool HW_AVX = false; if (nIds >= 0x00000001) { cpuid(cpuInfo, 0x00000001, 0); - HW_AVX = (cpuInfo[2] & ((int)1 << 28)) != 0; + HW_AVX = (cpuInfo[2] & (1 << 28)) != 0; } // OS support @@ -86,6 +94,7 @@ static bool AVXCapable() { return HW_AVX && avxSupported; } +HNSWLIB_MAYBE_UNUSED static bool AVX512Capable() { if (!AVXCapable()) return false; @@ -98,7 +107,7 @@ static bool AVX512Capable() { bool HW_AVX512F = false; if (nIds >= 0x00000007) { // AVX512 Foundation cpuid(cpuInfo, 0x00000007, 0); - HW_AVX512F = (cpuInfo[1] & ((int)1 << 16)) != 0; + HW_AVX512F = (cpuInfo[1] & (1 << 16)) != 0; } // OS support @@ -127,7 +136,7 @@ typedef size_t labeltype; // This can be extended to store state for filtering (e.g. from a std::set) class BaseFilterFunctor { public: - virtual bool operator()(hnswlib::labeltype id) { return true; } + virtual bool operator()(hnswlib::labeltype /*id*/) { return true; } virtual ~BaseFilterFunctor() {}; }; @@ -159,12 +168,12 @@ class pairGreater { template static void writeBinaryPOD(std::ostream &out, const T &podRef) { - out.write((char *) &podRef, sizeof(T)); + out.write(reinterpret_cast(&podRef), sizeof(T)); } template static void readBinaryPOD(std::istream &in, T &podRef) { - in.read((char *) &podRef, sizeof(T)); + in.read(reinterpret_cast(&podRef), sizeof(T)); } template diff --git a/hnswlib/space_ip.h b/hnswlib/space_ip.h index 0e6834c1..47e8ddfc 100644 --- a/hnswlib/space_ip.h +++ b/hnswlib/space_ip.h @@ -5,10 +5,12 @@ namespace hnswlib { static float InnerProduct(const void *pVect1, const void *pVect2, const void *qty_ptr) { - size_t qty = *((size_t *) qty_ptr); + size_t qty = *static_cast(qty_ptr); float res = 0; - for (unsigned i = 0; i < qty; i++) { - res += ((float *) pVect1)[i] * ((float *) pVect2)[i]; + const float* v1 = static_cast(pVect1); + const float* v2 = static_cast(pVect2); + for (size_t i = 0; i < qty; i++) { + res += v1[i] * v2[i]; } return res; } @@ -24,9 +26,9 @@ InnerProductDistance(const void *pVect1, const void *pVect2, const void *qty_ptr static float InnerProductSIMD4ExtAVX(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { float PORTABLE_ALIGN32 TmpRes[8]; - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); size_t qty16 = qty / 16; size_t qty4 = qty / 4; @@ -80,9 +82,9 @@ InnerProductDistanceSIMD4ExtAVX(const void *pVect1v, const void *pVect2v, const static float InnerProductSIMD4ExtSSE(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { float PORTABLE_ALIGN32 TmpRes[8]; - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); size_t qty16 = qty / 16; size_t qty4 = qty / 4; @@ -146,9 +148,9 @@ InnerProductDistanceSIMD4ExtSSE(const void *pVect1v, const void *pVect2v, const static float InnerProductSIMD16ExtAVX512(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { float PORTABLE_ALIGN64 TmpRes[16]; - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); size_t qty16 = qty / 16; @@ -210,9 +212,9 @@ InnerProductDistanceSIMD16ExtAVX512(const void *pVect1v, const void *pVect2v, co static float InnerProductSIMD16ExtAVX(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { float PORTABLE_ALIGN32 TmpRes[8]; - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); size_t qty16 = qty / 16; @@ -255,9 +257,9 @@ InnerProductDistanceSIMD16ExtAVX(const void *pVect1v, const void *pVect2v, const static float InnerProductSIMD16ExtSSE(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { float PORTABLE_ALIGN32 TmpRes[8]; - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); size_t qty16 = qty / 16; @@ -312,11 +314,11 @@ static DISTFUNC InnerProductDistanceSIMD4Ext = InnerProductDistanceSIMD4E static float InnerProductDistanceSIMD16ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { - size_t qty = *((size_t *) qty_ptr); + size_t qty = *static_cast(qty_ptr); size_t qty16 = qty >> 4 << 4; float res = InnerProductSIMD16Ext(pVect1v, pVect2v, &qty16); - float *pVect1 = (float *) pVect1v + qty16; - float *pVect2 = (float *) pVect2v + qty16; + const float *pVect1 = static_cast(pVect1v) + qty16; + const float *pVect2 = static_cast(pVect2v) + qty16; size_t qty_left = qty - qty16; float res_tail = InnerProduct(pVect1, pVect2, &qty_left); @@ -325,14 +327,14 @@ InnerProductDistanceSIMD16ExtResiduals(const void *pVect1v, const void *pVect2v, static float InnerProductDistanceSIMD4ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { - size_t qty = *((size_t *) qty_ptr); + size_t qty = *static_cast(qty_ptr); size_t qty4 = qty >> 2 << 2; float res = InnerProductSIMD4Ext(pVect1v, pVect2v, &qty4); size_t qty_left = qty - qty4; - float *pVect1 = (float *) pVect1v + qty4; - float *pVect2 = (float *) pVect2v + qty4; + const float *pVect1 = static_cast(pVect1v) + qty4; + const float *pVect2 = static_cast(pVect2v) + qty4; float res_tail = InnerProduct(pVect1, pVect2, &qty_left); return 1.0f - (res + res_tail); diff --git a/hnswlib/space_l2.h b/hnswlib/space_l2.h index 834d19f7..b32eb664 100644 --- a/hnswlib/space_l2.h +++ b/hnswlib/space_l2.h @@ -5,9 +5,9 @@ namespace hnswlib { static float L2Sqr(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); float res = 0; for (size_t i = 0; i < qty; i++) { @@ -16,7 +16,7 @@ L2Sqr(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { pVect2++; res += t * t; } - return (res); + return res; } #if defined(USE_AVX512) @@ -24,9 +24,9 @@ L2Sqr(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { // Favor using AVX512 if available. static float L2SqrSIMD16ExtAVX512(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); float PORTABLE_ALIGN64 TmpRes[16]; size_t qty16 = qty >> 4; @@ -59,9 +59,9 @@ L2SqrSIMD16ExtAVX512(const void *pVect1v, const void *pVect2v, const void *qty_p // Favor using AVX if available. static float L2SqrSIMD16ExtAVX(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); float PORTABLE_ALIGN32 TmpRes[8]; size_t qty16 = qty >> 4; @@ -96,9 +96,9 @@ L2SqrSIMD16ExtAVX(const void *pVect1v, const void *pVect2v, const void *qty_ptr) static float L2SqrSIMD16ExtSSE(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); float PORTABLE_ALIGN32 TmpRes[8]; size_t qty16 = qty >> 4; @@ -148,15 +148,15 @@ static DISTFUNC L2SqrSIMD16Ext = L2SqrSIMD16ExtSSE; static float L2SqrSIMD16ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { - size_t qty = *((size_t *) qty_ptr); + size_t qty = *static_cast(qty_ptr); size_t qty16 = qty >> 4 << 4; float res = L2SqrSIMD16Ext(pVect1v, pVect2v, &qty16); - float *pVect1 = (float *) pVect1v + qty16; - float *pVect2 = (float *) pVect2v + qty16; + const float *pVect1 = static_cast(pVect1v) + qty16; + const float *pVect2 = static_cast(pVect2v) + qty16; size_t qty_left = qty - qty16; float res_tail = L2Sqr(pVect1, pVect2, &qty_left); - return (res + res_tail); + return res + res_tail; } #endif @@ -165,9 +165,9 @@ L2SqrSIMD16ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qt static float L2SqrSIMD4Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { float PORTABLE_ALIGN32 TmpRes[8]; - float *pVect1 = (float *) pVect1v; - float *pVect2 = (float *) pVect2v; - size_t qty = *((size_t *) qty_ptr); + const float *pVect1 = static_cast(pVect1v); + const float *pVect2 = static_cast(pVect2v); + size_t qty = *static_cast(qty_ptr); size_t qty4 = qty >> 2; @@ -191,17 +191,17 @@ L2SqrSIMD4Ext(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { static float L2SqrSIMD4ExtResiduals(const void *pVect1v, const void *pVect2v, const void *qty_ptr) { - size_t qty = *((size_t *) qty_ptr); + size_t qty = *static_cast(qty_ptr); size_t qty4 = qty >> 2 << 2; float res = L2SqrSIMD4Ext(pVect1v, pVect2v, &qty4); size_t qty_left = qty - qty4; - float *pVect1 = (float *) pVect1v + qty4; - float *pVect2 = (float *) pVect2v + qty4; + const float *pVect1 = static_cast(pVect1v) + qty4; + const float *pVect2 = static_cast(pVect2v) + qty4; float res_tail = L2Sqr(pVect1, pVect2, &qty_left); - return (res + res_tail); + return res + res_tail; } #endif @@ -254,10 +254,10 @@ class L2Space : public SpaceInterface { static int L2SqrI4x(const void *__restrict pVect1, const void *__restrict pVect2, const void *__restrict qty_ptr) { - size_t qty = *((size_t *) qty_ptr); + size_t qty = *static_cast(qty_ptr); int res = 0; - unsigned char *a = (unsigned char *) pVect1; - unsigned char *b = (unsigned char *) pVect2; + const unsigned char *a = static_cast(pVect1); + const unsigned char *b = static_cast(pVect2); qty = qty >> 2; for (size_t i = 0; i < qty; i++) { @@ -278,10 +278,10 @@ L2SqrI4x(const void *__restrict pVect1, const void *__restrict pVect2, const voi } static int L2SqrI(const void* __restrict pVect1, const void* __restrict pVect2, const void* __restrict qty_ptr) { - size_t qty = *((size_t*)qty_ptr); + size_t qty = *static_cast(qty_ptr); int res = 0; - unsigned char* a = (unsigned char*)pVect1; - unsigned char* b = (unsigned char*)pVect2; + const unsigned char* a = static_cast(pVect1); + const unsigned char* b = static_cast(pVect2); for (size_t i = 0; i < qty; i++) { res += ((*a) - (*b)) * ((*a) - (*b)); diff --git a/hnswlib/stop_condition.h b/hnswlib/stop_condition.h index acc80ebe..75feaf53 100644 --- a/hnswlib/stop_condition.h +++ b/hnswlib/stop_condition.h @@ -63,14 +63,14 @@ class MultiVectorL2Space : public BaseMultiVectorSpace { } DOCIDTYPE get_doc_id(const void *datapoint) override { - return *(DOCIDTYPE *)((char *)datapoint + vector_size_); + return *reinterpret_cast(static_cast(datapoint) + vector_size_); } void set_doc_id(void *datapoint, DOCIDTYPE doc_id) override { - *(DOCIDTYPE*)((char *)datapoint + vector_size_) = doc_id; + *reinterpret_cast(static_cast(datapoint) + vector_size_) = doc_id; } - ~MultiVectorL2Space() {} + ~MultiVectorL2Space() override {} }; @@ -115,6 +115,7 @@ class MultiVectorInnerProductSpace : public BaseMultiVectorSpace { else if (dim > 4) fstdistfunc_ = InnerProductDistanceSIMD4ExtResiduals; #endif + dim_ = dim; vector_size_ = dim * sizeof(float); data_size_ = vector_size_ + sizeof(DOCIDTYPE); } @@ -132,14 +133,14 @@ class MultiVectorInnerProductSpace : public BaseMultiVectorSpace { } DOCIDTYPE get_doc_id(const void *datapoint) override { - return *(DOCIDTYPE *)((char *)datapoint + vector_size_); + return *reinterpret_cast(static_cast(datapoint) + vector_size_); } void set_doc_id(void *datapoint, DOCIDTYPE doc_id) override { - *(DOCIDTYPE*)((char *)datapoint + vector_size_) = doc_id; + *reinterpret_cast(static_cast(datapoint) + vector_size_) = doc_id; } - ~MultiVectorInnerProductSpace() {} + ~MultiVectorInnerProductSpace() override {} }; @@ -163,7 +164,7 @@ class MultiVectorSearchStopCondition : public BaseSearchStopCondition { ef_collection_ = std::max(ef_collection, num_docs_to_search); } - void add_point_to_result(labeltype label, const void *datapoint, dist_t dist) override { + void add_point_to_result(labeltype /*label*/, const void *datapoint, dist_t dist) override { DOCIDTYPE doc_id = space_.get_doc_id(datapoint); if (doc_counter_[doc_id] == 0) { curr_num_docs_ += 1; @@ -172,7 +173,7 @@ class MultiVectorSearchStopCondition : public BaseSearchStopCondition { doc_counter_[doc_id] += 1; } - void remove_point_from_result(labeltype label, const void *datapoint, dist_t dist) override { + void remove_point_from_result(labeltype /*label*/, const void *datapoint, dist_t /*dist*/) override { DOCIDTYPE doc_id = space_.get_doc_id(datapoint); doc_counter_[doc_id] -= 1; if (doc_counter_[doc_id] == 0) { @@ -198,9 +199,7 @@ class MultiVectorSearchStopCondition : public BaseSearchStopCondition { void filter_results(std::vector> &candidates) override { while (curr_num_docs_ > num_docs_to_search_) { - dist_t dist_cand = candidates.back().first; - dist_t dist_res = search_results_.top().first; - assert(dist_cand == dist_res); + assert(candidates.back().first == search_results_.top().first); DOCIDTYPE doc_id = search_results_.top().second; doc_counter_[doc_id] -= 1; if (doc_counter_[doc_id] == 0) { @@ -231,11 +230,11 @@ class EpsilonSearchStopCondition : public BaseSearchStopCondition { curr_num_items_ = 0; } - void add_point_to_result(labeltype label, const void *datapoint, dist_t dist) override { + void add_point_to_result(labeltype /*label*/, const void* /*datapoint*/, dist_t /*dist*/) override { curr_num_items_ += 1; } - void remove_point_from_result(labeltype label, const void *datapoint, dist_t dist) override { + void remove_point_from_result(labeltype /*label*/, const void* /*datapoint*/, dist_t /*dist*/) override { curr_num_items_ -= 1; } @@ -257,7 +256,7 @@ class EpsilonSearchStopCondition : public BaseSearchStopCondition { return flag_consider_candidate; } - bool should_remove_extra() { + bool should_remove_extra() override { bool flag_remove_extra = curr_num_items_ > max_num_candidates_; return flag_remove_extra; } diff --git a/hnswlib/visited_list_pool.h b/hnswlib/visited_list_pool.h index 2e201ec4..2b3c8399 100644 --- a/hnswlib/visited_list_pool.h +++ b/hnswlib/visited_list_pool.h @@ -11,12 +11,12 @@ class VisitedList { public: vl_type curV; vl_type *mass; - unsigned int numelements; + size_t numelements; - VisitedList(int numelements1) { - curV = -1; - numelements = numelements1; - mass = new vl_type[numelements]; + explicit VisitedList(size_t numelements_init) + : curV(static_cast(-1)), + mass(new vl_type[numelements_init]), + numelements(numelements_init) { } void reset() { @@ -38,12 +38,12 @@ class VisitedList { class VisitedListPool { std::deque pool; std::mutex poolguard; - int numelements; + size_t numelements; public: - VisitedListPool(int initmaxpools, int numelements1) { - numelements = numelements1; - for (int i = 0; i < initmaxpools; i++) + VisitedListPool(size_t initmaxpools, size_t numelements_init) + : numelements(numelements_init) { + for (size_t i = 0; i < initmaxpools; i++) pool.push_front(new VisitedList(numelements)); } diff --git a/tests/cpp/epsilon_search_test.cpp b/tests/cpp/epsilon_search_test.cpp index 38df6246..d5883801 100644 --- a/tests/cpp/epsilon_search_test.cpp +++ b/tests/cpp/epsilon_search_test.cpp @@ -53,7 +53,6 @@ int main() { alg_hnsw->searchStopConditionClosest(query_data, stop_condition); // check that returned results are in epsilon region - size_t num_vectors = result_hnsw.size(); std::unordered_set hnsw_labels; for (auto pair: result_hnsw) { float dist = pair.first; @@ -92,12 +91,11 @@ int main() { // Query the elements for themselves and check that query can be found float epsilon2_small = 0.0001f; - int min_candidates_small = 500; - for (size_t i = 0; i < max_elements; i++) { + size_t min_candidates_small = 500; + for (int i = 0; i < max_elements; i++) { hnswlib::EpsilonSearchStopCondition stop_condition(epsilon2_small, min_candidates_small, max_num_candidates); - std::vector> result = - alg_hnsw->searchStopConditionClosest(alg_hnsw->getDataByInternalId(i), stop_condition); - size_t num_vectors = result.size(); + std::vector> result = + alg_hnsw->searchStopConditionClosest(alg_hnsw->getDataByInternalId(static_cast(i)), stop_condition); // get closest distance float dist = -1; if (!result.empty()) { diff --git a/tests/cpp/multiThreadLoad_test.cpp b/tests/cpp/multiThreadLoad_test.cpp index 4d2b4aa2..b3c2c5c7 100644 --- a/tests/cpp/multiThreadLoad_test.cpp +++ b/tests/cpp/multiThreadLoad_test.cpp @@ -29,7 +29,7 @@ int main() { // add elements by batches std::uniform_int_distribution<> distrib_int(start_label, start_label + num_labels - 1); std::vector threads; - for (size_t thread_id = 0; thread_id < num_threads; thread_id++) { + for (int thread_id = 0; thread_id < num_threads; thread_id++) { threads.push_back( std::thread( [&] { @@ -48,14 +48,14 @@ int main() { for (auto &thread : threads) { thread.join(); } - if (alg_hnsw->cur_element_count > max_elements - num_labels) { + if (alg_hnsw->cur_element_count > static_cast(max_elements - num_labels)) { break; } start_label += num_labels; } // insert remaining elements if needed - for (hnswlib::labeltype label = 0; label < max_elements; label++) { + for (int label = 0; label < max_elements; label++) { auto search = alg_hnsw->label_lookup_.find(label); if (search == alg_hnsw->label_lookup_.end()) { std::cout << "Adding " << label << std::endl; @@ -77,7 +77,7 @@ int main() { std::cout << "Starting markDeleted and unmarkDeleted threads" << std::endl; num_threads = 20; int chunk_size = max_elements / num_threads; - for (size_t thread_id = 0; thread_id < num_threads; thread_id++) { + for (int thread_id = 0; thread_id < num_threads; thread_id++) { threads.push_back( std::thread( [&, thread_id] { @@ -104,7 +104,7 @@ int main() { std::cout << "Starting add and update elements threads" << std::endl; num_threads = 20; std::uniform_int_distribution<> distrib_int_add(max_elements, 2 * max_elements - 1); - for (size_t thread_id = 0; thread_id < num_threads; thread_id++) { + for (int thread_id = 0; thread_id < num_threads; thread_id++) { threads.push_back( std::thread( [&] { @@ -115,8 +115,8 @@ int main() { data[i] = distrib_real(rng); } alg_hnsw->addPoint(data.data(), label); - std::vector data = alg_hnsw->getDataByLabel(label); - float max_val = *max_element(data.begin(), data.end()); + std::vector retrieved_data = alg_hnsw->getDataByLabel(label); + float max_val = *max_element(retrieved_data.begin(), retrieved_data.end()); // never happens but prevents compiler from deleting unused code if (max_val > 10) { throw std::runtime_error("Unexpected value in data"); diff --git a/tests/cpp/multiThread_replace_test.cpp b/tests/cpp/multiThread_replace_test.cpp index 203cdb0d..b0ee9f2e 100644 --- a/tests/cpp/multiThread_replace_test.cpp +++ b/tests/cpp/multiThread_replace_test.cpp @@ -93,7 +93,7 @@ int main() { hnswlib::HierarchicalNSW* alg_hnsw = new hnswlib::HierarchicalNSW(&space, max_elements, 16, 200, 123, true); // add batch1 data - ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t threadId) { + ParallelFor(0, max_elements, num_threads, [&](size_t row, size_t /*threadId*/) { alg_hnsw->addPoint((void*)(batch1 + d * row), row); }); @@ -103,7 +103,7 @@ int main() { } // replace deleted elements with batch2 data - ParallelFor(0, num_elements, num_threads, [&](size_t row, size_t threadId) { + ParallelFor(0, num_elements, num_threads, [&](size_t row, size_t /*threadId*/) { int label = rand_labels[row] + max_elements; alg_hnsw->addPoint((void*)(batch2 + d * row), label, true); }); diff --git a/tests/cpp/multivector_search_test.cpp b/tests/cpp/multivector_search_test.cpp index be783176..9cca575d 100644 --- a/tests/cpp/multivector_search_test.cpp +++ b/tests/cpp/multivector_search_test.cpp @@ -79,17 +79,17 @@ int main() { docidtype doc_id = label_docid_lookup[label]; hnsw_docs.emplace(doc_id); } - assert(hnsw_docs.size() == num_docs); + assert(hnsw_docs.size() == static_cast(num_docs)); // Check overall recall - std::vector> gt_results = + std::vector> gt_results = alg_brute->searchKnnCloserFirst(query_data, max_elements); std::unordered_set gt_docs; - for (int i = 0; i < gt_results.size(); i++) { - if (gt_docs.size() == num_docs) { + for (size_t j = 0; j < gt_results.size(); j++) { + if (gt_docs.size() == static_cast(num_docs)) { break; } - hnswlib::labeltype gt_label = gt_results[i].second; + hnswlib::labeltype gt_label = gt_results[j].second; if (hnsw_labels.find(gt_label) != hnsw_labels.end()) { correct += 1; } @@ -109,13 +109,13 @@ int main() { hnswlib::MultiVectorSearchStopCondition stop_condition(space, num_docs, ef_collection); std::vector> result = alg_hnsw->searchStopConditionClosest(data + i * data_point_size, stop_condition); - hnswlib::labeltype label = -1; + hnswlib::labeltype label = static_cast(-1); if (!result.empty()) { label = result[0].second; } - if (label == i) correct++; + if (label == static_cast(i)) correct++; } - recall = correct / max_elements; + recall = correct / static_cast(max_elements); std::cout << "same elements search recall : " << recall << "\n"; assert(recall > 0.99); diff --git a/tests/cpp/searchKnnWithFilter_test.cpp b/tests/cpp/searchKnnWithFilter_test.cpp index 0557b7e4..e79e52b6 100644 --- a/tests/cpp/searchKnnWithFilter_test.cpp +++ b/tests/cpp/searchKnnWithFilter_test.cpp @@ -17,14 +17,14 @@ unsigned int divisor = 1; PickDivisibleIds(unsigned int divisor): divisor(divisor) { assert(divisor != 0); } - bool operator()(idx_t label_id) { + bool operator()(idx_t label_id) override { return label_id % divisor == 0; } }; class PickNothing: public hnswlib::BaseFilterFunctor { public: - bool operator()(idx_t label_id) { + bool operator()(idx_t /*label_id*/) override { return false; } }; @@ -151,7 +151,7 @@ class CustomFilterFunctor: public hnswlib::BaseFilterFunctor { public: explicit CustomFilterFunctor(const std::unordered_set& values) : allowed_values(values) {} - bool operator()(idx_t id) { + bool operator()(idx_t id) override { return allowed_values.count(id) != 0; } }; diff --git a/tests/cpp/sift_1b.cpp b/tests/cpp/sift_1b.cpp index c0f296c2..197324cd 100644 --- a/tests/cpp/sift_1b.cpp +++ b/tests/cpp/sift_1b.cpp @@ -66,7 +66,7 @@ class StopW { * memory use) measured in bytes, or zero if the value cannot be * determined on this OS. */ -static size_t getPeakRSS() { +[[maybe_unused]] static size_t getPeakRSS() { #if defined(_WIN32) /* Windows -------------------------------------------------- */ PROCESS_MEMORY_COUNTERS info; @@ -146,19 +146,18 @@ static size_t getCurrentRSS() { static void get_gt( unsigned int *massQA, - unsigned char *massQ, - unsigned char *mass, - size_t vecsize, + unsigned char * /*massQ*/, + unsigned char * /*mass*/, + size_t /*vecsize*/, size_t qsize, - L2SpaceI &l2space, - size_t vecdim, + L2SpaceI & /*l2space*/, + size_t /*vecdim*/, vector>> &answers, size_t k) { (vector>>(qsize)).swap(answers); - DISTFUNC fstdistfunc_ = l2space.get_dist_func(); cout << qsize << "\n"; - for (int i = 0; i < qsize; i++) { - for (int j = 0; j < k; j++) { + for (size_t i = 0; i < qsize; i++) { + for (size_t j = 0; j < k; j++) { answers[i].emplace(0.0f, massQA[1000 * i + j]); } } @@ -167,7 +166,7 @@ get_gt( static float test_approx( unsigned char *massQ, - size_t vecsize, + size_t /*vecsize*/, size_t qsize, HierarchicalNSW &appr_alg, size_t vecdim, @@ -177,7 +176,7 @@ test_approx( size_t total = 0; // uncomment to test in parallel mode: //#pragma omp parallel for - for (int i = 0; i < qsize; i++) { + for (size_t i = 0; i < qsize; i++) { std::priority_queue> result = appr_alg.searchKnn(massQ + vecdim * i, k); std::priority_queue> gt(answers[i]); unordered_set g; @@ -261,7 +260,7 @@ void sift_test1B() { cout << "Loading GT:\n"; ifstream inputGT(path_gt, ios::binary); unsigned int *massQA = new unsigned int[qsize * 1000]; - for (int i = 0; i < qsize; i++) { + for (size_t i = 0; i < qsize; i++) { int t; inputGT.read((char *) &t, 4); inputGT.read((char *) (massQA + 1000 * i), t * 4); @@ -276,7 +275,7 @@ void sift_test1B() { unsigned char *massQ = new unsigned char[qsize * vecdim]; ifstream inputQ(path_q, ios::binary); - for (int i = 0; i < qsize; i++) { + for (size_t i = 0; i < qsize; i++) { int in = 0; inputQ.read((char *) &in, 4); if (in != 128) { @@ -284,7 +283,7 @@ void sift_test1B() { exit(1); } inputQ.read((char *) massb, in); - for (int j = 0; j < vecdim; j++) { + for (size_t j = 0; j < vecdim; j++) { massQ[i * vecdim + j] = massb[j]; } } @@ -312,19 +311,19 @@ void sift_test1B() { } input.read((char *) massb, in); - for (int j = 0; j < vecdim; j++) { + for (size_t j = 0; j < vecdim; j++) { mass[j] = massb[j] * (1.0f); } appr_alg->addPoint((void *) (massb), (size_t) 0); - int j1 = 0; + size_t j1 = 0; StopW stopw = StopW(); StopW stopw_full = StopW(); size_t report_every = 100000; #pragma omp parallel for - for (int i = 1; i < vecsize; i++) { + for (size_t i = 1; i < vecsize; i++) { unsigned char mass[128]; - int j2 = 0; + size_t j2 = 0; #pragma omp critical { input.read((char *) &in, 4); @@ -333,7 +332,7 @@ void sift_test1B() { exit(1); } input.read((char *) massb, in); - for (int j = 0; j < vecdim; j++) { + for (size_t j = 0; j < vecdim; j++) { mass[j] = massb[j]; } j1++; diff --git a/tests/cpp/updates_test.cpp b/tests/cpp/updates_test.cpp index 4dff2f85..071b986a 100644 --- a/tests/cpp/updates_test.cpp +++ b/tests/cpp/updates_test.cpp @@ -110,8 +110,8 @@ test_approx(std::vector &queries, size_t qsize, hnswlib::HierarchicalNSW< size_t correct = 0; size_t total = 0; - for (int i = 0; i < qsize; i++) { - std::priority_queue> result = appr_alg.searchKnn((char *)(queries.data() + vecdim * i), K); + for (size_t i = 0; i < qsize; i++) { + std::priority_queue> result = appr_alg.searchKnn(reinterpret_cast(queries.data() + vecdim * i), K); total += K; while (result.size()) { if (answers[i].find(result.top().second) != answers[i].end()) { @@ -226,12 +226,12 @@ int main(int argc, char **argv) { if (update) { std::cout << "Update iteration 0\n"; - ParallelFor(1, N, num_threads, [&](size_t i, size_t threadId) { + ParallelFor(1, N, num_threads, [&](size_t i, size_t /*threadId*/) { appr_alg.addPoint((void *)(dummy_batch.data() + i * d), i); }); appr_alg.checkIntegrity(); - ParallelFor(1, N, num_threads, [&](size_t i, size_t threadId) { + ParallelFor(1, N, num_threads, [&](size_t i, size_t /*threadId*/) { appr_alg.addPoint((void *)(dummy_batch.data() + i * d), i); }); appr_alg.checkIntegrity(); @@ -242,7 +242,7 @@ int main(int argc, char **argv) { snprintf(cpath, sizeof(cpath), "batch_dummy_%02d.bin", b); std::vector dummy_batchb = load_batch(path + cpath, N * d); - ParallelFor(0, N, num_threads, [&](size_t i, size_t threadId) { + ParallelFor(0, N, num_threads, [&](size_t i, size_t /*threadId*/) { appr_alg.addPoint((void *)(dummy_batch.data() + i * d), i); }); appr_alg.checkIntegrity(); @@ -253,7 +253,7 @@ int main(int argc, char **argv) { std::vector final_batch = load_batch(path + "batch_final.bin", N * d); stopw.reset(); - ParallelFor(0, N, num_threads, [&](size_t i, size_t threadId) { + ParallelFor(0, N, num_threads, [&](size_t i, size_t /*threadId*/) { appr_alg.addPoint((void *)(final_batch.data() + i * d), i); }); std::cout << "Finished. Time taken:" << stopw.getElapsedTimeMicro()*1e-6 << " s\n";