diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ea4340..6a671bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,10 @@ ## [Unreleased] +### Changed +- sdpa `PLATFORM.md` 补记多算子 perf registry 顺序加载时的顶层 + `reference` 遮蔽约束;backend 导入回归测试同步覆盖 P800 与 MLU + ### Fixed - P800 性能门禁多算子加载时,`ops.sdpa` backend 的裸 `reference` 导入可能命中 `sdpa_math.reference` 等同名顶层模块,导致 diff --git a/ops/sdpa/PLATFORM.md b/ops/sdpa/PLATFORM.md index 88f3847..75336a8 100644 --- a/ops/sdpa/PLATFORM.md +++ b/ops/sdpa/PLATFORM.md @@ -94,6 +94,13 @@ kernel/backends/ 合并流程与后续平台扩展仍按 [MERGE.md](MERGE.md) 执行。 +多算子同进程/perf registry 会按 provider 顺序加载多个 `reference.py`。 +backend 内不允许裸 `from reference import ...` 作为首选路径:一旦其他 +算子的顶层 `reference` 已进入 `sys.modules`,该导入会解析到错误模块。 +正确顺序是包态相对导入优先(如 `from ...reference import ...`),仅 +单算子脚本模式 fallback 到顶层 `reference`。该问题已在 +`tests/unit/test_sdpa_backend_import.py` 固化,实测记录见 PR #22。 + ## 6. 引用防误用 函数名**有意**保持 `sdpa_triton`(公共 API 稳定)。平台区分靠三层: diff --git a/tests/unit/test_sdpa_backend_import.py b/tests/unit/test_sdpa_backend_import.py index e388c65..e5723e4 100644 --- a/tests/unit/test_sdpa_backend_import.py +++ b/tests/unit/test_sdpa_backend_import.py @@ -5,7 +5,17 @@ import types -def test_p800_backend_survives_foreign_top_level_reference(monkeypatch): +import pytest + + +@pytest.mark.parametrize( + ("module_name",), + [ + ("ops.sdpa.kernel.backends.p800_kunlunxin",), + ("ops.sdpa.kernel.backends.mlu590",), + ], +) +def test_backend_survives_foreign_top_level_reference(module_name, monkeypatch): """Guard the multi-operator perf-registry import order. Earlier standalone operators can leave their own ``reference`` module in @@ -15,9 +25,11 @@ def test_p800_backend_survives_foreign_top_level_reference(monkeypatch): foreign = types.ModuleType("reference") monkeypatch.setitem(sys.modules, "reference", foreign) - module = importlib.import_module( - "ops.sdpa.kernel.backends.p800_kunlunxin" - ) + module = importlib.import_module(module_name) + # Package scanning may have imported this backend before this test. Reload + # after installing the foreign top-level module so the test always covers + # the import statements rather than a cached module object. module = importlib.reload(module) assert module.sdpa_reference.__module__ == "ops.sdpa.reference" + assert callable(module.sdpa_reference)