| 22 | , metric_(metric_from_string(metric)) {} |
| 23 | |
| 24 | void build(py::handle data, size_t ef_construction, size_t num_threads = 1) { |
| 25 | auto data_array = ensure_2d_array<float>(data, "data"); |
| 26 | if (static_cast<size_t>(data_array.shape(1)) != dim_) { |
| 27 | throw std::invalid_argument("data dimension does not match index dim"); |
| 28 | } |
| 29 | |
| 30 | num_points_ = static_cast<size_t>(data_array.shape(0)); |
| 31 | index_ = std::make_unique<rabitqlib::symqg::QuantizedGraph<float>>( |
| 32 | num_points_, dim_, max_degree_, metric_, rabitqlib::RotatorType::FhtKacRotator |
| 33 | ); |
| 34 | |
| 35 | rabitqlib::symqg::QGBuilder builder(*index_, ef_construction, data_array.data(), num_threads); |
| 36 | builder.build(); |
| 37 | built_ = true; |
| 38 | } |
| 39 | |
| 40 | py::tuple search(py::handle queries, size_t k, size_t ef, size_t num_threads = 1) { |
| 41 | auto query_array = ensure_2d_array<float>(queries, "queries"); |