-
Notifications
You must be signed in to change notification settings - Fork 16
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
fix memory leak for hnsw #137
Conversation
Signed-off-by: jinjiabao.jjb <jinjiabao.jjb@antgroup.com>
src/algorithm/hnswlib/hnswalg.cpp
Outdated
@@ -73,6 +71,11 @@ HierarchicalNSW::HierarchicalNSW(SpaceInterface* s, | |||
|
|||
void | |||
HierarchicalNSW::reset() { | |||
if (visited_list_pool_) { | |||
visited_list_pool_->~VisitedListPool(); |
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.
here we can overloading new/delete operator
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.
done
src/algorithm/hnswlib/hnswalg.cpp
Outdated
@@ -89,6 +92,12 @@ bool | |||
HierarchicalNSW::init_memory_space() { | |||
// release the memory allocated by the init_memory_space function that was called earlier | |||
reset(); | |||
auto visited_list_mem = allocator_->Allocate(sizeof(VisitedListPool)); |
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.
ditto
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.
done
src/algorithm/hnswlib/hnswalg.cpp
Outdated
@@ -73,6 +71,10 @@ HierarchicalNSW::HierarchicalNSW(SpaceInterface* s, | |||
|
|||
void | |||
HierarchicalNSW::reset() { | |||
if (visited_list_pool_) { | |||
VisitedListPool::operator delete(visited_list_pool_, allocator_); |
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.
delete visitored_list_pool_
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.
Because an allocator is used, the default new and delete cannot be used.
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.
Ok, maybe we can add New
and Delete
function to Allocator, like this:
class Allocator {
public:
void* Allocate(size_t size) { ... }
void Deallocate(void* p) { ... }
template<typename T, typename ...Args>
T* New(Args&&... args) {
void* p = Allocate(sizeof(T));
return (T*) ::new (p) T(std::forward<Args>(args)...);
}
template<typename T>
void Delete(T* p) {
p->~T();
Deallocate(static_cast<void*>(p));
}
}
// ....
void HierarchicalNSW::init_memory_space() {
// ...
visited_list_pool_ = allocator_->New<VisitedListPool>(max_elements_, allocator_);
}
void HierarchicalNSW::reset() {
if (visited_list_pool_) {
allocator_->Delete(visited_list_pool_);
}
// ...
}
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.
OK, I have modified it.
} | ||
|
||
void | ||
operator delete(void* p, vsag::Allocator* alloc) noexcept { |
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.
void operator delete(void* p) noexcept {
alloc->Deallocate(p);
}
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.
ditto
@@ -77,11 +79,20 @@ using VisitedListPtr = std::shared_ptr<VisitedList>; | |||
|
|||
class VisitedListPool { | |||
public: | |||
VisitedListPool(int initmaxpools, uint64_t numelements1, vsag::Allocator* allocator) | |||
: allocator_(allocator) { | |||
VisitedListPool(uint64_t numelements1, vsag::Allocator* allocator) |
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.
numelements1
typo ?
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.
I have renamed it to max_element_count
@@ -161,7 +161,7 @@ class StaticHierarchicalNSW : public AlgorithmInterface<float> { | |||
|
|||
cur_element_count_ = 0; | |||
|
|||
visited_list_pool_ = new VisitedListPool(1, max_elements, allocator_); | |||
visited_list_pool_ = new (allocator_) VisitedListPool(max_elements, allocator_); |
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.
visited_list_pool_ = allocator_->New(max_elements, allocator_);
@@ -187,7 +187,7 @@ class StaticHierarchicalNSW : public AlgorithmInterface<float> { | |||
} | |||
allocator_->Deallocate(element_levels_); | |||
allocator_->Deallocate(linkLists_); | |||
delete visited_list_pool_; | |||
VisitedListPool::operator delete(visited_list_pool_, allocator_); |
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.
miss change ?
@@ -935,8 +935,8 @@ class StaticHierarchicalNSW : public AlgorithmInterface<float> { | |||
throw std::runtime_error( | |||
"Cannot Resize, max element is less than the current number of elements"); | |||
|
|||
delete visited_list_pool_; | |||
visited_list_pool_ = new VisitedListPool(1, new_max_elements, allocator_); | |||
VisitedListPool::operator delete(visited_list_pool_, allocator_); |
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.
ditto
@@ -1527,8 +1527,7 @@ class StaticHierarchicalNSW : public AlgorithmInterface<float> { | |||
std::vector<std::mutex>(max_elements).swap(link_list_locks_); | |||
std::vector<std::mutex>(MAX_LABEL_OPERATION_LOCKS).swap(label_op_locks_); | |||
|
|||
delete visited_list_pool_; | |||
visited_list_pool_ = new VisitedListPool(1, max_elements, allocator_); | |||
visited_list_pool_ = new (allocator_) VisitedListPool(max_elements, allocator_); |
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.
ditto
} | ||
|
||
private: | ||
std::deque<VisitedListPtr> pool; | ||
vsag::Vector<VisitedListPtr> pool; |
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.
pool -> pool_
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.
done
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.
LGTM
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.
lgtm
Signed-off-by: jinjiabao.jjb <jinjiabao.jjb@antgroup.com>
fixed: #70