Skip to content

Commit 8d6154d

Browse files
committed
Merge remote-tracking branch 'origin/master_modular_genai' into xp/enable_release_weights
2 parents 2e3450f + 6298c5c commit 8d6154d

File tree

5 files changed

+74
-50
lines changed

5 files changed

+74
-50
lines changed

src/cpp/src/module_genai/module_base.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,15 @@ bool IBaseModule::check_bool_param(const std::string& param_name, const bool& de
164164
return default_value;
165165
}
166166

167+
// PipelineDesc implementation
168+
PipelineDesc::PipelineDesc() : m_resource_cache(std::make_unique<PipelineResourceCache>()) {}
169+
170+
PipelineDesc::~PipelineDesc() = default;
171+
172+
PipelineResourceCache& PipelineDesc::get_resource_cache() {
173+
return *m_resource_cache;
174+
}
175+
167176
} // namespace module
168177
} // namespace genai
169178
} // namespace ov

src/cpp/src/module_genai/module_desc.hpp

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
#pragma once
55

6+
#include <mutex>
7+
#include <any>
8+
#include <functional>
9+
#include <memory>
10+
611
#include "module_genai/module_data_type.hpp"
712
#include "module_genai/module_print_config.hpp"
813
#include "module_genai/module_type.hpp"
@@ -52,14 +57,56 @@ class IBaseModuleDesc {
5257
// map: module name -> module desc
5358
using PipelineModulesDesc = std::unordered_map<std::string, IBaseModuleDesc::PTR>;
5459

60+
// Pipeline-scoped resource cache for sharing compiled models across modules
61+
// Resources are automatically released when PipelineDesc is destroyed
62+
class PipelineResourceCache {
63+
public:
64+
PipelineResourceCache() = default;
65+
~PipelineResourceCache() = default;
66+
67+
// Non-copyable
68+
PipelineResourceCache(const PipelineResourceCache&) = delete;
69+
PipelineResourceCache& operator=(const PipelineResourceCache&) = delete;
70+
71+
// Get or create a resource with the given key
72+
// Returns {resource, was_cached} - the bool indicates whether the resource was already in the cache
73+
template<typename T>
74+
std::pair<std::shared_ptr<T>, bool> get_or_create(
75+
std::size_t cache_key,
76+
std::function<std::shared_ptr<T>()> creator) {
77+
std::lock_guard<std::mutex> lock(m_mutex);
78+
auto it = m_cache.find(cache_key);
79+
if (it != m_cache.end()) {
80+
auto typed = std::any_cast<std::shared_ptr<T>>(&it->second);
81+
if (!typed) {
82+
OPENVINO_THROW("PipelineResourceCache: cache key collision - entry exists with a different type for key ",
83+
cache_key);
84+
}
85+
return {*typed, true};
86+
}
87+
auto resource = creator();
88+
m_cache[cache_key] = resource;
89+
return {resource, false};
90+
}
91+
92+
void clear() {
93+
std::lock_guard<std::mutex> lock(m_mutex);
94+
m_cache.clear();
95+
}
96+
97+
private:
98+
std::mutex m_mutex;
99+
std::unordered_map<std::size_t, std::any> m_cache;
100+
};
101+
55102
class PipelineDesc {
56103
protected:
57-
PipelineDesc() = default;
104+
PipelineDesc();
58105
PipelineDesc(const PipelineDesc&) = delete;
59106
PipelineDesc& operator=(const PipelineDesc&) = delete;
60107

61108
public:
62-
~PipelineDesc() = default;
109+
~PipelineDesc();
63110
// global_context;
64111
std::string model_type;
65112

@@ -75,13 +122,18 @@ class PipelineDesc {
75122
return m_models_map;
76123
}
77124

125+
// Pipeline-scoped resource cache for modules to share resources
126+
// Resources are released when PipelineDesc is destroyed
127+
PipelineResourceCache& get_resource_cache();
128+
78129
using PTR = std::shared_ptr<PipelineDesc>;
79130
static PTR create() {
80131
return std::shared_ptr<PipelineDesc>(new PipelineDesc());
81132
}
82133

83134
private:
84135
ConfigModelsMap m_models_map;
136+
std::unique_ptr<PipelineResourceCache> m_resource_cache;
85137
};
86138

87139
} // namespace module

src/cpp/src/module_genai/modules/md_clip_text_encoder.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,11 @@ bool ClipTextEncoderModule::initialize() {
8989
// Create cache key hash from model XML content and device
9090
std::size_t cache_key = compute_cache_key(text_encoder_path, device);
9191

92-
// Check if resources already exist in cache
93-
bool is_cached = ClipTextEncoderResourceCache::instance().exists(cache_key);
94-
if (is_cached) {
95-
GENAI_INFO("ClipTextEncoderModule: Reusing cached model for: " + root_dir.string() + " on device: " + device);
96-
}
92+
// Get pipeline-scoped resource cache (resources released when pipeline is destroyed)
93+
auto& resource_cache = pipeline_desc->get_resource_cache();
9794

98-
// Get or create shared resources
99-
m_shared_resources = ClipTextEncoderResourceCache::instance().get_or_create(
95+
// Get or create shared resources (cache hit detected atomically under the same lock)
96+
auto [shared_resources, was_cached] = resource_cache.get_or_create<ClipTextEncoderSharedResources>(
10097
cache_key,
10198
[this, &root_dir, &device, &text_encoder_path, model_type]() -> std::shared_ptr<ClipTextEncoderSharedResources> {
10299
GENAI_INFO("ClipTextEncoderModule: Loading model from: " + root_dir.string() + " to device: " + device);
@@ -148,6 +145,11 @@ bool ClipTextEncoderModule::initialize() {
148145
return resources;
149146
});
150147

148+
m_shared_resources = shared_resources;
149+
if (was_cached) {
150+
GENAI_INFO("ClipTextEncoderModule: Reusing cached model for: " + root_dir.string() + " on device: " + device);
151+
}
152+
151153
if (!m_shared_resources) {
152154
GENAI_ERR("ClipTextEncoderModule[" + module_desc->name + "]: Failed to initialize shared resources");
153155
return false;

src/cpp/src/module_genai/modules/md_clip_text_encoder.hpp

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
#pragma once
55

66
#include <yaml-cpp/yaml.h>
7-
#include <mutex>
8-
#include <unordered_map>
97
#include <fstream>
108
#include <filesystem>
119

@@ -50,51 +48,14 @@ inline std::size_t compute_cache_key(const std::filesystem::path& model_xml_path
5048
return std::hash<std::string_view>{}(std::string_view(content.data(), content.size()));
5149
}
5250

53-
// Global cache for shared resources
54-
class ClipTextEncoderResourceCache {
55-
public:
56-
static ClipTextEncoderResourceCache& instance() {
57-
static ClipTextEncoderResourceCache cache;
58-
return cache;
59-
}
60-
61-
std::shared_ptr<ClipTextEncoderSharedResources> get_or_create(
62-
std::size_t cache_key,
63-
std::function<std::shared_ptr<ClipTextEncoderSharedResources>()> creator) {
64-
std::lock_guard<std::mutex> lock(m_mutex);
65-
auto it = m_cache.find(cache_key);
66-
if (it != m_cache.end()) {
67-
return it->second;
68-
}
69-
auto resources = creator();
70-
m_cache[cache_key] = resources;
71-
return resources;
72-
}
73-
74-
bool exists(std::size_t cache_key) {
75-
std::lock_guard<std::mutex> lock(m_mutex);
76-
return m_cache.find(cache_key) != m_cache.end();
77-
}
78-
79-
void clear() {
80-
std::lock_guard<std::mutex> lock(m_mutex);
81-
m_cache.clear();
82-
}
83-
84-
private:
85-
ClipTextEncoderResourceCache() = default;
86-
std::mutex m_mutex;
87-
std::unordered_map<std::size_t, std::shared_ptr<ClipTextEncoderSharedResources>> m_cache;
88-
};
89-
9051
class ClipTextEncoderModule : public IBaseModule {
9152
DeclareModuleConstructor(ClipTextEncoderModule);
9253

9354
private:
9455
bool initialize();
9556
bool do_classifier_free_guidance(float guidance_scale);
9657

97-
// Shared resources (shared across modules with same model_path)
58+
// Shared resources (shared across modules with same model_path within the same pipeline)
9859
std::shared_ptr<ClipTextEncoderSharedResources> m_shared_resources;
9960

10061
// Per-instance infer request (each module has its own)

src/cpp/src/module_genai/modules/md_denoiser_loop/class.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ bool DenoiserLoopModule::initialize() {
113113
}
114114

115115
if (m_splitted_model) {
116-
m_splitted_model_infer = CSplittedModelInfer::create(transformer_model_path,
116+
m_splitted_model_infer = CSplittedModelInfer::create(transformer_model_path.string(),
117117
module_desc->device,
118118
m_dynamic_load_weights,
119119
properties);

0 commit comments

Comments
 (0)