Skip to content

Commit 5508c80

Browse files
zheng1claude
andcommitted
fix(ascend): correct flattened argmin semantics
argmin(inp) with dim=None returned wrong indices on the Ascend backend. Three issues on the same code path: 1. Tie breaking. tl.min(..., return_indices=True) did not request return_indices_tie_break_left, so equal values could resolve to an arbitrary index instead of the first one. PyTorch returns the first occurrence. 2. Block size. block_size was derived only from sqrt(numel) with no upper bound. For large inputs it exceeded what the device could handle on this path and produced wrong indices. It is now capped at 1024. 3. keepdim. The output was allocated with torch.empty([]) unconditionally, so keepdim=True was dropped. PyTorch returns shape [1] * inp.dim(). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent a8d3068 commit 5508c80

2 files changed

Lines changed: 42 additions & 4 deletions

File tree

src/flag_gems/runtime/backend/_ascend/ops/argmin.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ def argmin_kernel_1(
4343

4444
max_value = get_dtype_max(inp.type.element_ty)
4545
inp_val = tl.load(inp_ptrs, mask=mask, other=max_value)
46-
min_val, min_index = tl.min(inp_val, axis=0, return_indices=True)
46+
min_val, min_index = tl.min(
47+
inp_val,
48+
axis=0,
49+
return_indices=True,
50+
return_indices_tie_break_left=True,
51+
)
4752
min_index = min_index + pid * BLOCK_SIZE
4853
mid_value_ptr = mid_value + pid
4954
min_index_ptr = mid_index + pid
@@ -128,13 +133,14 @@ def argmin(inp, dim=None, keepdim=False, *, dtype=None):
128133
M = inp.numel()
129134
if dtype is None:
130135
dtype = inp.dtype
131-
block_size = triton.next_power_of_2(math.ceil(math.sqrt(M)))
136+
block_size = min(1024, triton.next_power_of_2(math.ceil(math.sqrt(M))))
132137
mid_size = triton.cdiv(M, block_size)
133138
block_mid = triton.next_power_of_2(mid_size)
134139

135140
mid_value = torch.empty((mid_size,), dtype=dtype, device=inp.device)
136141
mid_index = torch.empty((mid_size,), dtype=torch.int64, device=inp.device)
137-
out = torch.empty([], dtype=torch.int64, device=inp.device)
142+
out_shape = [1] * inp.dim() if keepdim else []
143+
out = torch.empty(out_shape, dtype=torch.int64, device=inp.device)
138144

139145
with torch_device_fn.device(inp.device):
140146
argmin_kernel_1[(mid_size, 1, 1)](

tests/test_argmin.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,42 @@ def test_argmin(shape, dim, keepdim, dtype):
3939
else:
4040
inp = torch.randn(shape, dtype=dtype, device=flag_gems.device)
4141

42-
ref_inp = utils.to_reference(inp)
42+
use_cpu_ref = flag_gems.vendor_name == "ascend" and dim is None and keepdim
43+
ref_inp = inp.cpu() if use_cpu_ref else utils.to_reference(inp)
4344
ref_out = torch.argmin(ref_inp, dim=dim, keepdim=keepdim)
45+
if use_cpu_ref and not cfg.TO_CPU:
46+
ref_out = ref_out.to(inp.device)
4447

4548
with flag_gems.use_gems():
4649
res_out = torch.argmin(inp, dim=dim, keepdim=keepdim)
4750

4851
utils.gems_assert_equal(res_out, ref_out)
52+
53+
54+
@pytest.mark.argmin
55+
@pytest.mark.skipif(
56+
flag_gems.vendor_name != "ascend", reason="regression test for Ascend"
57+
)
58+
def test_argmin_large_flattened_index():
59+
inp = torch.ones((200, 2560, 3), dtype=torch.float32, device=flag_gems.device)
60+
inp.flatten()[1024 * 1200] = -1
61+
ref_out = torch.argmin(inp.cpu())
62+
63+
with flag_gems.use_gems():
64+
res_out = torch.argmin(inp)
65+
66+
torch.testing.assert_close(res_out.cpu(), ref_out, atol=0, rtol=0)
67+
68+
69+
@pytest.mark.argmin
70+
@pytest.mark.skipif(
71+
flag_gems.vendor_name != "ascend", reason="regression test for Ascend"
72+
)
73+
def test_argmin_flattened_nan_index():
74+
inp = torch.tensor([3.0, float("nan"), -5.0, float("nan")], device=flag_gems.device)
75+
ref_out = torch.argmin(inp.cpu())
76+
77+
with flag_gems.use_gems():
78+
res_out = torch.argmin(inp)
79+
80+
torch.testing.assert_close(res_out.cpu(), ref_out, atol=0, rtol=0)

0 commit comments

Comments
 (0)