aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/profiler
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2018-01-12 13:20:27 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-01-12 13:24:39 -0800
commit5a814028e2c0531b9936ac3286ab43e3670f36c6 (patch)
tree8437a60bf74cad9559ef9dcb7e39e9e10e1586d7 /tensorflow/core/profiler
parentce10f988fc5417b1df17bb2905dc77943136db85 (diff)
tfprof support for eager.
PiperOrigin-RevId: 181784078
Diffstat (limited to 'tensorflow/core/profiler')
-rw-r--r--tensorflow/core/profiler/g3doc/command_line.md17
-rw-r--r--tensorflow/core/profiler/internal/print_model_analysis.cc36
-rw-r--r--tensorflow/core/profiler/internal/print_model_analysis.h3
-rw-r--r--tensorflow/core/profiler/internal/tfprof_utils.cc16
-rw-r--r--tensorflow/core/profiler/profiler.cc17
5 files changed, 63 insertions, 26 deletions
diff --git a/tensorflow/core/profiler/g3doc/command_line.md b/tensorflow/core/profiler/g3doc/command_line.md
index d41ac7290d..bbaf55e613 100644
--- a/tensorflow/core/profiler/g3doc/command_line.md
+++ b/tensorflow/core/profiler/g3doc/command_line.md
@@ -21,7 +21,8 @@ See QuickStart on generating the file.
<b>THE OLD WAY BELOW IS DEPRECATED:</b>
-<b>--graph_path:</b> GraphDef proto file (required). Used to build in-memory
+<b>--graph_path:</b> GraphDef proto file (optional in eager execution).
+Used to build in-memory
data structure of the model. For example, graph.pbtxt written by tf.Supervisor
can be passed to --graph_path. You can also easily get GraphDef using
tf.get_default_graph().as_graph_def(add_shapes=True) or other API.
@@ -72,6 +73,15 @@ bazel-bin/tensorflow/core/profiler/profiler help
```shell
# The following commands will start tfprof interactive mode.
#
+# Recommended:
+#
+# The file contains the binary string of ProfileProto.
+# It contains all needed information in one file.
+bazel-bin/tensorflow/core/profiler/profiler \
+ --profile_path=profile_xxx
+#
+# Alternatively, user can pass separate files.
+#
# --graph_path contains the model architecutre and tensor shapes.
# --run_meta_path contains the memory and time information.
# --op_log_path contains float operation and code traces.
@@ -80,6 +90,11 @@ bazel-bin/tensorflow/core/profiler/profiler help
# Only includes model architecture, parameters and shapes.
bazel-bin/tensorflow/core/profiler/profiler \
--graph_path=graph.pbtxt
+
+# For profiling eager execution, user can only specify run_meta_path
+# and profile execution info of each operation.
+bazel-bin/tensorflow/core/profiler/profiler \
+ --run_meta_path=run_meta
#
# Additionally profile ops memory and timing.
bazel-bin/tensorflow/core/profiler/profiler \
diff --git a/tensorflow/core/profiler/internal/print_model_analysis.cc b/tensorflow/core/profiler/internal/print_model_analysis.cc
index 4971471604..5a31c7d789 100644
--- a/tensorflow/core/profiler/internal/print_model_analysis.cc
+++ b/tensorflow/core/profiler/internal/print_model_analysis.cc
@@ -84,12 +84,13 @@ string RunProfile(const string& command, const string& options,
} // namespace
bool NewProfiler(const string* graph, const string* op_log) {
- CHECK(graph) << "graph mustn't be null";
std::unique_ptr<GraphDef> graph_ptr(new GraphDef());
- if (!graph_ptr->ParseFromString(*graph)) {
- if (!protobuf::TextFormat::ParseFromString(*graph, graph_ptr.get())) {
- fprintf(stderr, "Failed to parse graph\n");
- return false;
+ if (graph && !graph->empty()) {
+ if (!graph_ptr->ParseFromString(*graph)) {
+ if (!protobuf::TextFormat::ParseFromString(*graph, graph_ptr.get())) {
+ fprintf(stderr, "Failed to parse graph\n");
+ return false;
+ }
}
}
@@ -123,14 +124,15 @@ double AddStep(int64 step, const string* graph, const string* run_meta,
const string* op_log) {
CHECK(tf_stat);
- CHECK(graph && !graph->empty());
- std::unique_ptr<GraphDef> graph_ptr(new GraphDef());
- if (!graph_ptr->ParseFromString(*graph)) {
- if (!protobuf::TextFormat::ParseFromString(*graph, graph_ptr.get())) {
- fprintf(stderr, "Failed to parse graph\n");
+ if (graph && !graph->empty()) {
+ std::unique_ptr<GraphDef> graph_ptr(new GraphDef());
+ if (!graph_ptr->ParseFromString(*graph)) {
+ if (!protobuf::TextFormat::ParseFromString(*graph, graph_ptr.get())) {
+ fprintf(stderr, "Failed to parse graph\n");
+ }
}
+ tf_stat->AddGraph(std::move(graph_ptr));
}
- tf_stat->AddGraph(std::move(graph_ptr));
CHECK(run_meta && !run_meta->empty());
// TODO(xpan): Better error handling.
@@ -154,6 +156,13 @@ string Profile(const string* command, const string* options) {
return RunProfile(*command, *options, tf_stat);
}
+string SerializeToString() {
+ CHECK(tf_stat);
+ string content;
+ tf_stat->SerializeToString(&content);
+ return content;
+}
+
void WriteProfile(const string* filename) {
CHECK(tf_stat);
CHECK(filename) << "empty file name when asking to write profile.";
@@ -163,11 +172,12 @@ void WriteProfile(const string* filename) {
string PrintModelAnalysis(const string* graph, const string* run_meta,
const string* op_log, const string* command,
const string* options) {
- CHECK(graph) << "graph mustn't be null";
CHECK(command) << "command mustn't be null";
CHECK(options) << "options mustn't be null";
std::unique_ptr<GraphDef> graph_ptr(new GraphDef());
- graph_ptr->ParseFromString(*graph);
+ if (graph && !graph->empty()) {
+ graph_ptr->ParseFromString(*graph);
+ }
std::unique_ptr<RunMetadata> run_meta_ptr;
if (run_meta && !run_meta->empty()) {
diff --git a/tensorflow/core/profiler/internal/print_model_analysis.h b/tensorflow/core/profiler/internal/print_model_analysis.h
index 31ff5b07b0..90166aa7d5 100644
--- a/tensorflow/core/profiler/internal/print_model_analysis.h
+++ b/tensorflow/core/profiler/internal/print_model_analysis.h
@@ -44,6 +44,9 @@ void WriteProfile(const string* filename);
// Load the profile to profiler from a proto buffer file.
void ProfilerFromFile(const string* filename);
+// Returns a binary string that represents the serialized ProfileProto.
+string SerializeToString();
+
string Profile(const string* command, const string* options);
// Single-step Profiler.
diff --git a/tensorflow/core/profiler/internal/tfprof_utils.cc b/tensorflow/core/profiler/internal/tfprof_utils.cc
index 1ce59ad755..9eba2ccf04 100644
--- a/tensorflow/core/profiler/internal/tfprof_utils.cc
+++ b/tensorflow/core/profiler/internal/tfprof_utils.cc
@@ -297,17 +297,21 @@ void PrintHelp() {
"See https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/profiler/"
"g3doc/command_line.md for command line tool tutorial.\n");
printf(
- "profiler --profile_path=<ProfileProto binary file> # required\nor:\n"
- "profiler --graph_path=<GraphDef proto file> # required\n"
- " --run_meta_patn=<RunMetadata proto file> # optional\n"
- " --run_log_path=<OpLogProto proto file> # optional\n\n");
+ "profiler --profile_path=<ProfileProto binary file> # required\n"
+ "\nOr:\n\n"
+ "profiler --graph_path=<GraphDef proto file> "
+ "# Contains model graph info (no needed for eager execution)\n"
+ " --run_meta_path=<RunMetadata proto file> "
+ "# Contains runtime info. Optional.\n"
+ " --run_log_path=<OpLogProto proto file> "
+ "# Contains extra source code, flops, custom type info. Optional\n\n");
printf(
- "\nCommands:\n"
+ "\nTo skip interactive mode, append one of the following commands:\n"
" scope: Organize profiles based on name scopes.\n"
" graph: Organize profiles based on graph node input/output.\n"
" op: Organize profiles based on operation type.\n"
" code: Organize profiles based on python codes (need op_log_path).\n"
- " advise: Auto-profile and advise.\n"
+ " advise: Auto-profile and advise. (experimental)\n"
" set: Set options that will be default for follow up commands.\n"
" help: Show helps.\n");
fflush(stdout);
diff --git a/tensorflow/core/profiler/profiler.cc b/tensorflow/core/profiler/profiler.cc
index 6a965c5b73..2cc212d589 100644
--- a/tensorflow/core/profiler/profiler.cc
+++ b/tensorflow/core/profiler/profiler.cc
@@ -140,10 +140,12 @@ int Run(int argc, char** argv) {
}
port::InitMain(argv[0], &argc, &argv);
- if (!FLAGS_profile_path.empty() && !FLAGS_graph_path.empty()) {
+ if (!FLAGS_profile_path.empty() &&
+ (!FLAGS_graph_path.empty() || !FLAGS_run_meta_path.empty())) {
fprintf(stderr,
- "both --graph_path and --profile_path are set. "
- "Ignore graph_path\n");
+ "--profile_path is set, do not set --graph_path or "
+ "--run_meta_path\n");
+ return 1;
}
std::vector<string> account_type_regexes =
@@ -165,7 +167,8 @@ int Run(int argc, char** argv) {
CHECK(s.ok()) << s.ToString();
string cmd = "";
- if (argc == 1 && FLAGS_graph_path.empty() && FLAGS_profile_path.empty()) {
+ if (argc == 1 && FLAGS_graph_path.empty() && FLAGS_profile_path.empty() &&
+ FLAGS_run_meta_path.empty()) {
PrintHelp();
return 0;
} else if (argc > 1) {
@@ -202,8 +205,10 @@ int Run(int argc, char** argv) {
"Try to use a single --profile_path instead of "
"graph_path,op_log_path,run_meta_path\n");
std::unique_ptr<GraphDef> graph(new GraphDef());
- TF_CHECK_OK(
- ReadProtoFile(Env::Default(), FLAGS_graph_path, graph.get(), false));
+ if (!FLAGS_graph_path.empty()) {
+ TF_CHECK_OK(
+ ReadProtoFile(Env::Default(), FLAGS_graph_path, graph.get(), false));
+ }
std::unique_ptr<OpLogProto> op_log(new OpLogProto());
if (!FLAGS_op_log_path.empty()) {