Files
Liger-Kernel/Makefile
T
Vaibhav JindalandCopilot 38c6a455ea test: organize DSL tests into per-DSL folders (cutedsl/cutile/cute) (#1410)
## Summary

The three opt-in GPU DSL backends — **cutedsl**, **cutile**, and
**cute** (fused-MoE) — had their tests inconsistently placed: a partial
`test/cutedsl/` folder existed, but most DSL tests were scattered in
`test/transformers/`. This PR gives each DSL its **own test folder**,
mirroring the existing `test/cutedsl/` convention (drop the DSL prefix
from filenames), and wires up matching `make` targets.

One minor change in cron schedule for nvidia-ci.

## Changes

### cutedsl → `test/cutedsl/`
- Moved `test_cutedsl_fused_linear_cross_entropy_sm90` →
`test_fused_linear_cross_entropy_sm90`
- Moved `test_cutedsl_rms_norm_fastpath` → `test_rms_norm_fastpath`
- Moved `test_cutedsl_rope` → `test_rope`
- Moved `test_swiglu_cutedsl` → `test_swiglu`
- **Deleted** `test_cutedsl_rms_norm` — it was a duplicate *subset* of
the canonical `test/cutedsl/test_rms_norm.py` (same two test-function
names; the canonical file is a strict superset with the extra Blackwell
fast-path tests and stricter mode-specific bf16 dW tolerances). Deleting
avoids a filename + test-name collision; the canonical file is left
untouched.
- Fixed a stale docstring path in `test/cutedsl/test_backend.py`.

### cutile → new `test/cutile/`
- Moved `test_cutile_backend` → `test_backend`,
`test_cutile_fused_linear_cross_entropy_sm90` →
`test_fused_linear_cross_entropy_sm90`, `test_cutile_rms_norm` →
`test_rms_norm`, `test_cutile_rope` → `test_rope`, `test_cutile_swiglu`
→ `test_swiglu`.
- **Split** the 7 env-gated `test_cutile_*` tests out of the shared
`test/transformers/test_fused_linear_scaled_cross_entropy.py` into
`test/cutile/test_fused_linear_scaled_cross_entropy.py`. The
backend-agnostic frontend/dispatcher tests stay in `test/transformers/`.

### cute (fused-MoE) → new `test/cute/`
- Moved `test_cute_moe_autograd` → `test_moe_autograd` and `test_moe` →
`test_moe`.
- `test_fused_moe.py` is the general Triton MoE test and **stays** in
`test/transformers/`.

### Makefile
- `test:` and `test-verbose:` now `--ignore=test/cutile` and
`--ignore=test/cute` (and `test-verbose` also ignores `test/cutedsl` for
consistency), so DSL tests run only via their dedicated targets.
- New **`test-cutile`** (`LIGER_KERNEL_IMPL=cutile`, mirrors
`test-cutedsl`).
- New **`test-cute`** — intentionally does **not** set
`LIGER_KERNEL_IMPL=cute`, because selecting it would force `import
liger_kernel.ops` to load the separate `liger_cute_kernels` (lck) wheel
and break the always-on registration/import-guard tests.

## Notes / decisions
- All moves use `git mv` to preserve history. The `test.utils` import
blocks in the moved rope/swiglu files were re-sorted by ruff because
`test` is now first-party inside the packaged DSL folders.
- **Coverage shift (intended):** a few always-on pure-Python tests
(cutedsl rms_norm fastpath, cute registration/import-guard) previously
ran under `make test`; they now run via the dedicated `test-*` targets,
consistent with the one-folder-per-DSL model.
- No new basename collisions: the DSL folders all have `__init__.py`
(unique package-qualified module names) and are ignored by `make test`.

## Validation
- `ruff check` and `ruff format --check` pass across the whole `test/`
tree.
- All affected files pass `py_compile`; `make -n` dry-runs verified for
the new targets.
- ⚠️ GPU/Modal test execution (`make test-cutedsl` / `test-cutile` /
`test-cute`) was **not** run in this environment (no CUDA/torch
available). These should be validated on a GPU host with the
corresponding extras installed.

---------

Co-authored-by: Copilot <[email protected]>
2026-08-27 05:37:31 +00:00

107 lines
3.5 KiB
Makefile

.PHONY: test test-verbose checkstyle test-convergence test-cutedsl test-cutile test-cute all serve build clean
all: checkstyle test test-convergence
# Command to run pytest for correctness tests
test:
python -m pytest --disable-warnings \
--ignore=test/convergence \
--ignore=test/cutedsl \
--ignore=test/cutile \
--ignore=test/cute \
test/
# Command to run pytest for CuTe DSL kernel tests
# Requires nvidia-cutlass-dsl: pip install -e '.[cutedsl]'
test-cutedsl:
LIGER_KERNEL_IMPL=cutedsl python -m pytest --disable-warnings test/cutedsl/
# Command to run pytest for cuTile kernel tests
# Requires cuda-tile: pip install -e '.[cutile]' (or '.[cutile-tileiras]')
test-cutile:
LIGER_KERNEL_IMPL=cutile python -m pytest --disable-warnings test/cutile/
# Command to run pytest for the cute fused-MoE tests
# The pure-Python registration/import-guard tests always run; the functional
# tests need the separate liger_cute_kernels (lck) wheel and >=2 CUDA devices.
# LIGER_KERNEL_IMPL is intentionally NOT set to 'cute': selecting it would force
# `import liger_kernel.ops` to load the lck wheel and break the always-on tests.
test-cute:
python -m pytest --disable-warnings test/cute/
# Command to run pytest for correctness tests with coverage reporting and full test-duration breakdown
test-verbose:
python -m pytest --disable-warnings \
--cov=src/liger_kernel \
--cov-report=term-missing \
--cov-report=html \
--cov-config=pyproject.toml \
--durations=0 \
--ignore=test/convergence \
--ignore=test/cutedsl \
--ignore=test/cutile \
--ignore=test/cute \
test/
# Command to run coverage report
coverage:
coverage report -m
# Command to run ruff for linting and formatting code
checkstyle:
ruff check --output-format=concise .; ruff_check_status=$$?; \
ruff format --check --diff .; ruff_format_status=$$?; \
ruff check . --fix; \
ruff format .; \
if [ $$ruff_check_status -ne 0 ] || [ $$ruff_format_status -ne 0 ]; then \
exit 1; \
fi
# Command to run pytest for convergence tests
# We have to explicitly set HF_DATASETS_OFFLINE=1, or dataset will silently try to send metrics and timeout (80s) https://github.com/huggingface/datasets/blob/37a603679f451826cfafd8aae00738b01dcb9d58/src/datasets/load.py#L286
test-convergence:
HF_DATASETS_OFFLINE=1 python -m pytest --disable-warnings \
test/convergence/fp32/test_mini_models.py \
test/convergence/fp32/test_mini_models_multimodal.py \
test/convergence/fp32/test_mini_models_with_logits.py \
test/convergence/bf16/test_mini_models.py \
test/convergence/bf16/test_mini_models_multimodal.py \
test/convergence/bf16/test_mini_models_with_logits.py
# Command to run all benchmark scripts and update benchmarking data file
# By default this doesn't overwrite existing data for the same benchmark experiment
# run with `make run-benchmarks OVERWRITE=1` to overwrite existing benchmark data
BENCHMARK_DIR = benchmark/scripts
BENCHMARK_SCRIPTS = $(wildcard $(BENCHMARK_DIR)/benchmark_*.py)
OVERWRITE ?= 0
run-benchmarks:
@for script in $(BENCHMARK_SCRIPTS); do \
echo "Running benchmark: $$script"; \
if [ $(OVERWRITE) -eq 1 ]; then \
python $$script --overwrite; \
else \
python $$script; \
fi; \
done
# MkDocs Configuration
MKDOCS = mkdocs
CONFIG_FILE = mkdocs.yml
SITE_DIR = site
# MkDocs targets
# Serve the documentation
serve:
$(MKDOCS) serve -f $(CONFIG_FILE)
# Build the documentation into the specified site directory
build:
$(MKDOCS) build -f $(CONFIG_FILE) --site-dir $(SITE_DIR)
# Clean the output directory
clean:
rm -rf $(SITE_DIR)/