[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())
|
||||
enforceBF16 = false;
|
||||
|
||||
CPU_DEBUG_CAP_ENABLE(readDebugCapsProperties());
|
||||
updateProperties();
|
||||
}
|
||||
|
||||
@ -136,6 +137,7 @@ void Config::readProperties(const std::map<std::string, std::string> &prop) {
|
||||
if (exclusiveAsyncRequests) // Exclusive request feature disables the streams
|
||||
streamExecutorConfig._streams = 1;
|
||||
|
||||
CPU_DEBUG_CAP_ENABLE(readDebugCapsProperties());
|
||||
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
|
||||
|
@ -39,14 +39,34 @@ struct Config {
|
||||
bool manualEnforceBF16 = false;
|
||||
#endif
|
||||
|
||||
#ifdef CPU_DEBUG_CAPS
|
||||
DebugCaps::Config debugCaps;
|
||||
#endif
|
||||
std::string cache_dir{};
|
||||
|
||||
void readProperties(const std::map<std::string, std::string> &config);
|
||||
void updateProperties();
|
||||
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
|
||||
|
@ -311,7 +311,6 @@ void MKLDNNGraph::Replicate(const CNNNetwork &network, const MKLDNNExtensionMana
|
||||
|
||||
void MKLDNNGraph::InitGraph() {
|
||||
MKLDNNGraphOptimizer optimizer;
|
||||
CPU_DEBUG_CAP_ENABLE(initNodeDumper(config.debugCaps));
|
||||
|
||||
SortTopologically();
|
||||
InitNodes();
|
||||
@ -838,7 +837,7 @@ void MKLDNNGraph::PullOutputData(BlobMap &out) {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (node->isDynamicNode()) {
|
||||
@ -856,7 +855,7 @@ void MKLDNNGraph::Infer(MKLDNNInferRequest* request, int batch) {
|
||||
mkldnn::stream stream(eng);
|
||||
|
||||
for (const auto& node : executableGraphNodes) {
|
||||
VERBOSE(node, config.debugCaps.verbose);
|
||||
VERBOSE(node, config.verbose);
|
||||
PERF(node, config.collectPerfCounters);
|
||||
|
||||
if (request)
|
||||
|
@ -209,7 +209,7 @@ std::shared_ptr<ngraph::Function> dump_graph_as_ie_ngraph_net(const MKLDNNGraph
|
||||
|
||||
#ifdef CPU_DEBUG_CAPS
|
||||
void serialize(const MKLDNNGraph &graph) {
|
||||
const std::string& path = graph.getConfig().debugCaps.execGraphPath;
|
||||
const std::string& path = graph.getConfig().execGraphPath;
|
||||
|
||||
if (path.empty())
|
||||
return;
|
||||
|
@ -579,6 +579,10 @@ public:
|
||||
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
|
||||
* If node has only scale or shift value, fill missing value with default values
|
||||
@ -671,7 +675,6 @@ protected:
|
||||
friend class MKLDNNEdge;
|
||||
friend class MKLDNNGraph;
|
||||
friend class MKLDNNGraphOptimizer;
|
||||
friend class NodeDumper;
|
||||
|
||||
void selectPreferPrimitiveDescriptor(const std::vector<impl_desc_type>& priority, bool ignoreConstInputs);
|
||||
bool isConfigDefined(const NodeConfig &config) const;
|
||||
|
@ -231,7 +231,7 @@ void BlobDumper::dump(const std::string &dump_path) const {
|
||||
std::ofstream dump_file;
|
||||
dump_file.open(dump_path);
|
||||
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_file.close();
|
||||
@ -241,7 +241,7 @@ void BlobDumper::dumpAsTxt(const std::string& dump_path) const {
|
||||
std::ofstream dump_file;
|
||||
dump_file.open(dump_path);
|
||||
if (!dump_file.is_open())
|
||||
IE_THROW() << "Dumper cannot create dump file";
|
||||
IE_THROW() << "Dumper cannot create dump file " << dump_path;
|
||||
|
||||
dumpAsTxt(dump_file);
|
||||
dump_file.close();
|
||||
|
@ -5,50 +5,11 @@
|
||||
|
||||
#ifdef CPU_DEBUG_CAPS
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#define CPU_DEBUG_CAP_ENABLE(_x) _x;
|
||||
#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
|
||||
|
||||
#define CPU_DEBUG_CAP_ENABLE(_x)
|
||||
#define CPU_DEBUG_CAPS_ALWAYS_TRUE(x) x
|
||||
|
||||
|
@ -8,10 +8,8 @@
|
||||
#include "mkldnn_node.h"
|
||||
#include "ie_common.h"
|
||||
#include "utils/blob_dump.h"
|
||||
#include "utils/debug_capabilities.h"
|
||||
#include "memory_desc/cpu_memory_desc_utils.h"
|
||||
|
||||
#include <array>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
@ -20,30 +18,105 @@ using namespace InferenceEngine;
|
||||
|
||||
namespace MKLDNNPlugin {
|
||||
|
||||
NodeDumper::NodeDumper(const DebugCaps::Config& config)
|
||||
: dumpFormat(FORMAT::BIN)
|
||||
, dumpDirName("mkldnn_dump") {
|
||||
if (!config.blobDumpDir.empty())
|
||||
dumpDirName = config.blobDumpDir;
|
||||
|
||||
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;
|
||||
static void formatNodeName(std::string& name) {
|
||||
std::replace(name.begin(), name.end(), '\\', '_');
|
||||
std::replace(name.begin(), name.end(), '/', '_');
|
||||
std::replace(name.begin(), name.end(), ' ', '_');
|
||||
std::replace(name.begin(), name.end(), ':', '-');
|
||||
}
|
||||
|
||||
void NodeDumper::dumpInputBlobs(const MKLDNNNodePtr& node, int count) const {
|
||||
if (!shouldBeDumped(node, "IN"))
|
||||
static bool shouldBeDumped(const MKLDNNNodePtr& node, const Config& config, const std::string& portsKind) {
|
||||
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;
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
auto& desc = prEdge->getMemory().getDesc();
|
||||
@ -70,14 +143,14 @@ void NodeDumper::dumpInputBlobs(const MKLDNNNodePtr& node, int count) const {
|
||||
continue;
|
||||
|
||||
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 {
|
||||
if (!shouldBeDumped(node, "OUT"))
|
||||
void dumpOutputBlobs(const MKLDNNNodePtr& node, const Config& config, int count) {
|
||||
if (!shouldBeDumped(node, config, "OUT"))
|
||||
return;
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
auto& desc = childEdge->getMemory().getDesc();
|
||||
@ -103,122 +176,9 @@ void NodeDumper::dumpOutputBlobs(const MKLDNNNodePtr& node, int count) const {
|
||||
continue;
|
||||
|
||||
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
|
||||
#endif // CPU_DEBUG_CAPS
|
||||
|
@ -5,71 +5,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "mkldnn_node.h"
|
||||
#include "utils/blob_dump.h"
|
||||
#include "utils/debug_capabilities.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include "config.h"
|
||||
|
||||
namespace MKLDNNPlugin {
|
||||
|
||||
/**
|
||||
* Blobs are not dumped by default
|
||||
* 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();
|
||||
void dumpInputBlobs(const MKLDNNNodePtr &node, const Config& config, int count = -1);
|
||||
void dumpOutputBlobs(const MKLDNNNodePtr &node, const Config& config, int count = -1);
|
||||
|
||||
class DumpHelper {
|
||||
const MKLDNNNodePtr& node;
|
||||
const int count;
|
||||
const Config& config;
|
||||
|
||||
public:
|
||||
explicit DumpHelper(const MKLDNNNodePtr& _node, int _count = -1): node(_node), count(_count) {
|
||||
getNodeDumper()->dumpInputBlobs(node, count);
|
||||
explicit DumpHelper(const MKLDNNNodePtr& _node, const Config& _config, int _count = -1): node(_node), config(_config), count(_count) {
|
||||
dumpInputBlobs(node, config, count);
|
||||
}
|
||||
|
||||
~DumpHelper() {
|
||||
getNodeDumper()->dumpOutputBlobs(node, count);
|
||||
dumpOutputBlobs(node, config, count);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -21,13 +21,15 @@ public:
|
||||
return;
|
||||
printInfo();
|
||||
}
|
||||
virtual ~Verbose() {
|
||||
|
||||
~Verbose() {
|
||||
if (!shouldBePrinted())
|
||||
return;
|
||||
|
||||
printDuration();
|
||||
flush();
|
||||
}
|
||||
|
||||
private:
|
||||
const MKLDNNNodePtr& node;
|
||||
const int lvl;
|
||||
@ -39,7 +41,8 @@ private:
|
||||
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
|
||||
#else
|
||||
#define VERBOSE(...)
|
||||
|
Loading…
Reference in New Issue
Block a user