test_idmap.cpp 7.0 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.

X
xj.lin 已提交
18 19 20
#include <gtest/gtest.h>
#include <iostream>

X
xiaojun.lin 已提交
21 22
#include "knowhere/adapter/Structure.h"
#include "knowhere/common/Exception.h"
S
starlord 已提交
23 24 25
#include "knowhere/index/vector_index/IndexIDMAP.h"
#include "knowhere/index/vector_index/helpers/Cloner.h"

26
#include "unittest/utils.h"
X
xj.lin 已提交
27

28
static int device_id = 0;
X
xj.lin 已提交
29 30
class IDMAPTest : public DataGen, public ::testing::Test {
 protected:
S
starlord 已提交
31 32
    void
    SetUp() override {
S
starlord 已提交
33
        knowhere::FaissGpuResourceMgr::GetInstance().InitDevice(device_id, 1024 * 1024 * 200, 1024 * 1024 * 300, 2);
X
xj.lin 已提交
34
        Init_with_default();
S
starlord 已提交
35
        index_ = std::make_shared<knowhere::IDMAP>();
X
xj.lin 已提交
36
    }
37

S
starlord 已提交
38 39
    void
    TearDown() override {
S
starlord 已提交
40
        knowhere::FaissGpuResourceMgr::GetInstance().Free();
41 42
    }

X
xj.lin 已提交
43
 protected:
S
starlord 已提交
44
    knowhere::IDMAPPtr index_ = nullptr;
X
xj.lin 已提交
45 46
};

S
starlord 已提交
47
void
S
starlord 已提交
48
AssertAnns(const knowhere::DatasetPtr& result, const int& nq, const int& k) {
X
xj.lin 已提交
49 50 51 52 53 54
    auto ids = result->array()[0];
    for (auto i = 0; i < nq; i++) {
        EXPECT_EQ(i, *(ids->data()->GetValues<int64_t>(1, i * k)));
    }
}

S
starlord 已提交
55
void
S
starlord 已提交
56
PrintResult(const knowhere::DatasetPtr& result, const int& nq, const int& k) {
X
xj.lin 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    auto ids = result->array()[0];
    auto dists = result->array()[1];

    std::stringstream ss_id;
    std::stringstream ss_dist;
    for (auto i = 0; i < 10; i++) {
        for (auto j = 0; j < k; ++j) {
            ss_id << *(ids->data()->GetValues<int64_t>(1, i * k + j)) << " ";
            ss_dist << *(dists->data()->GetValues<float>(1, i * k + j)) << " ";
        }
        ss_id << std::endl;
        ss_dist << std::endl;
    }
    std::cout << "id\n" << ss_id.str() << std::endl;
    std::cout << "dist\n" << ss_dist.str() << std::endl;
}

TEST_F(IDMAPTest, idmap_basic) {
X
xj.lin 已提交
75
    ASSERT_TRUE(!xb.empty());
X
xj.lin 已提交
76

S
starlord 已提交
77
    auto conf = std::make_shared<knowhere::Cfg>();
X
xiaojun.lin 已提交
78 79
    conf->d = dim;
    conf->k = k;
S
starlord 已提交
80
    conf->metric_type = knowhere::METRICTYPE::L2;
X
xiaojun.lin 已提交
81 82 83

    index_->Train(conf);
    index_->Add(base_dataset, conf);
X
xj.lin 已提交
84 85
    EXPECT_EQ(index_->Count(), nb);
    EXPECT_EQ(index_->Dimension(), dim);
X
xj.lin 已提交
86 87
    ASSERT_TRUE(index_->GetRawVectors() != nullptr);
    ASSERT_TRUE(index_->GetRawIds() != nullptr);
X
xiaojun.lin 已提交
88
    auto result = index_->Search(query_dataset, conf);
X
xj.lin 已提交
89 90 91
    AssertAnns(result, nq, k);
    PrintResult(result, nq, k);

X
xj.lin 已提交
92
    index_->Seal();
X
xj.lin 已提交
93
    auto binaryset = index_->Serialize();
S
starlord 已提交
94
    auto new_index = std::make_shared<knowhere::IDMAP>();
X
xj.lin 已提交
95
    new_index->Load(binaryset);
X
xiaojun.lin 已提交
96
    auto re_result = index_->Search(query_dataset, conf);
X
xj.lin 已提交
97 98 99 100 101
    AssertAnns(re_result, nq, k);
    PrintResult(re_result, nq, k);
}

TEST_F(IDMAPTest, idmap_serialize) {
S
starlord 已提交
102
    auto serialize = [](const std::string& filename, knowhere::BinaryPtr& bin, uint8_t* ret) {
X
xj.lin 已提交
103
        FileIOWriter writer(filename);
S
starlord 已提交
104
        writer(static_cast<void*>(bin->data.get()), bin->size);
X
xj.lin 已提交
105 106 107 108 109

        FileIOReader reader(filename);
        reader(ret, bin->size);
    };

S
starlord 已提交
110
    auto conf = std::make_shared<knowhere::Cfg>();
X
xiaojun.lin 已提交
111 112
    conf->d = dim;
    conf->k = k;
S
starlord 已提交
113
    conf->metric_type = knowhere::METRICTYPE::L2;
X
xiaojun.lin 已提交
114

X
xj.lin 已提交
115 116
    {
        // serialize index
X
xiaojun.lin 已提交
117
        index_->Train(conf);
S
starlord 已提交
118
        index_->Add(base_dataset, knowhere::Config());
X
xiaojun.lin 已提交
119
        auto re_result = index_->Search(query_dataset, conf);
X
xj.lin 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
        AssertAnns(re_result, nq, k);
        PrintResult(re_result, nq, k);
        EXPECT_EQ(index_->Count(), nb);
        EXPECT_EQ(index_->Dimension(), dim);
        auto binaryset = index_->Serialize();
        auto bin = binaryset.GetByName("IVF");

        std::string filename = "/tmp/idmap_test_serialize.bin";
        auto load_data = new uint8_t[bin->size];
        serialize(filename, bin, load_data);

        binaryset.clear();
        auto data = std::make_shared<uint8_t>();
        data.reset(load_data);
        binaryset.Append("IVF", data, bin->size);

        index_->Load(binaryset);
        EXPECT_EQ(index_->Count(), nb);
        EXPECT_EQ(index_->Dimension(), dim);
X
xiaojun.lin 已提交
139
        auto result = index_->Search(query_dataset, conf);
X
xj.lin 已提交
140 141 142 143 144 145
        AssertAnns(result, nq, k);
        PrintResult(result, nq, k);
    }
}

TEST_F(IDMAPTest, copy_test) {
X
xj.lin 已提交
146
    ASSERT_TRUE(!xb.empty());
X
xj.lin 已提交
147

S
starlord 已提交
148
    auto conf = std::make_shared<knowhere::Cfg>();
X
xiaojun.lin 已提交
149 150
    conf->d = dim;
    conf->k = k;
S
starlord 已提交
151
    conf->metric_type = knowhere::METRICTYPE::L2;
X
xiaojun.lin 已提交
152 153 154

    index_->Train(conf);
    index_->Add(base_dataset, conf);
X
xj.lin 已提交
155 156
    EXPECT_EQ(index_->Count(), nb);
    EXPECT_EQ(index_->Dimension(), dim);
X
xj.lin 已提交
157 158
    ASSERT_TRUE(index_->GetRawVectors() != nullptr);
    ASSERT_TRUE(index_->GetRawIds() != nullptr);
X
xiaojun.lin 已提交
159
    auto result = index_->Search(query_dataset, conf);
X
xj.lin 已提交
160
    AssertAnns(result, nq, k);
S
starlord 已提交
161
    // PrintResult(result, nq, k);
X
xj.lin 已提交
162 163 164 165

    {
        // clone
        auto clone_index = index_->Clone();
X
xiaojun.lin 已提交
166
        auto clone_result = clone_index->Search(query_dataset, conf);
X
xj.lin 已提交
167 168 169 170 171
        AssertAnns(clone_result, nq, k);
    }

    {
        // cpu to gpu
S
starlord 已提交
172
        auto clone_index = knowhere::cloner::CopyCpuToGpu(index_, device_id, conf);
X
xiaojun.lin 已提交
173
        auto clone_result = clone_index->Search(query_dataset, conf);
X
xj.lin 已提交
174
        AssertAnns(clone_result, nq, k);
S
starlord 已提交
175
        ASSERT_THROW({ std::static_pointer_cast<knowhere::GPUIDMAP>(clone_index)->GetRawVectors(); },
S
starlord 已提交
176
                     knowhere::KnowhereException);
S
starlord 已提交
177
        ASSERT_THROW({ std::static_pointer_cast<knowhere::GPUIDMAP>(clone_index)->GetRawIds(); },
S
starlord 已提交
178
                     knowhere::KnowhereException);
X
xj.lin 已提交
179 180 181

        auto binary = clone_index->Serialize();
        clone_index->Load(binary);
X
xiaojun.lin 已提交
182
        auto new_result = clone_index->Search(query_dataset, conf);
X
xj.lin 已提交
183 184
        AssertAnns(new_result, nq, k);

X
xj.lin 已提交
185
        auto clone_gpu_idx = clone_index->Clone();
X
xiaojun.lin 已提交
186
        auto clone_gpu_res = clone_gpu_idx->Search(query_dataset, conf);
X
xj.lin 已提交
187 188 189
        AssertAnns(clone_gpu_res, nq, k);

        // gpu to cpu
S
starlord 已提交
190
        auto host_index = knowhere::cloner::CopyGpuToCpu(clone_index, conf);
X
xiaojun.lin 已提交
191
        auto host_result = host_index->Search(query_dataset, conf);
X
xj.lin 已提交
192
        AssertAnns(host_result, nq, k);
S
starlord 已提交
193 194
        ASSERT_TRUE(std::static_pointer_cast<knowhere::IDMAP>(host_index)->GetRawVectors() != nullptr);
        ASSERT_TRUE(std::static_pointer_cast<knowhere::IDMAP>(host_index)->GetRawIds() != nullptr);
X
xj.lin 已提交
195 196

        // gpu to gpu
S
starlord 已提交
197 198 199
        auto device_index = knowhere::cloner::CopyCpuToGpu(index_, device_id, conf);
        auto new_device_index =
            std::static_pointer_cast<knowhere::GPUIDMAP>(device_index)->CopyGpuToGpu(device_id, conf);
X
xiaojun.lin 已提交
200
        auto device_result = new_device_index->Search(query_dataset, conf);
X
xj.lin 已提交
201 202 203
        AssertAnns(device_result, nq, k);
    }
}