-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Enable mmap for reading model from cache #26696
base: master
Are you sure you want to change the base?
Changes from all commits
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 | ||||
---|---|---|---|---|---|---|
|
@@ -8,7 +8,7 @@ | |||||
|
||||||
namespace ov { | ||||||
|
||||||
/// \brief SharedBuffer class to store pointer to pre-acclocated buffer. | ||||||
/// \brief SharedBuffer class to store pointer to pre-acclocated buffer. Own the shared object. | ||||||
template <typename T> | ||||||
class SharedBuffer : public ov::AlignedBuffer { | ||||||
public: | ||||||
|
@@ -28,4 +28,51 @@ class SharedBuffer : public ov::AlignedBuffer { | |||||
T _shared_object; | ||||||
}; | ||||||
|
||||||
/// \brief SharedStreamBuffer class to store pointer to pre-acclocated buffer and provide streambuf interface. | ||||||
class SharedStreamBuffer : public std::streambuf { | ||||||
public: | ||||||
SharedStreamBuffer(char* data, size_t size) : m_data(data), m_size(size), m_offset(0) {} | ||||||
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. 'data' is not passed to std::streambuf, so operator>> for std::istream should not work in core_impl and HeaderException should be thrown. Actually, it could be done on Linux only, due to the std::streambuf has different implementations depend on OS. |
||||||
|
||||||
protected: | ||||||
std::streamsize xsgetn(char* s, std::streamsize count) override { | ||||||
auto real_count = std::min<std::streamsize>(m_size - m_offset, count); | ||||||
std::memcpy(s, m_data + m_offset, real_count); | ||||||
m_offset += real_count; | ||||||
return real_count; | ||||||
} | ||||||
|
||||||
int_type underflow() override { | ||||||
return (m_size == m_offset) ? traits_type::eof() : traits_type::to_int_type(*(m_data + m_offset)); | ||||||
} | ||||||
|
||||||
int_type uflow() override { | ||||||
return (m_size == m_offset) ? traits_type::eof() : traits_type::to_int_type(*(m_data + m_offset++)); | ||||||
} | ||||||
|
||||||
std::streamsize showmanyc() override { | ||||||
return m_size - m_offset; | ||||||
} | ||||||
|
||||||
char* m_data; | ||||||
size_t m_size; | ||||||
size_t m_offset; | ||||||
}; | ||||||
|
||||||
/// \brief OwningSharedStreamBuffer is a SharedStreamBuffer which owns its shared object. Can return AlignedBuffer to | ||||||
/// shared memory | ||||||
class OwningSharedStreamBuffer : public SharedStreamBuffer { | ||||||
public: | ||||||
template <typename T> | ||||||
OwningSharedStreamBuffer(char* data, size_t size, const T& shared_object) | ||||||
: SharedStreamBuffer(data, size), | ||||||
m_alligned_buffer(std::make_shared<SharedBuffer<T>>(data, size, shared_object)) {} | ||||||
|
||||||
std::shared_ptr<AlignedBuffer> get_aligned_buffer() { | ||||||
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. Why is required and why not just return internal buffer. When shared buffer used it will just increment counter in stored shared object. |
||||||
return m_alligned_buffer; | ||||||
} | ||||||
|
||||||
protected: | ||||||
std::shared_ptr<AlignedBuffer> m_alligned_buffer; | ||||||
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. Why shared pointer is required. The ov::SharedBuffer will manage owner ship
Suggested change
Should be sufficient |
||||||
}; | ||||||
|
||||||
} // namespace ov |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -212,6 +212,12 @@ class OPENVINO_RUNTIME_API IPlugin : public std::enable_shared_from_this<IPlugin | |
*/ | ||
const std::shared_ptr<ov::threading::ExecutorManager>& get_executor_manager() const; | ||
|
||
/** | ||
* @brief Check if plugin support mmap for cached model reading. Returns false is the method is not overrided by plugin. | ||
* @return true if mmap is supported, false otherwise | ||
*/ | ||
virtual bool support_mmap_for_caching() const; | ||
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. Use property instead adding functions? And add ENABLE_MMAP to supported properties in GPU plugin 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 would not like to show this "property" via public API. |
||
|
||
virtual ~IPlugin() = default; | ||
|
||
protected: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,9 @@ | |
#include <memory> | ||
#include <string> | ||
|
||
#include "openvino/runtime/shared_buffer.hpp" | ||
#include "openvino/util/file_util.hpp" | ||
#include "openvino/util/mmap_object.hpp" | ||
|
||
namespace ov { | ||
|
||
|
@@ -78,7 +80,7 @@ class ICacheManager { | |
* @param id Id of cache (hash of the model) | ||
* @param reader Lambda function to be called when input stream is created | ||
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. Add new parameter to doxy comment. 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. there is not new parameter anymore 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 parameter |
||
*/ | ||
virtual void read_cache_entry(const std::string& id, StreamReader reader) = 0; | ||
virtual void read_cache_entry(const std::string& id, bool enable_mmap, StreamReader reader) = 0; | ||
|
||
/** | ||
* @brief Callback when OpenVINO intends to remove cache entry | ||
|
@@ -129,13 +131,20 @@ class FileStorageCacheManager final : public ICacheManager { | |
writer(stream); | ||
} | ||
|
||
void read_cache_entry(const std::string& id, StreamReader reader) override { | ||
void read_cache_entry(const std::string& id, bool enable_mmap, StreamReader reader) override { | ||
// Fix the bug caused by pugixml, which may return unexpected results if the locale is different from "C". | ||
ScopedLocale plocal_C(LC_ALL, "C"); | ||
auto blobFileName = getBlobFile(id); | ||
if (ov::util::file_exists(blobFileName)) { | ||
std::ifstream stream(blobFileName, std::ios_base::binary); | ||
reader(stream); | ||
if (enable_mmap) { | ||
auto mmap = ov::load_mmap_object(blobFileName); | ||
OwningSharedStreamBuffer buf(mmap->data(), mmap->size(), mmap); | ||
std::istream stream(&buf); | ||
reader(stream); | ||
} else { | ||
std::ifstream stream(blobFileName, std::ios_base::binary); | ||
reader(stream); | ||
} | ||
} | ||
} | ||
|
||
|
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.
Consider:
Just another alternative to integrate it with ov buffer interface.
If multiple inheritance is an issue the composition can be used.