Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/flag_gems/runtime/backend/_ascend/ops/argmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ def argmin_kernel_1(

max_value = get_dtype_max(inp.type.element_ty)
inp_val = tl.load(inp_ptrs, mask=mask, other=max_value)
min_val, min_index = tl.min(inp_val, axis=0, return_indices=True)
min_val, min_index = tl.min(
inp_val,
axis=0,
return_indices=True,
return_indices_tie_break_left=True,
)
min_index = min_index + pid * BLOCK_SIZE
mid_value_ptr = mid_value + pid
min_index_ptr = mid_index + pid
Expand Down Expand Up @@ -128,13 +133,14 @@ def argmin(inp, dim=None, keepdim=False, *, dtype=None):
M = inp.numel()
if dtype is None:
dtype = inp.dtype
block_size = triton.next_power_of_2(math.ceil(math.sqrt(M)))
block_size = min(1024, triton.next_power_of_2(math.ceil(math.sqrt(M))))
mid_size = triton.cdiv(M, block_size)
block_mid = triton.next_power_of_2(mid_size)

mid_value = torch.empty((mid_size,), dtype=dtype, device=inp.device)
mid_index = torch.empty((mid_size,), dtype=torch.int64, device=inp.device)
out = torch.empty([], dtype=torch.int64, device=inp.device)
out_shape = [1] * inp.dim() if keepdim else []
out = torch.empty(out_shape, dtype=torch.int64, device=inp.device)

with torch_device_fn.device(inp.device):
argmin_kernel_1[(mid_size, 1, 1)](
Expand Down
34 changes: 33 additions & 1 deletion tests/test_argmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,42 @@ def test_argmin(shape, dim, keepdim, dtype):
else:
inp = torch.randn(shape, dtype=dtype, device=flag_gems.device)

ref_inp = utils.to_reference(inp)
use_cpu_ref = flag_gems.vendor_name == "ascend" and dim is None and keepdim
ref_inp = inp.cpu() if use_cpu_ref else utils.to_reference(inp)
ref_out = torch.argmin(ref_inp, dim=dim, keepdim=keepdim)
if use_cpu_ref and not cfg.TO_CPU:
ref_out = ref_out.to(inp.device)

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

utils.gems_assert_equal(res_out, ref_out)


@pytest.mark.argmin
@pytest.mark.skipif(
flag_gems.vendor_name != "ascend", reason="regression test for Ascend"
)
def test_argmin_large_flattened_index():
inp = torch.ones((200, 2560, 3), dtype=torch.float32, device=flag_gems.device)
inp.flatten()[1024 * 1200] = -1
ref_out = torch.argmin(inp.cpu())

with flag_gems.use_gems():
res_out = torch.argmin(inp)

torch.testing.assert_close(res_out.cpu(), ref_out, atol=0, rtol=0)


@pytest.mark.argmin
@pytest.mark.skipif(
flag_gems.vendor_name != "ascend", reason="regression test for Ascend"
)
def test_argmin_flattened_nan_index():
inp = torch.tensor([3.0, float("nan"), -5.0, float("nan")], device=flag_gems.device)
ref_out = torch.argmin(inp.cpu())

with flag_gems.use_gems():
res_out = torch.argmin(inp)

torch.testing.assert_close(res_out.cpu(), ref_out, atol=0, rtol=0)
Loading