Skip to content

[TEST] Keep the descriptor-builtins scope test from poisoning the builtin cache - #531

Open
mark14wu wants to merge 1 commit into
mainfrom
fix/patch-scope-test-cache
Open

mark14wu wants to merge 1 commit into
mainfrom
fix/patch-scope-test-cache

Conversation

@mark14wu

@mark14wu mark14wu commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator

Problem

tests/unit/test_patch_scope.py::test_scope_restores_tensor_descriptor_base_builtins monkeypatches inspect.getmembers and tl.core.is_builtin so that only one fake builtin exists, then takes a frontend snapshot scope. The Triton frontend caches each language object's builtin names on first use (_triton_builtin_attr_cache, keyed by object id). When this test is the first in the process to take a snapshot, the cache is filled from the fake member lists, so it holds almost no names. The monkeypatches are undone afterwards, but the cache is not.

From then on, every patch_lang / unpatch_lang in the process saves and restores only those few names, and the interpreter's replacements of triton.language.core builtins (load, store, atomic_*, arange, dot, ...) stay installed. Running only

pytest tests/unit/test_patch_scope.py::test_scope_restores_tensor_descriptor_base_builtins \
       tests/unit/test_patch_scope.py::test_patch_lang_restores_core_reduce_scan_from_tl_kernel

leaves about 40 tl.core builtins replaced. On the IR-mode stack, every later host compile in that process then fails (13 failures in test_ir_lifecycle_compiled.py with that ordering). Which tests run first on an xdist worker decides whether it happens, so CI can fail at random.

Change

The test also monkeypatches the frontend's cache with an empty dict of its own, so whatever it caches under the fake member lists is discarded with the other monkeypatches. No product code changes.

Tests

  • The two tests above, with a session-end check of every tl / tl.core / tl.core.tensor attribute: without the change ~40 tl.core builtins differ from their originals; with it, none do.
  • On the IR-mode stack, the same two tests followed by tests/end_to_end/test_ir_lifecycle_compiled.py: 13 failed before, 18 passed / 4 skipped after.
  • tests/unit/test_patch_scope.py: 8 passed; with tests/end_to_end/test_core.py under -n 4: 19 passed, 1 skipped.

…ltin cache

test_scope_restores_tensor_descriptor_base_builtins fakes
inspect.getmembers and tl.core.is_builtin, then takes a snapshot scope.
The frontend caches each language object's builtin names on first use, so
when this test was the first to snapshot in the process it cached almost
no names, and every later patch_lang/unpatch_lang left triton.language's
builtins (load, store, atomic_*, arange, ...) patched by the interpreter.
Run after it, test_patch_lang_restores_core_reduce_scan_from_tl_kernel
and any later host compile then saw the patched language. Give the test
an empty cache of its own, restored with the other monkeypatches.
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown

Performance Benchmark

Benchmark main (min) PR (min) Change Samples
gemm 0.065s 0.065s -0.2% 20 / 20
gemm_oob 0.072s 0.072s +0.0% 20 / 20
indirect_load 0.013s 0.013s +1.2% 20 / 20
nested_loop 0.133s 0.134s +1.0% 20 / 20
block_pointer_loop_advance 0.072s 0.071s -0.7% 20 / 20
liger_jsd 0.093s 0.093s +0.3% 20 / 20
flaggems_layernorm 0.231s 0.230s -0.3% 20 / 20
swiglu 0.110s 0.110s +0.6% 20 / 20
cross_entropy 0.605s 0.609s +0.7% 20 / 20
fused_linear_jsd 0.141s 0.142s +0.5% 20 / 20
Total 1.533s 1.539s +0.4% N/A

Iterations: 1 warmup + 20 measured
Samples are shown as main / PR; long pytest benchmarks may use fewer samples.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant