Skip to content
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

[WIP] feature : add zero copy support for vector index #1032

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

foxspy
Copy link
Collaborator

@foxspy foxspy commented Jan 15, 2025

issue: #1031

@sre-ci-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: foxspy

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@foxspy foxspy changed the title feature : add zero copy support for vector index [WIP] feature : add zero copy support for vector index Jan 15, 2025
@mergify mergify bot added the dco-passed label Jan 15, 2025
Copy link

mergify bot commented Jan 15, 2025

@foxspy 🔍 Important: PR Classification Needed!

For efficient project management and a seamless review process, it's essential to classify your PR correctly. Here's how:

  1. If you're fixing a bug, label it as kind/bug.
  2. For small tweaks (less than 20 lines without altering any functionality), please use kind/improvement.
  3. Significant changes that don't modify existing functionalities should be tagged as kind/enhancement.
  4. Adjusting APIs or changing functionality? Go with kind/feature.

For any PR outside the kind/improvement category, ensure you link to the associated issue using the format: “issue: #”.

Thanks for your efforts and contribution to the community!.

@foxspy foxspy force-pushed the zero_copy_support branch 3 times, most recently from 5385cae to dc5a6ac Compare January 15, 2025 13:03
Copy link

codecov bot commented Jan 15, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 72.81%. Comparing base (3c46f4c) to head (771d36e).
Report is 322 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           main    #1032       +/-   ##
=========================================
+ Coverage      0   72.81%   +72.81%     
=========================================
  Files         0       82       +82     
  Lines         0     7529     +7529     
=========================================
+ Hits          0     5482     +5482     
- Misses        0     2047     +2047     

see 82 files with indirect coverage changes

Copy link
Collaborator

@alexanderguzhva alexanderguzhva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one topic to discuss. Otherwise, lgtm

@@ -81,6 +82,8 @@ struct Index {
MetricType metric_type;
float metric_arg; ///< argument of the metric type

std::shared_ptr<MmappedFileMappingOwner> mmap_owner;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a very tricky point. Although, I understand why this was introduced, I'd like to avoid adding it here. Basically, the approach is similar to a std::string_view, which does not have a business to maintain the memory. Similar, here: It is not Index's instance business to maintain the view.

I'm open for discussions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@foxspy any comments on this? Basically, I doubt that we'll able to introduce this variable in vanilla Faiss when porting back

}
}

ZeroCopyIOReader* zr = dynamic_cast<ZeroCopyIOReader*>(f);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a todo for the future: basically, a reader need to instantiate an object. But this is a later business, because it needs to be properly synchronized with the vanilla faiss first.
So, let's keep the change in the way you proposed it.

Copy link
Collaborator Author

@foxspy foxspy Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, so I put the PR up first; zero copy is needed here mainly for

  1. Optimizing memory expansion caused by copying during loading
  2. The memory will be managed uniformly through Eyrie later, and the index does not hold data, but only views
  3. The implementation of mmap and zero copy can be unified (mmap externally first, load through zero copy)
    If you have any ideas about this, please feel free to communicate; has faiss considered supporting this mode?

@foxspy foxspy force-pushed the zero_copy_support branch from dc5a6ac to 7dc2032 Compare January 16, 2025 02:39
@foxspy foxspy force-pushed the zero_copy_support branch 2 times, most recently from b58a68a to 91cfcde Compare February 6, 2025 08:06
@foxspy foxspy force-pushed the zero_copy_support branch from 91cfcde to 771d36e Compare February 6, 2025 08:09
@mergify mergify bot added the ci-passed label Feb 6, 2025
if (binary == nullptr) {
LOG_KNOWHERE_ERROR_ << "Invalid binary set.";
return Status::invalid_binary_set;
}

MemoryIOReader reader(binary->data.get(), binary->size);
int io_flags = faiss::IO_FLAG_ZERO_COPY;
faiss::ZeroCopyIOReader reader(binary->data.get(), binary->size);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such an approach won't lead to a memory leak, correct?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The binary will be held by the index; so there will be no memory leak

@@ -81,6 +82,8 @@ struct Index {
MetricType metric_type;
float metric_arg; ///< argument of the metric type

std::shared_ptr<MmappedFileMappingOwner> mmap_owner;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@foxspy any comments on this? Basically, I doubt that we'll able to introduce this variable in vanilla Faiss when porting back


namespace faiss {

ZeroCopyIOReader::ZeroCopyIOReader(uint8_t* data, size_t size) : data_(data), rp_(0), total_(size) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A duplicate code, similar to src/io/memory_io.h

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because Knowhere is a hub that is adapted to multiple indexes. For indexes other than faiss, it uses the memory_io.h. Faiss needs to remain independent zerocopy_io.cpp and not rely on related objects of knowhere.

@foxspy
Copy link
Collaborator Author

foxspy commented Feb 24, 2025

Zero copy may cause data misalignment, because data serialization in Faiss does not require alignment, which may cause errors or even crashes in some scenarios. @alexanderguzhva Do you have any suggestions for this?

@foxspy foxspy closed this Feb 24, 2025
@foxspy foxspy reopened this Feb 24, 2025
@mergify mergify bot removed the ci-passed label Feb 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants