[LibTorch] How to print the content of a tensor in gdb?

miguelvr: <p>Hey guys,</p>
<p>I’m relatively new to C++ and LibTorch, but I would like to know how to inspect a tensor content in the debugger, since my workflow involves a lot of usage of the debugger.</p>
<p>In gdb I’m trying to do:</p>
<pre><code class="lang-auto">print x

$8 = {impl_ = {target_ = 0x14dfa20}}

print x.data()

Couldn't find method at::Tensor::data
</code></pre>
<p>I know torch::Tensor is a pointer, but I just can’t figure out how to dereference it</p>
<p>Cheers,<br>
Miguel</p>

dtmoodie: <p>You could try something like the following:<br>
<aside class="onebox githubblob">
  <header class="source">
      <a href="https://github.com/dtmoodie/GDB-ImageWatch/blob/master/cv_imshow.py" target="_blank" rel="nofollow noopener">github.com</a>
  </header>
  <article class="onebox-body">
    <h4><a href="https://github.com/dtmoodie/GDB-ImageWatch/blob/master/cv_imshow.py" target="_blank" rel="nofollow noopener">dtmoodie/GDB-ImageWatch/blob/master/cv_imshow.py</a></h4>
<pre><code class="lang-py"># Copyright (c) 2012, Renato Florentino Garcia &lt;fgarcia.renato@gmail.com&gt;
#                     Stefano Pellegrini &lt;stefpell@ee.ethz.ch&gt;
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the authors nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
</code></pre>

  This file has been truncated. <a href="https://github.com/dtmoodie/GDB-ImageWatch/blob/master/cv_imshow.py" target="_blank" rel="nofollow noopener">show original</a>

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>
</p>
<p>With some modifications it could be used for visualizing tensors.</p>

miguelvr: <p>how do you import that into gdb?</p>

afshin67: <p>You can use some <code>p *x[0].data&lt;float&gt;()</code> if it is a single dimension tensor, or <code>p *x.data&lt;float&gt;()</code> if it is a no-dim tensor, and so on.</p>
<p>Afshin</p>

miguelvr: <p>it is a 4 dimensional tensor, but I would like to know how to do it for a tensor of arbitrary size.</p>
<p>Basically what I’m looking for is an output similar to</p>
<pre><code class="lang-auto">std::cout &lt;&lt; x &lt;&lt; '\n';
</code></pre>
<p>if I have to implement a python extension, so be it… but I still don’t understand how to do it.</p>

afshin67: <p>I think you can see the content using <code>cout</code> in either run or debug consoles. Since you asked about <code>gdb</code>, I mentioned that approach. If you want to use <code>gdb,</code> you need to add more dimensions, e.g. <code>p *x[i][j][k][l].data&lt;float&gt;()</code>.</p>

miguelvr: <p>that is not working for me</p>
<p>it either says <code>Could not find operator[].</code> or <code>No symbol "operator*" in current context.</code></p>
<p>I also couldn’t use <code>cout</code> directly in gdb, so far.</p>
<p>I’m new to C++, so I might be doing something wrong.</p>

afshin67: <p>you cannot use <code>cout</code> in <code>gdb</code>, you need to hard code it. The error of <code>Could not find operator[]</code> is your <code>gdb</code> error. Probably it does not mach <code>torch</code>.</p>

yf225: <p>Can you try <code>print x.toString()</code>?</p>

miguelvr: <p>That prints a memory address and the type of tensor</p>

tom: <p><code>print at::print(std::cout, x, 99)</code>, 99 being the line width.</p>
<p>Best regards</p>
<p>Thomas</p>

miguelvr: <p>I’m getting <code>No symbol "print" in namespace "at".</code></p>
<p>I must be missing something…</p>

tom: <p>It’s defined in <a href="https://github.com/pytorch/pytorch/blob/master/aten/src/ATen/core/Formatting.h" rel="nofollow noopener"><code>ATen/core/Formatting.h</code></a>. As far as I can see it should be there for 1.0, 1.0.1, and master. You could try using it in your code to see what’s wrong.</p>
<p>Best regards</p>
<p>Thomas</p>

miguelvr: <p>i can use it while running the script, just not while attached to gdb</p>

tom: <p>Strange. It worked for me the other day. While the version without the ostream might not be available due to the inlining, I would have expected the one with to be exported at the least.</p>

Y.E_Zhou: <p>Have you found a good solution?<br>
In pytorch_1.3, try:</p>
<pre><code class="lang-auto">p self.impl_-&gt;sizes() 
# such as 4-dims
p self.impl_-&gt;sizes().Data[0]
...
p self.impl_-&gt;sizes().Data[3]
</code></pre>
<p>to inspect data size, and</p>
<pre><code class="lang-auto">p self.impl_-&gt;storage().storage_impl_-&gt;numel()   # num of elements
p  ((float *)self.impl_-&gt;storage().storage_impl_-&gt;data())[0]  # the first element
</code></pre>
<p>to inspect value of tensor.</p>

tshadley: <p>As of 1.5.0, Tensor.print() seems to work to print type and shape info.</p>
<pre><code class="lang-auto">gdb) call t.print()
[CPUByteType [1, 10, 1, 10]]
</code></pre>
<p>To print full contents, it seems the form std::cout &lt;&lt; Tensor &lt;&lt; std::endl must be present in debugged C++ file first.  But you also have to call fflush(0) since gdb has trouble with std::endl in my test case.</p>
<p>A .gdbinit quick solution:</p>
<pre><code class="lang-auto">define ptensor
  call std::cout &lt;&lt; $arg0
  call fflush(0)
end
</code></pre>
<pre><code class="lang-auto">(gdb) ptensor tensor
(1,1,.,.) =
  0  0  1  3  4  4  3  1  0  0
...

$4 = (std::ostream &amp;) @0x55555597e740: &lt;incomplete type&gt;
[ CPUByteType{1,10,1,10} ]$5 = 0
</code></pre>
<p>But this prints the WHOLE tensor so only a partial solution.</p>

isai_roman: <p>Hi,<br>
got it working in LLDB … but it has to be similar. Are you still interested?<br>
Best regards</p>

sardanian: <p>I’d love to know how to view a tensor in CLION’s debugger. I have not been able to get any of these solutions to work. I would love to be able to see the contents of the tensor while inspecting or evaluating an expression like I am able to see a vector.<br>
How were you able to get it working in LLDB?</p>

TachikakaMin: <p>Maybe try:</p>
<p>tensor[0].item.v.i</p>