ConfAdapter.cpp 9.8 KB
Newer Older
X
xiaojun.lin 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

S
starlord 已提交
18
#include "wrapper/ConfAdapter.h"
Z
zirui.chen 已提交
19
#include "WrapperException.h"
S
starlord 已提交
20
#include "knowhere/index/vector_index/helpers/IndexParameter.h"
21
#include "server/Config.h"
S
starlord 已提交
22
#include "utils/Log.h"
X
xiaojun.lin 已提交
23 24

#include <cmath>
S
starlord 已提交
25
#include <memory>
X
xiaojun.lin 已提交
26
#include <vector>
X
xiaojun.lin 已提交
27

S
starlord 已提交
28
// TODO(lxj): add conf checker
X
xiaojun.lin 已提交
29 30 31 32 33 34 35 36 37 38 39

namespace milvus {
namespace engine {

#if CUDA_VERSION > 9000
#define GPU_MAX_NRPOBE 2048
#else
#define GPU_MAX_NRPOBE 1024
#endif

void
G
groot 已提交
40
ConfAdapter::MatchBase(knowhere::Config conf, knowhere::METRICTYPE default_metric) {
X
xiaojun.lin 已提交
41
    if (conf->metric_type == knowhere::DEFAULT_TYPE)
G
groot 已提交
42
        conf->metric_type = default_metric;
X
xiaojun.lin 已提交
43 44 45
}

knowhere::Config
S
starlord 已提交
46
ConfAdapter::Match(const TempMetaConf& metaconf) {
X
xiaojun.lin 已提交
47 48 49
    auto conf = std::make_shared<knowhere::Cfg>();
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
X
xiaojun.lin 已提交
50 51
    conf->gpu_id = metaconf.gpu_id;
    conf->k = metaconf.k;
X
xiaojun.lin 已提交
52 53 54 55 56
    MatchBase(conf);
    return conf;
}

knowhere::Config
S
starlord 已提交
57
ConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) {
X
xiaojun.lin 已提交
58 59 60 61 62 63
    auto conf = std::make_shared<knowhere::Cfg>();
    conf->k = metaconf.k;
    return conf;
}

knowhere::Config
S
starlord 已提交
64
IVFConfAdapter::Match(const TempMetaConf& metaconf) {
X
xiaojun.lin 已提交
65
    auto conf = std::make_shared<knowhere::IVFCfg>();
G
groot 已提交
66
    conf->nlist = MatchNlist(metaconf.size, metaconf.nlist, 16384);
X
xiaojun.lin 已提交
67 68
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
X
xiaojun.lin 已提交
69
    conf->gpu_id = metaconf.gpu_id;
X
xiaojun.lin 已提交
70 71 72 73 74 75 76
    MatchBase(conf);
    return conf;
}

static constexpr float TYPICAL_COUNT = 1000000.0;

int64_t
G
groot 已提交
77 78
IVFConfAdapter::MatchNlist(const int64_t& size, const int64_t& nlist, const int64_t& per_nlist) {
    if (size <= TYPICAL_COUNT / per_nlist + 1) {
X
xiaojun.lin 已提交
79 80
        // handle less row count, avoid nlist set to 0
        return 1;
Z
zirui.chen 已提交
81
    } else if (int(size / TYPICAL_COUNT) * nlist <= 0) {
X
xiaojun.lin 已提交
82
        // calculate a proper nlist if nlist not specified or size less than TYPICAL_COUNT
G
groot 已提交
83
        return int(size / TYPICAL_COUNT * per_nlist);
X
xiaojun.lin 已提交
84
    }
85
    return nlist;
X
xiaojun.lin 已提交
86 87 88
}

knowhere::Config
S
starlord 已提交
89
IVFConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) {
X
xiaojun.lin 已提交
90 91
    auto conf = std::make_shared<knowhere::IVFCfg>();
    conf->k = metaconf.k;
Z
zirui.chen 已提交
92 93 94 95 96

    if (metaconf.nprobe <= 0)
        conf->nprobe = 16;  // hardcode here
    else
        conf->nprobe = metaconf.nprobe;
X
xiaojun.lin 已提交
97 98 99 100 101 102 103

    switch (type) {
        case IndexType::FAISS_IVFFLAT_GPU:
        case IndexType::FAISS_IVFSQ8_GPU:
        case IndexType::FAISS_IVFPQ_GPU:
            if (conf->nprobe > GPU_MAX_NRPOBE) {
                WRAPPER_LOG_WARNING << "When search with GPU, nprobe shoud be no more than " << GPU_MAX_NRPOBE
S
starlord 已提交
104 105
                                    << ", but you passed " << conf->nprobe << ". Search with " << GPU_MAX_NRPOBE
                                    << " instead";
X
xiaojun.lin 已提交
106 107 108 109 110 111 112
                conf->nprobe = GPU_MAX_NRPOBE;
            }
    }
    return conf;
}

knowhere::Config
S
starlord 已提交
113
IVFSQConfAdapter::Match(const TempMetaConf& metaconf) {
X
xiaojun.lin 已提交
114
    auto conf = std::make_shared<knowhere::IVFSQCfg>();
G
groot 已提交
115
    conf->nlist = MatchNlist(metaconf.size, metaconf.nlist, 16384);
X
xiaojun.lin 已提交
116 117
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
X
xiaojun.lin 已提交
118
    conf->gpu_id = metaconf.gpu_id;
X
xiaojun.lin 已提交
119 120 121 122 123 124
    conf->nbits = 8;
    MatchBase(conf);
    return conf;
}

knowhere::Config
S
starlord 已提交
125
IVFPQConfAdapter::Match(const TempMetaConf& metaconf) {
X
xiaojun.lin 已提交
126 127 128 129
    auto conf = std::make_shared<knowhere::IVFPQCfg>();
    conf->nlist = MatchNlist(metaconf.size, metaconf.nlist);
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
X
xiaojun.lin 已提交
130
    conf->gpu_id = metaconf.gpu_id;
X
xiaojun.lin 已提交
131 132
    conf->nbits = 8;
    MatchBase(conf);
X
xiaojun.lin 已提交
133

134 135 136 137 138 139 140 141 142 143 144
#ifdef MILVUS_GPU_VERSION
    Status s;
    bool enable_gpu = false;
    server::Config& config = server::Config::GetInstance();
    s = config.GetGpuResourceConfigEnable(enable_gpu);
    if (s.ok() && conf->metric_type == knowhere::METRICTYPE::IP) {
        WRAPPER_LOG_ERROR << "PQ not support IP in GPU version!";
        throw WrapperException("PQ not support IP in GPU version!");
    }
#endif

X
xiaojun.lin 已提交
145 146
    /*
     * Faiss 1.6
147
     * Only 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32 dims per sub-quantizer are currently supported with
X
xiaojun.lin 已提交
148 149
     * no precomputed codes. Precomputed codes supports any number of dimensions, but will involve memory overheads.
     */
X
update  
xiaojun.lin 已提交
150 151 152 153 154 155 156 157 158 159
    static std::vector<int64_t> support_dim_per_subquantizer{32, 28, 24, 20, 16, 12, 10, 8, 6, 4, 3, 2, 1};
    static std::vector<int64_t> support_subquantizer{96, 64, 56, 48, 40, 32, 28, 24, 20, 16, 12, 8, 4, 3, 2, 1};
    std::vector<int64_t> resset;
    for (const auto& dimperquantizer : support_dim_per_subquantizer) {
        if (!(conf->d % dimperquantizer)) {
            auto subquantzier_num = conf->d / dimperquantizer;
            auto finder = std::find(support_subquantizer.begin(), support_subquantizer.end(), subquantzier_num);
            if (finder != support_subquantizer.end()) {
                resset.push_back(subquantzier_num);
            }
X
xiaojun.lin 已提交
160
        }
X
xiaojun.lin 已提交
161
    }
X
update  
xiaojun.lin 已提交
162 163 164

    if (resset.empty()) {
        // todo(linxj): throw exception here.
165 166
        WRAPPER_LOG_ERROR << "The dims of PQ is wrong : only 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32 dims per sub-"
                             "quantizer are currently supported with no precomputed codes.";
167 168 169
        throw WrapperException(
            "The dims of PQ is wrong : only 1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32 dims "
            "per sub-quantizer are currently supported with no precomputed codes.");
170
        // return nullptr;
X
update  
xiaojun.lin 已提交
171
    }
T
Tinkerrr 已提交
172
    static int64_t compression_level = 1;  // 1:low, 2:high
X
update  
xiaojun.lin 已提交
173
    if (compression_level == 1) {
T
Tinkerrr 已提交
174 175
        conf->m = resset[int(resset.size() / 2)];
        WRAPPER_LOG_DEBUG << "PQ m = " << conf->m << ", compression radio = " << conf->d / conf->m * 4;
X
update  
xiaojun.lin 已提交
176 177
    }
    return conf;
X
xiaojun.lin 已提交
178 179
}

Z
zirui.chen 已提交
180 181 182 183 184
knowhere::Config
IVFPQConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) {
    auto conf = std::make_shared<knowhere::IVFPQCfg>();
    conf->k = metaconf.k;

Z
zirui.chen 已提交
185
    if (metaconf.nprobe <= 0) {
Z
zirui.chen 已提交
186 187
        WRAPPER_LOG_ERROR << "The nprobe of PQ is wrong!";
        throw WrapperException("The nprobe of PQ is wrong!");
Z
zirui.chen 已提交
188
    } else {
Z
zirui.chen 已提交
189
        conf->nprobe = metaconf.nprobe;
Z
zirui.chen 已提交
190
    }
Z
zirui.chen 已提交
191 192 193 194

    return conf;
}

Z
zirui.chen 已提交
195 196 197 198 199 200 201 202 203 204 205 206
int64_t
IVFPQConfAdapter::MatchNlist(const int64_t& size, const int64_t& nlist) {
    if (size <= TYPICAL_COUNT / 16384 + 1) {
        // handle less row count, avoid nlist set to 0
        return 1;
    } else if (int(size / TYPICAL_COUNT) * nlist <= 0) {
        // calculate a proper nlist if nlist not specified or size less than TYPICAL_COUNT
        return int(size / TYPICAL_COUNT * 16384);
    }
    return nlist;
}

X
xiaojun.lin 已提交
207
knowhere::Config
S
starlord 已提交
208
NSGConfAdapter::Match(const TempMetaConf& metaconf) {
X
xiaojun.lin 已提交
209
    auto conf = std::make_shared<knowhere::NSGCfg>();
G
groot 已提交
210
    conf->nlist = MatchNlist(metaconf.size, metaconf.nlist, 16384);
X
xiaojun.lin 已提交
211 212
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
X
xiaojun.lin 已提交
213 214
    conf->gpu_id = metaconf.gpu_id;
    conf->k = metaconf.k;
X
xiaojun.lin 已提交
215 216 217

    auto scale_factor = round(metaconf.dim / 128.0);
    scale_factor = scale_factor >= 4 ? 4 : scale_factor;
X
xiaojun.lin 已提交
218
    conf->nprobe = int64_t(conf->nlist * 0.01);
X
xiaojun.lin 已提交
219
    //    conf->knng = 40 + 10 * scale_factor;  // the size of knng
X
xiaojun.lin 已提交
220 221
    conf->knng = 50;
    conf->search_length = 50 + 5 * scale_factor;
X
xiaojun.lin 已提交
222
    conf->out_degree = 50 + 5 * scale_factor;
X
xiaojun.lin 已提交
223
    conf->candidate_pool_size = 300;
X
xiaojun.lin 已提交
224 225 226 227 228
    MatchBase(conf);
    return conf;
}

knowhere::Config
S
starlord 已提交
229
NSGConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) {
X
xiaojun.lin 已提交
230 231 232
    auto conf = std::make_shared<knowhere::NSGCfg>();
    conf->k = metaconf.k;
    conf->search_length = metaconf.search_length;
Z
zirui.chen 已提交
233 234 235
    if (metaconf.search_length == TEMPMETA_DEFAULT_VALUE) {
        conf->search_length = 30;  // TODO(linxj): hardcode here.
    }
X
xiaojun.lin 已提交
236 237 238
    return conf;
}

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
knowhere::Config
SPTAGKDTConfAdapter::Match(const TempMetaConf& metaconf) {
    auto conf = std::make_shared<knowhere::KDTCfg>();
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
    return conf;
}

knowhere::Config
SPTAGKDTConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) {
    auto conf = std::make_shared<knowhere::KDTCfg>();
    conf->k = metaconf.k;
    return conf;
}

knowhere::Config
SPTAGBKTConfAdapter::Match(const TempMetaConf& metaconf) {
    auto conf = std::make_shared<knowhere::BKTCfg>();
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
    return conf;
}

knowhere::Config
SPTAGBKTConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) {
    auto conf = std::make_shared<knowhere::BKTCfg>();
    conf->k = metaconf.k;
    return conf;
}

G
groot 已提交
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
knowhere::Config
BinIDMAPConfAdapter::Match(const TempMetaConf& metaconf) {
    auto conf = std::make_shared<knowhere::BinIDMAPCfg>();
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
    conf->gpu_id = metaconf.gpu_id;
    conf->k = metaconf.k;
    MatchBase(conf, knowhere::METRICTYPE::HAMMING);
    return conf;
}

knowhere::Config
BinIVFConfAdapter::Match(const TempMetaConf& metaconf) {
    auto conf = std::make_shared<knowhere::IVFBinCfg>();
    conf->nlist = MatchNlist(metaconf.size, metaconf.nlist, 2048);
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
    conf->gpu_id = metaconf.gpu_id;
    MatchBase(conf, knowhere::METRICTYPE::HAMMING);
    return conf;
}
S
starlord 已提交
290 291
}  // namespace engine
}  // namespace milvus