Skip to content

Commit

Permalink
NPUW: Add new option to dump representative subset (#28308)
Browse files Browse the repository at this point in the history
### Details:
Added new possible value for dump options to let NPUW decide which
subgraphs need to dump.
With "MIN" option it will dump all non-repeating blocks and just one
instance of the repeating block.

### Tickets:
 - *E-139858*
eshiryae authored Jan 14, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 42cb92e commit da4c16e
Showing 5 changed files with 32 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -338,9 +338,10 @@ static constexpr ov::Property<bool> full{"NPUW_DUMP_FULL"};
* @brief
* Type: std::string.
* Dump the specified subgraph(s) in OpenVINO IR form in the current directory.
* Possible values: Comma-separated list of subgraph indices or "YES" for all
* subgraphs, "NO" or just empty value to turn option off. Keyword "last" can
* be used for dumping last subgraph without specifying it by specific index.
* Possible values: Comma-separated list of subgraph indices ("last" can be used
* for dumping last subgraph without specifying it by specific index), "YES" for
* all subgraphs, "MIN" for representative subgraph subset (all non-repeated and
* one instance of repeated block), "NO" or just empty value to turn option off.
* E.g. "0,1" or "0,1,last" or "YES".
* Default value: empty.
*/
@@ -350,9 +351,10 @@ static constexpr ov::Property<std::string> subgraphs{"NPUW_DUMP_SUBS"};
* @brief
* Type: std::string.
* Dump subgraph on disk if a compilation failure happens.
* Possible values: Comma-separated list of subgraph indices or "YES" for all
* subgraphs, "NO" or just empty value to turn option off. Keyword "last" can
* be used for dumping last subgraph. E.g. "0,1" or "0,1,last" or "YES".
* Possible values: Comma-separated list of subgraph indices ("last" can be used
* for dumping last subgraph) or "YES" for all subgraphs, "MIN" for representative
* subgraph subset, "NO" or just empty value to turn option off. E.g. "0,1" or
* "0,1,last" or "YES".
* Default value: empty.
*/
static constexpr ov::Property<std::string> subgraphs_on_fail{"NPUW_DUMP_SUBS_ON_FAIL"};
@@ -361,9 +363,9 @@ static constexpr ov::Property<std::string> subgraphs_on_fail{"NPUW_DUMP_SUBS_ON_
* @brief
* Type: std::string.
* Dump input & output tensors for subgraph(s).
* Possible values: Comma-separated list of subgraph indices or "YES" for all
* subgraphs, "NO" or just empty value to turn option off. Keyword "last" can
* be used for last subgraph. E.g. "0,1" or "0,1,last" or "YES".
* Possible values: Comma-separated list of subgraph indices ("last" can be used for
* last subgraph) or "YES" for all subgraphs, "MIN" for representative subgraph subset,
* "NO" or just empty value to turn option off. E.g. "0,1" or "0,1,last" or "YES".
* Default value: empty.
*/
static constexpr ov::Property<std::string> inputs_outputs{"NPUW_DUMP_IO"};
Original file line number Diff line number Diff line change
@@ -491,11 +491,12 @@ void ov::npuw::IBaseInferRequest::bind_global_results(std::size_t idx, RqPtr req
void ov::npuw::IBaseInferRequest::dump_input_tensors(std::size_t idx) {
const std::string dump_ios_opt = m_npuw_model->m_cfg.get<::intel_npu::NPUW_DUMP_IO>();
const std::size_t end_idx = m_npuw_model->m_compiled_submodels.size();
if (!ov::npuw::util::is_set(idx, dump_ios_opt, end_idx)) {
auto real_idx = m_npuw_model->m_compiled_submodels[idx].replaced_by.value_or(idx);

if (!ov::npuw::util::is_set(idx, dump_ios_opt, real_idx, end_idx)) {
return;
}

auto real_idx = m_npuw_model->m_compiled_submodels[idx].replaced_by.value_or(idx);
const auto& comp_submodel_desc = m_npuw_model->m_compiled_submodels[real_idx];
const auto& comp_submodel = comp_submodel_desc.compiled_model;

@@ -569,11 +570,12 @@ void ov::npuw::IBaseInferRequest::dump_input_tensors(std::size_t idx) {
void ov::npuw::IBaseInferRequest::dump_output_tensors(std::size_t idx) {
const std::string dump_ios_opt = m_npuw_model->m_cfg.get<::intel_npu::NPUW_DUMP_IO>();
const std::size_t end_idx = m_npuw_model->m_compiled_submodels.size();
if (!ov::npuw::util::is_set(idx, dump_ios_opt, end_idx)) {
auto real_idx = m_npuw_model->m_compiled_submodels[idx].replaced_by.value_or(idx);

if (!ov::npuw::util::is_set(idx, dump_ios_opt, real_idx, end_idx)) {
return;
}

auto real_idx = m_npuw_model->m_compiled_submodels[idx].replaced_by.value_or(idx);
const auto& comp_submodel_desc = m_npuw_model->m_compiled_submodels[real_idx];
const auto& comp_submodel = comp_submodel_desc.compiled_model;

5 changes: 3 additions & 2 deletions src/plugins/intel_npu/src/plugin/npuw/compiled_model.cpp
Original file line number Diff line number Diff line change
@@ -364,7 +364,7 @@ ov::npuw::CompiledModel::CompiledModel(const std::shared_ptr<ov::Model>& model,
fill_empty_tensor_names(m_compiled_submodels[real_id].model);
}

if (ov::npuw::util::is_set(id, dump_sub_opt, end_sub_idx)) {
if (ov::npuw::util::is_set(id, dump_sub_opt, real_id, end_sub_idx)) {
LOG_INFO("Dumping Subgraph[" << id << "]");
LOG_BLOCK();
if (real_id != id) {
@@ -996,8 +996,9 @@ ov::SoPtr<ov::ICompiledModel> ov::npuw::CompiledModel::compile_submodel(const st
void ov::npuw::CompiledModel::dump_on_fail(std::size_t id, const std::string& device_to_try, const char* extra) {
const std::string dof_opt = m_cfg.get<::intel_npu::NPUW_DUMP_SUBS_ON_FAIL>();
const std::size_t end_idx = m_compiled_submodels.size();
const std::size_t real_idx = m_compiled_submodels[id].replaced_by.value_or(id);

if (ov::npuw::util::is_set(id, dof_opt, end_idx)) {
if (ov::npuw::util::is_set(id, dof_opt, real_idx, end_idx)) {
ov::npuw::dump_failure(m_compiled_submodels[id].model, device_to_try, extra);
}
}
9 changes: 8 additions & 1 deletion src/plugins/intel_npu/src/plugin/npuw/util.cpp
Original file line number Diff line number Diff line change
@@ -18,14 +18,21 @@
#include "openvino/runtime/make_tensor.hpp" // get_tensor_impl
#include "util_xarch.hpp"

bool ov::npuw::util::is_set(const std::size_t sub_idx, const std::string& opt, const std::size_t end_idx) {
bool ov::npuw::util::is_set(const std::size_t sub_idx,
const std::string& opt,
const std::size_t real_idx,
const std::size_t end_idx) {
if (opt.empty() || opt == "NO") {
return false;
}
if (opt == "YES") {
return true;
}

if (opt == "MIN") {
return sub_idx == real_idx;
}

std::string str(opt);
std::size_t last_pos = str.find("last");
if (last_pos != std::string::npos) {
5 changes: 4 additions & 1 deletion src/plugins/intel_npu/src/plugin/npuw/util.hpp
Original file line number Diff line number Diff line change
@@ -15,7 +15,10 @@ namespace ov {
namespace npuw {
namespace util {

bool is_set(const std::size_t sub_idx, const std::string& opt, const std::size_t end_idx = SIZE_MAX);
bool is_set(const std::size_t sub_idx,
const std::string& opt,
const std::size_t real_idx = SIZE_MAX,
const std::size_t end_idx = SIZE_MAX);

// Every great project has its own string class...
// NB: Newer C++ standards would allow to use string views or smt

0 comments on commit da4c16e

Please sign in to comment.