[CPU] [DEBUG CAPS] Implicitly enable perf counters for verbose mode (#8754)
Also refactor debug capabilities configuration. Now debug caps config parameters are the part of plugin configuration.
This commit is contained in:
parent
71b7c7000a
commit
3a9dba7362
@ -43,6 +43,7 @@ Config::Config() {
|
|||||||
if (!with_cpu_x86_bfloat16())
|
if (!with_cpu_x86_bfloat16())
|
||||||
enforceBF16 = false;
|
enforceBF16 = false;
|
||||||
|
|
||||||
|
CPU_DEBUG_CAP_ENABLE(readDebugCapsProperties());
|
||||||
updateProperties();
|
updateProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +137,7 @@ void Config::readProperties(const std::map<std::string, std::string> &prop) {
|
|||||||
if (exclusiveAsyncRequests) // Exclusive request feature disables the streams
|
if (exclusiveAsyncRequests) // Exclusive request feature disables the streams
|
||||||
streamExecutorConfig._streams = 1;
|
streamExecutorConfig._streams = 1;
|
||||||
|
|
||||||
|
CPU_DEBUG_CAP_ENABLE(readDebugCapsProperties());
|
||||||
updateProperties();
|
updateProperties();
|
||||||
}
|
}
|
||||||
void Config::updateProperties() {
|
void Config::updateProperties() {
|
||||||
@ -184,4 +186,51 @@ void Config::updateProperties() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CPU_DEBUG_CAPS
|
||||||
|
void Config::readDebugCapsProperties() {
|
||||||
|
auto readEnv = [](const char* envVar) {
|
||||||
|
return std::getenv(envVar);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto parseDumpFormat = [](const std::string& format) {
|
||||||
|
if (format == "BIN")
|
||||||
|
return FORMAT::BIN;
|
||||||
|
else if (format == "TEXT")
|
||||||
|
return FORMAT::TEXT;
|
||||||
|
else
|
||||||
|
IE_THROW() << "readDebugCapsProperties: Unknown dump format";
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* envVarValue = nullptr;
|
||||||
|
|
||||||
|
if (envVarValue = readEnv("OV_CPU_EXEC_GRAPH_PATH"))
|
||||||
|
execGraphPath = envVarValue;
|
||||||
|
|
||||||
|
if (envVarValue = readEnv("OV_CPU_VERBOSE"))
|
||||||
|
verbose = envVarValue;
|
||||||
|
|
||||||
|
if (envVarValue = readEnv("OV_CPU_BLOB_DUMP_DIR"))
|
||||||
|
blobDumpDir = envVarValue;
|
||||||
|
|
||||||
|
if (envVarValue = readEnv("OV_CPU_BLOB_DUMP_FORMAT"))
|
||||||
|
blobDumpFormat = parseDumpFormat(envVarValue);
|
||||||
|
|
||||||
|
if (envVarValue = readEnv("OV_CPU_BLOB_DUMP_NODE_EXEC_ID"))
|
||||||
|
blobDumpFilters[BY_EXEC_ID] = envVarValue;
|
||||||
|
|
||||||
|
if (envVarValue = readEnv("OV_CPU_BLOB_DUMP_NODE_PORTS"))
|
||||||
|
blobDumpFilters[BY_PORTS] = envVarValue;
|
||||||
|
|
||||||
|
if (envVarValue = readEnv("OV_CPU_BLOB_DUMP_NODE_TYPE"))
|
||||||
|
blobDumpFilters[BY_TYPE] = envVarValue;
|
||||||
|
|
||||||
|
if (envVarValue = readEnv("OV_CPU_BLOB_DUMP_NODE_NAME"))
|
||||||
|
blobDumpFilters[BY_NAME] = envVarValue;
|
||||||
|
|
||||||
|
// always enable perf counters for verbose mode
|
||||||
|
if (!verbose.empty())
|
||||||
|
collectPerfCounters = true;
|
||||||
|
}
|
||||||
|
#endif // CPU_DEBUG_CAPS
|
||||||
|
|
||||||
} // namespace MKLDNNPlugin
|
} // namespace MKLDNNPlugin
|
||||||
|
@ -39,14 +39,34 @@ struct Config {
|
|||||||
bool manualEnforceBF16 = false;
|
bool manualEnforceBF16 = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CPU_DEBUG_CAPS
|
|
||||||
DebugCaps::Config debugCaps;
|
|
||||||
#endif
|
|
||||||
std::string cache_dir{};
|
std::string cache_dir{};
|
||||||
|
|
||||||
void readProperties(const std::map<std::string, std::string> &config);
|
void readProperties(const std::map<std::string, std::string> &config);
|
||||||
void updateProperties();
|
void updateProperties();
|
||||||
std::map<std::string, std::string> _config;
|
std::map<std::string, std::string> _config;
|
||||||
|
|
||||||
|
#ifdef CPU_DEBUG_CAPS
|
||||||
|
enum FILTER {
|
||||||
|
BY_PORTS,
|
||||||
|
BY_EXEC_ID,
|
||||||
|
BY_TYPE,
|
||||||
|
BY_NAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class FORMAT {
|
||||||
|
BIN,
|
||||||
|
TEXT,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string execGraphPath;
|
||||||
|
std::string verbose;
|
||||||
|
std::string blobDumpDir = "mkldnn_dump";
|
||||||
|
FORMAT blobDumpFormat = FORMAT::TEXT;
|
||||||
|
// std::hash<int> is necessary for Ubuntu-16.04 (gcc-5.4 and defect in C++11 standart)
|
||||||
|
std::unordered_map<FILTER, std::string, std::hash<int>> blobDumpFilters;
|
||||||
|
|
||||||
|
void readDebugCapsProperties();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MKLDNNPlugin
|
} // namespace MKLDNNPlugin
|
||||||
|
@ -311,7 +311,6 @@ void MKLDNNGraph::Replicate(const CNNNetwork &network, const MKLDNNExtensionMana
|
|||||||
|
|
||||||
void MKLDNNGraph::InitGraph() {
|
void MKLDNNGraph::InitGraph() {
|
||||||
MKLDNNGraphOptimizer optimizer;
|
MKLDNNGraphOptimizer optimizer;
|
||||||
CPU_DEBUG_CAP_ENABLE(initNodeDumper(config.debugCaps));
|
|
||||||
|
|
||||||
SortTopologically();
|
SortTopologically();
|
||||||
InitNodes();
|
InitNodes();
|
||||||
@ -838,7 +837,7 @@ void MKLDNNGraph::PullOutputData(BlobMap &out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void MKLDNNGraph::ExecuteNode(const MKLDNNNodePtr& node, const mkldnn::stream& stream) const {
|
inline void MKLDNNGraph::ExecuteNode(const MKLDNNNodePtr& node, const mkldnn::stream& stream) const {
|
||||||
DUMP(node, infer_count);
|
DUMP(node, config, infer_count);
|
||||||
OV_ITT_SCOPED_TASK(itt::domains::MKLDNNPlugin, node->profiling.execute);
|
OV_ITT_SCOPED_TASK(itt::domains::MKLDNNPlugin, node->profiling.execute);
|
||||||
|
|
||||||
if (node->isDynamicNode()) {
|
if (node->isDynamicNode()) {
|
||||||
@ -856,7 +855,7 @@ void MKLDNNGraph::Infer(MKLDNNInferRequest* request, int batch) {
|
|||||||
mkldnn::stream stream(eng);
|
mkldnn::stream stream(eng);
|
||||||
|
|
||||||
for (const auto& node : executableGraphNodes) {
|
for (const auto& node : executableGraphNodes) {
|
||||||
VERBOSE(node, config.debugCaps.verbose);
|
VERBOSE(node, config.verbose);
|
||||||
PERF(node, config.collectPerfCounters);
|
PERF(node, config.collectPerfCounters);
|
||||||
|
|
||||||
if (request)
|
if (request)
|
||||||
|
@ -209,7 +209,7 @@ std::shared_ptr<ngraph::Function> dump_graph_as_ie_ngraph_net(const MKLDNNGraph
|
|||||||
|
|
||||||
#ifdef CPU_DEBUG_CAPS
|
#ifdef CPU_DEBUG_CAPS
|
||||||
void serialize(const MKLDNNGraph &graph) {
|
void serialize(const MKLDNNGraph &graph) {
|
||||||
const std::string& path = graph.getConfig().debugCaps.execGraphPath;
|
const std::string& path = graph.getConfig().execGraphPath;
|
||||||
|
|
||||||
if (path.empty())
|
if (path.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -579,6 +579,10 @@ public:
|
|||||||
return outputShapes[port];
|
return outputShapes[port];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<InferenceEngine::Blob::Ptr>& getInternalBlobs() const {
|
||||||
|
return internalBlobs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return scales and shift if nodes can be executed as ScaleShift, else raise exception
|
* @brief Return scales and shift if nodes can be executed as ScaleShift, else raise exception
|
||||||
* If node has only scale or shift value, fill missing value with default values
|
* If node has only scale or shift value, fill missing value with default values
|
||||||
@ -671,7 +675,6 @@ protected:
|
|||||||
friend class MKLDNNEdge;
|
friend class MKLDNNEdge;
|
||||||
friend class MKLDNNGraph;
|
friend class MKLDNNGraph;
|
||||||
friend class MKLDNNGraphOptimizer;
|
friend class MKLDNNGraphOptimizer;
|
||||||
friend class NodeDumper;
|
|
||||||
|
|
||||||
void selectPreferPrimitiveDescriptor(const std::vector<impl_desc_type>& priority, bool ignoreConstInputs);
|
void selectPreferPrimitiveDescriptor(const std::vector<impl_desc_type>& priority, bool ignoreConstInputs);
|
||||||
bool isConfigDefined(const NodeConfig &config) const;
|
bool isConfigDefined(const NodeConfig &config) const;
|
||||||
|
@ -231,7 +231,7 @@ void BlobDumper::dump(const std::string &dump_path) const {
|
|||||||
std::ofstream dump_file;
|
std::ofstream dump_file;
|
||||||
dump_file.open(dump_path);
|
dump_file.open(dump_path);
|
||||||
if (!dump_file.is_open())
|
if (!dump_file.is_open())
|
||||||
IE_THROW() << "Dumper cannot create dump file";
|
IE_THROW() << "Dumper cannot create dump file " << dump_path;
|
||||||
|
|
||||||
dump(dump_file);
|
dump(dump_file);
|
||||||
dump_file.close();
|
dump_file.close();
|
||||||
@ -241,7 +241,7 @@ void BlobDumper::dumpAsTxt(const std::string& dump_path) const {
|
|||||||
std::ofstream dump_file;
|
std::ofstream dump_file;
|
||||||
dump_file.open(dump_path);
|
dump_file.open(dump_path);
|
||||||
if (!dump_file.is_open())
|
if (!dump_file.is_open())
|
||||||
IE_THROW() << "Dumper cannot create dump file";
|
IE_THROW() << "Dumper cannot create dump file " << dump_path;
|
||||||
|
|
||||||
dumpAsTxt(dump_file);
|
dumpAsTxt(dump_file);
|
||||||
dump_file.close();
|
dump_file.close();
|
||||||
|
@ -5,50 +5,11 @@
|
|||||||
|
|
||||||
#ifdef CPU_DEBUG_CAPS
|
#ifdef CPU_DEBUG_CAPS
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
#define CPU_DEBUG_CAP_ENABLE(_x) _x;
|
#define CPU_DEBUG_CAP_ENABLE(_x) _x;
|
||||||
#define CPU_DEBUG_CAPS_ALWAYS_TRUE(x) true
|
#define CPU_DEBUG_CAPS_ALWAYS_TRUE(x) true
|
||||||
|
|
||||||
namespace MKLDNNPlugin {
|
|
||||||
namespace DebugCaps {
|
|
||||||
|
|
||||||
class Config {
|
|
||||||
public:
|
|
||||||
Config() {
|
|
||||||
readParam(blobDumpDir, "OV_CPU_BLOB_DUMP_DIR");
|
|
||||||
readParam(blobDumpFormat, "OV_CPU_BLOB_DUMP_FORMAT");
|
|
||||||
readParam(blobDumpNodeExecId, "OV_CPU_BLOB_DUMP_NODE_EXEC_ID");
|
|
||||||
readParam(blobDumpNodePorts, "OV_CPU_BLOB_DUMP_NODE_PORTS");
|
|
||||||
readParam(blobDumpNodeType, "OV_CPU_BLOB_DUMP_NODE_TYPE");
|
|
||||||
readParam(blobDumpNodeName, "OV_CPU_BLOB_DUMP_NODE_NAME");
|
|
||||||
readParam(execGraphPath, "OV_CPU_EXEC_GRAPH_PATH");
|
|
||||||
readParam(verbose, "OV_CPU_VERBOSE");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string blobDumpDir;
|
|
||||||
std::string blobDumpFormat;
|
|
||||||
std::string blobDumpNodeExecId;
|
|
||||||
std::string blobDumpNodePorts;
|
|
||||||
std::string blobDumpNodeType;
|
|
||||||
std::string blobDumpNodeName;
|
|
||||||
std::string execGraphPath;
|
|
||||||
std::string verbose;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void readParam(std::string& param, const char* envVar) {
|
|
||||||
if (const char* envValue = std::getenv(envVar))
|
|
||||||
param = envValue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace DebugCaps
|
|
||||||
} // namespace MKLDNNPlugin
|
|
||||||
|
|
||||||
#else // !CPU_DEBUG_CAPS
|
#else // !CPU_DEBUG_CAPS
|
||||||
|
|
||||||
#define CPU_DEBUG_CAP_ENABLE(_x)
|
#define CPU_DEBUG_CAP_ENABLE(_x)
|
||||||
#define CPU_DEBUG_CAPS_ALWAYS_TRUE(x) x
|
#define CPU_DEBUG_CAPS_ALWAYS_TRUE(x) x
|
||||||
|
|
||||||
|
@ -8,10 +8,8 @@
|
|||||||
#include "mkldnn_node.h"
|
#include "mkldnn_node.h"
|
||||||
#include "ie_common.h"
|
#include "ie_common.h"
|
||||||
#include "utils/blob_dump.h"
|
#include "utils/blob_dump.h"
|
||||||
#include "utils/debug_capabilities.h"
|
|
||||||
#include "memory_desc/cpu_memory_desc_utils.h"
|
#include "memory_desc/cpu_memory_desc_utils.h"
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -20,30 +18,105 @@ using namespace InferenceEngine;
|
|||||||
|
|
||||||
namespace MKLDNNPlugin {
|
namespace MKLDNNPlugin {
|
||||||
|
|
||||||
NodeDumper::NodeDumper(const DebugCaps::Config& config)
|
static void formatNodeName(std::string& name) {
|
||||||
: dumpFormat(FORMAT::BIN)
|
std::replace(name.begin(), name.end(), '\\', '_');
|
||||||
, dumpDirName("mkldnn_dump") {
|
std::replace(name.begin(), name.end(), '/', '_');
|
||||||
if (!config.blobDumpDir.empty())
|
std::replace(name.begin(), name.end(), ' ', '_');
|
||||||
dumpDirName = config.blobDumpDir;
|
std::replace(name.begin(), name.end(), ':', '-');
|
||||||
|
|
||||||
if (!config.blobDumpFormat.empty())
|
|
||||||
dumpFormat = parseDumpFormat(config.blobDumpFormat);
|
|
||||||
|
|
||||||
if (!config.blobDumpNodeExecId.empty())
|
|
||||||
dumpFilters[FILTER::BY_EXEC_ID] = config.blobDumpNodeExecId;
|
|
||||||
|
|
||||||
if (!config.blobDumpNodePorts.empty())
|
|
||||||
dumpFilters[FILTER::BY_PORTS] = config.blobDumpNodePorts;
|
|
||||||
|
|
||||||
if (!config.blobDumpNodeType.empty())
|
|
||||||
dumpFilters[FILTER::BY_TYPE] = config.blobDumpNodeType;
|
|
||||||
|
|
||||||
if (!config.blobDumpNodeName.empty())
|
|
||||||
dumpFilters[FILTER::BY_NAME] = config.blobDumpNodeName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeDumper::dumpInputBlobs(const MKLDNNNodePtr& node, int count) const {
|
static bool shouldBeDumped(const MKLDNNNodePtr& node, const Config& config, const std::string& portsKind) {
|
||||||
if (!shouldBeDumped(node, "IN"))
|
const auto& dumpFilters = config.blobDumpFilters;
|
||||||
|
|
||||||
|
if (dumpFilters.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (dumpFilters.count(Config::FILTER::BY_PORTS)) { // filter by ports configured
|
||||||
|
if (dumpFilters.at(Config::FILTER::BY_PORTS) != "ALL" &&
|
||||||
|
portsKind != dumpFilters.at(Config::FILTER::BY_PORTS))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dumpFilters.count(Config::FILTER::BY_EXEC_ID)) { // filter by exec id configured
|
||||||
|
std::stringstream ss(dumpFilters.at(Config::FILTER::BY_EXEC_ID));
|
||||||
|
int id;
|
||||||
|
bool matched = false;
|
||||||
|
|
||||||
|
while (ss >> id) {
|
||||||
|
if (node->getExecIndex() == id) {// exec id matches
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matched)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dumpFilters.count(Config::FILTER::BY_TYPE)) { // filter by type configured
|
||||||
|
std::stringstream ss(dumpFilters.at(Config::FILTER::BY_TYPE));
|
||||||
|
std::string type;
|
||||||
|
bool matched = false;
|
||||||
|
|
||||||
|
while (ss >> type) {
|
||||||
|
if (NameFromType(node->getType()) == type) {// type does not match
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matched)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dumpFilters.count(Config::FILTER::BY_NAME)) { // filter by name configured
|
||||||
|
if (dumpFilters.at(Config::FILTER::BY_NAME) != "*" && // to have 'single char' option for matching all the names
|
||||||
|
!std::regex_match(node->getName(), std::regex(dumpFilters.at(Config::FILTER::BY_NAME)))) // name does not match
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump(const BlobDumper& bd, const std::string& file, const Config& config) {
|
||||||
|
switch (config.blobDumpFormat) {
|
||||||
|
case Config::FORMAT::BIN: {
|
||||||
|
bd.dump(file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Config::FORMAT::TEXT: {
|
||||||
|
bd.dumpAsTxt(file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
IE_THROW() << "NodeDumper: Unknown dump format";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpInternalBlobs(const MKLDNNNodePtr& node, const Config& config) {
|
||||||
|
std::string nodeName = node->getName();
|
||||||
|
formatNodeName(nodeName);
|
||||||
|
|
||||||
|
const auto& internalBlobs = node->getInternalBlobs();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < internalBlobs.size(); i++) {
|
||||||
|
const auto& blb = internalBlobs[i];
|
||||||
|
std::string file_name = NameFromType(node->getType()) + "_" + nodeName + "_blb" + std::to_string(i) + ".ieb";
|
||||||
|
auto dump_file = config.blobDumpDir + "/#" + std::to_string(node->getExecIndex()) + "_" + file_name;
|
||||||
|
|
||||||
|
TensorDesc desc = blb->getTensorDesc();
|
||||||
|
if (desc.getPrecision() == Precision::BIN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MKLDNNMemoryPtr memory = std::make_shared<MKLDNNMemory>(node->getEngine());
|
||||||
|
memory->Create(MemoryDescUtils::convertToDnnlBlockedMemoryDesc(desc), blb->buffer());
|
||||||
|
BlobDumper dumper(memory);
|
||||||
|
dump(dumper, dump_file, config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpInputBlobs(const MKLDNNNodePtr& node, const Config& config, int count) {
|
||||||
|
if (!shouldBeDumped(node, config, "IN"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto exec_order = std::to_string(node->getExecIndex());
|
auto exec_order = std::to_string(node->getExecIndex());
|
||||||
@ -62,7 +135,7 @@ void NodeDumper::dumpInputBlobs(const MKLDNNNodePtr& node, int count) const {
|
|||||||
if (file_name.size() > 240)
|
if (file_name.size() > 240)
|
||||||
file_name = file_name.substr(file_name.size() - 240);
|
file_name = file_name.substr(file_name.size() - 240);
|
||||||
|
|
||||||
auto dump_file = dumpDirName + "/#" + exec_order + "_" + file_name;
|
auto dump_file = config.blobDumpDir + "/#" + exec_order + "_" + file_name;
|
||||||
std::cout << "Dump inputs: " << dump_file << std::endl;
|
std::cout << "Dump inputs: " << dump_file << std::endl;
|
||||||
|
|
||||||
auto& desc = prEdge->getMemory().getDesc();
|
auto& desc = prEdge->getMemory().getDesc();
|
||||||
@ -70,14 +143,14 @@ void NodeDumper::dumpInputBlobs(const MKLDNNNodePtr& node, int count) const {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
BlobDumper dumper(prEdge->getMemoryPtr());
|
BlobDumper dumper(prEdge->getMemoryPtr());
|
||||||
dump(dumper, dump_file);
|
dump(dumper, dump_file, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
dumpInternalBlobs(node);
|
dumpInternalBlobs(node, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeDumper::dumpOutputBlobs(const MKLDNNNodePtr& node, int count) const {
|
void dumpOutputBlobs(const MKLDNNNodePtr& node, const Config& config, int count) {
|
||||||
if (!shouldBeDumped(node, "OUT"))
|
if (!shouldBeDumped(node, config, "OUT"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto exec_order = std::to_string(node->getExecIndex());
|
auto exec_order = std::to_string(node->getExecIndex());
|
||||||
@ -95,7 +168,7 @@ void NodeDumper::dumpOutputBlobs(const MKLDNNNodePtr& node, int count) const {
|
|||||||
if (file_name.size() > 240)
|
if (file_name.size() > 240)
|
||||||
file_name = file_name.substr(file_name.size() - 240);
|
file_name = file_name.substr(file_name.size() - 240);
|
||||||
|
|
||||||
auto dump_file = dumpDirName + "/#" + exec_order + "_" + file_name;
|
auto dump_file = config.blobDumpDir + "/#" + exec_order + "_" + file_name;
|
||||||
std::cout << "Dump outputs: " << dump_file << std::endl;
|
std::cout << "Dump outputs: " << dump_file << std::endl;
|
||||||
|
|
||||||
auto& desc = childEdge->getMemory().getDesc();
|
auto& desc = childEdge->getMemory().getDesc();
|
||||||
@ -103,122 +176,9 @@ void NodeDumper::dumpOutputBlobs(const MKLDNNNodePtr& node, int count) const {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
BlobDumper dumper(childEdge->getMemoryPtr());
|
BlobDumper dumper(childEdge->getMemoryPtr());
|
||||||
dump(dumper, dump_file);
|
dump(dumper, dump_file, config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeDumper::dumpInternalBlobs(const MKLDNNNodePtr& node) const {
|
|
||||||
std::string nodeName = node->getName();
|
|
||||||
formatNodeName(nodeName);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < node->internalBlobs.size(); i++) {
|
|
||||||
const auto& blb = node->internalBlobs[i];
|
|
||||||
std::string file_name = NameFromType(node->getType()) + "_" + nodeName + "_blb" + std::to_string(i) + ".ieb";
|
|
||||||
auto dump_file = dumpDirName + "/#" + std::to_string(node->getExecIndex()) + "_" + file_name;
|
|
||||||
|
|
||||||
TensorDesc desc = blb->getTensorDesc();
|
|
||||||
if (desc.getPrecision() == Precision::BIN)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MKLDNNMemoryPtr memory = std::make_shared<MKLDNNMemory>(node->getEngine());
|
|
||||||
memory->Create(MemoryDescUtils::convertToDnnlBlockedMemoryDesc(desc), blb->buffer());
|
|
||||||
BlobDumper dumper(memory);
|
|
||||||
dump(dumper, dump_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeDumper::dump(const BlobDumper& bd, const std::string& file) const {
|
|
||||||
switch (dumpFormat) {
|
|
||||||
case FORMAT::BIN: {
|
|
||||||
bd.dump(file);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FORMAT::TEXT: {
|
|
||||||
bd.dumpAsTxt(file);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
IE_THROW() << "NodeDumper: Unknown dump format";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeDumper::shouldBeDumped(const MKLDNNNodePtr& node, const std::string& portsKind) const {
|
|
||||||
if (dumpFilters.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (dumpFilters.count(FILTER::BY_PORTS)) { // filter by ports configured
|
|
||||||
if (dumpFilters.at(FILTER::BY_PORTS) != "ALL" &&
|
|
||||||
portsKind != dumpFilters.at(FILTER::BY_PORTS))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dumpFilters.count(FILTER::BY_EXEC_ID)) { // filter by exec id configured
|
|
||||||
std::stringstream ss(dumpFilters.at(FILTER::BY_EXEC_ID));
|
|
||||||
int id;
|
|
||||||
bool matched = false;
|
|
||||||
|
|
||||||
while (ss >> id) {
|
|
||||||
if (node->getExecIndex() == id) {// exec id matches
|
|
||||||
matched = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!matched)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dumpFilters.count(FILTER::BY_TYPE)) { // filter by type configured
|
|
||||||
std::stringstream ss(dumpFilters.at(FILTER::BY_TYPE));
|
|
||||||
std::string type;
|
|
||||||
bool matched = false;
|
|
||||||
|
|
||||||
while (ss >> type) {
|
|
||||||
if (NameFromType(node->getType()) == type) {// type does not match
|
|
||||||
matched = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!matched)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dumpFilters.count(FILTER::BY_NAME)) { // filter by name configured
|
|
||||||
if (dumpFilters.at(FILTER::BY_NAME) != "*" && // to have 'single char' option for matching all the names
|
|
||||||
!std::regex_match(node->getName(), std::regex(dumpFilters.at(FILTER::BY_NAME)))) // name does not match
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeDumper::FORMAT NodeDumper::parseDumpFormat(const std::string& format) const {
|
|
||||||
if (format == "BIN")
|
|
||||||
return FORMAT::BIN;
|
|
||||||
else if (format == "TEXT")
|
|
||||||
return FORMAT::TEXT;
|
|
||||||
else
|
|
||||||
IE_THROW() << "NodeDumper: Unknown dump format";
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeDumper::formatNodeName(std::string& name) const {
|
|
||||||
std::replace(name.begin(), name.end(), '\\', '_');
|
|
||||||
std::replace(name.begin(), name.end(), '/', '_');
|
|
||||||
std::replace(name.begin(), name.end(), ' ', '_');
|
|
||||||
std::replace(name.begin(), name.end(), ':', '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<NodeDumper> nd;
|
|
||||||
|
|
||||||
void initNodeDumper(const DebugCaps::Config& config) {
|
|
||||||
nd.reset(new NodeDumper(config));
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::unique_ptr<NodeDumper>& getNodeDumper() {
|
|
||||||
assert(nd.get() != nullptr);
|
|
||||||
return nd;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MKLDNNPlugin
|
} // namespace MKLDNNPlugin
|
||||||
#endif // CPU_DEBUG_CAPS
|
#endif // CPU_DEBUG_CAPS
|
||||||
|
@ -5,71 +5,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mkldnn_node.h"
|
#include "mkldnn_node.h"
|
||||||
#include "utils/blob_dump.h"
|
#include "config.h"
|
||||||
#include "utils/debug_capabilities.h"
|
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace MKLDNNPlugin {
|
namespace MKLDNNPlugin {
|
||||||
|
|
||||||
/**
|
void dumpInputBlobs(const MKLDNNNodePtr &node, const Config& config, int count = -1);
|
||||||
* Blobs are not dumped by default
|
void dumpOutputBlobs(const MKLDNNNodePtr &node, const Config& config, int count = -1);
|
||||||
* Blobs are dumped if node matches all specified env filters
|
|
||||||
*
|
|
||||||
* To dump blobs from all the nodes use the following filter:
|
|
||||||
*
|
|
||||||
* OV_CPU_BLOB_DUMP_NODE_NAME=.+
|
|
||||||
*/
|
|
||||||
class NodeDumper {
|
|
||||||
public:
|
|
||||||
NodeDumper(const DebugCaps::Config& config);
|
|
||||||
|
|
||||||
void dumpInputBlobs(const MKLDNNNodePtr &node, int count = -1) const;
|
|
||||||
void dumpOutputBlobs(const MKLDNNNodePtr &node, int count = -1) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void dumpInternalBlobs(const MKLDNNNodePtr& node) const;
|
|
||||||
void dump(const BlobDumper& bd, const std::string& file) const;
|
|
||||||
bool shouldBeDumped(const MKLDNNNodePtr &node, const std::string& portsKind) const;
|
|
||||||
|
|
||||||
enum class FORMAT {
|
|
||||||
BIN,
|
|
||||||
TEXT,
|
|
||||||
};
|
|
||||||
|
|
||||||
FORMAT parseDumpFormat(const std::string& format) const;
|
|
||||||
void formatNodeName(std::string& name) const;
|
|
||||||
|
|
||||||
FORMAT dumpFormat;
|
|
||||||
std::string dumpDirName;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
enum FILTER {
|
|
||||||
BY_PORTS,
|
|
||||||
BY_EXEC_ID,
|
|
||||||
BY_TYPE,
|
|
||||||
BY_NAME,
|
|
||||||
};
|
|
||||||
|
|
||||||
// std::hash<int> is necessary for Ubuntu-16.04 (gcc-5.4 and defect in C++11 standart)
|
|
||||||
std::unordered_map<FILTER, std::string, std::hash<int>> dumpFilters;
|
|
||||||
};
|
|
||||||
|
|
||||||
void initNodeDumper(const DebugCaps::Config& config);
|
|
||||||
const std::unique_ptr<NodeDumper>& getNodeDumper();
|
|
||||||
|
|
||||||
class DumpHelper {
|
class DumpHelper {
|
||||||
const MKLDNNNodePtr& node;
|
const MKLDNNNodePtr& node;
|
||||||
const int count;
|
const int count;
|
||||||
|
const Config& config;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DumpHelper(const MKLDNNNodePtr& _node, int _count = -1): node(_node), count(_count) {
|
explicit DumpHelper(const MKLDNNNodePtr& _node, const Config& _config, int _count = -1): node(_node), config(_config), count(_count) {
|
||||||
getNodeDumper()->dumpInputBlobs(node, count);
|
dumpInputBlobs(node, config, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
~DumpHelper() {
|
~DumpHelper() {
|
||||||
getNodeDumper()->dumpOutputBlobs(node, count);
|
dumpOutputBlobs(node, config, count);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,13 +21,15 @@ public:
|
|||||||
return;
|
return;
|
||||||
printInfo();
|
printInfo();
|
||||||
}
|
}
|
||||||
virtual ~Verbose() {
|
|
||||||
|
~Verbose() {
|
||||||
if (!shouldBePrinted())
|
if (!shouldBePrinted())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printDuration();
|
printDuration();
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const MKLDNNNodePtr& node;
|
const MKLDNNNodePtr& node;
|
||||||
const int lvl;
|
const int lvl;
|
||||||
@ -39,7 +41,8 @@ private:
|
|||||||
void flush() const;
|
void flush() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define VERBOSE(...) Verbose(__VA_ARGS__)
|
// use heap allocation instead of stack to align with PERF macro (to have proper destruction order)
|
||||||
|
#define VERBOSE(...) const auto verbose = std::unique_ptr<Verbose>(new Verbose(__VA_ARGS__));
|
||||||
} // namespace MKLDNNPlugin
|
} // namespace MKLDNNPlugin
|
||||||
#else
|
#else
|
||||||
#define VERBOSE(...)
|
#define VERBOSE(...)
|
||||||
|
Loading…
Reference in New Issue
Block a user