Use Python-like slice indexing across a given dimension

vadimkantorov: <p>Is it possible to dynamically apply Python-style indexing <code>slice(start, stop, step)</code> to a given dimension? <code>narrow</code> doesn’t help here, since it doesn’t support step. <code>as_strided</code> would likely help. Is there a more idiomatic way?</p>

albanD: <p>Hi,</p>
<p>I don’t think we have a function to do that. But you can use indexing like <code>a[:, 0:4:2]</code> to achieve this. Or give the slice object directly inside the <code>[]</code>.<br>
Will that work for you?</p>

vadimkantorov: <p>I’d like to support a dynamic dimension. My current workaround is:</p>
<pre><code class="lang-python">def tensor_slice(tensor, dim, s):
    if dim &lt; 0:
        dim += tensor.dim()
    return tensor[(slice(None),) * dim + (s, )]
</code></pre>
<p>I do it to implement packbits: <a href="https://github.com/pytorch/pytorch/issues/32867" rel="nofollow noopener">https://github.com/pytorch/pytorch/issues/32867</a></p>
<p>A question: if I do <code>as_strided</code> instead, can I control the shape of the result? Basically I need to select every 8th bool element, then every 8th+1, … 8th+7 in order to pack them into one uint8 array.</p>

vadimkantorov: <p>I guess adding a step parameter to <code>narrow</code> would fix my usecase</p>

albanD: <p>You can do everything with as_strided <img src="https://discuss.pytorch.org/images/emoji/apple/stuck_out_tongue.png?v=12" title=":stuck_out_tongue:" class="emoji" alt=":stuck_out_tongue:" loading="lazy" width="20" height="20"> But it might not be easy to read.</p>
<blockquote>
<p>I guess adding a step parameter to <code>narrow</code> would fix my usecase</p>
</blockquote>
<p>I do think that this is the way to go yes.<br>
With the potential that it fails if the underlying Tensor cannot be viewed this way.</p>

vadimkantorov: <p>You can check out my implementation of <code>packbits</code>: <a href="https://github.com/pytorch/pytorch/issues/32867#issuecomment-660230647" rel="nofollow noopener">https://github.com/pytorch/pytorch/issues/32867#issuecomment-660230647</a></p>
<p>Seems to work. Of course it’d be faster to implement this natively in C++</p>

tom: <aside class="quote no-group quote-modified" data-username="albanD" data-post="5" data-topic="89606">
<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/alband/48/215_2.png" class="avatar"> albanD:</div>
<blockquote>
<blockquote>
<p>I guess adding a step parameter to <code>narrow</code> would fix my usecase</p>
</blockquote>
<p>I do think that this is the way to go yes.</p>
</blockquote>
</aside>
<p>I don’t, instead I think that investigating why ATen’s slice isn’t visible in Python is probably the way to go…</p>

vadimkantorov: <p>Should I file a GitHub issue about what <a class="mention" href="/u/tom">@tom</a> suggests?</p>

tom: <p>You might want to read about the background. Personally I don’t think we would do the same these days with JIT .code giving slice, but what do I know. Here and in the PR that is linked is the thing:</p>
<aside class="onebox githubpullrequest">
  <header class="source">
      <a href="https://github.com/pytorch/pytorch/pull/7902" target="_blank" rel="nofollow noopener">github.com/pytorch/pytorch</a>
  </header>
  <article class="onebox-body">
    <div class="github-row">
  <div class="github-icon-container" title="Pull Request">
    <svg width="60" height="60" class="github-icon" viewBox="0 0 12 16" aria-hidden="true"><path d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
  </div>

  <div class="github-info-container">
    <h4>
      <a href="https://github.com/pytorch/pytorch/pull/7902" target="_blank" rel="nofollow noopener">Add docstring for `torch.slice`</a>
    </h4>

    <div class="branches">
      <code>pytorch:master</code> ← <code>sethah:slice_doc</code>
    </div>

    <div class="github-info">
      <div class="date">
        opened <span class="discourse-local-date" data-format="ll" data-date="2018-05-28" data-time="23:17:50" data-timezone="UTC">11:17PM - 28 May 18 UTC</span>
      </div>

      <div class="user">
        <a href="https://github.com/sethah" target="_blank" rel="nofollow noopener">
          <img alt="sethah" src="https://avatars2.githubusercontent.com/u/7275795?v=4" class="onebox-avatar-inline" width="20" height="20">
          sethah
        </a>
      </div>

      <div class="lines" title="4 commits changed 4 files with 50 additions and 0 deletions">
        <a href="https://github.com/pytorch/pytorch/pull/7902/files" target="_blank" rel="nofollow noopener">
          <span class="added">+50</span>
          <span class="removed">-0</span>
        </a>
      </div>
    </div>

  </div>
</div>

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>

<p>In the meantime, you can just call the JIT op (<code>torch.ops.aten.slice(tensor, dim, start, stop, step)</code>)</p>
<p>Best regards</p>
<p>Thomas</p>