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

NPUW: Fix nullptr reference parameter in rearrange_to_proto #26869

Merged

Conversation

AsyaPronina
Copy link
Contributor

@AsyaPronina AsyaPronina commented Sep 30, 2024

Details:

  • Add subgraph identificator for operation name, so one operation in two subgraphs can be distinguished as two different operations
  • ...

Tickets:

  • EISW-139849

@AsyaPronina AsyaPronina requested review from a team as code owners September 30, 2024 14:16
@AsyaPronina AsyaPronina marked this pull request as draft September 30, 2024 14:16
@github-actions github-actions bot added category: NPU OpenVINO NPU plugin category: NPUW NPUW plugin labels Sep 30, 2024
@dmatveev dmatveev changed the title Add subgraph identificator for operation name, so one operation in two subgraphs can be distincted as two different operations NPUW: Fix nullptr reference parameter in rearrange_to_proto Sep 30, 2024
@dmatveev dmatveev self-assigned this Sep 30, 2024
@dmatveev dmatveev added this to the 2024.5 milestone Sep 30, 2024
Copy link
Contributor

@dmatveev dmatveev left a 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.

Comment on lines 184 to 185
std::unordered_map<std::string, PPtr> param_call_to_proto;
std::unordered_map<std::string, RPtr> result_call_to_proto;
Copy link
Contributor

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

Suggested change
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;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, thanks!

Comment on lines 205 to 206
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) {
Copy link
Contributor

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)

Copy link
Contributor Author

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());
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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});

Copy link
Contributor Author

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;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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;

Copy link
Contributor

Choose a reason for hiding this comment

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

and so on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, thanks!

Comment on lines 1791 to 1792
std::cout << "SUBGRAPH PARAM: " << model->get_friendly_name() + "_" +
sg_desc._funcall + "__" + std::to_string(subgr_idx_to - 1) + "_" + ptr->get_friendly_name() << std::endl;
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, thanks!

Comment on lines 1796 to 1797
at(model->get_friendly_name() + "_" +
sg_desc._funcall + "__" + std::to_string(subgr_idx_to - 1) + "_" + ptr->get_friendly_name());
Copy link
Contributor

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?

Suggested change
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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, thanks!

@smirnov-alexey
Copy link
Contributor

@AsyaPronina AsyaPronina force-pushed the one_op_in_two_subgraphs branch 2 times, most recently from d335ac0 to b894bcd Compare October 1, 2024 17:37
@AsyaPronina AsyaPronina marked this pull request as ready for review October 1, 2024 17:38
…o subgraphs can be distinguuished as two different operations
@@ -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) {
Copy link
Contributor

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 {}

Copy link
Contributor

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

Copy link
Contributor Author

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));
Copy link
Contributor Author

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

clang-format fixed it

Copy link
Contributor

@dmatveev dmatveev left a 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

Comment on lines +187 to +188
using SubgParam = std::pair<ov::npuw::Subgraph::Ref, PPtr>;
using SubgResult = std::pair<ov::npuw::Subgraph::Ref, RPtr>;
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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) {
Copy link
Contributor

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

Comment on lines 1360 to 1367
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()) {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, thanks!

Comment on lines 1420 to 1422
auto model = model_group[call_idx];
auto subg_ref = func.refs[call_idx];
for (auto&& node : model->get_ordered_ops()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

here too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, thanks!

Comment on lines 1904 to 1905
auto get_idx_param = [this](std::size_t subgr_idx_to,
const PPtr& ptr) -> std::size_t {
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, thanks!

Copy link
Contributor

@dmatveev dmatveev left a 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

Comment on lines +187 to +188
using SubgParam = std::pair<ov::npuw::Subgraph::Ref, PPtr>;
using SubgResult = std::pair<ov::npuw::Subgraph::Ref, RPtr>;
Copy link
Contributor

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

@dmatveev dmatveev added this pull request to the merge queue Oct 2, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Oct 2, 2024
@AsyaPronina AsyaPronina added this pull request to the merge queue Oct 2, 2024
Merged via the queue into openvinotoolkit:master with commit 0b21860 Oct 2, 2024
130 checks passed
@AsyaPronina AsyaPronina deleted the one_op_in_two_subgraphs branch October 2, 2024 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: NPU OpenVINO NPU plugin category: NPUW NPUW plugin
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants