ConfAdapter.cpp 10.1 KB
Newer Older
1
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
X
xiaojun.lin 已提交
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
X
xiaojun.lin 已提交
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.
X
xiaojun.lin 已提交
11

S
starlord 已提交
12
#include "wrapper/ConfAdapter.h"
X
xiaojun.lin 已提交
13

S
shengjh 已提交
14
#include <fiu-local.h>
X
xiaojun.lin 已提交
15
#include <cmath>
S
starlord 已提交
16
#include <memory>
X
xiaojun.lin 已提交
17
#include <vector>
X
xiaojun.lin 已提交
18

T
Tinkerrr 已提交
19 20 21 22 23
#include "WrapperException.h"
#include "knowhere/index/vector_index/helpers/IndexParameter.h"
#include "server/Config.h"
#include "utils/Log.h"

S
starlord 已提交
24
// TODO(lxj): add conf checker
X
xiaojun.lin 已提交
25 26 27 28 29 30 31 32 33 34 35

namespace milvus {
namespace engine {

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

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

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

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

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

static constexpr float TYPICAL_COUNT = 1000000.0;

int64_t
G
groot 已提交
73 74
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 已提交
75 76
        // handle less row count, avoid nlist set to 0
        return 1;
Z
zirui.chen 已提交
77
    } else if (int(size / TYPICAL_COUNT) * nlist <= 0) {
X
xiaojun.lin 已提交
78
        // calculate a proper nlist if nlist not specified or size less than TYPICAL_COUNT
G
groot 已提交
79
        return int(size / TYPICAL_COUNT * per_nlist);
X
xiaojun.lin 已提交
80
    }
81
    return nlist;
X
xiaojun.lin 已提交
82 83 84
}

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

    if (metaconf.nprobe <= 0)
        conf->nprobe = 16;  // hardcode here
    else
        conf->nprobe = metaconf.nprobe;
X
xiaojun.lin 已提交
93 94 95 96 97 98 99

    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 已提交
100 101
                                    << ", but you passed " << conf->nprobe << ". Search with " << GPU_MAX_NRPOBE
                                    << " instead";
X
xiaojun.lin 已提交
102 103 104 105 106 107 108
                conf->nprobe = GPU_MAX_NRPOBE;
            }
    }
    return conf;
}

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

knowhere::Config
S
starlord 已提交
121
IVFPQConfAdapter::Match(const TempMetaConf& metaconf) {
X
xiaojun.lin 已提交
122 123 124 125
    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 已提交
126
    conf->gpu_id = metaconf.gpu_id;
X
xiaojun.lin 已提交
127 128
    conf->nbits = 8;
    MatchBase(conf);
X
xiaojun.lin 已提交
129

130 131 132 133 134 135 136 137 138 139 140
#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 已提交
141 142
    /*
     * Faiss 1.6
143
     * 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 已提交
144 145
     * no precomputed codes. Precomputed codes supports any number of dimensions, but will involve memory overheads.
     */
X
update  
xiaojun.lin 已提交
146 147 148 149 150 151 152 153 154 155
    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 已提交
156
        }
X
xiaojun.lin 已提交
157
    }
S
shengjh 已提交
158
    fiu_do_on("IVFPQConfAdapter.Match.empty_resset", resset.clear());
X
update  
xiaojun.lin 已提交
159 160
    if (resset.empty()) {
        // todo(linxj): throw exception here.
161 162
        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.";
163 164 165
        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.");
166
        // return nullptr;
X
update  
xiaojun.lin 已提交
167
    }
T
Tinkerrr 已提交
168
    static int64_t compression_level = 1;  // 1:low, 2:high
X
update  
xiaojun.lin 已提交
169
    if (compression_level == 1) {
T
Tinkerrr 已提交
170 171
        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 已提交
172 173
    }
    return conf;
X
xiaojun.lin 已提交
174 175
}

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

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

    return conf;
}

Z
zirui.chen 已提交
191 192 193 194 195 196 197 198 199 200 201 202
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 已提交
203
knowhere::Config
S
starlord 已提交
204
NSGConfAdapter::Match(const TempMetaConf& metaconf) {
X
xiaojun.lin 已提交
205
    auto conf = std::make_shared<knowhere::NSGCfg>();
G
groot 已提交
206
    conf->nlist = MatchNlist(metaconf.size, metaconf.nlist, 16384);
X
xiaojun.lin 已提交
207 208
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;
X
xiaojun.lin 已提交
209 210
    conf->gpu_id = metaconf.gpu_id;
    conf->k = metaconf.k;
X
xiaojun.lin 已提交
211 212 213

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

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

235 236 237 238 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
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;
}

T
Tinkerrr 已提交
265 266 267 268 269 270
knowhere::Config
HNSWConfAdapter::Match(const TempMetaConf& metaconf) {
    auto conf = std::make_shared<knowhere::HNSWCfg>();
    conf->d = metaconf.dim;
    conf->metric_type = metaconf.metric_type;

T
Tinkerrr 已提交
271 272
    conf->ef = 200;  // ef can be auto-configured by using sample data.
    conf->M = 32;    // A reasonable range of M is from 5 to 48.
T
Tinkerrr 已提交
273 274 275
    return conf;
}

G
groot 已提交
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
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 已提交
297 298
}  // namespace engine
}  // namespace milvus