diff --git a/include/knowhere/feature.h b/include/knowhere/feature.h new file mode 100644 index 000000000..858fe59d9 --- /dev/null +++ b/include/knowhere/feature.h @@ -0,0 +1,54 @@ +// Copyright (C) 2019-2023 Zilliz. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#ifndef FEATURE_H +#define FEATURE_H + +// these features have been report to outside (milvus); pls sync the feature code when it needs to be changed. +namespace knowhere::feature { +// vector datatype support : binary +constexpr uint64_t BINARY = 1UL << 0; +// vector datatype support : float32 +constexpr uint64_t FLOAT32 = 1UL << 1; +// vector datatype support : fp16 +constexpr uint64_t FP16 = 1UL << 2; +// vector datatype support : bf16 +constexpr uint64_t BF16 = 1UL << 3; +// vector datatype support : sparse_float32 +constexpr uint64_t SPARSE_FLOAT32 = 1UL << 4; + +// This flag indicates that there is no need to create any index structure (build stage can be skipped) +constexpr uint64_t NO_TRAIN = 1UL << 16; +// This flag indicates that the index defaults to KNN search, meaning the recall is 100% (no precision loss compared +// with original data) +constexpr uint64_t KNN = 1UL << 17; +// This flag indicates that the index search stage will be performed on GPU (need GPU devices) +constexpr uint64_t GPU = 1UL << 18; +// This flag indicates that the index support using mmap manage its mainly memory, which can significant improve the +// capacity +constexpr uint64_t MMAP = 1UL << 19; +// This flag indicates that the index support using materialized view to accelerate filtering search +constexpr uint64_t MV = 1UL << 20; +// This flag indicates that the index need disk during search stage +constexpr uint64_t DISK = 1UL << 21; + +constexpr uint64_t ALL_TYPE = BINARY | FLOAT32 | FP16 | BF16 | SPARSE_FLOAT32; +constexpr uint64_t ALL_DENSE_TYPE = BINARY | FLOAT32 | FP16 | BF16; +constexpr uint64_t ALL_DENSE_FLOAT_TYPE = FLOAT32 | FP16 | BF16; + +constexpr uint64_t NO_TRAIN_INDEX = NO_TRAIN; +constexpr uint64_t GPU_KNN_FLOAT_INDEX = FLOAT32 | GPU | KNN; +constexpr uint64_t GPU_ANN_FLOAT_INDEX = FLOAT32 | GPU; +} // namespace knowhere::feature +#endif /* FEATURE_H */ diff --git a/include/knowhere/index/index.h b/include/knowhere/index/index.h index 41d119910..4f3f21604 100644 --- a/include/knowhere/index/index.h +++ b/include/knowhere/index/index.h @@ -203,8 +203,10 @@ class Index { if (node == nullptr) return; node->DecRef(); - if (!node->Ref()) + if (!node->Ref()) { delete node; + node = nullptr; + } } private: diff --git a/include/knowhere/index/index_factory.h b/include/knowhere/index/index_factory.h index 80c5d4b9e..029ea08da 100644 --- a/include/knowhere/index/index_factory.h +++ b/include/knowhere/index/index_factory.h @@ -27,12 +27,22 @@ class IndexFactory { template expected> Create(const std::string& name, const int32_t& version, const Object& object = nullptr); + template const IndexFactory& - Register(const std::string& name, std::function(const int32_t&, const Object&)> func); + Register(const std::string& name, std::function(const int32_t&, const Object&)> func, + const uint64_t features); + static IndexFactory& Instance(); typedef std::tuple>, std::set> GlobalIndexTable; + + bool + FeatureCheck(const std::string& name, uint64_t feature) const; + + static const std::map& + GetIndexFeatures(); + static GlobalIndexTable& StaticIndexTableInstance(); @@ -47,31 +57,39 @@ class IndexFactory { } std::function fun_value; }; - typedef std::map> FuncMap; + using FuncMap = std::map>; + using FeatureMap = std::map; IndexFactory(); + static FuncMap& MapInstance(); -}; + static FeatureMap& + FeatureMapInstance(); +}; +// register the index adapter corresponding to indexType #define KNOWHERE_FACTOR_CONCAT(x, y) index_factory_ref_##x##y -#define KNOWHERE_STATIC_CONCAT(x, y) index_static_ref_##x##y +#define KNOWHERE_REGISTER_GLOBAL(name, func, data_type, condition, features) \ + const IndexFactory& KNOWHERE_FACTOR_CONCAT(name, data_type) = \ + condition ? IndexFactory::Instance().Register(#name, func, features) : IndexFactory::Instance(); +// register some static methods that are bound to indexType +#define KNOWHERE_STATIC_CONCAT(x, y) index_static_ref_##x##y #define KNOWHERE_REGISTER_STATIC(name, index_node, data_type, ...) \ const IndexStaticFaced& KNOWHERE_STATIC_CONCAT(name, data_type) = \ IndexStaticFaced::Instance().RegisterStaticFunc>(#name); -#define KNOWHERE_REGISTER_GLOBAL(name, func, data_type) \ - const IndexFactory& KNOWHERE_FACTOR_CONCAT(name, data_type) = \ - IndexFactory::Instance().Register(#name, func) - -#define KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, data_type, ...) \ +// register the index implementation along with its associated features. Please carefully check the types and features +// supported by the index—both need to be consistent, otherwise the registration will be skipped +#define KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, data_type, features, ...) \ KNOWHERE_REGISTER_STATIC(name, index_node, data_type, ##__VA_ARGS__) \ KNOWHERE_REGISTER_GLOBAL( \ name, \ (static_cast> (*)(const int32_t&, const Object&)>( \ &Index>::Create)), \ - data_type) -#define KNOWHERE_MOCK_REGISTER_GLOBAL(name, index_node, data_type, ...) \ + data_type, typeCheck(features), features) + +#define KNOWHERE_MOCK_REGISTER_GLOBAL(name, index_node, data_type, features, ...) \ KNOWHERE_REGISTER_STATIC(name, index_node, data_type, ##__VA_ARGS__) \ KNOWHERE_REGISTER_GLOBAL( \ name, \ @@ -79,8 +97,55 @@ class IndexFactory { return (Index>::Create( \ std::make_unique::type, ##__VA_ARGS__>>(version, object))); \ }, \ - data_type) -#define KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(name, index_node, data_type, thread_size) \ + data_type, typeCheck(features), features) + +// Below are some group index registration methods for batch registration of indexes that support multiple data types. +// Please review carefully and select with caution + +// register vector index supporting ALL_TYPE(binary, bf16, fp16, fp32, sparse_float32) data types +#define KNOWHERE_SIMPLE_REGISTER_ALL_GLOBAL(name, index_node, features, ...) \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, bin1, (features | knowhere::feature::ALL_TYPE), ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, bf16, (features | knowhere::feature::ALL_TYPE), ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, fp16, (features | knowhere::feature::ALL_TYPE), ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, fp32, (features | knowhere::feature::ALL_TYPE), ##__VA_ARGS__); + +// register vector index supporting sparse_float32 +#define KNOWHERE_SIMPLE_REGISTER_SPARSE_FLOAT_GLOBAL(name, index_node, features, ...) \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, fp32, (features | knowhere::feature::SPARSE_FLOAT32), \ + ##__VA_ARGS__); + +// register vector index supporting ALL_DENSE_TYPE(binary, bf16, fp16, fp32) data types +#define KNOWHERE_SIMPLE_REGISTER_DENSE_ALL_GLOBAL(name, index_node, features, ...) \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, bin1, (features | knowhere::feature::ALL_DENSE_TYPE), \ + ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, bf16, (features | knowhere::feature::ALL_DENSE_TYPE), \ + ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, fp16, (features | knowhere::feature::ALL_DENSE_TYPE), \ + ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, fp32, (features | knowhere::feature::ALL_DENSE_TYPE), \ + ##__VA_ARGS__); +// register vector index supporting binary data type +#define KNOWHERE_SIMPLE_REGISTER_DENSE_BIN_GLOBAL(name, index_node, features, ...) \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, bin1, (features | knowhere::feature::BINARY), ##__VA_ARGS__); + +// register vector index supporting ALL_DENSE_FLOAT_TYPE(float32, bf16, fp16) data types +#define KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(name, index_node, features, ...) \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, bf16, (features | knowhere::feature::ALL_DENSE_FLOAT_TYPE), \ + ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, fp16, (features | knowhere::feature::ALL_DENSE_FLOAT_TYPE), \ + ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, fp32, (features | knowhere::feature::ALL_DENSE_FLOAT_TYPE), \ + ##__VA_ARGS__); +// register vector index supporting ALL_DENSE_FLOAT_TYPE(float32, bf16, fp16) data types, but mocked bf16 and fp16 +#define KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(name, index_node, features, ...) \ + KNOWHERE_MOCK_REGISTER_GLOBAL(name, index_node, bf16, (features | knowhere::feature::ALL_DENSE_FLOAT_TYPE), \ + ##__VA_ARGS__); \ + KNOWHERE_MOCK_REGISTER_GLOBAL(name, index_node, fp16, (features | knowhere::feature::ALL_DENSE_FLOAT_TYPE), \ + ##__VA_ARGS__); \ + KNOWHERE_SIMPLE_REGISTER_GLOBAL(name, index_node, fp32, (features | knowhere::feature::ALL_DENSE_FLOAT_TYPE), \ + ##__VA_ARGS__); + +#define KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(name, index_node, data_type, features, thread_size) \ KNOWHERE_REGISTER_STATIC(name, index_node, data_type) \ KNOWHERE_REGISTER_GLOBAL( \ name, \ @@ -88,7 +153,7 @@ class IndexFactory { return (Index::Create( \ std::make_unique::type>>(version, object), thread_size)); \ }, \ - data_type) + data_type, typeCheck(features), features) #define KNOWHERE_SET_STATIC_GLOBAL_INDEX_TABLE(table_index, name, index_table) \ static int name = []() -> int { \ auto& static_index_table = std::get(IndexFactory::StaticIndexTableInstance()); \ diff --git a/include/knowhere/operands.h b/include/knowhere/operands.h index 6db211ef7..0db13a3df 100644 --- a/include/knowhere/operands.h +++ b/include/knowhere/operands.h @@ -19,6 +19,8 @@ #include #include +#include "feature.h" + namespace { union fp32_bits { uint32_t as_bits; @@ -143,6 +145,25 @@ struct bf16 { } }; +template +bool +typeCheck(uint64_t features) { + if constexpr (std::is_same_v) { + return features & knowhere::feature::BINARY; + } + if constexpr (std::is_same_v) { + return features & knowhere::feature::FP16; + } + if constexpr (std::is_same_v) { + return features & knowhere::feature::BF16; + } + // TODO : add sparse_fp32 data type + if constexpr (std::is_same_v) { + return (features & knowhere::feature::FLOAT32) || (features & knowhere::feature::SPARSE_FLOAT32); + } + return false; +} + template using TypeMatch = std::bool_constant<(... | std::is_same_v)>; template diff --git a/src/index/diskann/diskann.cc b/src/index/diskann/diskann.cc index 44d20495f..0987f0317 100644 --- a/src/index/diskann/diskann.cc +++ b/src/index/diskann/diskann.cc @@ -22,6 +22,7 @@ #include "knowhere/comp/thread_pool.h" #include "knowhere/dataset.h" #include "knowhere/expected.h" +#include "knowhere/feature.h" #include "knowhere/file_manager.h" #include "knowhere/index/index_factory.h" #include "knowhere/log.h" @@ -724,12 +725,8 @@ DiskANNIndexNode::GetCachedNodeNum(const float cache_dram_budget, cons } #ifdef KNOWHERE_WITH_CARDINAL -KNOWHERE_SIMPLE_REGISTER_GLOBAL(DISKANN_DEPRECATED, DiskANNIndexNode, fp32); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(DISKANN_DEPRECATED, DiskANNIndexNode, fp16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(DISKANN_DEPRECATED, DiskANNIndexNode, bf16); +KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(DISKANN_DEPRECATED, DiskANNIndexNode, knowhere::feature::DISK) #else -KNOWHERE_SIMPLE_REGISTER_GLOBAL(DISKANN, DiskANNIndexNode, fp32); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(DISKANN, DiskANNIndexNode, fp16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(DISKANN, DiskANNIndexNode, bf16); +KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(DISKANN, DiskANNIndexNode, knowhere::feature::DISK) #endif } // namespace knowhere diff --git a/src/index/flat/flat.cc b/src/index/flat/flat.cc index f1e3ecde6..837352f2f 100644 --- a/src/index/flat/flat.cc +++ b/src/index/flat/flat.cc @@ -18,6 +18,7 @@ #include "io/memory_io.h" #include "knowhere/bitsetview_idselector.h" #include "knowhere/comp/thread_pool.h" +#include "knowhere/feature.h" #include "knowhere/index/index_factory.h" #include "knowhere/index/index_node_data_mock_wrapper.h" #include "knowhere/log.h" @@ -394,9 +395,17 @@ class FlatIndexNode : public IndexNode { std::shared_ptr search_pool_; }; -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FLAT, FlatIndexNode, fp32, faiss::IndexFlat); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(BINFLAT, FlatIndexNode, bin1, faiss::IndexBinaryFlat); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(BIN_FLAT, FlatIndexNode, bin1, faiss::IndexBinaryFlat); -KNOWHERE_MOCK_REGISTER_GLOBAL(FLAT, FlatIndexNode, fp16, faiss::IndexFlat); -KNOWHERE_MOCK_REGISTER_GLOBAL(FLAT, FlatIndexNode, bf16, faiss::IndexFlat); +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(FLAT, FlatIndexNode, + knowhere::feature::NO_TRAIN | knowhere::feature::KNN | + knowhere::feature::MMAP, + faiss::IndexFlat); + +KNOWHERE_SIMPLE_REGISTER_DENSE_BIN_GLOBAL(BINFLAT, FlatIndexNode, + knowhere::feature::NO_TRAIN | knowhere::feature::KNN | + knowhere::feature::MMAP, + faiss::IndexBinaryFlat); +KNOWHERE_SIMPLE_REGISTER_DENSE_BIN_GLOBAL(BIN_FLAT, FlatIndexNode, + knowhere::feature::NO_TRAIN | knowhere::feature::KNN | + knowhere::feature::MMAP, + faiss::IndexBinaryFlat); } // namespace knowhere diff --git a/src/index/gpu/flat_gpu/flat_gpu.cc b/src/index/gpu/flat_gpu/flat_gpu.cc index 851d577e5..547474fa1 100644 --- a/src/index/gpu/flat_gpu/flat_gpu.cc +++ b/src/index/gpu/flat_gpu/flat_gpu.cc @@ -194,6 +194,5 @@ class GpuFlatIndexNode : public IndexNode { mutable ResWPtr res_; std::unique_ptr index_; }; - -KNOWHERE_SIMPLE_REGISTER_GLOBAL(GPU_FAISS_FLAT, GpuFlatIndexNode, fp32); +// GPU_FAISS_FLAT is deprecated } // namespace knowhere diff --git a/src/index/gpu/ivf_gpu/ivf_gpu.cc b/src/index/gpu/ivf_gpu/ivf_gpu.cc index f15ef82b8..8a062dbf8 100644 --- a/src/index/gpu/ivf_gpu/ivf_gpu.cc +++ b/src/index/gpu/ivf_gpu/ivf_gpu.cc @@ -277,8 +277,5 @@ class GpuIvfIndexNode : public IndexNode { mutable ResWPtr res_; std::unique_ptr index_; }; - -KNOWHERE_SIMPLE_REGISTER_GLOBAL(GPU_FAISS_IVF_FLAT, GpuIvfIndexNode, fp32, faiss::IndexIVFFlat); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(GPU_FAISS_IVF_PQ, GpuIvfIndexNode, fp32, faiss::IndexIVFPQ); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(GPU_FAISS_IVF_SQ8, GpuIvfIndexNode, fp32, faiss::IndexIVFScalarQuantizer); +// GPU_FAISS_IVF_FLAT/GPU_FAISS_IVF_PQ/GPU_FAISS_IVF_SQ8 is deprecated } // namespace knowhere diff --git a/src/index/gpu_raft/gpu_raft.h b/src/index/gpu_raft/gpu_raft.h index b8a3652af..04fe6f596 100644 --- a/src/index/gpu_raft/gpu_raft.h +++ b/src/index/gpu_raft/gpu_raft.h @@ -196,7 +196,7 @@ struct GpuRaftIndexNode : public IndexNode { } Status - DeserializeFromFile(const std::string& filename, std::shared_ptr) { + DeserializeFromFile(const std::string& filename, std::shared_ptr) override { return Status::not_implemented; } diff --git a/src/index/gpu_raft/gpu_raft_brute_force.cc b/src/index/gpu_raft/gpu_raft_brute_force.cc index 7e4200567..2626fe408 100644 --- a/src/index/gpu_raft/gpu_raft_brute_force.cc +++ b/src/index/gpu_raft/gpu_raft_brute_force.cc @@ -24,14 +24,16 @@ #include "raft/util/cuda_rt_essentials.hpp" namespace knowhere { -KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_RAFT_BRUTE_FORCE, GpuRaftBruteForceIndexNode, fp32, []() { - int count; - RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); - return count * cuda_concurrent_size_per_device; -}()); -KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_BRUTE_FORCE, GpuRaftBruteForceIndexNode, fp32, []() { - int count; - RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); - return count * cuda_concurrent_size_per_device; -}()); +KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_RAFT_BRUTE_FORCE, GpuRaftBruteForceIndexNode, fp32, + knowhere::feature::GPU_KNN_FLOAT_INDEX, []() { + int count; + RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); + return count * cuda_concurrent_size_per_device; + }()); +KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_BRUTE_FORCE, GpuRaftBruteForceIndexNode, fp32, + knowhere::feature::GPU_KNN_FLOAT_INDEX, []() { + int count; + RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); + return count * cuda_concurrent_size_per_device; + }()); } // namespace knowhere diff --git a/src/index/gpu_raft/gpu_raft_cagra.cc b/src/index/gpu_raft/gpu_raft_cagra.cc index 813cba8fe..aa93c9c6f 100644 --- a/src/index/gpu_raft/gpu_raft_cagra.cc +++ b/src/index/gpu_raft/gpu_raft_cagra.cc @@ -151,7 +151,7 @@ class GpuRaftCagraHybridIndexNode : public GpuRaftCagraIndexNode { } Status - DeserializeFromFile(const std::string& filename, std::shared_ptr) { + DeserializeFromFile(const std::string& filename, std::shared_ptr) override { return Status::not_implemented; } @@ -160,14 +160,16 @@ class GpuRaftCagraHybridIndexNode : public GpuRaftCagraIndexNode { std::unique_ptr> hnsw_index_ = nullptr; }; -KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_RAFT_CAGRA, GpuRaftCagraHybridIndexNode, fp32, []() { - int count; - RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); - return count * cuda_concurrent_size_per_device; -}()); -KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_CAGRA, GpuRaftCagraHybridIndexNode, fp32, []() { - int count; - RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); - return count * cuda_concurrent_size_per_device; -}()); +KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_RAFT_CAGRA, GpuRaftCagraHybridIndexNode, fp32, + knowhere::feature::GPU_ANN_FLOAT_INDEX, []() { + int count; + RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); + return count * cuda_concurrent_size_per_device; + }()); +KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_CAGRA, GpuRaftCagraHybridIndexNode, fp32, + knowhere::feature::GPU_ANN_FLOAT_INDEX, []() { + int count; + RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); + return count * cuda_concurrent_size_per_device; + }()); } // namespace knowhere diff --git a/src/index/gpu_raft/gpu_raft_ivf_flat.cc b/src/index/gpu_raft/gpu_raft_ivf_flat.cc index 7b63cdb23..24c69e4b2 100644 --- a/src/index/gpu_raft/gpu_raft_ivf_flat.cc +++ b/src/index/gpu_raft/gpu_raft_ivf_flat.cc @@ -23,14 +23,16 @@ #include "knowhere/index/index_node_thread_pool_wrapper.h" #include "raft/util/cuda_rt_essentials.hpp" namespace knowhere { -KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_RAFT_IVF_FLAT, GpuRaftIvfFlatIndexNode, fp32, []() { - int count; - RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); - return count * cuda_concurrent_size_per_device; -}()); -KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_IVF_FLAT, GpuRaftIvfFlatIndexNode, fp32, []() { - int count; - RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); - return count * cuda_concurrent_size_per_device; -}()); +KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_RAFT_IVF_FLAT, GpuRaftIvfFlatIndexNode, fp32, + knowhere::feature::GPU_ANN_FLOAT_INDEX, []() { + int count; + RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); + return count * cuda_concurrent_size_per_device; + }()); +KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_IVF_FLAT, GpuRaftIvfFlatIndexNode, fp32, + knowhere::feature::GPU_ANN_FLOAT_INDEX, []() { + int count; + RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); + return count * cuda_concurrent_size_per_device; + }()); } // namespace knowhere diff --git a/src/index/gpu_raft/gpu_raft_ivf_pq.cc b/src/index/gpu_raft/gpu_raft_ivf_pq.cc index fbed9337e..c1baf66b8 100644 --- a/src/index/gpu_raft/gpu_raft_ivf_pq.cc +++ b/src/index/gpu_raft/gpu_raft_ivf_pq.cc @@ -25,6 +25,7 @@ namespace knowhere { KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_RAFT_IVF_PQ, GpuRaftIvfPqIndexNode, fp32, + knowhere::feature::GPU_ANN_FLOAT_INDEX, []() { int count; RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); @@ -33,6 +34,7 @@ KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_RAFT_IVF_PQ, GpuRaftIvfPqIndexNode ); KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(GPU_IVF_PQ, GpuRaftIvfPqIndexNode, fp32, + knowhere::feature::GPU_ANN_FLOAT_INDEX, []() { int count; RAFT_CUDA_TRY(cudaGetDeviceCount(&count)); diff --git a/src/index/hnsw/faiss_hnsw.cc b/src/index/hnsw/faiss_hnsw.cc index 6175d082e..013c0875f 100644 --- a/src/index/hnsw/faiss_hnsw.cc +++ b/src/index/hnsw/faiss_hnsw.cc @@ -2057,20 +2057,13 @@ class BaseFaissRegularIndexHNSWPRQNodeTemplate : public BaseFaissRegularIndexHNS }; // -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_FLAT, BaseFaissRegularIndexHNSWFlatNodeTemplate, fp32); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_FLAT, BaseFaissRegularIndexHNSWFlatNodeTemplate, fp16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_FLAT, BaseFaissRegularIndexHNSWFlatNodeTemplate, bf16); - -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_SQ, BaseFaissRegularIndexHNSWSQNodeTemplate, fp32); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_SQ, BaseFaissRegularIndexHNSWSQNodeTemplate, fp16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_SQ, BaseFaissRegularIndexHNSWSQNodeTemplate, bf16); - -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_PQ, BaseFaissRegularIndexHNSWPQNodeTemplate, fp32); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_PQ, BaseFaissRegularIndexHNSWPQNodeTemplate, fp16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_PQ, BaseFaissRegularIndexHNSWPQNodeTemplate, bf16); - -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_PRQ, BaseFaissRegularIndexHNSWPRQNodeTemplate, fp32); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_PRQ, BaseFaissRegularIndexHNSWPRQNodeTemplate, fp16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(FAISS_HNSW_PRQ, BaseFaissRegularIndexHNSWPRQNodeTemplate, bf16); +KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(FAISS_HNSW_FLAT, BaseFaissRegularIndexHNSWFlatNodeTemplate, + knowhere::feature::MMAP) +KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(FAISS_HNSW_SQ, BaseFaissRegularIndexHNSWSQNodeTemplate, + knowhere::feature::MMAP) +KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(FAISS_HNSW_PQ, BaseFaissRegularIndexHNSWPQNodeTemplate, + knowhere::feature::MMAP) +KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(FAISS_HNSW_PRQ, BaseFaissRegularIndexHNSWPRQNodeTemplate, + knowhere::feature::MMAP) } // namespace knowhere diff --git a/src/index/hnsw/hnsw.cc b/src/index/hnsw/hnsw.cc index 8f4cd7c8a..9cf77e097 100644 --- a/src/index/hnsw/hnsw.cc +++ b/src/index/hnsw/hnsw.cc @@ -22,6 +22,7 @@ #include "knowhere/comp/time_recorder.h" #include "knowhere/config.h" #include "knowhere/expected.h" +#include "knowhere/feature.h" #include "knowhere/index/index_factory.h" #include "knowhere/index/index_node_data_mock_wrapper.h" #include "knowhere/log.h" @@ -595,21 +596,13 @@ class HnswIndexNode : public IndexNode { }; #ifdef KNOWHERE_WITH_CARDINAL -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_DEPRECATED, HnswIndexNode, fp32); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_DEPRECATED, HnswIndexNode, fp16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_DEPRECATED, HnswIndexNode, bf16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_DEPRECATED, HnswIndexNode, bin1); +KNOWHERE_SIMPLE_REGISTER_DENSE_ALL_GLOBAL(HNSW_DEPRECATED, HnswIndexNode, + knowhere::feature::MMAP | knowhere::feature::MV) #else -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW, HnswIndexNode, fp32); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW, HnswIndexNode, fp16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW, HnswIndexNode, bf16); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW, HnswIndexNode, bin1); +KNOWHERE_SIMPLE_REGISTER_DENSE_ALL_GLOBAL(HNSW, HnswIndexNode, knowhere::feature::MMAP | knowhere::feature::MV) #endif -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_SQ8, HnswIndexNode, fp32, QuantType::SQ8); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_SQ8_REFINE, HnswIndexNode, fp32, QuantType::SQ8Refine); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_SQ8, HnswIndexNode, fp16, QuantType::SQ8); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_SQ8_REFINE, HnswIndexNode, fp16, QuantType::SQ8Refine); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_SQ8, HnswIndexNode, bf16, QuantType::SQ8); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(HNSW_SQ8_REFINE, HnswIndexNode, bf16, QuantType::SQ8Refine); +KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(HNSW_SQ8, HnswIndexNode, knowhere::feature::MMAP, QuantType::SQ8) +KNOWHERE_SIMPLE_REGISTER_DENSE_FLOAT_ALL_GLOBAL(HNSW_SQ8_REFINE, HnswIndexNode, knowhere::feature::MMAP, + QuantType::SQ8Refine) } // namespace knowhere diff --git a/src/index/index_factory.cc b/src/index/index_factory.cc index e96bc747b..7e9f8086b 100644 --- a/src/index/index_factory.cc +++ b/src/index/index_factory.cc @@ -71,12 +71,21 @@ IndexFactory::Create(const std::string& name, const int32_t& version, const Obje template const IndexFactory& -IndexFactory::Register(const std::string& name, std::function(const int32_t&, const Object&)> func) { +IndexFactory::Register(const std::string& name, std::function(const int32_t&, const Object&)> func, + const uint64_t features) { static_assert(KnowhereDataTypeCheck::value == true); auto& func_mapping_ = MapInstance(); auto key = GetKey(name); assert(func_mapping_.find(key) == func_mapping_.end()); func_mapping_[key] = std::make_unique>>(func); + auto& feature_mapping_ = FeatureMapInstance(); + // Index feature use the raw name + if (feature_mapping_.find(name) == feature_mapping_.end()) { + feature_mapping_[name] = features; + } else { + // All data types should have the same features; please try to avoid breaking this rule. + feature_mapping_[name] = feature_mapping_[name] & features; + } return *this; } @@ -93,12 +102,31 @@ IndexFactory::MapInstance() { static FuncMap func_map; return func_map; } + +IndexFactory::FeatureMap& +IndexFactory::FeatureMapInstance() { + static FeatureMap featureMap; + return featureMap; +} + IndexFactory::GlobalIndexTable& IndexFactory::StaticIndexTableInstance() { static GlobalIndexTable static_index_table; return static_index_table; } +bool +IndexFactory::FeatureCheck(const std::string& name, uint64_t feature) const { + auto& feature_mapping_ = IndexFactory::FeatureMapInstance(); + assert(feature_mapping_.find(name) != feature_mapping_.end()); + return (feature_mapping_[name] & feature) == feature; +} + +const std::map& +IndexFactory::GetIndexFeatures() { + return FeatureMapInstance(); +} + } // namespace knowhere // template knowhere::expected> @@ -111,13 +139,17 @@ template knowhere::expected> knowhere::IndexFactory::Create(const std::string&, const int32_t&, const Object&); template const knowhere::IndexFactory& knowhere::IndexFactory::Register( - const std::string&, std::function(const int32_t&, const Object&)>); + const std::string&, std::function(const int32_t&, const Object&)>, + const uint64_t); template const knowhere::IndexFactory& knowhere::IndexFactory::Register( - const std::string&, std::function(const int32_t&, const Object&)>); + const std::string&, std::function(const int32_t&, const Object&)>, + const uint64_t); template const knowhere::IndexFactory& knowhere::IndexFactory::Register( - const std::string&, std::function(const int32_t&, const Object&)>); + const std::string&, std::function(const int32_t&, const Object&)>, + const uint64_t); template const knowhere::IndexFactory& knowhere::IndexFactory::Register( - const std::string&, std::function(const int32_t&, const Object&)>); + const std::string&, std::function(const int32_t&, const Object&)>, + const uint64_t); diff --git a/src/index/ivf/ivf.cc b/src/index/ivf/ivf.cc index 132511d6c..8298e711e 100644 --- a/src/index/ivf/ivf.cc +++ b/src/index/ivf/ivf.cc @@ -27,6 +27,7 @@ #include "knowhere/comp/thread_pool.h" #include "knowhere/dataset.h" #include "knowhere/expected.h" +#include "knowhere/feature.h" #include "knowhere/feder/IVFFlat.h" #include "knowhere/index/index_factory.h" #include "knowhere/index/index_node_data_mock_wrapper.h" @@ -1202,39 +1203,24 @@ IvfIndexNode::DeserializeFromFile(const std::string& filena return Status::success; } // bin1 -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVFBIN, IvfIndexNode, bin1, faiss::IndexBinaryIVF); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(BIN_IVF_FLAT, IvfIndexNode, bin1, faiss::IndexBinaryIVF); -// fp32 -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVFFLAT, IvfIndexNode, fp32, faiss::IndexIVFFlat); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVF_FLAT, IvfIndexNode, fp32, faiss::IndexIVFFlat); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVFFLATCC, IvfIndexNode, fp32, faiss::IndexIVFFlatCC); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVF_FLAT_CC, IvfIndexNode, fp32, faiss::IndexIVFFlatCC); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(SCANN, IvfIndexNode, fp32, faiss::IndexScaNN); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVFPQ, IvfIndexNode, fp32, faiss::IndexIVFPQ); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVF_PQ, IvfIndexNode, fp32, faiss::IndexIVFPQ); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVFSQ, IvfIndexNode, fp32, faiss::IndexIVFScalarQuantizer); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVF_SQ8, IvfIndexNode, fp32, faiss::IndexIVFScalarQuantizer); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(IVF_SQ_CC, IvfIndexNode, fp32, faiss::IndexIVFScalarQuantizerCC); -// fp16 -KNOWHERE_MOCK_REGISTER_GLOBAL(IVFFLAT, IvfIndexNode, fp16, faiss::IndexIVFFlat); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_FLAT, IvfIndexNode, fp16, faiss::IndexIVFFlat); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVFFLATCC, IvfIndexNode, fp16, faiss::IndexIVFFlatCC); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_FLAT_CC, IvfIndexNode, fp16, faiss::IndexIVFFlatCC); -KNOWHERE_MOCK_REGISTER_GLOBAL(SCANN, IvfIndexNode, fp16, faiss::IndexScaNN); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVFPQ, IvfIndexNode, fp16, faiss::IndexIVFPQ); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_PQ, IvfIndexNode, fp16, faiss::IndexIVFPQ); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVFSQ, IvfIndexNode, fp16, faiss::IndexIVFScalarQuantizer); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_SQ8, IvfIndexNode, fp16, faiss::IndexIVFScalarQuantizer); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_SQ_CC, IvfIndexNode, fp16, faiss::IndexIVFScalarQuantizerCC); -// bf16 -KNOWHERE_MOCK_REGISTER_GLOBAL(IVFFLAT, IvfIndexNode, bf16, faiss::IndexIVFFlat); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_FLAT, IvfIndexNode, bf16, faiss::IndexIVFFlat); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVFFLATCC, IvfIndexNode, bf16, faiss::IndexIVFFlatCC); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_FLAT_CC, IvfIndexNode, bf16, faiss::IndexIVFFlatCC); -KNOWHERE_MOCK_REGISTER_GLOBAL(SCANN, IvfIndexNode, bf16, faiss::IndexScaNN); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVFPQ, IvfIndexNode, bf16, faiss::IndexIVFPQ); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_PQ, IvfIndexNode, bf16, faiss::IndexIVFPQ); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVFSQ, IvfIndexNode, bf16, faiss::IndexIVFScalarQuantizer); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_SQ8, IvfIndexNode, bf16, faiss::IndexIVFScalarQuantizer); -KNOWHERE_MOCK_REGISTER_GLOBAL(IVF_SQ_CC, IvfIndexNode, bf16, faiss::IndexIVFScalarQuantizerCC); +KNOWHERE_SIMPLE_REGISTER_DENSE_BIN_GLOBAL(IVFBIN, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexBinaryIVF) +KNOWHERE_SIMPLE_REGISTER_DENSE_BIN_GLOBAL(BIN_IVF_FLAT, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexBinaryIVF) + +// float +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVFFLAT, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexIVFFlat) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVF_FLAT, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexIVFFlat) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVFFLATCC, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexIVFFlatCC) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVF_FLAT_CC, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexIVFFlatCC) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(SCANN, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexScaNN) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVFPQ, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexIVFPQ) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVF_PQ, IvfIndexNode, knowhere::feature::MMAP, faiss::IndexIVFPQ) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVFSQ, IvfIndexNode, knowhere::feature::MMAP, + faiss::IndexIVFScalarQuantizer) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVF_SQ, IvfIndexNode, knowhere::feature::MMAP, + faiss::IndexIVFScalarQuantizer) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVF_SQ8, IvfIndexNode, knowhere::feature::MMAP, + faiss::IndexIVFScalarQuantizer) +KNOWHERE_MOCK_REGISTER_DENSE_FLOAT_ALL_GLOBAL(IVF_SQ_CC, IvfIndexNode, knowhere::feature::MMAP, + faiss::IndexIVFScalarQuantizerCC) + } // namespace knowhere diff --git a/src/index/sparse/sparse_index_node.cc b/src/index/sparse/sparse_index_node.cc index 4ebd7cef8..28324c504 100644 --- a/src/index/sparse/sparse_index_node.cc +++ b/src/index/sparse/sparse_index_node.cc @@ -19,6 +19,7 @@ #include "knowhere/config.h" #include "knowhere/dataset.h" #include "knowhere/expected.h" +#include "knowhere/feature.h" #include "knowhere/index/index_factory.h" #include "knowhere/index/index_node.h" #include "knowhere/log.h" @@ -320,7 +321,8 @@ class SparseInvertedIndexNode : public IndexNode { size_t map_size_ = 0; }; // class SparseInvertedIndexNode -KNOWHERE_SIMPLE_REGISTER_GLOBAL(SPARSE_INVERTED_INDEX, SparseInvertedIndexNode, fp32, /*use_wand=*/false); -KNOWHERE_SIMPLE_REGISTER_GLOBAL(SPARSE_WAND, SparseInvertedIndexNode, fp32, /*use_wand=*/true); - +KNOWHERE_SIMPLE_REGISTER_SPARSE_FLOAT_GLOBAL(SPARSE_INVERTED_INDEX, SparseInvertedIndexNode, knowhere::feature::MMAP, + /*use_wand=*/false) +KNOWHERE_SIMPLE_REGISTER_SPARSE_FLOAT_GLOBAL(SPARSE_WAND, SparseInvertedIndexNode, knowhere::feature::MMAP, + /*use_wand=*/true) } // namespace knowhere diff --git a/tests/ut/test_index_check.cc b/tests/ut/test_index_check.cc index 319700c77..c821b63c3 100644 --- a/tests/ut/test_index_check.cc +++ b/tests/ut/test_index_check.cc @@ -203,10 +203,10 @@ TEST_CASE("Test index has raw data", "[IndexHasRawData]") { // gpu index #ifdef KNOWHERE_WITH_RAFT - CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_GPU_BRUTEFORCE, ver, {})); - CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_GPU_IVFFLAT, ver, {})); - CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_GPU_IVFPQ, ver, {})); - CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_GPU_CAGRA, ver, {})); + CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_RAFT_BRUTEFORCE, ver, {})); + CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_RAFT_IVFFLAT, ver, {})); + CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_RAFT_IVFPQ, ver, {})); + CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_RAFT_CAGRA, ver, {})); #endif // sparse index CHECK(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_SPARSE_INVERTED_INDEX, ver, {})); @@ -255,3 +255,235 @@ TEST_CASE("Test index has raw data", "[IndexHasRawData]") { CHECK_FALSE(knowhere::IndexStaticFaced::HasRawData(IndexEnum::INDEX_FAISS_HNSW_SQ, ver, faiss_hnsw_cfg)); } } + +TEST_CASE("Test index feature check", "[IndexFeatureCheck]") { + SECTION("Check MMap") { + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::MMAP)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::MMAP)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::MMAP)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFSQ8, knowhere::feature::MMAP)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::MMAP)); + + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IDMAP, knowhere::feature::MMAP)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IVFFLAT, knowhere::feature::MMAP)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_SCANN, knowhere::feature::MMAP)); + +#ifdef KNOWHERE_WITH_RAFT + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::MMAP)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::MMAP)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::MMAP)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::MMAP)); +#endif + +#ifdef KNOWHERE_WITH_DISKANN + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::MMAP)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::DISK)); +#endif + + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::DISK)); + } + + SECTION("Check GPU") { +#ifdef KNOWHERE_WITH_RAFT + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::GPU)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::GPU)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::GPU)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::GPU)); +#endif + + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::GPU)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::GPU)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::GPU)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::GPU)); + +#ifdef KNOWHERE_WITH_DISKANN + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::GPU)); +#endif + } + + SECTION("Check DataType") { + // FAISS Flat Indexes + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::FLOAT32)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::FP16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::SPARSE_FLOAT32)); + + // FAISS IVF Indexes + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::FLOAT32)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::FP16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::SPARSE_FLOAT32)); + + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::FLOAT32)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::FP16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::SPARSE_FLOAT32)); + + // FAISS Binary Indexes + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IDMAP, knowhere::feature::FLOAT32)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IDMAP, knowhere::feature::FP16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IDMAP, knowhere::feature::BF16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IDMAP, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IDMAP, knowhere::feature::SPARSE_FLOAT32)); + + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IVFFLAT, knowhere::feature::FLOAT32)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IVFFLAT, knowhere::feature::FP16)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IVFFLAT, knowhere::feature::BF16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IVFFLAT, knowhere::feature::BINARY)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IVFFLAT, + knowhere::feature::SPARSE_FLOAT32)); + + // HNSW Index + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::FLOAT32)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::FP16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::BF16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::BINARY)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::SPARSE_FLOAT32)); + + // Sparse Indexes + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_INVERTED_INDEX, knowhere::feature::FLOAT32)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_INVERTED_INDEX, knowhere::feature::FP16)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_INVERTED_INDEX, knowhere::feature::BF16)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_INVERTED_INDEX, knowhere::feature::BINARY)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_INVERTED_INDEX, + knowhere::feature::SPARSE_FLOAT32)); + + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_WAND, knowhere::feature::FLOAT32)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_WAND, knowhere::feature::FP16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_WAND, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_WAND, knowhere::feature::BINARY)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_WAND, knowhere::feature::SPARSE_FLOAT32)); + + // GPU Indexes +#ifdef KNOWHERE_WITH_RAFT + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::FLOAT32)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::FP16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::BF16)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::SPARSE_FLOAT32)); + + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::FLOAT32)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::FP16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::SPARSE_FLOAT32)); + + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::FLOAT32)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::FP16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::SPARSE_FLOAT32)); + + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::FLOAT32)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::FP16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::SPARSE_FLOAT32)); +#endif + + // DiskANN Index +#ifdef KNOWHERE_WITH_DISKANN + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::FLOAT32)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::FP16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::SPARSE_FLOAT32)); + +#endif + + // SCANN Index + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_SCANN, knowhere::feature::FLOAT32)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_SCANN, knowhere::feature::FP16)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_SCANN, knowhere::feature::BF16)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_SCANN, knowhere::feature::BINARY)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_SCANN, knowhere::feature::SPARSE_FLOAT32)); + } + + SECTION("Check NoTrain") { + // Flat indexes typically don't require training + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::NO_TRAIN)); + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IDMAP, knowhere::feature::NO_TRAIN)); + + // Indexes that typically require training + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::NO_TRAIN)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::NO_TRAIN)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IVFFLAT, knowhere::feature::NO_TRAIN)); + + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::NO_TRAIN)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_SCANN, knowhere::feature::NO_TRAIN)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_INVERTED_INDEX, knowhere::feature::NO_TRAIN)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_WAND, knowhere::feature::NO_TRAIN)); + +#ifdef KNOWHERE_WITH_RAFT + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::NO_TRAIN)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::NO_TRAIN)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::NO_TRAIN)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::NO_TRAIN)); +#endif + +#ifdef KNOWHERE_WITH_DISKANN + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::NO_TRAIN)); +#endif + } + + SECTION("Check MV") { + // Only HNSW supports Materialized View + REQUIRE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW, knowhere::feature::MV)); + + // All other indexes do not support MV + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IDMAP, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFFLAT, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFPQ, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_IVFSQ8, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_SCANN, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IDMAP, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_BIN_IVFFLAT, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW_SQ8, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_HNSW_SQ8_REFINE, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_HNSW_FLAT, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_HNSW_SQ, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_HNSW_PQ, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_FAISS_HNSW_PRQ, knowhere::feature::MV)); + REQUIRE_FALSE( + IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_INVERTED_INDEX, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_SPARSE_WAND, knowhere::feature::MV)); + +#ifdef KNOWHERE_WITH_RAFT + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_BRUTEFORCE, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFFLAT, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_IVFPQ, knowhere::feature::MV)); + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_RAFT_CAGRA, knowhere::feature::MV)); +#endif + +#ifdef KNOWHERE_WITH_DISKANN + REQUIRE_FALSE(IndexFactory::Instance().FeatureCheck(IndexEnum::INDEX_DISKANN, knowhere::feature::MV)); +#endif + } +} diff --git a/tests/ut/test_index_node.cc b/tests/ut/test_index_node.cc index 66d3379d8..553d71543 100644 --- a/tests/ut/test_index_node.cc +++ b/tests/ut/test_index_node.cc @@ -57,7 +57,7 @@ class BaseFlatIndexNode : public IndexNode { } expected> - AnnIterator(const DataSetPtr dataset, std::unique_ptr cfg, const BitsetView& bitset) const { + AnnIterator(const DataSetPtr dataset, std::unique_ptr cfg, const BitsetView& bitset) const override { LOG_KNOWHERE_INFO_ << "BaseFlatIndexNode::AnnIterator()"; return expected>::Err(Status::not_implemented, "BaseFlatIndexNode::AnnIterator() not implemented"); @@ -139,7 +139,7 @@ TEST_CASE("Test index node") { BinarySet binset; SECTION("Test IndexNode") { - KNOWHERE_SIMPLE_REGISTER_GLOBAL(BASE_FLAT, BaseFlatIndexNode, fp32); + KNOWHERE_SIMPLE_REGISTER_GLOBAL(BASE_FLAT, BaseFlatIndexNode, fp32, knowhere::feature::FLOAT32); auto index = IndexFactory::Instance().Create("BASE_FLAT", version).value(); REQUIRE(index.Build(ds, {}) == Status::success); REQUIRE(index.Train(ds, {}) == Status::success); @@ -160,7 +160,7 @@ TEST_CASE("Test index node") { } SECTION("Test IndexNodeDataMockWrapper") { - KNOWHERE_MOCK_REGISTER_GLOBAL(BASE_FLAT_MOCK, BaseFlatIndexNode, fp16); + KNOWHERE_MOCK_REGISTER_GLOBAL(BASE_FLAT_MOCK, BaseFlatIndexNode, fp16, knowhere::feature::FP16); auto index = IndexFactory::Instance().Create("BASE_FLAT_MOCK", version).value(); REQUIRE(index.Build(ds, {}) == Status::success); REQUIRE(index.Train(ds, {}) == Status::success); @@ -181,7 +181,8 @@ TEST_CASE("Test index node") { } SECTION("Test IndexNodeThreadPoolWrapper") { - KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(BASE_FLAT_THREAD, BaseFlatIndexNode, fp32, 4); + KNOWHERE_REGISTER_GLOBAL_WITH_THREAD_POOL(BASE_FLAT_THREAD, BaseFlatIndexNode, fp32, knowhere::feature::FLOAT32, + 4); auto index = IndexFactory::Instance().Create("BASE_FLAT_THREAD", version).value(); REQUIRE(index.Build(ds, {}) == Status::success); REQUIRE(index.Train(ds, {}) == Status::success);