Tensor.to() specification for out-of-range value

username: kiszk
cooked: <p>Where is the specification of torch.Tensor.to() for out-of-range values in the result? I cannot find the specification at <a href="https://pytorch.org/docs/stable/generated/torch.Tensor.to.html" class="inline-onebox" rel="noopener nofollow ugc">torch.Tensor.to — PyTorch 2.0 documentation</a>. This question is related to <a href="https://github.com/pytorch/pytorch/issues/97794" rel="noopener nofollow ugc">this issue</a>.</p>
<p>The following conversion is from the negative value to unsigned value. Since uint8 can have a value from 0 to 255, the value -2 is out-of-range.</p>
<pre><code class="lang-auto">t = torch.tensor([-2], dtype=torch.float)
tt = torch.to(t, dtype=torch.uint8)
</code></pre>
<p>When I executed the following command on different platforms, I got the same result 254 for pytorch. So, I want to know where the specification, which leads to this result, exists.</p>
<p>On the other hand, I got different results for numpy. The numpy specialist explains that this difference comes from the undefined behavior of C language.</p>
<pre><code class="lang-auto">on x86_64
python -c "import torch; import numpy as np; vals = (2, -2); t = torch.tensor(vals, dtype=torch.float).to(torch.uint8); print(t); a = np.array(vals, dtype=np.float32).astype(np.uint8); print (a)"
tensor([  2, 254], dtype=torch.uint8)
[  2 254]
</code></pre>
<pre><code class="lang-auto"># on s390x
python -c "import torch; import numpy as np; vals = (2, -2); t = torch.tensor(vals, dtype=torch.float).to(torch.uint8); print(t); a = np.array(vals, dtype=np.float32).astype(np.uint8); print (a)"
tensor([  2, 254], dtype=torch.uint8)
&lt;string&gt;:1: RuntimeWarning: invalid value encountered in cast
[2 0]
</code></pre>

username: J_Johnson
cooked: <p>Perhaps someone else can provide the specific answer to your question regarding the default value.</p>
<p>However, there is a simple way to set the value to anything you want it to be via masks:</p>
<pre><code class="lang-auto">cutoff = 0
newval = 127

t = torch.randn((100, 100), dtype=torch.float) * 127 #10000 values between -127 and 127
t[t &lt; cutoff] = newval # mask to replace values below cutoff
tt = torch.to(t, dtype=torch.uint8)
</code></pre>

username: ptrblck
cooked: <aside class="quote no-group" data-username="kiszk" data-post="1" data-topic="176973">
<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/kiszk/48/56297_2.png" class="avatar"> kiszk:</div>
<blockquote>
<p>The numpy specialist explains that this difference comes from the undefined behavior of C language.</p>
</blockquote>
</aside>
<p>I think this is correct as I’ve also forwarded a similar issue showing different behavior between <code>x86</code> and <code>ARM</code> in <a href="https://github.com/numpy/numpy/issues/19881">this <code>numpy</code> issue</a>:</p>
<blockquote>
<p>Float to int casts are undefined behaviour in C. And NumPy currently inherits it being undefined. Since it is undefined, it can depend a bit on how you do it or which system.</p>
</blockquote>

username: kiszk
cooked: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> Thank you for referring to your answer. I was not able to include three links in my post since I am new to this forum <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>