Result of indexing depends on datatypes of indexes?

Sascha_Frolich: <p>I just came upon this:</p>
<pre><code class="lang-auto">$ idx_long = torch.tensor(2).type('torch.LongTensor')
$ idx_byte = torch.tensor(2).type('torch.ByteTensor')
</code></pre>
<pre><code class="lang-auto">$ torch.eye(4)[idx_long,:]
tensor([0., 0., 1., 0.])
</code></pre>
<p>while</p>
<pre><code class="lang-auto">$ torch.eye(4)[idx_byte,:]
tensor([[[1., 0., 0., 0.],
         [0., 1., 0., 0.],
         [0., 0., 1., 0.],
         [0., 0., 0., 1.]]])
</code></pre>
<p>So the result of the indexing depends on the datatype of the indexing tensor. Why?</p>

KFrank: <p>Hi Sascha!</p>
<aside class="quote no-group" data-username="Sascha_Frolich" data-post="1" data-topic="180306" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/sascha_frolich/48/60640_2.png" class="avatar"> Sascha_Frolich:</div>
<blockquote>
<p>So the result of the indexing depends on the datatype of the indexing tensor. Why?</p>
</blockquote>
</aside>
<p>The short story is that indexing with a <code>ByteTensor</code> (<code>dtype = torch.uint8</code>) is<br>
(although deprecated) <em>boolean</em> indexing, which works differently than indexing<br>
with positional integer indices.</p>
<p>Three things are going on:  Your <code>ByteTensor</code> gets cast (at least in effect) to<br>
<code>bool</code>; boolean indexing works differently than integer indexing; and your index<br>
tensors are <em>zero-dimensional</em> tensors, which may make the expected shapes<br>
of the result tensors less obvious.</p>
<p>Pytorch didn’t used to have boolean tensors so byte tensors were used for<br>
logical operations.  Such use has now been deprecated.</p>
<p>Pytorch doesn’t document its <em>advanced indexing</em> directly, but, instead, refers<br>
to <a href="https://numpy.org/doc/1.24/user/basics.indexing.html#boolean-array-indexing" rel="noopener nofollow ugc">numpy’s documentation.</a></p>
<p>Consider:</p>
<pre><code class="lang-plaintext">&gt;&gt;&gt; import torch
&gt;&gt;&gt; print (torch.__version__)
2.0.0
&gt;&gt;&gt;
&gt;&gt;&gt; t_byte = torch.tensor ([1, 0, 2, 0, 3], dtype = torch.uint8)
&gt;&gt;&gt; t_bool = t_byte.bool()
&gt;&gt;&gt; t_long = t_byte.long()
&gt;&gt;&gt;
&gt;&gt;&gt; t_byte
tensor([1, 0, 2, 0, 3], dtype=torch.uint8)
&gt;&gt;&gt; t_bool
tensor([ True, False,  True, False,  True])
&gt;&gt;&gt; t_long
tensor([1, 0, 2, 0, 3])
&gt;&gt;&gt;
&gt;&gt;&gt; t = torch.tensor ([11.0, 12.0, 13.0, 14.0, 15.0])
&gt;&gt;&gt; t
tensor([11., 12., 13., 14., 15.])
&gt;&gt;&gt;
&gt;&gt;&gt; t[t_bool]   # boolean indexing -- note shape is [3]
tensor([11., 13., 15.])
&gt;&gt;&gt; t[t_long]   # regular indexing -- shape is [5]
tensor([12., 11., 13., 11., 14.])
&gt;&gt;&gt;
&gt;&gt;&gt; t[t_byte]   # byte gets cast to bool (but byte indexing is deprecated)
&lt;stdin&gt;:1: UserWarning: indexing with dtype torch.uint8 is now deprecated, please use a dtype torch.bool instead. (Triggered internally at C:\cb\pytorch_1000000000000\work\aten\src\ATen/native/IndexingUtils.h:28.)
tensor([11., 13., 15.])
</code></pre>
<p>Best.</p>
<p>K. Frank</p>