How to get the max value with smallest index

username: Houjue_Wang
cooked: <p>How to get the max value with smallest index(if multiple max value) of a 2d tensor ?Thx.</p>

username: jpeg729
cooked: <p>If you just want the max value, then <a href="http://pytorch.org/docs/0.3.1/torch.html#torch.max">torch.max</a> will do the trick.<br>
If you specify the dimension over which to take the max, then it returns two tensors, the max values and their indices.</p>
<pre><code class="lang-auto">maxes, indices = torch.max(my_tensor, dim=0)
</code></pre>
<p>I don’t know whether it will take the smallest index value if there are two identical max values, though it the values are all floats then it is not very likely there will be two identical max values.</p>

username: cleros
cooked: <p>Hey! As this thread discusses, the index returned may be randomly selected from all max values:<br>
<a href="https://discuss.pytorch.org/t/function-torch-max-return-indices-inconsistency-between-cup-and-gpu/1890/2">https://discuss.pytorch.org/t/function-torch-max-return-indices-inconsistency-between-cup-and-gpu/1890/2</a></p>
<p>Here is a link to a solution to this on stackoverflow:<br>
<a href="https://stackoverflow.com/questions/55139801/index-selection-in-case-of-conflict-in-pytorch-argmax/55146371#55146371" rel="nofollow noopener">https://stackoverflow.com/questions/55139801/index-selection-in-case-of-conflict-in-pytorch-argmax/55146371#55146371</a></p>

username: imaluengo
cooked: <p>Is it faster than doing it in the cpu?</p>
<p><code>argmax = torch.max(my_tensor.cpu(), dim=0)[1]</code></p>
<p>as it is known that cpu computes the correct result</p>

username: cleros
cooked: <p>Hi! it’s not that <code>argmax</code> or <code>max</code> do not produce a correct result, but that the result they produce may not necessarily be consistent over different runs and different devices, and is not guaranteed to give you first/last values, even if that is what you want.</p>
<p>The implementation in the link above, though, is guaranteed to give you either the first or last <code>argmax</code> index.</p>

username: imaluengo
cooked: <p>Just checked and you are right.</p>
<p>Sorry I didn’t link the link before:<br>
<aside class="onebox githubissue">
  <header class="source">
      <a href="https://github.com/pytorch/pytorch/issues/14147" target="_blank" rel="nofollow noopener">github.com/pytorch/pytorch</a>
  </header>
  <article class="onebox-body">
    <a href="https://github.com/carefree0910" rel="nofollow noopener">
<img src="https://avatars1.githubusercontent.com/u/15677328?v=2&amp;s=96" class="thumbnail onebox-avatar" width="96" height="96">
</a>

<h4><a href="https://github.com/pytorch/pytorch/issues/14147" target="_blank" rel="nofollow noopener">Issue: torch.argmin behaves differently on CPU and GPU</a></h4>

<div class="date" style="margin-top:10px;">
	<div class="user" style="margin-top:10px;">
	opened by <a href="https://github.com/carefree0910" target="_blank" rel="nofollow noopener">carefree0910</a>
	on <a href="https://github.com/pytorch/pytorch/issues/14147" target="_blank" rel="nofollow noopener">2018-11-17</a>
	</div>
	<div class="user">
	closed by <a href="https://github.com/soumith" target="_blank" rel="nofollow noopener">soumith</a>
	on <a href="https://github.com/pytorch/pytorch/issues/14147" target="_blank" rel="nofollow noopener">2018-11-17</a>
	</div>
</div>

<pre class="content" style="white-space: pre-wrap;">🐛 Bug
torch.argmin behaves differently on cpu (which is correct) and gpu (which is wrong)
I'm not sure whether this 'bug' (or 'feature')...</pre>

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

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>
</p>
<p>But according to that answer (which in current pytorch versions is no longer valid) CPU version of <code>torch.max</code> and <code>torch.min</code> always returned the correct argmax, which is not true anymore.</p>

username: belonogov
cooked: <p>It can be done in the following way:</p>
<pre><code class="lang-auto">def argmax_first_and_last(a):
    b = torch.stack([torch.arange(a.shape[1])] * a.shape[0])
    max_values, _ = torch.max(a, dim=1)
    b[a != max_values[:, None]] = a.shape[1]
    first_max, _ = torch.min(b, dim=1)
    b[a != max_values[:, None]] = -1
    last_max, _ = torch.max(b, dim=1)
    return first_max, last_max
    
a = torch.tensor([[ 0, 0, 2, 2, 0, 2, 0, 0],
                  [-1, 0, 0, 1, 0, 0, 1, 0]])

first_max, last_max = argmax_first_and_last(a)
print(first_max) # [2, 3]
print(last_max) # [5, 6]
</code></pre>