diff --git a/onnxruntime/core/framework/debug_node_inputs_outputs_utils.cc b/onnxruntime/core/framework/debug_node_inputs_outputs_utils.cc index 3f4718b0ac..100779a5ca 100644 --- a/onnxruntime/core/framework/debug_node_inputs_outputs_utils.cc +++ b/onnxruntime/core/framework/debug_node_inputs_outputs_utils.cc @@ -11,6 +11,7 @@ #include "core/common/path_utils.h" #include "core/framework/tensorprotoutils.h" #include "core/platform/env.h" +#include "core/platform/env_var_utils.h" namespace onnxruntime { namespace utils { @@ -188,7 +189,13 @@ const NodeDumpOptions& NodeDumpOptionsFromEnvironmentVariables() { NodeDumpOptions opts{}; - opts.dump_flags = NodeDumpOptions::DumpFlags::ShapeOnly; + // Preserve existing behavior of printing the shapes by default. Turn it off only if the user has requested so + // explicitly by setting the value of the env variable to 0. + opts.dump_flags = NodeDumpOptions::DumpFlags::None; + if (ParseEnvironmentVariable(env_vars::kDumpShapeData, true)) { + opts.dump_flags |= NodeDumpOptions::DumpFlags::Shape; + } + if (get_bool_env_var(env_vars::kDumpInputData)) { opts.dump_flags |= NodeDumpOptions::DumpFlags::InputData; } @@ -215,7 +222,10 @@ const NodeDumpOptions& NodeDumpOptionsFromEnvironmentVariables() { opts.output_dir = Path::Parse(ToPathString(Env::Default().GetEnvironmentVar(env_vars::kOutputDir))); // check for confirmation for dumping data to files for all nodes - if (opts.dump_flags != NodeDumpOptions::DumpFlags::ShapeOnly && + const bool is_input_or_output_requested = ((opts.dump_flags & NodeDumpOptions::DumpFlags::InputData) != 0) || + ((opts.dump_flags & NodeDumpOptions::DumpFlags::OutputData) != 0); + + if (is_input_or_output_requested && opts.data_destination == NodeDumpOptions::DataDestination::TensorProtoFiles && opts.filter.name_pattern.empty() && opts.filter.op_type_pattern.empty()) { ORT_ENFORCE( @@ -231,9 +241,24 @@ const NodeDumpOptions& NodeDumpOptionsFromEnvironmentVariables() { return node_dump_options; } +static bool IsAnyOutputDumped(const NodeDumpOptions& dump_options) { + return dump_options.dump_flags != NodeDumpOptions::DumpFlags::None; +} + +static void PrintIf(bool boolean_expression, const std::string& message) { + if (boolean_expression) { + std::cout << message; + } +} + void DumpNodeInputs( const NodeDumpOptions& dump_options, const OpKernelContext& context, const Node& node, const SessionState& session_state) { + const bool is_any_output_dumped = IsAnyOutputDumped(dump_options); + if (!is_any_output_dumped) { + return; + } + if (!FilterNode(dump_options, node)) return; std::cout << "-----------\n"; @@ -252,7 +277,8 @@ void DumpNodeInputs( const auto& tensor = *context.Input(i); const auto& shape = tensor.Shape(); - std::cout << " Shape: " << shape << "\n"; + const bool is_shape_set = (dump_options.dump_flags & NodeDumpOptions::DumpFlags::Shape) != 0; + PrintIf(is_shape_set, MakeString(" Shape: ", shape, "\n")); if ((dump_options.dump_flags & NodeDumpOptions::DumpFlags::InputData) != 0) { DumpTensor(dump_options, tensor, input_defs[i]->Name(), session_state); @@ -276,6 +302,11 @@ void DumpNodeInputs( } void DumpNodeOutputs(const NodeDumpOptions& dump_options, OpKernelContext& context, const Node& node, const SessionState& session_state) { + const bool is_any_output_dumped = IsAnyOutputDumped(dump_options); + if (!is_any_output_dumped) { + return; + } + if (!FilterNode(dump_options, node)) return; std::cout << "-----------\n"; @@ -291,7 +322,8 @@ void DumpNodeOutputs(const NodeDumpOptions& dump_options, OpKernelContext& conte const auto& tensor = *context.Output(i); const auto& shape = tensor.Shape(); - std::cout << " Shape: " << shape << "\n"; + const bool is_shape_set = (dump_options.dump_flags & NodeDumpOptions::DumpFlags::Shape) != 0; + PrintIf(is_shape_set, MakeString(" Shape: ", shape, "\n")); if ((dump_options.dump_flags & NodeDumpOptions::DumpFlags::OutputData) != 0) { DumpTensor(dump_options, tensor, output_defs[i]->Name(), session_state); diff --git a/onnxruntime/core/framework/debug_node_inputs_outputs_utils.h b/onnxruntime/core/framework/debug_node_inputs_outputs_utils.h index bed1a9cb3c..a7b1699bfe 100644 --- a/onnxruntime/core/framework/debug_node_inputs_outputs_utils.h +++ b/onnxruntime/core/framework/debug_node_inputs_outputs_utils.h @@ -18,6 +18,10 @@ namespace utils { // environment variables that control debug node dumping behavior namespace debug_node_inputs_outputs_env_vars { +// Shape is printed by default unless it's turned OFF by setting environment +// variable ORT_DEBUG_NODE_IO_DUMP_SHAPE_DATA to 0. +// set to non-zero to dump shape data +constexpr const char* kDumpShapeData = "ORT_DEBUG_NODE_IO_DUMP_SHAPE_DATA"; // set to non-zero to dump node input data constexpr const char* kDumpInputData = "ORT_DEBUG_NODE_IO_DUMP_INPUT_DATA"; // set to non-zero to dump node output data @@ -43,10 +47,11 @@ constexpr char kFilterPatternDelimiter = ';'; struct NodeDumpOptions { enum DumpFlags { - ShapeOnly = 0, - InputData = 1 << 0, - OutputData = 1 << 1, - AllData = InputData | OutputData, + None = 0, + Shape = 1 << 0, + InputData = 1 << 1, + OutputData = 1 << 2, + AllData = Shape | InputData | OutputData, }; // specifies the information to dump per node @@ -54,7 +59,7 @@ struct NodeDumpOptions { // Note: // When dumping every node, dumping both input and output may be redundant. // Doing that may be more useful when dumping a subset of all nodes. - int dump_flags{DumpFlags::ShapeOnly}; + int dump_flags{DumpFlags::Shape}; // filters the nodes that are dumped // Note: