-
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
NPUW: Fix nullptr reference parameter in rearrange_to_proto #26869
NPUW: Fix nullptr reference parameter in rearrange_to_proto #26869
Conversation
63b7088
to
d000317
Compare
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.
The key change is trivial and should work.
If a key is a pair of (model + param), then all you miss in finalizeLinks
is a pointer to the right function's model.
std::unordered_map<std::string, PPtr> param_call_to_proto; | ||
std::unordered_map<std::string, RPtr> result_call_to_proto; |
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.
To avoid invasive changes, let's introduce a type alias, let it be
std::unordered_map<std::string, PPtr> param_call_to_proto; | |
std::unordered_map<std::string, RPtr> result_call_to_proto; | |
using MPtr = std::shared_ptr<ov::Model>; | |
using CallParam = std::pair<PPtr, MPtr>; | |
using CallResult = std::pair<RPtr, MPtr>; | |
std::unordered_map<CallParam, PPtr> param_call_to_proto; | |
std::unordered_map<CallResult, RPtr> result_call_to_proto; |
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.
Fixed, thanks!
void rearrange_to_function_protocol(const std::vector<T>& protocol, std::vector<T>& call, const M& call_to_proto, | ||
const std::shared_ptr<ov::Model>& model) { |
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.
to avoid confusion, I'd rename here model
to fcall
(standing for function call)
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.
Used another variable, but thank you!
@@ -214,7 +215,7 @@ class Partitioner { | |||
LOG_DEBUG("Call: " << call.size()); | |||
for (auto&& c : call) { | |||
LOG_BLOCK(); | |||
auto p_c = call_to_proto.at(c); | |||
auto p_c = call_to_proto.at(model->get_friendly_name() + "_" + c->get_friendly_name()); |
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.
auto p_c = call_to_proto.at(model->get_friendly_name() + "_" + c->get_friendly_name()); | |
auto p_c = call_to_proto.at(CallParam{fcall, c}); |
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.
Fixed, thanks!
@@ -1347,7 +1348,7 @@ void Partitioner::matchParameters(const std::string& func_name) { | |||
LOG_DEBUG("Find orig parameter for " << node); | |||
auto& orig_param = proto_parameters.at(pkey); | |||
auto this_param = std::dynamic_pointer_cast<PPtr::element_type>(node); | |||
func.param_call_to_proto[this_param] = orig_param; | |||
func.param_call_to_proto[call.get()->get_friendly_name() + "_" + this_param->get_friendly_name()] = orig_param; |
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.
func.param_call_to_proto[call.get()->get_friendly_name() + "_" + this_param->get_friendly_name()] = orig_param; | |
func.param_call_to_proto[CallParam{fcall, this_param}] = orig_param; |
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.
and so on.
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.
Fixed, thanks!
std::cout << "SUBGRAPH PARAM: " << model->get_friendly_name() + "_" + | ||
sg_desc._funcall + "__" + std::to_string(subgr_idx_to - 1) + "_" + ptr->get_friendly_name() << std::endl; |
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.
this is something very strange. Obviously, taking the model name into account is not correct
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.
Fixed, thanks!
at(model->get_friendly_name() + "_" + | ||
sg_desc._funcall + "__" + std::to_string(subgr_idx_to - 1) + "_" + ptr->get_friendly_name()); |
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.
So shouldn't this just work?
at(model->get_friendly_name() + "_" + | |
sg_desc._funcall + "__" + std::to_string(subgr_idx_to - 1) + "_" + ptr->get_friendly_name()); | |
at(CallParam{fcall, ptr}); |
where fcall is the pointer to a particular function call model?
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.
Fixed, thanks!
@AsyaPronina please add an assert here https://github.com/openvinotoolkit/openvino/blob/master/src/plugins/intel_npu/src/plugin/npuw/compiled_model.cpp#L181 |
d335ac0
to
b894bcd
Compare
…o subgraphs can be distinguuished as two different operations
b894bcd
to
1092f5e
Compare
@@ -1327,14 +1354,17 @@ void Partitioner::matchParameters(const std::string& func_name) { | |||
|
|||
// Now walk other submodels and match parameters with the same key | |||
// (yes, including the first one) | |||
for (auto&& call : model_group) { | |||
for (std::size_t call_id{}; call_id < model_group.size(); ++call_id) { |
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.
Please use = 0
instead of {}
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 on earth people decided to use int something{}
. Why
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.
Fixed
@@ -1904,7 +1939,8 @@ void Partitioner::finalizeLinks() { | |||
auto& results = P.functions.at(sg_desc._funcall)._model->get_results(); | |||
auto& proto = func_pipeline_type == FunctionPipelineType::CWAI | |||
? ptr // no protos in the CWAI case... | |||
: all_functions.at(sg_desc._funcall).result_call_to_proto.at(ptr); | |||
: all_functions.at(sg_desc._funcall).result_call_to_proto | |||
.at(SubgResult(sg_desc, ptr)); |
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.
Fix to the same .at
style in parameters
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.
clang-format fixed it
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.
Fine with the changes but let's fix the confusing naming
using SubgParam = std::pair<ov::npuw::Subgraph::Ref, PPtr>; | ||
using SubgResult = std::pair<ov::npuw::Subgraph::Ref, RPtr>; |
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 it is Subgraph and not Subgraph index? It'd be much easier if you just use indices.
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 for now Subgraph
structure doesn't contain its own index, unfortunately, and, we have std::vector<ov::npuw::Subgraph::Ref>
in FunctionPipeline
structure, what we can reference to, when working with function and its calls and creating/using param_call_to_proto
and result_call_to_proto
for them. It was just more easy to implement that way.
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.
Well you could've put indices yourself in the code I pointed to. But this may also work
@@ -1327,14 +1354,17 @@ void Partitioner::matchParameters(const std::string& func_name) { | |||
|
|||
// Now walk other submodels and match parameters with the same key | |||
// (yes, including the first one) | |||
for (auto&& call : model_group) { | |||
for (std::size_t call_id{}; call_id < model_group.size(); ++call_id) { |
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 on earth people decided to use int something{}
. Why
auto model = model_group[call_id]; | ||
auto subg_ref = func.refs[call_id]; | ||
|
||
std::unordered_set<ov::Node*> this_model_nodes; | ||
for (auto&& node_ptr : call->get_ordered_ops()) { | ||
for (auto&& node_ptr : model->get_ordered_ops()) { | ||
this_model_nodes.insert(node_ptr.get()); | ||
} | ||
for (auto&& node : call->get_ordered_ops()) { | ||
for (auto&& node : model->get_ordered_ops()) { |
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.
so why it couldn't stay call = model_group[call_id]
? model
in general can be confused with the global, big, parent Model.
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.
Fixed, thanks!
auto model = model_group[call_idx]; | ||
auto subg_ref = func.refs[call_idx]; | ||
for (auto&& node : model->get_ordered_ops()) { |
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 too
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.
Fixed, thanks!
auto get_idx_param = [this](std::size_t subgr_idx_to, | ||
const PPtr& ptr) -> std::size_t { |
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 believe previously it was formatted by clang-format
. Did anything change here?
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.
Fixed, thanks!
f17b3c6
to
8882429
Compare
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.
Thanks @AsyaPronina ! Let's see how much problems it solves now
using SubgParam = std::pair<ov::npuw::Subgraph::Ref, PPtr>; | ||
using SubgResult = std::pair<ov::npuw::Subgraph::Ref, RPtr>; |
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.
Well you could've put indices yourself in the code I pointed to. But this may also work
Details:
Tickets: