Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable full message with tf.Print #8953

Closed
MicaelCarvalho opened this issue Apr 4, 2017 · 4 comments
Closed

Enable full message with tf.Print #8953

MicaelCarvalho opened this issue Apr 4, 2017 · 4 comments

Comments

@MicaelCarvalho
Copy link
Contributor

@MicaelCarvalho MicaelCarvalho commented Apr 4, 2017

Operating System: Debian 4.8.15-2
Installed version of CUDA and cuDNN: CUDA 8, cuDNN 5
python3 -c "import tensorflow; print(tensorflow.version)": 1.0.1

Minimal reproducible example

import tensorflow as tf
ph = tf.placeholder(tf.float32, [3,4,5,6])
ts = tf.shape(ph)
tp = tf.Print(ts, [ts])
tm = tf.reduce_mean(tp)
sess = tf.Session()
res = sess.run(tm)

Output
I tensorflow/core/kernels/logging_ops.cc:79] [3 4 5...]

Maybe there is some obvious way around this, but I couldn't find any on the docs. To state the obvious : I'm trying to see the full shape of the tensor, and not only the first 3 positions. In this example its size is 4, but I would like to be able to see whatever I want with whatever size it has.

Furthermore, debugging into TensorFlow did became a problem when I got to line 62 of logging_ops.py, where gen_logging_ops is used but it doesn't seem to be declared anywhere — and older versions already had this, I'm probably missing some link, because grep and find couldn't find anything useful:

Output of grep

tensorflow$ grep -R "gen_logging_ops" .
./tensorflow/python/framework/function_test.py:from tensorflow.python.ops import gen_logging_ops
./tensorflow/python/framework/function_test.py:      check = gen_logging_ops._assert(math_ops.greater(x, 0), [x])
./tensorflow/python/ops/control_flow_ops.py:from tensorflow.python.ops import gen_logging_ops
./tensorflow/python/ops/control_flow_ops.py:      return gen_logging_ops._assert(
./tensorflow/python/ops/control_flow_ops.py:        return gen_logging_ops._assert(
./tensorflow/python/ops/summary_ops.py:from tensorflow.python.ops import gen_logging_ops
./tensorflow/python/ops/summary_ops.py:from tensorflow.python.ops.gen_logging_ops import *
./tensorflow/python/ops/summary_ops.py:    val = gen_logging_ops._tensor_summary(
./tensorflow/python/ops/logging_ops.py:from tensorflow.python.ops import gen_logging_ops
./tensorflow/python/ops/logging_ops.py:from tensorflow.python.ops.gen_logging_ops import *
./tensorflow/python/ops/logging_ops.py:  return gen_logging_ops._print(input_, data, message, first_n, summarize, name)
./tensorflow/python/ops/logging_ops.py:    val = gen_logging_ops._histogram_summary(
./tensorflow/python/ops/logging_ops.py:    val = gen_logging_ops._image_summary(
./tensorflow/python/ops/logging_ops.py:    val = gen_logging_ops._audio_summary_v2(tag=tag,
./tensorflow/python/ops/logging_ops.py:    val = gen_logging_ops._merge_summary(inputs=inputs, name=name)
./tensorflow/python/ops/logging_ops.py:    val = gen_logging_ops._scalar_summary(tags=tags, values=values, name=scope)
./tensorflow/python/kernel_tests/control_flow_ops_py_test.py:from tensorflow.python.ops import gen_logging_ops
./tensorflow/python/kernel_tests/control_flow_ops_py_test.py:        unguarded_assert = gen_logging_ops._assert(
./tensorflow/python/summary/summary.py:from tensorflow.python.ops import gen_logging_ops as _gen_logging_ops
./tensorflow/python/summary/summary.py:    val = _gen_logging_ops._scalar_summary(
./tensorflow/python/summary/summary.py:    val = _gen_logging_ops._image_summary(
./tensorflow/python/summary/summary.py:    val = _gen_logging_ops._histogram_summary(
./tensorflow/python/summary/summary.py:    val = _gen_logging_ops._audio_summary_v2(
./tensorflow/python/summary/summary.py:    val = _gen_logging_ops._merge_summary(inputs=inputs, name=name)

Output of find

tensorflow$ find . -iname "*logging_ops*"
./tensorflow/core/ops/logging_ops.cc
./tensorflow/core/kernels/logging_ops_test.cc
./tensorflow/core/kernels/logging_ops.cc
./tensorflow/python/ops/logging_ops.py
./tensorflow/python/kernel_tests/logging_ops_test.py

Besides evaluating what I want with sess.run and manually printing it with python, is there any tensorflow-friendly solution to this? Debugging should be easier. :)

@MicaelCarvalho
Copy link
Contributor Author

@MicaelCarvalho MicaelCarvalho commented Apr 4, 2017

Closing: parameter summarize in tf.Print. Still no clue about the gen_logging_ops

Loading

@frreiss
Copy link
Contributor

@frreiss frreiss commented Jul 16, 2017

For the benefit of anyone else who reaches this issue while searching for the origin of gen_logging_ops: The file gen_logging_ops.py is generated by the bazel build. The rule that causes this file to be generated is located in the file tensorflow/core/BUILD (search for "tf_gen_op_libs"). The build rule takes as input the contents of tensorflow/core/ops/logging_ops.cc and generates a Python function for each instance of the REGISTER_OP macro in that C++ source file. By convention, the name of the generated Python function is a lowercased version of the corresponding operator's name, with an underscore placed before every character that was in uppercase in the original name (i.e. "Print" ==> "_print"). The corresponding kernel for the generated Python function _print() is located in tensorflow/core/kernels/logging_ops.cc.

Loading

@frreiss
Copy link
Contributor

@frreiss frreiss commented Jul 17, 2017

Correction: the tf_gen_op_libs rule is just the first step in the codegen process. That rule generates a compiled C++ library containing the operator. Later in the build, the rule at line 1146 of python/BUILD invokes the rule tf_gen_op_wrapper_private_py from python/build_defs.bzl. This rule in turn invokes the rule tf_gen_op_wrapper_py from tensorflow.bzl, which creates a static binary containing the library file for the logging ops and the compiled object file for python_op_gen_main.cc; then invokes the binary, passing it the contents of the text file python/ops/hidden_ops.txt.

Next, the main function in python_op_gen_main.cc creates an operators registry. Since the executable was only linked with the logging operators, this registry only contains the logging operators. The main function passes this registry, along with the list of operators in hidden_ops.txt, to the function PrintPythonOps(), which is defined in python_op_gen.cc. This function generates the contents of gen_logging_ops.py and prints those contents to STDOUT. Back in tensorflow.bzl, the tf_gen_op_wrapper_py rule directs STDOUT of the C++ program to gen_logging_ops.py.

Loading

@Yonv1943
Copy link

@Yonv1943 Yonv1943 commented Jul 27, 2018

I found a simple way to show the full message of tensor.shape.

def tensor_check(tensor): return tf.Print(tensor, [str(tensor.shape), tensor.shape,tf.shape(tensor), tensor.get_shape()], message='||| ')

and it will return the follow message:
||| [(2, 16, 16, 64)][2 16 16...][2 16 16...][2 16 16...]

just use str()

(゜-゜)つロ

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants