|
| 1 | +import pytest |
| 2 | +import torch |
| 3 | + |
| 4 | +import flag_gems |
| 5 | + |
| 6 | +from . import accuracy_utils as utils |
| 7 | +from . import conftest as cfg |
| 8 | + |
| 9 | +if cfg.QUICK_MODE: |
| 10 | + FLOAT_DTYPES = [torch.float32] |
| 11 | +else: |
| 12 | + FLOAT_DTYPES = utils.FLOAT_DTYPES |
| 13 | + |
| 14 | + |
| 15 | +@pytest.mark.allclose |
| 16 | +@pytest.mark.parametrize("shape", utils.POINTWISE_SHAPES) |
| 17 | +@pytest.mark.parametrize("dtype", utils.ALL_FLOAT_DTYPES + utils.ALL_INT_DTYPES) |
| 18 | +@pytest.mark.parametrize("equal_nan", [False, True]) |
| 19 | +@pytest.mark.parametrize("gen_nan", [0, 1, 2, 3, 4]) |
| 20 | +def test_allclose(shape, dtype, equal_nan, gen_nan): |
| 21 | + # [gen_nan] 1: nan, 2: inf, 3: -inf, 4: inf vs -inf |
| 22 | + rtol = torch.rand(1, dtype=torch.float32, device=flag_gems.device).item() * ( |
| 23 | + 0.0001 if dtype in [torch.bfloat16, torch.float16] else 0.01 |
| 24 | + ) |
| 25 | + if dtype in utils.ALL_FLOAT_DTYPES: |
| 26 | + atol = ( |
| 27 | + torch.finfo(dtype).tiny |
| 28 | + * torch.randint(0, 4, (1,), device=flag_gems.device).item() |
| 29 | + ) |
| 30 | + inp1 = torch.full(shape, 1.234, dtype=dtype, device=flag_gems.device) |
| 31 | + inp2 = torch.full(shape, 1.234, dtype=dtype, device=flag_gems.device) |
| 32 | + if gen_nan: |
| 33 | + nan_num = torch.full( |
| 34 | + (1,), |
| 35 | + float("nan" if gen_nan == 1 else "inf"), |
| 36 | + dtype=dtype, |
| 37 | + device=flag_gems.device, |
| 38 | + ) |
| 39 | + # FIXME: Neg doesn't support double on torch_musa, so workaround temporarily. |
| 40 | + inp1.view(-1)[0] = ( |
| 41 | + (-nan_num.cpu()).to(flag_gems.device) if gen_nan == 3 else nan_num |
| 42 | + ) |
| 43 | + inp2.view(-1)[0] = ( |
| 44 | + (-nan_num.cpu()).to(flag_gems.device) if gen_nan >= 3 else nan_num |
| 45 | + ) |
| 46 | + else: |
| 47 | + atol = ( |
| 48 | + torch.finfo(torch.float16).eps |
| 49 | + * torch.randint(0, 10, (1,), device=flag_gems.device).item() |
| 50 | + ) |
| 51 | + inp1 = torch.randint(-1000, 1000, shape, device=flag_gems.device).to(dtype) |
| 52 | + inp2 = torch.randint(-1000, 1000, shape, device=flag_gems.device).to(dtype) |
| 53 | + |
| 54 | + ref_inp1 = utils.to_reference(inp1, False) |
| 55 | + ref_inp2 = utils.to_reference(inp2, False) |
| 56 | + |
| 57 | + with flag_gems.use_gems(): |
| 58 | + res_out = torch.allclose(inp1, inp2, rtol, atol, equal_nan=equal_nan) |
| 59 | + |
| 60 | + ref_out = torch.allclose(ref_inp1, ref_inp2, rtol, atol, equal_nan=equal_nan) |
| 61 | + |
| 62 | + assert res_out == ref_out |
0 commit comments