Updating Pytorch Mobile to 1.8.0 from 1.7.1 causes "Dimension Out of Range" error in the PixelShuffle layer

ekremcet: <p>Hi,</p>
<p>I have updated the PytorchMobile for my Android application from 1.7.1 to 1.8.0 but doing so caused an error in the inference phase. Somehow the tensor dimensions became not valid anymore for PixelShuffle layer. Here is the error:</p>
<pre><code class="lang-auto">    Process: com.example.pytorchtutorial, PID: 14078
    java.lang.RuntimeException: The following operation failed in the TorchScript interpreter.
    Traceback of TorchScript, serialized code (most recent call last):
      File "code/__torch__/CARN_SR/carn_x2/___torch_mangle_86.py", line 130, in forward
        _62 = getattr(self, "prepack_folding._jit_pass_packed_weight_32")
        _63 = ops.prepacked.conv2d_clamp_run(_61, _62)
        out8 = torch.pixel_shuffle(_63, 2)
               ~~~~~~~~~~~~~~~~~~~ &lt;--- HERE
        _64 = getattr(self, "prepack_folding._jit_pass_packed_weight_33")
        out9 = ops.prepacked.conv2d_clamp_run(out8, _64)
    
    Traceback of TorchScript, original code (most recent call last):
      File "/usr/local/lib/python3.8/site-packages/torch/nn/modules/pixelshuffle.py", line 46, in forward
        def forward(self, input: Tensor) -&gt; Tensor:
            return F.pixel_shuffle(input, self.upscale_factor)
                   ~~~~~~~~~~~~~~~ &lt;--- HERE
    RuntimeError: Dimension out of range (expected to be in range of [-6, 5], but got 4294967290)
    
        at org.pytorch.NativePeer.forward(Native Method)
        at org.pytorch.Module.forward(Module.java:49)
        at com.example.pytorchtutorial.MainActivity.applySR(MainActivity.java:122)
        at com.example.pytorchtutorial.MainActivity$2.onClick(MainActivity.java:214)
        at android.view.View.performClick(View.java:7448)
        at android.view.View.performClickInternal(View.java:7425)
        at android.view.View.access$3600(View.java:810)
        at android.view.View$PerformClick.run(View.java:28305)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
</code></pre>
<p>When I downgrade the Pytorch Mobile version to 1.7.1 the error disappears. I think the problem is caused in PixelShuffle layer because when I use another model for inference, the error is thrown in that layer as well. For example:</p>
<pre><code class="lang-auto">    Traceback of TorchScript, serialized code (most recent call last):
      File "code/__torch__/Models/ESPCN/___torch_mangle_163.py", line 29, in forward
        _10 = (_4).forward(_8, )
        _11 = (_3).forward()
        _12 = (_0).forward((_1).forward((_2).forward(_10, ), ), )
                            ~~~~~~~~~~~ &lt;--- HERE
        _13 = torch.contiguous(_12, memory_format=0)
        return _13
      File "code/__torch__/torch/nn/modules/pixelshuffle/___torch_mangle_160.py", line 8, in forward
      def forward(self: __torch__.torch.nn.modules.pixelshuffle.___torch_mangle_160.PixelShuffle,
        argument_1: Tensor) -&gt; Tensor:
        return torch.pixel_shuffle(argument_1, 2)
               ~~~~~~~~~~~~~~~~~~~ &lt;--- HERE
</code></pre>
<p>I would appreciate any help with this. Thanks</p>
<p>EDIT: This issue is now on Github</p><aside class="onebox githubissue">
  <header class="source">
      <a href="https://github.com/pytorch/pytorch/issues/54051" target="_blank" rel="noopener nofollow ugc">github.com/pytorch/pytorch</a>
  </header>
  <article class="onebox-body">
    <div class="github-row">
  <div class="github-icon-container" title="Issue">
	  <svg width="60" height="60" class="github-icon" viewbox="0 0 14 16" aria-hidden="true"><path d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg>
  </div>

  <div class="github-info-container">
    <h4>
      <a href="https://github.com/pytorch/pytorch/issues/54051" target="_blank" rel="noopener nofollow ugc">Updating Pytorch Mobile to 1.8.0 from 1.7.1 causes “Dimension Out of Range” error in the PixelShuffle layer</a>
    </h4>

    <div class="github-info">
      <div class="date">
        opened <span class="discourse-local-date" data-format="ll" data-date="2021-03-16" data-time="07:51:06" data-timezone="UTC">07:51AM - 16 Mar 21 UTC</span>
      </div>


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

<div class="github-row">
  <p class="github-content">Hi,
I have updated the PytorchMobile for my Android application from 1.7.1 to 1.8.0 but doing so caused an error in the...</p>
</div>

<div class="labels">
</div>

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


ptrblck: <p>I’m a bit confused about the error message, as <code>F.pixel_shuffle</code> doesn’t expect a dimension argument, so it might be crashing internally?<br>
Could you create an issue on <a href="https://github.com/pytorch/pytorch/issues">GitHub</a> so that we could track this issue?</p>

tom: <p>The number looks a lot like -6 mod 2**32, so it might be signedness issue.</p>
<p>Maybe the change to feeding negative numbers to permute in</p><aside class="onebox githubpullrequest">
  <header class="source">
      <a href="https://github.com/pytorch/pytorch/pull/49187" target="_blank" rel="noopener nofollow ugc">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/49187" target="_blank" rel="noopener nofollow ugc">[pytorch] Expand PixelShuffle to support any number of batch dims</a>
    </h4>

    <div class="branches">
      <code>pytorch:master</code> ← <code>jbschlosser:export-D25399058</code>
    </div>

    <div class="github-info">
      <div class="date">
        opened <span class="discourse-local-date" data-format="ll" data-date="2020-12-10" data-time="21:21:37" data-timezone="UTC">09:21PM - 10 Dec 20 UTC</span>
      </div>

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

      <div class="lines" title="1 commits changed 3 files with 107 additions and 38 deletions">
        <a href="https://github.com/pytorch/pytorch/pull/49187/files" target="_blank" rel="noopener nofollow ugc">
          <span class="added">+107</span>
          <span class="removed">-38</span>
        </a>
      </div>
    </div>

  </div>
</div>

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>
<p>
didn’t go well.<br>
To make things specific, <code>-something.size()</code> seems very dubious in C++:</p>
<aside class="onebox githubblob">
  <header class="source">
      <a href="https://github.com/pytorch/pytorch/blob/603097be18824a33069addec7b8f14ba5c3bc67a/aten/src/ATen/native/PixelShuffle.cpp#L103" target="_blank" rel="noopener nofollow ugc">github.com</a>
  </header>
  <article class="onebox-body">
    <h4><a href="https://github.com/pytorch/pytorch/blob/603097be18824a33069addec7b8f14ba5c3bc67a/aten/src/ATen/native/PixelShuffle.cpp#L103" target="_blank" rel="noopener nofollow ugc">pytorch/pytorch/blob/603097be18824a33069addec7b8f14ba5c3bc67a/aten/src/ATen/native/PixelShuffle.cpp#L103</a></h4>
<pre class="onebox"><code class="lang-cpp"><ol class="start lines" start="93" style="counter-reset: li-counter 92 ;">
<li>      self.sizes().begin(), self_sizes_batch_end);</li>
<li>  added_dims_shape.insert(</li>
<li>      added_dims_shape.end(), {c, oh, downscale_factor, ow, downscale_factor});</li>
<li>  const auto input_reshaped = self.reshape(added_dims_shape);</li>
<li>
<li>  // Next, unshuffle by permuting the downscale_factor dims alongside the channel dim.</li>
<li>  std::vector&lt;int64_t&gt; permutation(self.sizes().begin(), self_sizes_batch_end);</li>
<li>  // std::iota is used to maintain the batch dims within the permutation.</li>
<li>  // Since 2 dims were added, the correct batch dim offsets are now:</li>
<li>  // -added_dims_shape.size(), ..., -7, -6.</li>
<li class="selected">  std::iota(permutation.begin(), permutation.end(), -added_dims_shape.size());</li>
<li>  permutation.insert(permutation.end(), {-5 /* c */, -3 /* 1st downscale_factor */, -1 /*2nd downscale_factor */,</li>
<li>                                         -4 /* oh */, -2 /* ow */});</li>
<li>  const auto input_permuted = input_reshaped.permute(permutation);</li>
<li>
<li>  // Finally, downscale by collapsing (c, downscale_factor, downscale_factor) -&gt; a single dim (oc),</li>
<li>  // resulting in height=oh and width=ow.</li>
<li>  std::vector&lt;int64_t&gt; final_shape(self.sizes().begin(), self_sizes_batch_end);</li>
<li>  final_shape.insert(final_shape.end(), {oc, oh, ow});</li>
<li>  return input_permuted.reshape(final_shape);</li>
<li>}</li>
</ol></code></pre>


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

<p><a class="mention" href="/u/jbschlosser">@jbschlosser</a> , what do you think?</p>
<p>Best regards</p>
<p>Thomas</p>

ekremcet: <p>Sure, I opened an issue using the same content here. Thanks</p>

tom: <p>Thank you for opening <a href="https://github.com/pytorch/pytorch/issues/54051" rel="noopener nofollow ugc">the issue</a>. It’s generally a good idea to cross link the forum and the issue.</p>

ekremcet: <p>I edited the first message to include the link to the Github issue. Thanks for the heads up <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>

tom: <p>So I’m happy to report that in 1.8.1 this is fixed thanks to your report.<br>
Thank you!</p>

ekremcet: <p>That is good news!  Thank you for the quick fix <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>