IndexBuilder.cpp 6.1 KB
Newer Older
X
xj.lin 已提交
1 2 3 4 5 6
////////////////////////////////////////////////////////////////////////////////
// Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited.
// Proprietary and confidential.
////////////////////////////////////////////////////////////////////////////////

X
xj.lin 已提交
7
#if 0
X
xj.lin 已提交
8 9
#include "mutex"

X
xj.lin 已提交
10

X
xj.lin 已提交
11
#ifdef GPU_VERSION
X
xj.lin 已提交
12
#include <faiss/gpu/StandardGpuResources.h>
X
xj.lin 已提交
13 14
#include <faiss/gpu/GpuIndexIVFFlat.h>
#include <faiss/gpu/GpuAutoTune.h>
X
xj.lin 已提交
15 16
#endif

X
xj.lin 已提交
17

X
xj.lin 已提交
18 19
#include <faiss/IndexFlat.h>
#include <easylogging++.h>
S
starlord 已提交
20
#include "faiss/IndexScalarQuantizer.h"
X
xj.lin 已提交
21 22

#include "server/ServerConfig.h"
X
xj.lin 已提交
23
#include "IndexBuilder.h"
S
starlord 已提交
24
#include "FaissGpuResources.h"
X
xj.lin 已提交
25

X
xj.lin 已提交
26

X
xj.lin 已提交
27
namespace zilliz {
J
jinhai 已提交
28
namespace milvus {
X
xj.lin 已提交
29 30 31 32
namespace engine {

using std::vector;

X
xj.lin 已提交
33
static std::mutex gpu_resource;
X
xj.lin 已提交
34
static std::mutex cpu_resource;
X
xj.lin 已提交
35 36 37

IndexBuilder::IndexBuilder(const Operand_ptr &opd) {
    opd_ = opd;
S
starlord 已提交
38 39 40 41 42 43

    using namespace zilliz::milvus::server;
    ServerConfig &config = ServerConfig::GetInstance();
    ConfigNode engine_config = config.GetConfig(CONFIG_ENGINE);
    use_hybrid_index_ = engine_config.GetBoolValue(CONFIG_USE_HYBRID_INDEX, false);
    hybrid_index_device_id_ = engine_config.GetInt32Value(server::CONFIG_HYBRID_INDEX_GPU, 0);
X
xj.lin 已提交
44 45
}

X
xj.lin 已提交
46
// Default: build use gpu
47
Index_ptr IndexBuilder::build_all(const long &nb,
X
xj.lin 已提交
48 49
                                  const float *xb,
                                  const long *ids,
50
                                  const long &nt,
X
xj.lin 已提交
51
                                  const float *xt) {
X
xj.lin 已提交
52
    std::shared_ptr<faiss::Index> host_index = nullptr;
X
xj.lin 已提交
53
#ifdef GPU_VERSION
X
xj.lin 已提交
54
    {
55
        LOG(DEBUG) << "Build index by GPU";
X
xj.lin 已提交
56
        // TODO: list support index-type.
57 58
        faiss::MetricType metric_type = opd_->metric_type == "L2" ? faiss::METRIC_L2 : faiss::METRIC_INNER_PRODUCT;
        faiss::Index *ori_index = faiss::index_factory(opd_->d, opd_->get_index_type(nb).c_str(), metric_type);
X
xj.lin 已提交
59 60

        std::lock_guard<std::mutex> lk(gpu_resource);
S
starlord 已提交
61 62

#ifdef UNITTEST_ONLY
X
xj.lin 已提交
63
        faiss::gpu::StandardGpuResources res;
S
starlord 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76
        int device_id = 0;
        faiss::gpu::GpuClonerOptions clone_option;
        clone_option.storeInCpu = use_hybrid_index_;
        auto device_index = faiss::gpu::index_cpu_to_gpu(&res, device_id, ori_index, &clone_option);
#else
        engine::FaissGpuResources res;
        int device_id = res.GetGpu();
        auto gpu_resources = engine::FaissGpuResources::GetGpuResources(device_id);
        faiss::gpu::GpuClonerOptions clone_option;
        clone_option.storeInCpu = use_hybrid_index_;
        auto device_index = faiss::gpu::index_cpu_to_gpu(gpu_resources.get(), device_id, ori_index, &clone_option);
#endif

X
xj.lin 已提交
77 78 79
        if (!device_index->is_trained) {
            nt == 0 || xt == nullptr ? device_index->train(nb, xb)
                                     : device_index->train(nt, xt);
X
xj.lin 已提交
80
        }
X
xj.lin 已提交
81
        device_index->add_with_ids(nb, xb, ids); // TODO: support with add_with_IDMAP
X
xj.lin 已提交
82

S
starlord 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
        if (dynamic_cast<faiss::IndexIVFScalarQuantizer*>(ori_index) != nullptr
            && use_hybrid_index_) {
            std::shared_ptr<faiss::Index> device_hybrid_index = nullptr;
            if (hybrid_index_device_id_ != device_id) {
                auto host_hybrid_index = faiss::gpu::index_gpu_to_cpu(device_index);
                auto hybrid_gpu_resources = engine::FaissGpuResources::GetGpuResources(hybrid_index_device_id_);
                auto another_device_index = faiss::gpu::index_cpu_to_gpu(hybrid_gpu_resources.get(),
                                                                         hybrid_index_device_id_,
                                                                         host_hybrid_index,
                                                                         &clone_option);
                device_hybrid_index.reset(another_device_index);
                delete device_index;
                delete host_hybrid_index;
            } else {
                device_hybrid_index.reset(device_index);
            }
            delete ori_index;
            return std::make_shared<Index>(device_hybrid_index);
        }

X
xj.lin 已提交
103
        host_index.reset(faiss::gpu::index_gpu_to_cpu(device_index));
X
xj.lin 已提交
104

X
xj.lin 已提交
105 106 107
        delete device_index;
        delete ori_index;
    }
X
xj.lin 已提交
108 109
#else
    {
110
        LOG(DEBUG) << "Build index by CPU";
111 112
        faiss::MetricType metric_type = opd_->metric_type == "L2" ? faiss::METRIC_L2 : faiss::METRIC_INNER_PRODUCT;
        faiss::Index *index = faiss::index_factory(opd_->d, opd_->get_index_type(nb).c_str(), metric_type);
X
xj.lin 已提交
113 114 115 116 117 118 119 120
        if (!index->is_trained) {
            nt == 0 || xt == nullptr ? index->train(nb, xb)
                                     : index->train(nt, xt);
        }
        index->add_with_ids(nb, xb, ids);
        host_index.reset(index);
    }
#endif
121

X
xj.lin 已提交
122
    return std::make_shared<Index>(host_index);
123 124 125 126 127 128
}

Index_ptr IndexBuilder::build_all(const long &nb, const vector<float> &xb,
                                  const vector<long> &ids,
                                  const long &nt, const vector<float> &xt) {
    return build_all(nb, xb.data(), ids.data(), nt, xt.data());
X
xj.lin 已提交
129 130
}

J
jinhai 已提交
131
BgCpuBuilder::BgCpuBuilder(const zilliz::milvus::engine::Operand_ptr &opd) : IndexBuilder(opd) {};
X
xj.lin 已提交
132 133 134

Index_ptr BgCpuBuilder::build_all(const long &nb, const float *xb, const long *ids, const long &nt, const float *xt) {
    std::shared_ptr<faiss::Index> index = nullptr;
135 136
    faiss::MetricType metric_type = opd_->metric_type == "L2" ? faiss::METRIC_L2 : faiss::METRIC_INNER_PRODUCT;
    index.reset(faiss::index_factory(opd_->d, opd_->get_index_type(nb).c_str(), metric_type));
X
xj.lin 已提交
137

138
    LOG(DEBUG) << "Build index by CPU";
X
xj.lin 已提交
139 140 141 142 143 144 145 146 147 148 149 150
    {
        std::lock_guard<std::mutex> lk(cpu_resource);
        if (!index->is_trained) {
            nt == 0 || xt == nullptr ? index->train(nb, xb)
                                     : index->train(nt, xt);
        }
        index->add_with_ids(nb, xb, ids);
    }

    return std::make_shared<Index>(index);
}

X
xj.lin 已提交
151
IndexBuilderPtr GetIndexBuilder(const Operand_ptr &opd) {
X
xj.lin 已提交
152 153 154 155 156
    if (opd->index_type == "IDMap") {
        IndexBuilderPtr index = nullptr;
        return std::make_shared<BgCpuBuilder>(opd);
    }

X
xj.lin 已提交
157 158 159 160 161 162
    return std::make_shared<IndexBuilder>(opd);
}

}
}
}
X
xj.lin 已提交
163
#endif