mirror of
https://github.com/unslothai/unsloth.git
synced 2026-10-24 07:21:02 +00:00
#13840 (fa15e69126) landed just before #13936 and puts two checks back
to red on main:
```
FAILED tests/python/test_accelerator_skip_guards.py::test_no_skip_guard_reads_a_spoofable_accelerator_probe
test_nvfp4_fused_gemm.py:365: torch.cuda.device_count()
FAILED tests/test_formatter_fixed_point.py::test_every_tracked_python_file_is_already_formatted
tests/test_nvfp4_fused_gemm.py
unsloth/kernels/nvfp4.py
```
Both are the same shape as #13936 and nothing in #13840's kernel
changes:
- `tests/test_nvfp4_fused_gemm.py` gated its two-GPU test on
`torch.cuda.device_count() < 2`, which
`tests/_zoo_aggressive_cuda_spoof.py` can patch process-wide, so it
un-skips on a CPU-only runner sharing a session with the version-compat
suites. It now reads `not has_real_cuda() or torch.cuda.device_count() <
2`, matching the rest of the tree. The module-level `pytestmark` used
`torch.cuda.is_available()` the same way; it now uses `has_real_cuda()`
too. On a real GPU both predicates answer as before.
- Formatter output for the two files (pinned ruff 0.6.9 via
`scripts/run_ruff_format.py`), no logic change.
Verification:
- `tests/python/test_accelerator_skip_guards.py`: fails on main as
above, 24 passed here.
- `tests/test_formatter_fixed_point.py`: fails on main as above, 16
passed here.
- `unsloth/kernels/nvfp4.py` compiles; the change there is line wrapping
only.
This commit is contained in:
parent
6d7afe0587
commit
565630c6b4
2 changed files with 14 additions and 5 deletions
|
|
@ -3,12 +3,13 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
from real_accelerator import has_real_cuda
|
||||
|
||||
torch = pytest.importorskip("torch")
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.gpu,
|
||||
pytest.mark.skipif(not torch.cuda.is_available(), reason = "needs CUDA"),
|
||||
pytest.mark.skipif(not has_real_cuda(), reason = "needs CUDA"),
|
||||
pytest.mark.skipif(torch.version.hip is not None, reason = "the fused path is CUDA only"),
|
||||
]
|
||||
|
||||
|
|
@ -286,7 +287,9 @@ def test_extra_scale_columns_are_ignored(N, fused, monkeypatch):
|
|||
assert _calls(N)["fwd"] == before["fwd"] + 1
|
||||
assert torch.equal(Y, N._nvfp4_matmul_fwd(X, packed, scale, gs))
|
||||
G = torch.randn(4, 64, device = "cuda", dtype = dtype)
|
||||
assert torch.equal(N._nvfp4_matmul_bwd(G, packed, wide, gs), N._nvfp4_matmul_bwd(G, packed, scale, gs))
|
||||
assert torch.equal(
|
||||
N._nvfp4_matmul_bwd(G, packed, wide, gs), N._nvfp4_matmul_bwd(G, packed, scale, gs)
|
||||
)
|
||||
|
||||
|
||||
def test_inf_scale_in_the_last_group_matches_dense(N, fused, monkeypatch):
|
||||
|
|
@ -319,7 +322,9 @@ def test_column_strided_e4m3_scales(N, fused, monkeypatch):
|
|||
dtype = _dtypes()[0]
|
||||
packed, scale, gs = _random_nvfp4(64, 128)
|
||||
strided = torch.stack([scale, scale], dim = -1).reshape(scale.shape[0], -1)[:, ::2]
|
||||
assert strided.stride(-1) == 2 and torch.equal(strided.view(torch.uint8), scale.view(torch.uint8))
|
||||
assert strided.stride(-1) == 2 and torch.equal(
|
||||
strided.view(torch.uint8), scale.view(torch.uint8)
|
||||
)
|
||||
X = torch.randn(4, 128, device = "cuda", dtype = dtype)
|
||||
assert torch.equal(_fwd(N, X, packed, strided, gs), _fwd(N, X, packed, scale, gs))
|
||||
|
||||
|
|
@ -347,6 +352,7 @@ def test_row_gate_keeps_unaligned_shapes_dense(N, monkeypatch):
|
|||
assert N._fused_ok(X, packed, scale, gs, k)
|
||||
monkeypatch.delenv("UNSLOTH_NVFP4_FUSED")
|
||||
|
||||
|
||||
def test_flags_are_read_once_per_process(N, live_env, monkeypatch):
|
||||
monkeypatch.setattr(N, "_FUSED_ENV", None)
|
||||
monkeypatch.setenv("UNSLOTH_NVFP4_FUSED", " Off ")
|
||||
|
|
@ -355,6 +361,7 @@ def test_flags_are_read_once_per_process(N, live_env, monkeypatch):
|
|||
monkeypatch.setenv("UNSLOTH_NVFP4_FUSED", "1")
|
||||
assert live_env() == ("off", 32)
|
||||
|
||||
|
||||
def test_offset_width_follows_the_strided_span(N):
|
||||
small = torch.empty((2, 4), device = "meta")
|
||||
assert not N._needs_int64(small)
|
||||
|
|
@ -362,7 +369,7 @@ def test_offset_width_follows_the_strided_span(N):
|
|||
assert N._needs_int64(small.as_strided((2, 4), (2**31, 1)))
|
||||
|
||||
|
||||
@pytest.mark.skipif(torch.cuda.device_count() < 2, reason = "needs two GPUs")
|
||||
@pytest.mark.skipif(not has_real_cuda() or torch.cuda.device_count() < 2, reason = "needs two GPUs")
|
||||
def test_operands_on_another_device_stay_dense(N, monkeypatch):
|
||||
monkeypatch.setenv("UNSLOTH_NVFP4_FUSED_MAX_ROWS", "64")
|
||||
dtype = _dtypes()[0]
|
||||
|
|
|
|||
|
|
@ -410,7 +410,9 @@ _FUSED_CALLS = {"fwd": 0, "bwd": 0}
|
|||
def _read_fused_env():
|
||||
# UNSLOTH_NVFP4_FUSED: 0 dense, 1 fused, unset = per-GPU row gate (UNSLOTH_NVFP4_FUSED_MAX_ROWS overrides it).
|
||||
rows = os.environ.get("UNSLOTH_NVFP4_FUSED_MAX_ROWS")
|
||||
return os.environ.get("UNSLOTH_NVFP4_FUSED", "auto").strip().lower(), int(rows) if rows else None
|
||||
return os.environ.get("UNSLOTH_NVFP4_FUSED", "auto").strip().lower(), int(
|
||||
rows
|
||||
) if rows else None
|
||||
|
||||
|
||||
_FUSED_ENV = None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue