ExecutionEngineImpl.cpp 36.1 KB
Newer Older
1
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
J
jinhai 已提交
2
//
3 4
// 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
J
jinhai 已提交
5
//
6 7 8 9 10
// 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.
J
jinhai 已提交
11

S
starlord 已提交
12
#include "db/engine/ExecutionEngineImpl.h"
T
Tinkerrr 已提交
13

14
#include <faiss/utils/ConcurrentBitset.h>
S
shengjh 已提交
15
#include <fiu-local.h>
16

T
Tinkerrr 已提交
17 18 19 20
#include <stdexcept>
#include <utility>
#include <vector>

S
starlord 已提交
21
#include "cache/CpuCacheMgr.h"
S
starlord 已提交
22
#include "cache/GpuCacheMgr.h"
23
#include "config/Config.h"
24
#include "db/Utils.h"
C
Cai Yudong 已提交
25
#include "index/archive/VecIndex.h"
X
xiaojun.lin 已提交
26
#include "knowhere/common/Config.h"
C
Cai Yudong 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39 40
#include "knowhere/index/vector_index/ConfAdapter.h"
#include "knowhere/index/vector_index/ConfAdapterMgr.h"
#include "knowhere/index/vector_index/IndexBinaryIDMAP.h"
#include "knowhere/index/vector_index/IndexIDMAP.h"
#include "knowhere/index/vector_index/VecIndex.h"
#include "knowhere/index/vector_index/VecIndexFactory.h"
#include "knowhere/index/vector_index/adapter/VectorAdapter.h"
#ifdef MILVUS_GPU_VERSION
#include "knowhere/index/vector_index/gpu/GPUIndex.h"
#include "knowhere/index/vector_index/gpu/IndexIVFSQHybrid.h"
#include "knowhere/index/vector_index/gpu/Quantizer.h"
#include "knowhere/index/vector_index/helpers/Cloner.h"
#endif
#include "knowhere/index/vector_index/helpers/IndexParameter.h"
S
starlord 已提交
41
#include "metrics/Metrics.h"
X
xiaojun.lin 已提交
42
#include "scheduler/Utils.h"
J
jinhai 已提交
43
#include "utils/CommonUtil.h"
S
starlord 已提交
44
#include "utils/Exception.h"
S
starlord 已提交
45
#include "utils/Log.h"
C
Cai Yudong 已提交
46
#include "utils/Status.h"
47
#include "utils/TimeRecorder.h"
G
groot 已提交
48
#include "utils/ValidationUtil.h"
X
xj.lin 已提交
49

S
starlord 已提交
50 51 52
namespace milvus {
namespace engine {

G
groot 已提交
53 54 55
namespace {

Status
56
MappingMetricType(MetricType metric_type, milvus::json& conf) {
G
groot 已提交
57 58
    switch (metric_type) {
        case MetricType::IP:
59
            conf[knowhere::Metric::TYPE] = knowhere::Metric::IP;
G
groot 已提交
60 61
            break;
        case MetricType::L2:
62
            conf[knowhere::Metric::TYPE] = knowhere::Metric::L2;
G
groot 已提交
63 64
            break;
        case MetricType::HAMMING:
65
            conf[knowhere::Metric::TYPE] = knowhere::Metric::HAMMING;
G
groot 已提交
66 67
            break;
        case MetricType::JACCARD:
68
            conf[knowhere::Metric::TYPE] = knowhere::Metric::JACCARD;
G
groot 已提交
69 70
            break;
        case MetricType::TANIMOTO:
71
            conf[knowhere::Metric::TYPE] = knowhere::Metric::TANIMOTO;
G
groot 已提交
72
            break;
73 74 75 76 77 78
        case MetricType::SUBSTRUCTURE:
            conf[knowhere::Metric::TYPE] = knowhere::Metric::SUBSTRUCTURE;
            break;
        case MetricType::SUPERSTRUCTURE:
            conf[knowhere::Metric::TYPE] = knowhere::Metric::SUPERSTRUCTURE;
            break;
G
groot 已提交
79 80 81 82 83 84 85 86
        default:
            return Status(DB_ERROR, "Unsupported metric type");
    }

    return Status::OK();
}

bool
C
Cai Yudong 已提交
87 88
IsBinaryIndexType(knowhere::IndexType type) {
    return type == knowhere::IndexEnum::INDEX_FAISS_BIN_IDMAP || type == knowhere::IndexEnum::INDEX_FAISS_BIN_IVFFLAT;
G
groot 已提交
89 90 91 92
}

}  // namespace

C
Cai Yudong 已提交
93
#ifdef MILVUS_GPU_VERSION
W
wxyu 已提交
94 95
class CachedQuantizer : public cache::DataObj {
 public:
W
wxyu 已提交
96 97
    explicit CachedQuantizer(knowhere::QuantizerPtr data) : data_(std::move(data)) {
    }
W
wxyu 已提交
98 99 100 101 102 103 104 105 106 107 108 109 110 111

    knowhere::QuantizerPtr
    Data() {
        return data_;
    }

    int64_t
    Size() override {
        return data_->size;
    }

 private:
    knowhere::QuantizerPtr data_;
};
C
Cai Yudong 已提交
112
#endif
W
wxyu 已提交
113

S
starlord 已提交
114
ExecutionEngineImpl::ExecutionEngineImpl(uint16_t dimension, const std::string& location, EngineType index_type,
115 116 117 118 119 120
                                         MetricType metric_type, const milvus::json& index_params)
    : location_(location),
      dim_(dimension),
      index_type_(index_type),
      metric_type_(metric_type),
      index_params_(index_params) {
121 122
    EngineType tmp_index_type =
        utils::IsBinaryMetricType((int32_t)metric_type) ? EngineType::FAISS_BIN_IDMAP : EngineType::FAISS_IDMAP;
G
groot 已提交
123
    index_ = CreatetVecIndex(tmp_index_type);
124
    if (!index_) {
125
        throw Exception(DB_ERROR, "Unsupported index type");
126
    }
X
xj.lin 已提交
127

128 129 130 131 132
    milvus::json conf = index_params;
    conf[knowhere::meta::DEVICEID] = gpu_num_;
    conf[knowhere::meta::DIM] = dimension;
    MappingMetricType(metric_type, conf);
    ENGINE_LOG_DEBUG << "Index params: " << conf.dump();
C
Cai Yudong 已提交
133 134
    auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(index_->index_type());
    if (!adapter->CheckTrain(conf, index_->index_mode())) {
135 136
        throw Exception(DB_ERROR, "Illegal index params");
    }
X
xiaojun.lin 已提交
137

C
Cai Yudong 已提交
138 139 140 141 142
    fiu_do_on("ExecutionEngineImpl.throw_exception", throw Exception(DB_ERROR, ""));
    if (auto bf_index = std::dynamic_pointer_cast<knowhere::IDMAP>(index_)) {
        bf_index->Train(knowhere::DatasetPtr(), conf);
    } else if (auto bf_bin_index = std::dynamic_pointer_cast<knowhere::BinaryIDMAP>(index_)) {
        bf_bin_index->Train(knowhere::DatasetPtr(), conf);
143
    }
S
starlord 已提交
144 145
}

C
Cai Yudong 已提交
146 147 148
ExecutionEngineImpl::ExecutionEngineImpl(knowhere::VecIndexPtr index, const std::string& location,
                                         EngineType index_type, MetricType metric_type,
                                         const milvus::json& index_params)
149 150 151 152 153
    : index_(std::move(index)),
      location_(location),
      index_type_(index_type),
      metric_type_(metric_type),
      index_params_(index_params) {
X
xj.lin 已提交
154
}
S
starlord 已提交
155

C
Cai Yudong 已提交
156
knowhere::VecIndexPtr
S
starlord 已提交
157
ExecutionEngineImpl::CreatetVecIndex(EngineType type) {
C
Cai Yudong 已提交
158 159
    knowhere::VecIndexFactory& vec_index_factory = knowhere::VecIndexFactory::GetInstance();
    knowhere::IndexMode mode = knowhere::IndexMode::MODE_CPU;
Y
yudong.cai 已提交
160
#ifdef MILVUS_GPU_VERSION
161 162 163
    server::Config& config = server::Config::GetInstance();
    bool gpu_resource_enable = true;
    config.GetGpuResourceConfigEnable(gpu_resource_enable);
S
shengjh 已提交
164
    fiu_do_on("ExecutionEngineImpl.CreatetVecIndex.gpu_res_disabled", gpu_resource_enable = false);
C
Cai Yudong 已提交
165 166 167
    if (gpu_resource_enable) {
        mode = knowhere::IndexMode::MODE_GPU;
    }
Y
yudong.cai 已提交
168
#endif
S
shengjh 已提交
169

C
Cai Yudong 已提交
170 171
    fiu_do_on("ExecutionEngineImpl.CreateVecIndex.invalid_type", type = EngineType::INVALID);
    knowhere::VecIndexPtr index = nullptr;
X
xj.lin 已提交
172 173
    switch (type) {
        case EngineType::FAISS_IDMAP: {
C
Cai Yudong 已提交
174
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_IDMAP, mode);
S
starlord 已提交
175 176
            break;
        }
J
jinhai 已提交
177
        case EngineType::FAISS_IVFFLAT: {
C
Cai Yudong 已提交
178
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_IVFFLAT, mode);
S
starlord 已提交
179 180
            break;
        }
C
Cai Yudong 已提交
181 182
        case EngineType::FAISS_PQ: {
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_IVFPQ, mode);
S
starlord 已提交
183 184
            break;
        }
C
Cai Yudong 已提交
185 186
        case EngineType::FAISS_IVFSQ8: {
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_IVFSQ8, mode);
X
xj.lin 已提交
187 188
            break;
        }
189
#ifdef MILVUS_GPU_VERSION
W
wxyu 已提交
190
        case EngineType::FAISS_IVFSQ8H: {
C
Cai Yudong 已提交
191
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_IVFSQ8H, mode);
W
wxyu 已提交
192 193
            break;
        }
Y
Yukikaze-CZR 已提交
194
#endif
C
Cai Yudong 已提交
195 196
        case EngineType::FAISS_BIN_IDMAP: {
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_BIN_IDMAP, mode);
Z
zirui.chen 已提交
197 198
            break;
        }
C
Cai Yudong 已提交
199 200
        case EngineType::FAISS_BIN_IVFFLAT: {
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_BIN_IVFFLAT, mode);
201 202
            break;
        }
C
Cai Yudong 已提交
203 204
        case EngineType::NSG_MIX: {
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_NSG, mode);
205 206
            break;
        }
C
Cai Yudong 已提交
207 208
        case EngineType::SPTAG_KDT: {
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_SPTAG_KDT_RNT, mode);
T
Tinkerrr 已提交
209 210
            break;
        }
C
Cai Yudong 已提交
211 212
        case EngineType::SPTAG_BKT: {
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_SPTAG_BKT_RNT, mode);
G
groot 已提交
213 214
            break;
        }
C
Cai Yudong 已提交
215 216
        case EngineType::HNSW: {
            index = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_HNSW, mode);
G
groot 已提交
217 218
            break;
        }
X
xj.lin 已提交
219
        default: {
C
Cai Yudong 已提交
220
            ENGINE_LOG_ERROR << "Unsupported index type " << (int)type;
S
starlord 已提交
221 222 223
            return nullptr;
        }
    }
C
Cai Yudong 已提交
224 225 226 227 228
    if (index == nullptr) {
        std::string err_msg = "Invalid index type " + std::to_string((int)type) + " mod " + std::to_string((int)mode);
        ENGINE_LOG_ERROR << err_msg;
        throw Exception(DB_ERROR, err_msg);
    }
X
xj.lin 已提交
229
    return index;
S
starlord 已提交
230 231
}

232
void
W
wxyu 已提交
233
ExecutionEngineImpl::HybridLoad() const {
C
Cai Yudong 已提交
234 235 236 237
#ifdef MILVUS_GPU_VERSION
    auto hybrid_index = std::dynamic_pointer_cast<knowhere::IVFSQHybrid>(index_);
    if (hybrid_index == nullptr) {
        ENGINE_LOG_WARNING << "HybridLoad only support with IVFSQHybrid";
W
update  
wxyu 已提交
238 239 240
        return;
    }

W
wxyu 已提交
241
    const std::string key = location_ + ".quantizer";
242 243

    server::Config& config = server::Config::GetInstance();
Y
yudong.cai 已提交
244
    std::vector<int64_t> gpus;
245 246 247 248 249
    Status s = config.GetGpuResourceConfigSearchResources(gpus);
    if (!s.ok()) {
        ENGINE_LOG_ERROR << s.message();
        return;
    }
W
wxyu 已提交
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265

    // cache hit
    {
        const int64_t NOT_FOUND = -1;
        int64_t device_id = NOT_FOUND;
        knowhere::QuantizerPtr quantizer = nullptr;

        for (auto& gpu : gpus) {
            auto cache = cache::GpuCacheMgr::GetInstance(gpu);
            if (auto cached_quantizer = cache->GetIndex(key)) {
                device_id = gpu;
                quantizer = std::static_pointer_cast<CachedQuantizer>(cached_quantizer)->Data();
            }
        }

        if (device_id != NOT_FOUND) {
C
Cai Yudong 已提交
266
            hybrid_index->SetQuantizer(quantizer);
W
wxyu 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
            return;
        }
    }

    // cache miss
    {
        std::vector<int64_t> all_free_mem;
        for (auto& gpu : gpus) {
            auto cache = cache::GpuCacheMgr::GetInstance(gpu);
            auto free_mem = cache->CacheCapacity() - cache->CacheUsage();
            all_free_mem.push_back(free_mem);
        }

        auto max_e = std::max_element(all_free_mem.begin(), all_free_mem.end());
        auto best_index = std::distance(all_free_mem.begin(), max_e);
        auto best_device_id = gpus[best_index];

284
        milvus::json quantizer_conf{{knowhere::meta::DEVICEID, best_device_id}, {"mode", 1}};
C
Cai Yudong 已提交
285
        auto quantizer = hybrid_index->LoadQuantizer(quantizer_conf);
286
        ENGINE_LOG_DEBUG << "Quantizer params: " << quantizer_conf.dump();
W
add log  
wxyu 已提交
287 288 289
        if (quantizer == nullptr) {
            ENGINE_LOG_ERROR << "quantizer is nullptr";
        }
C
Cai Yudong 已提交
290
        hybrid_index->SetQuantizer(quantizer);
W
wxyu 已提交
291 292 293
        auto cache_quantizer = std::make_shared<CachedQuantizer>(quantizer);
        cache::GpuCacheMgr::GetInstance(best_device_id)->InsertItem(key, cache_quantizer);
    }
G
groot 已提交
294
#endif
W
wxyu 已提交
295 296 297 298
}

void
ExecutionEngineImpl::HybridUnset() const {
C
Cai Yudong 已提交
299 300 301
#ifdef MILVUS_GPU_VERSION
    auto hybrid_index = std::dynamic_pointer_cast<knowhere::IVFSQHybrid>(index_);
    if (hybrid_index == nullptr) {
W
update  
wxyu 已提交
302 303
        return;
    }
C
Cai Yudong 已提交
304 305
    hybrid_index->UnsetQuantizer();
#endif
306 307
}

S
starlord 已提交
308
Status
S
starlord 已提交
309
ExecutionEngineImpl::AddWithIds(int64_t n, const float* xdata, const int64_t* xids) {
C
Cai Yudong 已提交
310 311 312
    auto dataset = knowhere::GenDatasetWithIds(n, index_->Dim(), xdata, xids);
    index_->Add(dataset, knowhere::Config());
    return Status::OK();
S
starlord 已提交
313 314
}

G
groot 已提交
315 316
Status
ExecutionEngineImpl::AddWithIds(int64_t n, const uint8_t* xdata, const int64_t* xids) {
C
Cai Yudong 已提交
317 318 319
    auto dataset = knowhere::GenDatasetWithIds(n, index_->Dim(), xdata, xids);
    index_->Add(dataset, knowhere::Config());
    return Status::OK();
G
groot 已提交
320 321
}

S
starlord 已提交
322 323 324
size_t
ExecutionEngineImpl::Count() const {
    if (index_ == nullptr) {
S
starlord 已提交
325
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, return count 0";
S
starlord 已提交
326 327
        return 0;
    }
X
xj.lin 已提交
328
    return index_->Count();
S
starlord 已提交
329 330
}

S
starlord 已提交
331 332 333
size_t
ExecutionEngineImpl::Dimension() const {
    if (index_ == nullptr) {
S
starlord 已提交
334
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, return dimension " << dim_;
S
starlord 已提交
335 336
        return dim_;
    }
C
Cai Yudong 已提交
337
    return index_->Dim();
S
starlord 已提交
338 339
}

S
starlord 已提交
340
size_t
341 342 343 344 345 346
ExecutionEngineImpl::Size() const {
    if (index_ == nullptr) {
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, return size 0";
        return 0;
    }
    return index_->Size();
S
starlord 已提交
347 348
}

S
starlord 已提交
349 350
Status
ExecutionEngineImpl::Serialize() {
351
    auto status = write_index(index_, location_);
352 353 354

    // here we reset index size by file size,
    // since some index type(such as SQ8) data size become smaller after serialized
355
    index_->set_size(server::CommonUtil::GetFileSize(location_));
G
add log  
groot 已提交
356
    ENGINE_LOG_DEBUG << "Finish serialize index file: " << location_ << " size: " << index_->Size();
357

G
groot 已提交
358 359 360 361 362
    if (index_->Size() == 0) {
        std::string msg = "Failed to serialize file: " + location_ + " reason: out of disk space or memory";
        status = Status(DB_ERROR, msg);
    }

363
    return status;
S
starlord 已提交
364 365
}

366 367 368 369
Status
ExecutionEngineImpl::Load(bool to_cache) {
    // TODO(zhiru): refactor

C
Cai Yudong 已提交
370
    index_ = std::static_pointer_cast<knowhere::VecIndex>(cache::CpuCacheMgr::GetInstance()->GetIndex(location_));
371 372 373 374 375
    bool already_in_cache = (index_ != nullptr);
    if (!already_in_cache) {
        std::string segment_dir;
        utils::GetParentPath(location_, segment_dir);
        auto segment_reader_ptr = std::make_shared<segment::SegmentReader>(segment_dir);
C
Cai Yudong 已提交
376
        knowhere::VecIndexFactory& vec_index_factory = knowhere::VecIndexFactory::GetInstance();
377

378
        if (utils::IsRawIndexType((int32_t)index_type_)) {
C
Cai Yudong 已提交
379 380 381 382 383
            if (index_type_ == EngineType::FAISS_IDMAP) {
                index_ = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_IDMAP);
            } else {
                index_ = vec_index_factory.CreateVecIndex(knowhere::IndexEnum::INDEX_FAISS_BIN_IDMAP);
            }
384 385
            milvus::json conf{{knowhere::meta::DEVICEID, gpu_num_}, {knowhere::meta::DIM, dim_}};
            MappingMetricType(metric_type_, conf);
C
Cai Yudong 已提交
386
            auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(index_->index_type());
387
            ENGINE_LOG_DEBUG << "Index params: " << conf.dump();
C
Cai Yudong 已提交
388
            if (!adapter->CheckTrain(conf, index_->index_mode())) {
389 390
                throw Exception(DB_ERROR, "Illegal index params");
            }
391

392
            auto status = segment_reader_ptr->Load();
393 394 395 396 397 398 399 400 401 402 403 404 405
            if (!status.ok()) {
                std::string msg = "Failed to load segment from " + location_;
                ENGINE_LOG_ERROR << msg;
                return Status(DB_ERROR, msg);
            }

            segment::SegmentPtr segment_ptr;
            segment_reader_ptr->GetSegment(segment_ptr);
            auto& vectors = segment_ptr->vectors_ptr_;
            auto& deleted_docs = segment_ptr->deleted_docs_ptr_->GetDeletedDocs();

            auto vectors_uids = vectors->GetUids();
            index_->SetUids(vectors_uids);
406
            ENGINE_LOG_DEBUG << "set uids " << index_->GetUids().size() << " for index " << location_;
407 408 409 410 411 412 413 414 415 416 417 418

            auto vectors_data = vectors->GetData();

            faiss::ConcurrentBitsetPtr concurrent_bitset_ptr =
                std::make_shared<faiss::ConcurrentBitset>(vectors->GetCount());
            for (auto& offset : deleted_docs) {
                if (!concurrent_bitset_ptr->test(offset)) {
                    concurrent_bitset_ptr->set(offset);
                }
            }

            if (index_type_ == EngineType::FAISS_IDMAP) {
C
Cai Yudong 已提交
419
                auto bf_index = std::static_pointer_cast<knowhere::IDMAP>(index_);
420 421 422
                std::vector<float> float_vectors;
                float_vectors.resize(vectors_data.size() / sizeof(float));
                memcpy(float_vectors.data(), vectors_data.data(), vectors_data.size());
C
Cai Yudong 已提交
423 424 425 426
                bf_index->Train(knowhere::DatasetPtr(), conf);
                auto dataset = knowhere::GenDataset(vectors->GetCount(), this->dim_, float_vectors.data());
                bf_index->AddWithoutIds(dataset, conf);
                bf_index->SetBlacklist(concurrent_bitset_ptr);
427
            } else if (index_type_ == EngineType::FAISS_BIN_IDMAP) {
C
Cai Yudong 已提交
428 429 430 431 432
                auto bin_bf_index = std::static_pointer_cast<knowhere::BinaryIDMAP>(index_);
                bin_bf_index->Train(knowhere::DatasetPtr(), conf);
                auto dataset = knowhere::GenDataset(vectors->GetCount(), this->dim_, vectors_data.data());
                bin_bf_index->AddWithoutIds(dataset, conf);
                bin_bf_index->SetBlacklist(concurrent_bitset_ptr);
433
            }
434 435 436 437 438

            int64_t index_size = vectors->Size();       // vector data size + vector ids size
            int64_t bitset_size = vectors->GetCount();  // delete list size
            index_->set_size(index_size + bitset_size);

439 440 441 442 443 444 445
            if (!status.ok()) {
                return status;
            }

            ENGINE_LOG_DEBUG << "Finished loading raw data from segment " << segment_dir;
        } else {
            try {
446 447
                //                size_t physical_size = PhysicalSize();
                //                server::CollectExecutionEngineMetrics metrics((double)physical_size);
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
                index_ = read_index(location_);

                if (index_ == nullptr) {
                    std::string msg = "Failed to load index from " + location_;
                    ENGINE_LOG_ERROR << msg;
                    return Status(DB_ERROR, msg);
                } else {
                    segment::DeletedDocsPtr deleted_docs_ptr;
                    auto status = segment_reader_ptr->LoadDeletedDocs(deleted_docs_ptr);
                    if (!status.ok()) {
                        std::string msg = "Failed to load deleted docs from " + location_;
                        ENGINE_LOG_ERROR << msg;
                        return Status(DB_ERROR, msg);
                    }
                    auto& deleted_docs = deleted_docs_ptr->GetDeletedDocs();

                    faiss::ConcurrentBitsetPtr concurrent_bitset_ptr =
                        std::make_shared<faiss::ConcurrentBitset>(index_->Count());
                    for (auto& offset : deleted_docs) {
                        if (!concurrent_bitset_ptr->test(offset)) {
                            concurrent_bitset_ptr->set(offset);
                        }
                    }

                    index_->SetBlacklist(concurrent_bitset_ptr);

                    std::vector<segment::doc_id_t> uids;
                    segment_reader_ptr->LoadUids(uids);
                    index_->SetUids(uids);
477
                    ENGINE_LOG_DEBUG << "set uids " << index_->GetUids().size() << " for index " << location_;
478

479 480 481 482
                    int64_t index_size = index_->Size();    // vector data size + vector ids size
                    int64_t bitset_size = index_->Count();  // delete list size
                    index_->set_size(index_size + bitset_size);

483 484 485 486 487 488 489 490 491 492 493 494 495 496
                    ENGINE_LOG_DEBUG << "Finished loading index file from segment " << segment_dir;
                }
            } catch (std::exception& e) {
                ENGINE_LOG_ERROR << e.what();
                return Status(DB_ERROR, e.what());
            }
        }
    }

    if (!already_in_cache && to_cache) {
        Cache();
    }
    return Status::OK();
}  // namespace engine
X
xj.lin 已提交
497

S
starlord 已提交
498
Status
W
wxyu 已提交
499
ExecutionEngineImpl::CopyToGpu(uint64_t device_id, bool hybrid) {
X
xiaojun.lin 已提交
500
#if 0
W
wxyu 已提交
501
    if (hybrid) {
X
xiaojun.lin 已提交
502
        const std::string key = location_ + ".quantizer";
W
wxyu 已提交
503
        std::vector<uint64_t> gpus{device_id};
X
xiaojun.lin 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521

        const int64_t NOT_FOUND = -1;
        int64_t device_id = NOT_FOUND;

        // cache hit
        {
            knowhere::QuantizerPtr quantizer = nullptr;

            for (auto& gpu : gpus) {
                auto cache = cache::GpuCacheMgr::GetInstance(gpu);
                if (auto cached_quantizer = cache->GetIndex(key)) {
                    device_id = gpu;
                    quantizer = std::static_pointer_cast<CachedQuantizer>(cached_quantizer)->Data();
                }
            }

            if (device_id != NOT_FOUND) {
                // cache hit
522
                milvus::json quantizer_conf{{knowhere::meta::DEVICEID : device_id}, {"mode" : 2}};
X
xiaojun.lin 已提交
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
                auto new_index = index_->LoadData(quantizer, config);
                index_ = new_index;
            }
        }

        if (device_id == NOT_FOUND) {
            // cache miss
            std::vector<int64_t> all_free_mem;
            for (auto& gpu : gpus) {
                auto cache = cache::GpuCacheMgr::GetInstance(gpu);
                auto free_mem = cache->CacheCapacity() - cache->CacheUsage();
                all_free_mem.push_back(free_mem);
            }

            auto max_e = std::max_element(all_free_mem.begin(), all_free_mem.end());
            auto best_index = std::distance(all_free_mem.begin(), max_e);
            device_id = gpus[best_index];

            auto pair = index_->CopyToGpuWithQuantizer(device_id);
            index_ = pair.first;

            // cache
            auto cached_quantizer = std::make_shared<CachedQuantizer>(pair.second);
            cache::GpuCacheMgr::GetInstance(device_id)->InsertItem(key, cached_quantizer);
        }
W
wxyu 已提交
548 549
        return Status::OK();
    }
X
xiaojun.lin 已提交
550
#endif
Y
youny626 已提交
551

G
groot 已提交
552
#ifdef MILVUS_GPU_VERSION
C
Cai Yudong 已提交
553 554
    auto data_obj_ptr = cache::GpuCacheMgr::GetInstance(device_id)->GetIndex(location_);
    auto index = std::static_pointer_cast<knowhere::VecIndex>(data_obj_ptr);
Y
youny626 已提交
555 556 557 558 559 560 561 562 563 564
    bool already_in_cache = (index != nullptr);
    if (already_in_cache) {
        index_ = index;
    } else {
        if (index_ == nullptr) {
            ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, failed to copy to gpu";
            return Status(DB_ERROR, "index is null");
        }

        try {
C
Cai Yudong 已提交
565
            index_ = knowhere::cloner::CopyCpuToGpu(index_, device_id, knowhere::Config());
Y
youny626 已提交
566 567 568 569 570
            ENGINE_LOG_DEBUG << "CPU to GPU" << device_id;
        } catch (std::exception& e) {
            ENGINE_LOG_ERROR << e.what();
            return Status(DB_ERROR, e.what());
        }
571
    }
Y
youny626 已提交
572 573 574 575

    if (!already_in_cache) {
        GpuCache(device_id);
    }
G
groot 已提交
576
#endif
Y
youny626 已提交
577

578 579 580
    return Status::OK();
}

Y
Yu Kun 已提交
581 582
Status
ExecutionEngineImpl::CopyToIndexFileToGpu(uint64_t device_id) {
G
groot 已提交
583
#ifdef MILVUS_GPU_VERSION
G
groot 已提交
584
    // the ToIndexData is only a placeholder, cpu-copy-to-gpu action is performed in
585 586
    if (index_) {
        gpu_num_ = device_id;
C
Cai Yudong 已提交
587
        auto to_index_data = std::make_shared<knowhere::ToIndexData>(index_->Size());
588 589 590
        cache::DataObjPtr obj = std::static_pointer_cast<cache::DataObj>(to_index_data);
        milvus::cache::GpuCacheMgr::GetInstance(device_id)->InsertItem(location_ + "_placeholder", obj);
    }
G
groot 已提交
591
#endif
Y
Yu Kun 已提交
592 593 594
    return Status::OK();
}

S
starlord 已提交
595 596
Status
ExecutionEngineImpl::CopyToCpu() {
C
Cai Yudong 已提交
597 598
#ifdef MILVUS_GPU_VERSION
    auto index = std::static_pointer_cast<knowhere::VecIndex>(cache::CpuCacheMgr::GetInstance()->GetIndex(location_));
W
wxyu 已提交
599 600 601 602
    bool already_in_cache = (index != nullptr);
    if (already_in_cache) {
        index_ = index;
    } else {
S
starlord 已提交
603
        if (index_ == nullptr) {
S
starlord 已提交
604
            ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, failed to copy to cpu";
S
starlord 已提交
605
            return Status(DB_ERROR, "index is null");
S
starlord 已提交
606 607
        }

Y
Yu Kun 已提交
608
        try {
C
Cai Yudong 已提交
609
            index_ = knowhere::cloner::CopyGpuToCpu(index_, knowhere::Config());
Y
Yu Kun 已提交
610
            ENGINE_LOG_DEBUG << "GPU to CPU";
S
starlord 已提交
611
        } catch (std::exception& e) {
S
starlord 已提交
612
            ENGINE_LOG_ERROR << e.what();
S
starlord 已提交
613
            return Status(DB_ERROR, e.what());
Y
Yu Kun 已提交
614 615 616
        }
    }

W
wxyu 已提交
617
    if (!already_in_cache) {
Y
Yu Kun 已提交
618
        Cache();
619 620
    }
    return Status::OK();
C
Cai Yudong 已提交
621 622 623 624
#else
    ENGINE_LOG_ERROR << "Calling ExecutionEngineImpl::CopyToCpu when using CPU version";
    return Status(DB_ERROR, "Calling ExecutionEngineImpl::CopyToCpu when using CPU version");
#endif
625 626
}

S
starlord 已提交
627
ExecutionEnginePtr
S
starlord 已提交
628
ExecutionEngineImpl::BuildIndex(const std::string& location, EngineType engine_type) {
X
xj.lin 已提交
629 630
    ENGINE_LOG_DEBUG << "Build index file: " << location << " from: " << location_;

C
Cai Yudong 已提交
631 632
    auto from_index = std::dynamic_pointer_cast<knowhere::IDMAP>(index_);
    auto bin_from_index = std::dynamic_pointer_cast<knowhere::BinaryIDMAP>(index_);
G
groot 已提交
633
    if (from_index == nullptr && bin_from_index == nullptr) {
S
starlord 已提交
634 635 636 637
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: from_index is null, failed to build index";
        return nullptr;
    }

S
starlord 已提交
638
    auto to_index = CreatetVecIndex(engine_type);
X
xj.lin 已提交
639
    if (!to_index) {
640
        throw Exception(DB_ERROR, "Unsupported index type");
X
xj.lin 已提交
641 642
    }

643 644 645 646 647 648
    milvus::json conf = index_params_;
    conf[knowhere::meta::DIM] = Dimension();
    conf[knowhere::meta::ROWS] = Count();
    conf[knowhere::meta::DEVICEID] = gpu_num_;
    MappingMetricType(metric_type_, conf);
    ENGINE_LOG_DEBUG << "Index params: " << conf.dump();
C
Cai Yudong 已提交
649 650
    auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(to_index->index_type());
    if (!adapter->CheckTrain(conf, to_index->index_mode())) {
651 652 653
        throw Exception(DB_ERROR, "Illegal index params");
    }
    ENGINE_LOG_DEBUG << "Index config: " << conf.dump();
654 655

    std::vector<segment::doc_id_t> uids;
Z
update  
Zhiru Zhu 已提交
656
    faiss::ConcurrentBitsetPtr blacklist;
G
groot 已提交
657
    if (from_index) {
C
Cai Yudong 已提交
658 659 660
        auto dataset =
            knowhere::GenDatasetWithIds(Count(), Dimension(), from_index->GetRawVectors(), from_index->GetRawIds());
        to_index->BuildAll(dataset, conf);
661
        uids = from_index->GetUids();
Z
update  
Zhiru Zhu 已提交
662
        from_index->GetBlacklist(blacklist);
G
groot 已提交
663
    } else if (bin_from_index) {
C
Cai Yudong 已提交
664 665 666
        auto dataset = knowhere::GenDatasetWithIds(Count(), Dimension(), bin_from_index->GetRawVectors(),
                                                   bin_from_index->GetRawIds());
        to_index->BuildAll(dataset, conf);
667
        uids = bin_from_index->GetUids();
Z
update  
Zhiru Zhu 已提交
668
        bin_from_index->GetBlacklist(blacklist);
G
groot 已提交
669
    }
C
Cai Yudong 已提交
670 671 672 673 674 675 676 677 678

#ifdef MILVUS_GPU_VERSION
    /* for GPU index, need copy back to CPU */
    if (to_index->index_mode() == knowhere::IndexMode::MODE_GPU) {
        auto device_index = std::dynamic_pointer_cast<knowhere::GPUIndex>(to_index);
        to_index = device_index->CopyGpuToCpu(conf);
    }
#endif

679
    to_index->SetUids(uids);
Z
update  
Zhiru Zhu 已提交
680 681 682 683 684
    ENGINE_LOG_DEBUG << "Set " << to_index->GetUids().size() << "uids for " << location;
    if (blacklist != nullptr) {
        to_index->SetBlacklist(blacklist);
        ENGINE_LOG_DEBUG << "Set blacklist for index " << location;
    }
685

686
    ENGINE_LOG_DEBUG << "Finish build index: " << location;
687
    return std::make_shared<ExecutionEngineImpl>(to_index, location, engine_type, metric_type_, index_params_);
S
starlord 已提交
688 689
}

690
void
C
Cai Yudong 已提交
691 692 693 694 695 696 697 698 699
MapAndCopyResult(const knowhere::DatasetPtr& dataset, const std::vector<milvus::segment::doc_id_t>& uids, int64_t nq,
                 int64_t k, float* distances, int64_t* labels) {
    int64_t* res_ids = dataset->Get<int64_t*>(knowhere::meta::IDS);
    float* res_dist = dataset->Get<float*>(knowhere::meta::DISTANCE);

    memcpy(distances, res_dist, sizeof(float) * nq * k);

    /* map offsets to ids */
    int64_t num = nq * k;
700
    for (int64_t i = 0; i < num; ++i) {
C
Cai Yudong 已提交
701
        int64_t offset = res_ids[i];
702
        if (offset != -1) {
C
Cai Yudong 已提交
703 704 705
            labels[i] = uids[offset];
        } else {
            labels[i] = -1;
706 707
        }
    }
C
Cai Yudong 已提交
708 709 710

    free(res_ids);
    free(res_dist);
711 712
}

S
starlord 已提交
713
Status
714 715
ExecutionEngineImpl::Search(int64_t n, const float* data, int64_t k, const milvus::json& extra_params, float* distances,
                            int64_t* labels, bool hybrid) {
716
#if 0
J
JinHai-CN 已提交
717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738
    if (index_type_ == EngineType::FAISS_IVFSQ8H) {
        if (!hybrid) {
            const std::string key = location_ + ".quantizer";
            std::vector<uint64_t> gpus = scheduler::get_gpu_pool();

            const int64_t NOT_FOUND = -1;
            int64_t device_id = NOT_FOUND;

            // cache hit
            {
                knowhere::QuantizerPtr quantizer = nullptr;

                for (auto& gpu : gpus) {
                    auto cache = cache::GpuCacheMgr::GetInstance(gpu);
                    if (auto cached_quantizer = cache->GetIndex(key)) {
                        device_id = gpu;
                        quantizer = std::static_pointer_cast<CachedQuantizer>(cached_quantizer)->Data();
                    }
                }

                if (device_id != NOT_FOUND) {
                    // cache hit
739
                    milvus::json quantizer_conf{{knowhere::meta::DEVICEID : device_id}, {"mode" : 2}};
J
JinHai-CN 已提交
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
                    auto new_index = index_->LoadData(quantizer, config);
                    index_ = new_index;
                }
            }

            if (device_id == NOT_FOUND) {
                // cache miss
                std::vector<int64_t> all_free_mem;
                for (auto& gpu : gpus) {
                    auto cache = cache::GpuCacheMgr::GetInstance(gpu);
                    auto free_mem = cache->CacheCapacity() - cache->CacheUsage();
                    all_free_mem.push_back(free_mem);
                }

                auto max_e = std::max_element(all_free_mem.begin(), all_free_mem.end());
                auto best_index = std::distance(all_free_mem.begin(), max_e);
                device_id = gpus[best_index];

                auto pair = index_->CopyToGpuWithQuantizer(device_id);
                index_ = pair.first;

                // cache
                auto cached_quantizer = std::make_shared<CachedQuantizer>(pair.second);
                cache::GpuCacheMgr::GetInstance(device_id)->InsertItem(key, cached_quantizer);
            }
        }
    }
767
#endif
768
    TimeRecorder rc("ExecutionEngineImpl::Search float");
J
JinHai-CN 已提交
769

S
starlord 已提交
770
    if (index_ == nullptr) {
S
starlord 已提交
771
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, failed to search";
S
starlord 已提交
772
        return Status(DB_ERROR, "index is null");
S
starlord 已提交
773 774
    }

775 776
    milvus::json conf = extra_params;
    conf[knowhere::meta::TOPK] = k;
C
Cai Yudong 已提交
777 778
    auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(index_->index_type());
    if (!adapter->CheckSearch(conf, index_->index_type(), index_->index_mode())) {
779 780
        throw Exception(DB_ERROR, "Illegal search params");
    }
X
xiaojun.lin 已提交
781

W
wxyu 已提交
782 783 784
    if (hybrid) {
        HybridLoad();
    }
W
wxyu 已提交
785

C
Cai Yudong 已提交
786 787 788 789
    rc.RecordSection("query prepare");
    auto dataset = knowhere::GenDataset(n, index_->Dim(), data);
    auto result = index_->Query(dataset, conf);
    rc.RecordSection("query done");
790

791
    ENGINE_LOG_DEBUG << "get uids " << index_->GetUids().size() << " from index " << location_;
C
Cai Yudong 已提交
792
    MapAndCopyResult(result, index_->GetUids(), n, k, distances, labels);
793
    rc.RecordSection("map uids " + std::to_string(n * k));
W
wxyu 已提交
794

W
wxyu 已提交
795 796 797
    if (hybrid) {
        HybridUnset();
    }
W
wxyu 已提交
798

C
Cai Yudong 已提交
799
    return Status::OK();
S
starlord 已提交
800 801
}

G
groot 已提交
802
Status
803 804
ExecutionEngineImpl::Search(int64_t n, const uint8_t* data, int64_t k, const milvus::json& extra_params,
                            float* distances, int64_t* labels, bool hybrid) {
805
    TimeRecorder rc("ExecutionEngineImpl::Search uint8");
806

G
groot 已提交
807 808 809 810 811
    if (index_ == nullptr) {
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, failed to search";
        return Status(DB_ERROR, "index is null");
    }

812 813
    milvus::json conf = extra_params;
    conf[knowhere::meta::TOPK] = k;
C
Cai Yudong 已提交
814 815
    auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(index_->index_type());
    if (!adapter->CheckSearch(conf, index_->index_type(), index_->index_mode())) {
816 817
        throw Exception(DB_ERROR, "Illegal search params");
    }
G
groot 已提交
818 819 820 821 822

    if (hybrid) {
        HybridLoad();
    }

C
Cai Yudong 已提交
823 824 825 826
    rc.RecordSection("query prepare");
    auto dataset = knowhere::GenDataset(n, index_->Dim(), data);
    auto result = index_->Query(dataset, conf);
    rc.RecordSection("query done");
827

828
    ENGINE_LOG_DEBUG << "get uids " << index_->GetUids().size() << " from index " << location_;
C
Cai Yudong 已提交
829
    MapAndCopyResult(result, index_->GetUids(), n, k, distances, labels);
830
    rc.RecordSection("map uids " + std::to_string(n * k));
831 832 833 834 835

    if (hybrid) {
        HybridUnset();
    }

C
Cai Yudong 已提交
836
    return Status::OK();
837 838 839
}

Status
840 841
ExecutionEngineImpl::Search(int64_t n, const std::vector<int64_t>& ids, int64_t k, const milvus::json& extra_params,
                            float* distances, int64_t* labels, bool hybrid) {
842
    TimeRecorder rc("ExecutionEngineImpl::Search vector of ids");
843 844 845 846 847 848

    if (index_ == nullptr) {
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, failed to search";
        return Status(DB_ERROR, "index is null");
    }

849 850
    milvus::json conf = extra_params;
    conf[knowhere::meta::TOPK] = k;
C
Cai Yudong 已提交
851 852
    auto adapter = knowhere::AdapterMgr::GetInstance().GetAdapter(index_->index_type());
    if (!adapter->CheckSearch(conf, index_->index_type(), index_->index_mode())) {
853 854
        throw Exception(DB_ERROR, "Illegal search params");
    }
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901

    if (hybrid) {
        HybridLoad();
    }

    rc.RecordSection("search prepare");

    // std::string segment_dir;
    // utils::GetParentPath(location_, segment_dir);
    // segment::SegmentReader segment_reader(segment_dir);
    //    segment::IdBloomFilterPtr id_bloom_filter_ptr;
    //    segment_reader.LoadBloomFilter(id_bloom_filter_ptr);

    // Check if the id is present. If so, find its offset
    const std::vector<segment::doc_id_t>& uids = index_->GetUids();

    std::vector<int64_t> offsets;
    /*
    std::vector<segment::doc_id_t> uids;
    auto status = segment_reader.LoadUids(uids);
    if (!status.ok()) {
        return status;
    }
     */

    // There is only one id in ids
    for (auto& id : ids) {
        //        if (id_bloom_filter_ptr->Check(id)) {
        //            if (uids.empty()) {
        //                segment_reader.LoadUids(uids);
        //            }
        //            auto found = std::find(uids.begin(), uids.end(), id);
        //            if (found != uids.end()) {
        //                auto offset = std::distance(uids.begin(), found);
        //                offsets.emplace_back(offset);
        //            }
        //        }
        auto found = std::find(uids.begin(), uids.end(), id);
        if (found != uids.end()) {
            auto offset = std::distance(uids.begin(), found);
            offsets.emplace_back(offset);
        }
    }

    rc.RecordSection("get offset");

    if (!offsets.empty()) {
C
Cai Yudong 已提交
902 903 904
        auto dataset = knowhere::GenDatasetWithIds(offsets.size(), index_->Dim(), nullptr, offsets.data());
        auto result = index_->QueryById(dataset, conf);
        rc.RecordSection("query by id done");
905

906
        ENGINE_LOG_DEBUG << "get uids " << index_->GetUids().size() << " from index " << location_;
C
Cai Yudong 已提交
907
        MapAndCopyResult(result, uids, offsets.size(), k, distances, labels);
908
        rc.RecordSection("map uids " + std::to_string(offsets.size() * k));
909 910 911 912 913 914
    }

    if (hybrid) {
        HybridUnset();
    }

C
Cai Yudong 已提交
915
    return Status::OK();
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930
}

Status
ExecutionEngineImpl::GetVectorByID(const int64_t& id, float* vector, bool hybrid) {
    if (index_ == nullptr) {
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, failed to search";
        return Status(DB_ERROR, "index is null");
    }

    if (hybrid) {
        HybridLoad();
    }

    // Only one id for now
    std::vector<int64_t> ids{id};
C
Cai Yudong 已提交
931 932 933 934
    auto dataset = knowhere::GenDatasetWithIds(1, index_->Dim(), nullptr, ids.data());
    auto result = index_->GetVectorById(dataset, knowhere::Config());
    float* res_vec = (float*)(result->Get<void*>(knowhere::meta::TENSOR));
    memcpy(vector, res_vec, sizeof(float) * 1 * index_->Dim());
935 936 937 938 939

    if (hybrid) {
        HybridUnset();
    }

C
Cai Yudong 已提交
940
    return Status::OK();
941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
}

Status
ExecutionEngineImpl::GetVectorByID(const int64_t& id, uint8_t* vector, bool hybrid) {
    if (index_ == nullptr) {
        ENGINE_LOG_ERROR << "ExecutionEngineImpl: index is null, failed to search";
        return Status(DB_ERROR, "index is null");
    }

    ENGINE_LOG_DEBUG << "Get binary vector by id:  " << id;

    if (hybrid) {
        HybridLoad();
    }

    // Only one id for now
    std::vector<int64_t> ids{id};
C
Cai Yudong 已提交
958 959 960 961
    auto dataset = knowhere::GenDatasetWithIds(1, index_->Dim(), nullptr, ids.data());
    auto result = index_->GetVectorById(dataset, knowhere::Config());
    uint8_t* res_vec = (uint8_t*)(result->Get<void*>(knowhere::meta::TENSOR));
    memcpy(vector, res_vec, sizeof(uint8_t) * 1 * index_->Dim());
G
groot 已提交
962 963 964 965 966

    if (hybrid) {
        HybridUnset();
    }

C
Cai Yudong 已提交
967
    return Status::OK();
G
groot 已提交
968 969
}

S
starlord 已提交
970 971
Status
ExecutionEngineImpl::Cache() {
972
    cache::DataObjPtr obj = std::static_pointer_cast<cache::DataObj>(index_);
S
starlord 已提交
973
    milvus::cache::CpuCacheMgr::GetInstance()->InsertItem(location_, obj);
S
starlord 已提交
974 975 976 977

    return Status::OK();
}

S
starlord 已提交
978 979
Status
ExecutionEngineImpl::GpuCache(uint64_t gpu_id) {
G
groot 已提交
980
#ifdef MILVUS_GPU_VERSION
981
    cache::DataObjPtr obj = std::static_pointer_cast<cache::DataObj>(index_);
S
starlord 已提交
982
    milvus::cache::GpuCacheMgr::GetInstance(gpu_id)->InsertItem(location_, obj);
G
groot 已提交
983
#endif
984
    return Status::OK();
Y
Yu Kun 已提交
985 986
}

X
xj.lin 已提交
987
// TODO(linxj): remove.
S
starlord 已提交
988 989
Status
ExecutionEngineImpl::Init() {
G
groot 已提交
990
#ifdef MILVUS_GPU_VERSION
S
starlord 已提交
991
    server::Config& config = server::Config::GetInstance();
Y
yudong.cai 已提交
992
    std::vector<int64_t> gpu_ids;
993
    Status s = config.GetGpuResourceConfigBuildIndexResources(gpu_ids);
F
fishpenguin 已提交
994
    if (!s.ok()) {
995
        gpu_num_ = -1;
996
        return s;
F
fishpenguin 已提交
997
    }
998 999 1000 1001
    for (auto id : gpu_ids) {
        if (gpu_num_ == id) {
            return Status::OK();
        }
S
starlord 已提交
1002
    }
S
starlord 已提交
1003

1004 1005
    std::string msg = "Invalid gpu_num";
    return Status(SERVER_INVALID_ARGUMENT, msg);
G
groot 已提交
1006 1007 1008
#else
    return Status::OK();
#endif
S
starlord 已提交
1009 1010
}

S
starlord 已提交
1011 1012
}  // namespace engine
}  // namespace milvus