-
Notifications
You must be signed in to change notification settings - Fork 222
[WIP] Vpq dataset serialisation #2480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
8b17608
f4e2e84
f24e9e3
bc6190f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2252,7 +2252,7 @@ void search( | |
| * @{ | ||
| */ | ||
|
|
||
| /** Dense dataset storage kind recorded in a serialized CAGRA index. */ | ||
| /** Dataset storage kind recorded in a serialized CAGRA index. */ | ||
| enum class serialized_dataset_kind : std::uint32_t { | ||
| /** The serialized index does not contain a dataset payload. */ | ||
| none = 0, | ||
|
|
@@ -2264,16 +2264,19 @@ enum class serialized_dataset_kind : std::uint32_t { | |
| host_padded = 3, | ||
| /** Host-resident dataset using its standard row layout. */ | ||
| host_standard = 4, | ||
| /** Device-resident VPQ-compressed dataset with f16 codebooks (CAGRA-Q). */ | ||
| device_vpq_f16 = 5, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we're adding new things, please rename to |
||
| }; | ||
|
|
||
| /** Current experimental CAGRA serialization format version. */ | ||
| inline constexpr int cagra_serialization_version = 6; | ||
|
|
||
| // Serialize and deserialize are overloaded for device/host and padded/standard dense indexes. | ||
| // They use the same strided dataset payload; the serialized dataset kind selects the matching | ||
| // owning dataset type during deserialization. To support a new dataset kind (e.g. vpq_f16_index), | ||
| // add matching overloads here and a corresponding deserialize_<kind> in | ||
| // detail/dataset_serialize.hpp (dense views use serialize_cagra_dense_dataset). | ||
| // Serialize and deserialize are overloaded for device/host and padded/standard dense indexes, | ||
| // which share the same strided dataset payload, and for vpq_f16_index, which writes a VPQ payload | ||
| // instead. The serialized dataset kind selects the matching owning dataset type during | ||
| // deserialization. To support a further kind, add matching overloads here and a corresponding | ||
| // serialize_/deserialize_<kind> in detail/dataset_serialize.hpp (dense views use | ||
| // serialize_cagra_dense_dataset, VPQ ones serialize_vpq_dataset). | ||
|
|
||
| /** | ||
| * Save the index to file. | ||
|
|
@@ -2824,6 +2827,106 @@ void deserialize(raft::resources const& handle, | |
| std::unique_ptr<cuvs::neighbors::device_standard_dataset<uint8_t, int64_t>>* | ||
| out_dataset = nullptr); | ||
|
|
||
| /* vpq_f16_index overloads (CAGRA-Q). | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| * | ||
| * The compressed rows travel with the index, so that a deserialized index can be searched without | ||
| * the dense dataset it was compressed from and without retraining the codebooks. As everywhere | ||
| * else, the index holds a view: `deserialize` returns the owning dataset through `out_dataset`, | ||
| * which the caller has to keep alive for as long as the index is used. | ||
| * | ||
| * Unlike the dense overloads, `out_dataset` is required. Nothing can be searched in a VPQ index | ||
| * whose rows were dropped, so there is no use for a graph-only load, and asking for one is an | ||
| * error rather than a silently unusable index. For the same reason `include_dataset = false` | ||
| * produces an index that only `update_dataset` can make searchable again. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use proper doxygen tags to denote which arguments are inputs and outputs. |
||
| */ | ||
| void serialize(raft::resources const& handle, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Order of argument should be handle, params (if applicable), input, output.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see the other functions did not follow the proper order. Let's at least make sure the new functions are in the proper order (we can have someone update the others in a follow-up). |
||
| const std::string& filename, | ||
| const cuvs::neighbors::cagra::vpq_f16_index<float>& index, | ||
| bool include_dataset = true); | ||
|
|
||
| void deserialize( | ||
| raft::resources const& handle, | ||
| const std::string& filename, | ||
| cuvs::neighbors::cagra::vpq_f16_index<float>* index, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please make the output dataset optional. The graph does not need to be deserialized with the vectors and we should not enforce this. Also- we would like to not require the dataset be known up front wen the user is deserializing a graph that might happen to have a dataset. Goal is to have it deserialize to some dataset owned by the user, but the user shouldn't have to care about its concrete type. In the C layer, we play to make this even more abstract. |
||
| std::unique_ptr<cuvs::neighbors::device_vpq_dataset<half, int64_t>>* out_dataset); | ||
|
|
||
| void serialize(raft::resources const& handle, | ||
| std::ostream& os, | ||
| const cuvs::neighbors::cagra::vpq_f16_index<float>& index, | ||
| bool include_dataset = true); | ||
|
|
||
| void deserialize( | ||
| raft::resources const& handle, | ||
| std::istream& is, | ||
| cuvs::neighbors::cagra::vpq_f16_index<float>* index, | ||
| std::unique_ptr<cuvs::neighbors::device_vpq_dataset<half, int64_t>>* out_dataset); | ||
|
|
||
| void serialize(raft::resources const& handle, | ||
| const std::string& filename, | ||
| const cuvs::neighbors::cagra::vpq_f16_index<half>& index, | ||
| bool include_dataset = true); | ||
|
|
||
| void deserialize( | ||
| raft::resources const& handle, | ||
| const std::string& filename, | ||
| cuvs::neighbors::cagra::vpq_f16_index<half>* index, | ||
| std::unique_ptr<cuvs::neighbors::device_vpq_dataset<half, int64_t>>* out_dataset); | ||
|
|
||
| void serialize(raft::resources const& handle, | ||
| std::ostream& os, | ||
| const cuvs::neighbors::cagra::vpq_f16_index<half>& index, | ||
| bool include_dataset = true); | ||
|
|
||
| void deserialize( | ||
| raft::resources const& handle, | ||
| std::istream& is, | ||
| cuvs::neighbors::cagra::vpq_f16_index<half>* index, | ||
| std::unique_ptr<cuvs::neighbors::device_vpq_dataset<half, int64_t>>* out_dataset); | ||
|
|
||
| void serialize(raft::resources const& handle, | ||
| const std::string& filename, | ||
| const cuvs::neighbors::cagra::vpq_f16_index<int8_t>& index, | ||
| bool include_dataset = true); | ||
|
|
||
| void deserialize( | ||
| raft::resources const& handle, | ||
| const std::string& filename, | ||
| cuvs::neighbors::cagra::vpq_f16_index<int8_t>* index, | ||
| std::unique_ptr<cuvs::neighbors::device_vpq_dataset<half, int64_t>>* out_dataset); | ||
|
|
||
| void serialize(raft::resources const& handle, | ||
| std::ostream& os, | ||
| const cuvs::neighbors::cagra::vpq_f16_index<int8_t>& index, | ||
| bool include_dataset = true); | ||
|
|
||
| void deserialize( | ||
| raft::resources const& handle, | ||
| std::istream& is, | ||
| cuvs::neighbors::cagra::vpq_f16_index<int8_t>* index, | ||
| std::unique_ptr<cuvs::neighbors::device_vpq_dataset<half, int64_t>>* out_dataset); | ||
|
|
||
| void serialize(raft::resources const& handle, | ||
| const std::string& filename, | ||
| const cuvs::neighbors::cagra::vpq_f16_index<uint8_t>& index, | ||
| bool include_dataset = true); | ||
|
|
||
| void deserialize( | ||
| raft::resources const& handle, | ||
| const std::string& filename, | ||
| cuvs::neighbors::cagra::vpq_f16_index<uint8_t>* index, | ||
| std::unique_ptr<cuvs::neighbors::device_vpq_dataset<half, int64_t>>* out_dataset); | ||
|
|
||
| void serialize(raft::resources const& handle, | ||
| std::ostream& os, | ||
| const cuvs::neighbors::cagra::vpq_f16_index<uint8_t>& index, | ||
| bool include_dataset = true); | ||
|
|
||
| void deserialize( | ||
| raft::resources const& handle, | ||
| std::istream& is, | ||
| cuvs::neighbors::cagra::vpq_f16_index<uint8_t>* index, | ||
| std::unique_ptr<cuvs::neighbors::device_vpq_dataset<half, int64_t>>* out_dataset); | ||
|
|
||
| /** @copydoc serialize */ | ||
| void serialize(raft::resources const& handle, | ||
| const std::string& filename, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not an acceptable way to handle things tha are not yet exposed to C. Folks use C because they have to (for C ABI stability guarantees, for example). We can't just throw an error and forward them to C++