-
Notifications
You must be signed in to change notification settings - Fork 940
Add 8-bit scalar quantization support for IVF index.
#231
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
Open
bohanliu5
wants to merge
1
commit into
pgvector:master
Choose a base branch
from
bohanliu5:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| #include "ivf_list.h" | ||
|
|
||
| #include "metadata.h" | ||
|
|
||
| /* PG C headers */ | ||
| #include "c.h" | ||
| #include "common/relpath.h" | ||
| #include "pg_config.h" | ||
| #include "utils/relcache.h" | ||
|
|
||
| IvfListV2 CreateIvfListV2(Relation rel, Metadata *metadata, bool external, | ||
| ForkNumber fork_num, size_t *list_size) | ||
| { | ||
| IvfListV2 list; | ||
| Metadata *list_metadata = metadata; | ||
| size_t metadata_size = | ||
| external ? EXTERNAL_METADATA_SIZE : VARSIZE_ANY(metadata); | ||
|
|
||
| Assert(!VARATT_IS_EXTERNAL(metadata)); | ||
| *list_size = offsetof(IvfListDataV2, metadata) + metadata_size; | ||
|
|
||
| list = (IvfListV2)palloc0(*list_size); | ||
| list->startPage = InvalidBlockNumber; | ||
| list->insertPage = InvalidBlockNumber; | ||
| list->unused = 0UL; | ||
| if (external) | ||
| { | ||
| list_metadata = WriteMetadata(rel, metadata, fork_num); | ||
| Assert(VARATT_IS_EXTERNAL(list_metadata)); | ||
| Assert(((ExternalMetadata *)list_metadata)->length == | ||
| (VARSIZE_ANY_EXHDR(metadata))); | ||
| } | ||
|
|
||
| memcpy(&list->metadata, list_metadata, metadata_size); | ||
| return list; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| #ifndef PGVECTOR_SRC_COMMON_IVF_LIST_H_ | ||
| #define PGVECTOR_SRC_COMMON_IVF_LIST_H_ | ||
|
|
||
| #include "postgres.h" | ||
|
|
||
| #include "storage/block.h" | ||
| #include "common/relpath.h" | ||
| #include "utils/relcache.h" | ||
|
|
||
| #include "metadata.h" | ||
|
|
||
| /* | ||
| * Partition ("list") metadata. It stores the location of its leaf pages | ||
| * (`start_page`), the location to insert new data into leaf pages | ||
| * (`insert_page`), together with some user defined metadata. | ||
| * | ||
| * STORAGE FORMAT | ||
| * -------------------------------------------------------- | ||
| * | start_page(4) | insert_page(4) | metadata (varlena) | | ||
| * -------------------------------------------------------- | ||
| */ | ||
| typedef struct IvfListDataV1 | ||
| { | ||
| BlockNumber startPage; | ||
| BlockNumber insertPage; | ||
| /* Inline or externalized storage. */ | ||
| Metadata metadata; | ||
| } IvfListDataV1; | ||
|
|
||
| typedef IvfListDataV1 *IvfListV1; | ||
|
|
||
| /* | ||
| * Similar to the above but added 8-bytes `unused` space for future use. | ||
| * Note that the newly built indexes are forced to use this format. | ||
| */ | ||
| typedef struct IvfListDataV2 | ||
| { | ||
| BlockNumber startPage; | ||
| BlockNumber insertPage; | ||
| uint64_t unused; | ||
| // Inline or externalized storage. | ||
| Metadata metadata; | ||
| } IvfListDataV2; | ||
|
|
||
| typedef IvfListDataV2 *IvfListV2; | ||
|
|
||
| #define IVF_LIST_GET_START_PAGE(item, version) \ | ||
| (((version) == 1) ? ((IvfListV1)(item))->startPage \ | ||
| : ((IvfListV2)(item))->startPage) | ||
|
|
||
| #define IVF_LIST_SET_START_PAGE(item, version, startPage) \ | ||
| do \ | ||
| { \ | ||
| if ((version) == 1) \ | ||
| ((IvfListV1)(item))->startPage = startPage; \ | ||
| else \ | ||
| ((IvfListV2)(item))->startPage = startPage; \ | ||
| } while (0); | ||
|
|
||
| #define IVF_LIST_SET_INSERT_PAGE(item, version, insertPage) \ | ||
| do \ | ||
| { \ | ||
| if ((version) == 1) \ | ||
| ((IvfListV1)(item))->insertPage = insertPage; \ | ||
| else \ | ||
| ((IvfListV2)(item))->insertPage = insertPage; \ | ||
| } while (0); | ||
|
|
||
| #define IVF_LIST_GET_INSERT_PAGE(item, version) \ | ||
| (((version) == 1) ? ((IvfListV1)(item))->insertPage \ | ||
| : ((IvfListV2)(item))->insertPage) | ||
|
|
||
| #define IVF_LIST_GET_METADATA(item, version) \ | ||
| (((version) == 1) ? &((IvfListV1)(item))->metadata \ | ||
| : &((IvfListV2)(item))->metadata) | ||
|
|
||
| /* | ||
| * Creates `IvfListV2` structure from `metadata`. The input `metadata` should be inlined. | ||
| * When `external` is `true`, it writes the `metadata` into external pages and an | ||
| * `ExternalMetadata` is written into the structure, otherwise, the `metadata` is copied | ||
| * into the result. | ||
| * RETURNS: `IvfListV2` structure on the heap with its size `list_size`. | ||
| */ | ||
| IvfListV2 CreateIvfListV2(Relation rel, Metadata *metadata, bool external, | ||
| ForkNumber fork_num, size_t *list_size); | ||
|
|
||
| #endif /* PGVECTOR_SRC_COMMON_IVF_LIST_H_ */ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Why is this implemented as a new index access method instead of as an option on the existing ivfflat code? Having it as an existing option would make it simpler for users to manage their indexes.
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.
We discussed this with @ankane. Our understanding is that
flatmeans no encoding - here are some examples from Milvus and Faiss and it would be good to be consistent.Agree that we should make it simpler for users to use. We think
ivfwith anquantizeroption would provide more flexibility - we could also supportivf WITH (quantizer = 'flat')if needed.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.
OR as another examples
That said, given
ivfflatindex AM is out there, we do need to be careful about introducing new access methods. Effectively we need to treativfflatas if it's not going away. Maybeivfbecomes the preferred choice when creating an IVF index and the default is to leverage theivfflatinfrastructure.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.
We discussed the same proposal with @ankane as well. I can update the PR to support
quantizer='flat', aliasing toivfflat. +1 on usingivfas the preferred choice.