forked from openvinotoolkit/openvino
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ebc247a
commit 19a4833
Showing
9 changed files
with
266 additions
and
27 deletions.
There are no files selected for viewing
18 changes: 12 additions & 6 deletions
18
src/common/snippets/docs/debug_capabilities/LIR_passes_serialization.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,20 @@ | ||
# Snippets LIR passes serialization | ||
|
||
LIR(Linear Intermediate Representation) is used as the graph format in control flow pipeline, where dozens of passes are applied to LIR. This is to transfer the graph gradually to the stage that can generate kernel directly via expression emit. When each pass applied to LIR, there are some changes to the LIR. Developers maybe want check if the the result is as expected. This capability is introduced to serialize LIRs after every pass, then developer can check all these LIR stages. | ||
LIR(Linear Intermediate Representation) is used as graph reprsentation in control flow pipeline, where dozens of passes are applied to LIR. This is to transfer the graph gradually to the stage that can generate kernel directly via expression instruction emission. When each pass is applied to LIR, there are some expected changes. Developers maybe want to check if the the result is as expected. This capability is introduced to serialize LIRs before and after passes, then developer can check these LIR changes and stages. | ||
|
||
To turn on snippets LIR passses serialization feature, the following environment variable should be used to set the folder that the LIRs is dumped to: | ||
To turn on snippets LIR passses serialization feature, the following environment variable should be used: | ||
```sh | ||
OV_CPU_SNIPPETS_LIR_PATH=<folder_path> binary ... | ||
OV_SNIPPETS_DUMP_LIR=<space_separated_options> binary ... | ||
``` | ||
|
||
Examples: | ||
```sh | ||
OV_CPU_SNIPPETS_LIR_PATH="/home/debug/LIRs" binary ... | ||
OV_CPU_SNIPPETS_LIR_PATH="/home/debug/LIRs/" binary ... | ||
``` | ||
OV_SNIPPETS_DUMP_LIR="passes=all dir=path/dumpdir formats=all" binary ... | ||
OV_SNIPPETS_DUMP_LIR="passes=Insert dir=path/dumpdir formats=control_flow" binary ... | ||
OV_SNIPPETS_DUMP_LIR="passes=Insert formats=data_flow" binary ... | ||
``` | ||
|
||
Option names are case insensitive, the following options are supported: | ||
- `passes` : Dump LIR around the pass if the set value is included in pass name. Key word 'all' means to dump LIR around every pass. If not set, will not dump. | ||
- `dir` : Path to dumped LIR files. If omitted, it defaults to intel_snippets_LIR_dump. | ||
- `formats` : Support value of control_flow, data_flow or all. If omitted, it defaults to control_flow. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
// Copyright (C) 2024 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
#ifdef SNIPPETS_DEBUG_CAPS | ||
|
||
#pragma once | ||
|
||
#include "openvino/util/common_util.hpp" | ||
#include "openvino/core/except.hpp" | ||
|
||
#include <bitset> | ||
#include <memory> | ||
#include <unordered_map> | ||
#include <utility> | ||
#include <vector> | ||
|
||
namespace ov { | ||
namespace snippets { | ||
|
||
class DebugCapsConfig { | ||
private: | ||
struct PropertySetter; | ||
using PropertySetterPtr = std::shared_ptr<PropertySetter>; | ||
|
||
public: | ||
DebugCapsConfig() { | ||
readProperties(); | ||
} | ||
|
||
struct LIRFormatFilter { | ||
enum Type : uint8_t { | ||
controlFlow = 0, dataFlow, NumOfTypes | ||
}; | ||
std::bitset<NumOfTypes> filter; | ||
|
||
PropertySetterPtr getPropertySetter() { | ||
return PropertySetterPtr(new BitsetFilterPropertySetter<NumOfTypes>("formats", filter, {{"all", {controlFlow, dataFlow}}, | ||
{"control_flow", {controlFlow}}, | ||
{"data_flow", {dataFlow}}, | ||
})); | ||
} | ||
}; | ||
|
||
struct PropertyGroup { | ||
virtual std::vector<PropertySetterPtr> getPropertySetters() = 0; | ||
|
||
void parseAndSet(const std::string& str) { | ||
const auto& options = ov::util::split(str, ' '); | ||
const auto& propertySetters = getPropertySetters(); | ||
bool failed = false; | ||
auto getHelp = [propertySetters]() { | ||
std::string help; | ||
for (const auto& property : propertySetters) | ||
help.append('\t' + property->getPropertyName() + "=<" + property->getPropertyValueDescription() + ">\n"); | ||
return help; | ||
}; | ||
|
||
for (const auto& option : options) { | ||
const auto& parts = ov::util::split(option, '='); | ||
if (parts.size() > 2) { | ||
failed = true; | ||
break; | ||
} | ||
const auto& propertyName = ov::util::to_lower(parts.front()); | ||
const auto& foundSetter = std::find_if(propertySetters.begin(), propertySetters.end(), | ||
[propertyName] (const PropertySetterPtr& setter) { return setter->getPropertyName() == propertyName; }); | ||
if (foundSetter == propertySetters.end() || | ||
!(*foundSetter)->parseAndSet(parts.size() == 1 ? "" : parts.back())) { | ||
failed = true; | ||
break; | ||
} | ||
} | ||
|
||
if (failed) | ||
OPENVINO_THROW( | ||
"Wrong syntax: ", | ||
str, | ||
"\n", | ||
"The following space separated options are supported (option names are case insensitive):", | ||
"\n", | ||
getHelp()); | ||
} | ||
}; | ||
|
||
struct : PropertyGroup { | ||
std::string dir = "intel_snippets_LIR_dump"; | ||
LIRFormatFilter format = { 1 << LIRFormatFilter::controlFlow }; | ||
std::string passes = ""; | ||
|
||
std::vector<PropertySetterPtr> getPropertySetters() override { | ||
return { PropertySetterPtr(new StringPropertySetter("dir", dir, "path to dumped LIRs")), | ||
format.getPropertySetter(), | ||
PropertySetterPtr(new StringPropertySetter("passes", passes, "indicate dumped LIRs around these passes"))}; | ||
} | ||
} dumpLIR; | ||
|
||
private: | ||
struct PropertySetter { | ||
virtual bool parseAndSet(const std::string& str) = 0; | ||
virtual std::string getPropertyValueDescription() const = 0; | ||
|
||
PropertySetter(std::string name) : propertyName(std::move(name)) {} | ||
|
||
virtual ~PropertySetter() = default; | ||
|
||
const std::string& getPropertyName() const { return propertyName; } | ||
|
||
private: | ||
const std::string propertyName; | ||
}; | ||
|
||
struct StringPropertySetter : PropertySetter { | ||
StringPropertySetter(const std::string& name, std::string& ref, const std::string&& valueDescription) | ||
: PropertySetter(name), property(ref), propertyValueDescription(valueDescription) {} | ||
|
||
~StringPropertySetter() override = default; | ||
|
||
bool parseAndSet(const std::string& str) override { | ||
property = str; | ||
return true; | ||
} | ||
std::string getPropertyValueDescription() const override { return propertyValueDescription; } | ||
|
||
private: | ||
std::string& property; | ||
const std::string propertyValueDescription; | ||
}; | ||
|
||
template<std::size_t NumOfBits> | ||
struct BitsetFilterPropertySetter : PropertySetter { | ||
struct Token { | ||
std::string name; | ||
std::vector<size_t> bits; | ||
}; | ||
|
||
BitsetFilterPropertySetter(const std::string& name, std::bitset<NumOfBits>& ref, const std::vector<Token>&& tokens) | ||
: PropertySetter(name), property(ref), propertyTokens(tokens) {} | ||
|
||
~BitsetFilterPropertySetter() override = default; | ||
|
||
bool parseAndSet(const std::string& str) override { | ||
const auto& tokens = str.empty() ? | ||
std::vector<std::string>{"all"} : ov::util::split(ov::util::to_lower(str), ','); | ||
property.reset(); | ||
for (const auto& token : tokens) { | ||
const bool tokenVal = (token.front() != '-'); | ||
const auto& tokenName = tokenVal ? token : token.substr(1); | ||
const auto& foundToken = std::find_if(propertyTokens.begin(), propertyTokens.end(), | ||
[tokenName] (const Token& token) { return token.name == tokenName; }); | ||
if (foundToken == propertyTokens.end()) | ||
return false; | ||
|
||
for (const auto& bit : foundToken->bits) { | ||
property.set(bit, tokenVal); | ||
} | ||
} | ||
return true; | ||
} | ||
std::string getPropertyValueDescription() const override { | ||
std::string supportedTokens = "comma separated filter tokens: "; | ||
for (size_t i = 0; i < propertyTokens.size(); i++) { | ||
if (i) | ||
supportedTokens.push_back(','); | ||
supportedTokens.append(propertyTokens[i].name); | ||
} | ||
supportedTokens.append("; -'token' is used for exclusion, case does not matter, no tokens is treated as 'all'"); | ||
return supportedTokens; | ||
} | ||
|
||
private: | ||
std::bitset<NumOfBits>& property; | ||
const std::vector<Token> propertyTokens; | ||
}; | ||
|
||
void readProperties(); | ||
}; | ||
|
||
} // namespace snippets | ||
} // namespace ov | ||
|
||
#endif // SNIPPETS_DEBUG_CAPS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright (C) 2024 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
#ifdef SNIPPETS_DEBUG_CAPS | ||
|
||
#include "snippets/debug_caps.hpp" | ||
|
||
namespace ov { | ||
namespace snippets { | ||
|
||
void DebugCapsConfig::readProperties() { | ||
auto readEnv = [](const char* envVar) { | ||
const char* env = std::getenv(envVar); | ||
if (env && *env) | ||
return env; | ||
|
||
return (const char*)nullptr; | ||
}; | ||
|
||
const char* envVarValue = nullptr; | ||
if ((envVarValue = readEnv("OV_SNIPPETS_DUMP_LIR"))) | ||
dumpLIR.parseAndSet(envVarValue); | ||
} | ||
|
||
} // namespace snippets | ||
} // namespace ov | ||
|
||
#endif // SNIPPETS_DEBUG_CAPS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters