VecIndex.cpp 8.1 KB
Newer Older
J
jinhai 已提交
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.

G
groot 已提交
18
#include "wrapper/VecIndex.h"
G
groot 已提交
19 20
#include "VecImpl.h"
#include "knowhere/common/Exception.h"
X
xiaojun.lin 已提交
21
#include "knowhere/index/vector_index/IndexGPUIVF.h"
X
xiaojun.lin 已提交
22
#include "knowhere/index/vector_index/IndexGPUIVFPQ.h"
G
groot 已提交
23
#include "knowhere/index/vector_index/IndexGPUIVFSQ.h"
X
xiaojun.lin 已提交
24
#include "knowhere/index/vector_index/IndexIDMAP.h"
G
groot 已提交
25 26 27
#include "knowhere/index/vector_index/IndexIVF.h"
#include "knowhere/index/vector_index/IndexIVFPQ.h"
#include "knowhere/index/vector_index/IndexIVFSQ.h"
X
xiaojun.lin 已提交
28 29
#include "knowhere/index/vector_index/IndexKDT.h"
#include "knowhere/index/vector_index/IndexNSG.h"
G
groot 已提交
30
#include "utils/Log.h"
X
MS-154  
xj.lin 已提交
31

32 33
#include <cuda.h>

X
MS-154  
xj.lin 已提交
34
namespace zilliz {
X
xj.lin 已提交
35
namespace milvus {
X
MS-154  
xj.lin 已提交
36 37
namespace engine {

X
xj.lin 已提交
38 39 40 41
struct FileIOReader {
    std::fstream fs;
    std::string name;

G
groot 已提交
42
    explicit FileIOReader(const std::string& fname);
43

X
xj.lin 已提交
44
    ~FileIOReader();
45 46

    size_t
G
groot 已提交
47
    operator()(void* ptr, size_t size);
48 49

    size_t
G
groot 已提交
50
    operator()(void* ptr, size_t size, size_t pos);
X
xj.lin 已提交
51 52
};

G
groot 已提交
53
FileIOReader::FileIOReader(const std::string& fname) {
X
xj.lin 已提交
54 55 56 57 58 59 60 61
    name = fname;
    fs = std::fstream(name, std::ios::in | std::ios::binary);
}

FileIOReader::~FileIOReader() {
    fs.close();
}

62
size_t
G
groot 已提交
63 64
FileIOReader::operator()(void* ptr, size_t size) {
    fs.read(reinterpret_cast<char*>(ptr), size);
X
xj.lin 已提交
65 66
}

67
size_t
G
groot 已提交
68
FileIOReader::operator()(void* ptr, size_t size, size_t pos) {
X
xj.lin 已提交
69 70 71
    return 0;
}

72 73 74 75
struct FileIOWriter {
    std::fstream fs;
    std::string name;

G
groot 已提交
76
    explicit FileIOWriter(const std::string& fname);
77
    ~FileIOWriter();
G
groot 已提交
78 79
    size_t
    operator()(void* ptr, size_t size);
80 81
};

G
groot 已提交
82
FileIOWriter::FileIOWriter(const std::string& fname) {
X
xj.lin 已提交
83 84 85 86 87 88 89 90
    name = fname;
    fs = std::fstream(name, std::ios::out | std::ios::binary);
}

FileIOWriter::~FileIOWriter() {
    fs.close();
}

91
size_t
G
groot 已提交
92 93
FileIOWriter::operator()(void* ptr, size_t size) {
    fs.write(reinterpret_cast<char*>(ptr), size);
X
xj.lin 已提交
94 95
}

96
VecIndexPtr
G
groot 已提交
97
GetVecIndexFactory(const IndexType& type, const Config& cfg) {
X
MS-154  
xj.lin 已提交
98
    std::shared_ptr<zilliz::knowhere::VectorIndex> index;
G
groot 已提交
99
    auto gpu_device = -1;  // TODO(linxj): remove hardcode here
X
xj.lin 已提交
100 101 102 103 104 105 106 107 108 109
    switch (type) {
        case IndexType::FAISS_IDMAP: {
            index = std::make_shared<zilliz::knowhere::IDMAP>();
            return std::make_shared<BFIndex>(index);
        }
        case IndexType::FAISS_IVFFLAT_CPU: {
            index = std::make_shared<zilliz::knowhere::IVF>();
            break;
        }
        case IndexType::FAISS_IVFFLAT_GPU: {
X
xj.lin 已提交
110
            index = std::make_shared<zilliz::knowhere::GPUIVF>(gpu_device);
X
xj.lin 已提交
111 112
            break;
        }
X
xj.lin 已提交
113
        case IndexType::FAISS_IVFFLAT_MIX: {
X
xiaojun.lin 已提交
114
            index = std::make_shared<zilliz::knowhere::GPUIVF>(gpu_device);
X
xj.lin 已提交
115
            return std::make_shared<IVFMixIndex>(index, IndexType::FAISS_IVFFLAT_MIX);
X
xj.lin 已提交
116
        }
X
xj.lin 已提交
117 118 119 120 121
        case IndexType::FAISS_IVFPQ_CPU: {
            index = std::make_shared<zilliz::knowhere::IVFPQ>();
            break;
        }
        case IndexType::FAISS_IVFPQ_GPU: {
X
xj.lin 已提交
122
            index = std::make_shared<zilliz::knowhere::GPUIVFPQ>(gpu_device);
X
xj.lin 已提交
123 124
            break;
        }
X
xj.lin 已提交
125 126 127
        case IndexType::SPTAG_KDT_RNT_CPU: {
            index = std::make_shared<zilliz::knowhere::CPUKDTRNG>();
            break;
X
xj.lin 已提交
128 129
        }
        case IndexType::FAISS_IVFSQ8_MIX: {
X
xj.lin 已提交
130
            index = std::make_shared<zilliz::knowhere::GPUIVFSQ>(gpu_device);
X
xj.lin 已提交
131
            return std::make_shared<IVFMixIndex>(index, IndexType::FAISS_IVFSQ8_MIX);
X
xj.lin 已提交
132
        }
X
xj.lin 已提交
133
        case IndexType::FAISS_IVFSQ8_CPU: {
W
wxyu 已提交
134 135 136
            index = std::make_shared<zilliz::knowhere::IVFSQ>();
            break;
        }
X
xj.lin 已提交
137 138 139 140
        case IndexType::FAISS_IVFSQ8_GPU: {
            index = std::make_shared<zilliz::knowhere::GPUIVFSQ>(gpu_device);
            break;
        }
141
        case IndexType::NSG_MIX: {
X
xj.lin 已提交
142
            index = std::make_shared<zilliz::knowhere::NSG>(gpu_device);
X
xj.lin 已提交
143 144
            break;
        }
G
groot 已提交
145
        default: { return nullptr; }
X
MS-154  
xj.lin 已提交
146
    }
X
xj.lin 已提交
147
    return std::make_shared<VecIndexImpl>(index, type);
X
MS-154  
xj.lin 已提交
148 149
}

150
VecIndexPtr
G
groot 已提交
151
LoadVecIndex(const IndexType& index_type, const zilliz::knowhere::BinarySet& index_binary) {
X
MS-154  
xj.lin 已提交
152 153 154 155 156
    auto index = GetVecIndexFactory(index_type);
    index->Load(index_binary);
    return index;
}

157
VecIndexPtr
G
groot 已提交
158
read_index(const std::string& location) {
X
xj.lin 已提交
159 160 161
    knowhere::BinarySet load_data_list;
    FileIOReader reader(location);
    reader.fs.seekg(0, reader.fs.end);
162
    int64_t length = reader.fs.tellg();
163
    if (length <= 0) {
164 165 166
        return nullptr;
    }

X
xj.lin 已提交
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
    reader.fs.seekg(0);

    size_t rp = 0;
    auto current_type = IndexType::INVALID;
    reader(&current_type, sizeof(current_type));
    rp += sizeof(current_type);
    while (rp < length) {
        size_t meta_length;
        reader(&meta_length, sizeof(meta_length));
        rp += sizeof(meta_length);
        reader.fs.seekg(rp);

        auto meta = new char[meta_length];
        reader(meta, meta_length);
        rp += meta_length;
        reader.fs.seekg(rp);

        size_t bin_length;
        reader(&bin_length, sizeof(bin_length));
        rp += sizeof(bin_length);
        reader.fs.seekg(rp);

        auto bin = new uint8_t[bin_length];
        reader(bin, bin_length);
        rp += bin_length;

        auto binptr = std::make_shared<uint8_t>();
        binptr.reset(bin);
        load_data_list.Append(std::string(meta, meta_length), binptr, bin_length);
196
        delete[] meta;
X
xj.lin 已提交
197 198 199 200 201
    }

    return LoadVecIndex(current_type, load_data_list);
}

202
Status
G
groot 已提交
203
write_index(VecIndexPtr index, const std::string& location) {
X
xj.lin 已提交
204 205 206 207 208 209
    try {
        auto binaryset = index->Serialize();
        auto index_type = index->GetType();

        FileIOWriter writer(location);
        writer(&index_type, sizeof(IndexType));
G
groot 已提交
210
        for (auto& iter : binaryset.binary_map_) {
X
xj.lin 已提交
211 212 213
            auto meta = iter.first.c_str();
            size_t meta_length = iter.first.length();
            writer(&meta_length, sizeof(meta_length));
G
groot 已提交
214
            writer((void*)meta, meta_length);
X
xj.lin 已提交
215 216 217 218

            auto binary = iter.second;
            int64_t binary_length = binary->size;
            writer(&binary_length, sizeof(binary_length));
G
groot 已提交
219
            writer((void*)binary->data.get(), binary_length);
X
xj.lin 已提交
220
        }
G
groot 已提交
221
    } catch (knowhere::KnowhereException& e) {
X
xj.lin 已提交
222
        WRAPPER_LOG_ERROR << e.what();
223
        return Status(KNOWHERE_UNEXPECTED_ERROR, e.what());
G
groot 已提交
224
    } catch (std::exception& e) {
X
xj.lin 已提交
225
        WRAPPER_LOG_ERROR << e.what();
226 227 228
        std::string estring(e.what());
        if (estring.find("No space left on device") != estring.npos) {
            WRAPPER_LOG_ERROR << "No space left on the device";
229
            return Status(KNOWHERE_NO_SPACE, "No space left on the device");
230
        } else {
231
            return Status(KNOWHERE_ERROR, e.what());
232
        }
X
xj.lin 已提交
233
    }
234
    return Status::OK();
X
xj.lin 已提交
235 236
}

237
IndexType
G
groot 已提交
238
ConvertToCpuIndexType(const IndexType& type) {
X
xj.lin 已提交
239
    // TODO(linxj): add IDMAP
W
wxyu 已提交
240
    switch (type) {
X
xj.lin 已提交
241
        case IndexType::FAISS_IVFFLAT_GPU:
W
wxyu 已提交
242 243 244
        case IndexType::FAISS_IVFFLAT_MIX: {
            return IndexType::FAISS_IVFFLAT_CPU;
        }
X
xj.lin 已提交
245
        case IndexType::FAISS_IVFSQ8_GPU:
W
wxyu 已提交
246
        case IndexType::FAISS_IVFSQ8_MIX: {
X
xj.lin 已提交
247
            return IndexType::FAISS_IVFSQ8_CPU;
W
wxyu 已提交
248
        }
G
groot 已提交
249
        default: { return type; }
W
wxyu 已提交
250 251 252
    }
}

253
IndexType
G
groot 已提交
254
ConvertToGpuIndexType(const IndexType& type) {
X
xj.lin 已提交
255 256 257 258 259 260 261 262 263
    switch (type) {
        case IndexType::FAISS_IVFFLAT_MIX:
        case IndexType::FAISS_IVFFLAT_CPU: {
            return IndexType::FAISS_IVFFLAT_GPU;
        }
        case IndexType::FAISS_IVFSQ8_MIX:
        case IndexType::FAISS_IVFSQ8_CPU: {
            return IndexType::FAISS_IVFSQ8_GPU;
        }
G
groot 已提交
264
        default: { return type; }
X
xj.lin 已提交
265 266 267
    }
}

G
groot 已提交
268 269 270
}  // namespace engine
}  // namespace milvus
}  // namespace zilliz