12 #include "IndexProxy.h"
13 #include "../FaissAssert.h"
15 #include "../Clustering.h"
16 #include "GpuIndexFlat.h"
17 #include "StandardGpuResources.h"
20 namespace faiss {
namespace gpu {
22 IndexProxy::IndexProxy():own_fields(false) {
25 IndexProxy::~IndexProxy() {
27 for (
auto& index : indices_)
35 if (!indices_.empty()) {
36 auto& existing = indices_.front().first;
38 if (index->
d != existing->d) {
43 if (index->
ntotal != existing->ntotal) {
62 indices_.emplace_back(
69 for (
auto it = indices_.begin(); it != indices_.end(); ++it) {
70 if (it->first == index) {
74 it->second->waitForThreadExit();
87 std::vector<std::future<bool>> v;
89 for (
auto& index : indices_) {
90 auto indexPtr = index.first;
91 v.emplace_back(index.second->add([indexPtr, f](){ f(indexPtr); }));
95 for (
auto& func : v) {
101 IndexProxy::reset() {
119 FAISS_ASSERT (count() > 0);
120 indices_[0].first->reconstruct (n, x);
130 FAISS_ASSERT(!indices_.empty());
131 if (indices_.empty()) {
135 auto dim = indices_.front().first->d;
137 std::vector<std::future<bool>> v;
140 auto queriesPerIndex =
142 FAISS_ASSERT(n / queriesPerIndex <= indices_.size());
144 for (
int i = 0; i < indices_.size(); ++i) {
145 auto base = i * queriesPerIndex;
150 auto numForIndex = std::min(queriesPerIndex, n - base);
151 auto queryStart = x + base * dim;
152 auto distancesStart = distances + base * k;
153 auto labelsStart = labels + base * k;
155 auto indexPtr = indices_[i].first;
157 [indexPtr, numForIndex, queryStart, k, distancesStart, labelsStart]() {
158 indexPtr->search(numForIndex, queryStart,
159 k, distancesStart, labelsStart);
162 v.emplace_back(indices_[i].second->add(std::move(fn)));
172 IndexProxy::set_typename() {
183 float kmeans_clustering_gpu (
int ngpu,
size_t d,
size_t n,
size_t k,
187 bool storeTransposed)
191 clus.verbose = d * n * k > (1L << 34);
192 FAISS_ASSERT(ngpu >= 1);
194 std::vector<std::unique_ptr<StandardGpuResources> > res;
195 std::vector<std::unique_ptr<GpuIndexFlatL2> > sub_indices;
196 for(
int dev_no = 0; dev_no < ngpu; dev_no++) {
197 res.emplace_back(
new StandardGpuResources());
200 GpuIndexFlatConfig config;
201 config.device = dev_no;
202 config.useFloat16 = useFloat16;
203 config.storeTransposed = storeTransposed;
205 sub_indices.emplace_back(
206 new GpuIndexFlatL2(res.back().get(), d, config));
212 index = sub_indices[0].get();
214 for(
int dev_no = 0; dev_no < ngpu; dev_no++) {
215 proxy.addIndex(sub_indices[dev_no].
get());
219 clus.
train (n, x, *index);
221 memcpy(centroids, clus.centroids.data(),
sizeof(*centroids) * d * k);
222 return clus.obj.back();
virtual void train(idx_t n, const float *x) override
void removeIndex(faiss::Index *index)
void runOnIndex(std::function< void(faiss::Index *)> f)
virtual void reset()=0
removes all elements from the database.
virtual void add(idx_t n, const float *x)=0
long idx_t
all indices are this type
idx_t ntotal
total nb of indexed vectors
bool verbose
verbosity level
void addIndex(faiss::Index *index)
MetricType metric_type
type of metric this index uses for search
bool is_trained
set if the Index does not require training, or if training is done already
virtual void train(idx_t n, const float *x)