From d918e2947d35c5225cfe30c883a933f4d0eef028 Mon Sep 17 00:00:00 2001 From: ysun67 Date: Tue, 19 May 2026 16:10:46 -0400 Subject: [PATCH 1/2] PR-1b: rename CudaRenderShim -> RenderShim, LowerScanPipelineShim -> LowerKernelBodyShim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Target-agnostic naming for two kernel-pipeline shims, per docs/phase_decomposition_redesign.md section 3.3.3. - CudaRenderShim -> RenderShim (name='cuda_render' -> 'render') Drops hardcoded 'Cuda' in the shim name; PR-1c will add the target kwarg the shim reads to dispatch. - LowerScanPipelineShim -> LowerKernelBodyShim (name='lower_scan_pipeline' -> 'lower_kernel_body') The legacy lower_scan_pipeline function name is historical from M1; the SHIM that wraps it should describe the role, not the legacy function. Underlying lower_scan_pipeline helper is unchanged. Pure rename: no behavior, no logic changes. Full byte-equivalence harness (test_runner_byte_equivalence.py + test_byte_equivalence_jit.py + test_cuda_complete_runner.py — 532 fixtures) passes unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/srdatalog/ir/codegen/cuda/api.py | 2 +- src/srdatalog/ir/default_pipelines.py | 34 +++++++++---------- .../lowerings/lower_mir_execute_pipeline.py | 6 ++-- tests/test_default_pipelines_shims.py | 22 ++++++------ ...er_mir_execute_pipeline_byte_equivalent.py | 10 +++--- tests/test_verify_renderability.py | 24 ++++++------- 6 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/srdatalog/ir/codegen/cuda/api.py b/src/srdatalog/ir/codegen/cuda/api.py index 8f57416..1a48257 100644 --- a/src/srdatalog/ir/codegen/cuda/api.py +++ b/src/srdatalog/ir/codegen/cuda/api.py @@ -163,7 +163,7 @@ def compile_kernel_body( pipeline=DEFAULT_KERNEL_PIPELINE, ) body_text = state.body_text - assert body_text is not None, 'compile_kernel_body: CudaRenderShim left body_text unset' + assert body_text is not None, 'compile_kernel_body: RenderShim left body_text unset' return body_text diff --git a/src/srdatalog/ir/default_pipelines.py b/src/srdatalog/ir/default_pipelines.py index e60868b..990ec3f 100644 --- a/src/srdatalog/ir/default_pipelines.py +++ b/src/srdatalog/ir/default_pipelines.py @@ -10,7 +10,7 @@ DEFAULT_KERNEL_PIPELINE — KernelCtx(ep, ...) -> body string AssignHandlesShim, CollectViewSpecsShim, EmitViewDeclsShim, - LowerScanPipelineShim, CudaRenderShim + LowerKernelBodyShim, RenderShim Each shim is a `ProgramPass` subclass mirroring one block of either `compile_to_mir` (src/srdatalog/ir/hir/__init__.py:96-124) or @@ -261,14 +261,14 @@ def _fn(state: KernelCtx, _compiler: Any) -> KernelCtx: ) -class LowerScanPipelineShim(ProgramPass): +class LowerKernelBodyShim(ProgramPass): '''Wraps `lower_scan_pipeline` (sorted_array dialect). Builds a `LoweringCtx` from the populated state and runs the MIR -> IIR walk. Adds `iir` to state.''' def __init__(self) -> None: super().__init__( - name='lower_scan_pipeline', + name='lower_kernel_body', consumes=('view_decls',), produces=('iir',), fn=self._fn, @@ -281,8 +281,8 @@ def _fn(state: KernelCtx, _compiler: Any) -> KernelCtx: lower_scan_pipeline, ) - assert state.name_map is not None, 'LowerScanPipelineShim: name_map not set' - assert state.base_map is not None, 'LowerScanPipelineShim: base_map not set' + assert state.name_map is not None, 'LowerKernelBodyShim: name_map not set' + assert state.base_map is not None, 'LowerKernelBodyShim: base_map not set' lower_ctx = LoweringCtx( view_var_names=state.name_map, is_counting=state.is_counting, @@ -310,10 +310,10 @@ class VerifyRenderabilityShim(ProgramPass): would surface, and with a precise message pointing at the missing plugin contribution. - Today's IIR rewrite step is conceptual — `LowerScanPipelineShim` + Today's IIR rewrite step is conceptual — `LowerKernelBodyShim` produces the final IIR directly. So this shim runs AFTER - `LowerScanPipelineShim` (which produces the IIR) and BEFORE - `CudaRenderShim` (which consumes it). The shim is structurally a + `LowerKernelBodyShim` (which produces the IIR) and BEFORE + `RenderShim` (which consumes it). The shim is structurally a pass-through on `KernelCtx` — it neither inspects nor mutates the state beyond the closure check. @@ -321,7 +321,7 @@ class VerifyRenderabilityShim(ProgramPass): introduce a new pseudo-dialect; it's a gate, not a transformation. Per the spec note in `code_discipline.md` R3, this is exactly the "pipeline-stage closure verification" that prevents silent - fall-through in `CudaRenderShim`.''' + fall-through in `RenderShim`.''' def __init__(self) -> None: super().__init__( @@ -340,14 +340,14 @@ def _fn(state: KernelCtx, compiler: Any) -> KernelCtx: return state -class CudaRenderShim(ProgramPass): +class RenderShim(ProgramPass): '''Wraps `srdatalog.ir.codegen.cuda.emit.emit` with an `EmitCtx(indent_level=4)`. Concatenates `view_decls` + emitted IIR into the final `body_text`.''' def __init__(self) -> None: super().__init__( - name='cuda_render', + name='render', consumes=('iir',), produces=('body_text',), fn=self._fn, @@ -357,8 +357,8 @@ def __init__(self) -> None: def _fn(state: KernelCtx, _compiler: Any) -> KernelCtx: from srdatalog.ir.codegen.cuda.emit import EmitCtx, emit - assert state.iir is not None, 'CudaRenderShim: iir not set' - assert state.view_decls is not None, 'CudaRenderShim: view_decls not set' + assert state.iir is not None, 'RenderShim: iir not set' + assert state.view_decls is not None, 'RenderShim: view_decls not set' emit_ctx = EmitCtx(indent_level=4) body_text = state.view_decls + emit(state.iir, emit_ctx) return dataclasses.replace(state, body_text=body_text) @@ -381,9 +381,9 @@ def _fn(state: KernelCtx, _compiler: Any) -> KernelCtx: AssignHandlesShim(), CollectViewSpecsShim(), EmitViewDeclsShim(), - LowerScanPipelineShim(), + LowerKernelBodyShim(), VerifyRenderabilityShim(), - CudaRenderShim(), + RenderShim(), ] @@ -392,14 +392,14 @@ def _fn(state: KernelCtx, _compiler: Any) -> KernelCtx: 'DEFAULT_PROGRAM_PIPELINE', 'AssignHandlesShim', 'CollectViewSpecsShim', - 'CudaRenderShim', 'EmitViewDeclsShim', 'HirPlanningShim', 'HirToMirShim', 'InitialProg', 'KernelCtx', - 'LowerScanPipelineShim', + 'LowerKernelBodyShim', 'MirOptShim', 'MirProgramAssembly', + 'RenderShim', 'VerifyRenderabilityShim', ] diff --git a/src/srdatalog/ir/dialects/relation/sorted_array/lowerings/lower_mir_execute_pipeline.py b/src/srdatalog/ir/dialects/relation/sorted_array/lowerings/lower_mir_execute_pipeline.py index 1d37eb1..1c7e682 100644 --- a/src/srdatalog/ir/dialects/relation/sorted_array/lowerings/lower_mir_execute_pipeline.py +++ b/src/srdatalog/ir/dialects/relation/sorted_array/lowerings/lower_mir_execute_pipeline.py @@ -41,17 +41,17 @@ Caller posture during the migration: - - `LowerScanPipelineShim` (in `srdatalog.ir.default_pipelines`) + - `LowerKernelBodyShim` (in `srdatalog.ir.default_pipelines`) still calls `lower_scan_pipeline(state.ep.pipeline, lower_ctx)` directly. That direct call is byte-equivalent to going through the registered `@lowering` (this module's entry is a 1-line delegate to the same function). The registry-driven dispatch path is a follow-up — see the TODO at - `LowerScanPipelineShim._fn` — that requires plumbing the + `LowerKernelBodyShim._fn` — that requires plumbing the Compiler reference through `KernelCtx` (F3's `LowerCtx` already carries one; `KernelCtx` does not yet). - `compile_pipeline(ep)` and `compile_kernel_body(ep, ...)` route - through `LowerScanPipelineShim` (post-F5.3) so they inherit the + through `LowerKernelBodyShim` (post-F5.3) so they inherit the same direct-call path. The new `@lowering` entry here is the discoverable canonical surface; direct callers and the shim are free to invoke it OR the underlying `lower_scan_pipeline` diff --git a/tests/test_default_pipelines_shims.py b/tests/test_default_pipelines_shims.py index 82c75b5..c5568b7 100644 --- a/tests/test_default_pipelines_shims.py +++ b/tests/test_default_pipelines_shims.py @@ -19,15 +19,15 @@ DEFAULT_PROGRAM_PIPELINE, AssignHandlesShim, CollectViewSpecsShim, - CudaRenderShim, EmitViewDeclsShim, HirPlanningShim, HirToMirShim, InitialProg, KernelCtx, - LowerScanPipelineShim, + LowerKernelBodyShim, MirOptShim, MirProgramAssembly, + RenderShim, ) # ----------------------------------------------------------------------------- @@ -100,9 +100,9 @@ def test_kernel_pipeline_names_unique_and_ordered(): 'assign_handles', 'collect_view_specs', 'emit_view_decls', - 'lower_scan_pipeline', + 'lower_kernel_body', 'verify_renderability', - 'cuda_render', + 'render', ] assert len(set(names)) == len(names) @@ -217,22 +217,22 @@ def test_emit_view_decls_shim_populates_maps(): assert all(k.isdigit() for k in out.name_map) -def test_lower_scan_pipeline_shim_produces_iir(): +def test_lower_kernel_body_shim_produces_iir(): state = _build_kernel_ctx() state = AssignHandlesShim().apply(state, None) state = CollectViewSpecsShim().apply(state, None) state = EmitViewDeclsShim().apply(state, None) - out = LowerScanPipelineShim().apply(state, None) + out = LowerKernelBodyShim().apply(state, None) assert out.iir is not None -def test_cuda_render_shim_returns_string_body(): +def test_render_shim_returns_string_body(): state = _build_kernel_ctx() state = AssignHandlesShim().apply(state, None) state = CollectViewSpecsShim().apply(state, None) state = EmitViewDeclsShim().apply(state, None) - state = LowerScanPipelineShim().apply(state, None) - out = CudaRenderShim().apply(state, None) + state = LowerKernelBodyShim().apply(state, None) + out = RenderShim().apply(state, None) assert isinstance(out.body_text, str) assert len(out.body_text) > 0 # Should contain the view-decls preamble + emitted body. @@ -449,8 +449,8 @@ def test_assign_handles_shim_is_idempotent(): test_assign_handles_shim_runs_in_isolation() test_collect_view_specs_shim_runs_in_isolation() test_emit_view_decls_shim_populates_maps() - test_lower_scan_pipeline_shim_produces_iir() - test_cuda_render_shim_returns_string_body() + test_lower_kernel_body_shim_produces_iir() + test_render_shim_returns_string_body() test_default_program_pipeline_end_to_end() test_default_kernel_pipeline_end_to_end() test_kernel_pipeline_count_phase_runs() diff --git a/tests/test_lower_mir_execute_pipeline_byte_equivalent.py b/tests/test_lower_mir_execute_pipeline_byte_equivalent.py index c6335e6..97d18f0 100644 --- a/tests/test_lower_mir_execute_pipeline_byte_equivalent.py +++ b/tests/test_lower_mir_execute_pipeline_byte_equivalent.py @@ -15,7 +15,7 @@ - looking up the registered Lowering on the dialect and applying it yields the same IIR tree as the direct call, - `compile_kernel_body(ep, ...)` still works end-to-end (it routes - through `LowerScanPipelineShim` which still calls + through `LowerKernelBodyShim` which still calls `lower_scan_pipeline` directly today), - `compile_pipeline(ep)` produces byte-identical CUDA text. - EP carrying a `DedupHash` pragma still lowers through the @@ -144,7 +144,7 @@ def _new_ctx(**kwargs: Any) -> LoweringCtx: def _real_ep_with_view_vars() -> tuple[mir.ExecutePipeline, dict[str, Any]]: - '''Run the kernel pipeline up to (but excluding) `LowerScanPipelineShim` + '''Run the kernel pipeline up to (but excluding) `LowerKernelBodyShim` to obtain a fully-prepared EP + view_var maps. Returns the pair so byte-equivalence tests on the real TC fixture can build a matching `LoweringCtx`. @@ -192,7 +192,7 @@ def test_direct_invocation_matches_legacy_lower_scan_pipeline(): def test_direct_invocation_on_real_tc_pipeline(): '''Same byte-equivalence claim against an EP produced by the production HIR->MIR pipeline (richer shape than the hand-built - fixture). Uses the kernel-pipeline's pre-LowerScanPipelineShim + fixture). Uses the kernel-pipeline's pre-LowerKernelBodyShim state to populate `view_var_names` / `view_slot_bases` so the inner ops resolve their view vars correctly.''' ep_pre, ctx_kwargs = _real_ep_with_view_vars() @@ -261,7 +261,7 @@ def test_registered_lowering_matches_legacy_on_real_ep(): def test_compile_kernel_body_still_works_through_kernel_pipeline(): - '''`compile_kernel_body(ep)` routes through `LowerScanPipelineShim` + '''`compile_kernel_body(ep)` routes through `LowerKernelBodyShim` (post-F5.3). The shim still calls `lower_scan_pipeline` directly today — the new registered `@lowering` gives the same lowering a discoverable entry point but does not change the shim's path. @@ -323,7 +323,7 @@ def test_pragma_dedup_hash_still_lowers_through_registered_path(): goes through the same `MirPragmaPass` consumer.''' ep_base = _simple_scan_ep() # Clone with dedup_hash=True; the field flows into LoweringCtx via - # LowerScanPipelineShim and affects InsertInto emit. We're just + # LowerKernelBodyShim and affects InsertInto emit. We're just # checking the EP wrap (`lower_mir_execute_pipeline`) doesn't choke # on it — the delegation pattern means anything that works in # `lower_scan_pipeline` works here. diff --git a/tests/test_verify_renderability.py b/tests/test_verify_renderability.py index 91b187b..26f3774 100644 --- a/tests/test_verify_renderability.py +++ b/tests/test_verify_renderability.py @@ -13,7 +13,7 @@ 4. Integration: `Compiler.run(KernelCtx, pipeline=DEFAULT_KERNEL_PIPELINE)` on a TC fixture passes (because every op renders); inserting a fake shim that produces an unrenderable op raises at the - `VerifyRenderabilityShim` step, BEFORE `CudaRenderShim` runs. + `VerifyRenderabilityShim` step, BEFORE `RenderShim` runs. ''' from __future__ import annotations @@ -117,7 +117,7 @@ def _real_iir_tree() -> object: prog_state = compiler.run(InitialProg(program=_tc_program()), pipeline=DEFAULT_PROGRAM_PIPELINE) assert prog_state.mir_program is not None ep = _first_ep(prog_state.mir_program) - # Run kernel pipeline up through LowerScanPipelineShim (inclusive) + # Run kernel pipeline up through LowerKernelBodyShim (inclusive) # — i.e. everything BEFORE the gate we're testing. This avoids # recursion (we're literally building the fixture the gate consumes). partial_pipeline = [] @@ -249,13 +249,13 @@ def _identity_rewrite(op, _compiler): # ----------------------------------------------------------------------------- -def test_verify_renderability_shim_is_between_lower_scan_and_cuda_render(): - '''Pipeline shape contract: the gate runs AFTER LowerScanPipelineShim - (which produces IIR) and BEFORE CudaRenderShim (which consumes it).''' +def test_verify_renderability_shim_is_between_lower_kernel_body_and_render(): + '''Pipeline shape contract: the gate runs AFTER LowerKernelBodyShim + (which produces IIR) and BEFORE RenderShim (which consumes it).''' names = [p.name for p in DEFAULT_KERNEL_PIPELINE] - i_lower = names.index('lower_scan_pipeline') + i_lower = names.index('lower_kernel_body') i_verify = names.index('verify_renderability') - i_render = names.index('cuda_render') + i_render = names.index('render') assert i_lower < i_verify < i_render @@ -295,7 +295,7 @@ def test_kernel_pipeline_with_injected_unrenderable_op_raises_at_gate(): '''Negative integration: insert a shim that REPLACES the IIR with a tree containing an unrenderable synthetic op. The pipeline must raise `UnrenderableOpError` at `VerifyRenderabilityShim` — BEFORE - `CudaRenderShim` runs (which would otherwise hit its own KeyError). + `RenderShim` runs (which would otherwise hit its own KeyError). The injected shim consumes 'iir' and produces 'iir' so the pipeline ordering check still passes; only the closure check fires.''' @@ -322,12 +322,12 @@ def _fn(state: KernelCtx, _compiler): ep = _first_ep(prog_state.mir_program) # Build a pipeline that injects the unrenderable op AFTER - # LowerScanPipelineShim but BEFORE the gate. The gate must catch it. + # LowerKernelBodyShim but BEFORE the gate. The gate must catch it. inject = _InjectUnrenderable() patched: list = [] for p in DEFAULT_KERNEL_PIPELINE: patched.append(p) - if p.name == 'lower_scan_pipeline': + if p.name == 'lower_kernel_body': patched.append(inject) with pytest.raises(UnrenderableOpError) as excinfo: @@ -338,7 +338,7 @@ def _fn(state: KernelCtx, _compiler): def test_verify_renderability_shim_consumes_iir_produces_nothing(): '''Pipeline-data contract: the gate consumes the iir dialect produced - by LowerScanPipelineShim. Because it doesn't introduce a new + by LowerKernelBodyShim. Because it doesn't introduce a new pseudo-dialect, `produces=()`.''' shim = VerifyRenderabilityShim() assert shim.consumes == ('iir',) @@ -353,7 +353,7 @@ def test_verify_renderability_shim_consumes_iir_produces_nothing(): test_verify_renderability_raises_on_nested_unrenderable_op() test_verify_renderability_raises_on_unknown_target() test_rewrite_closes_an_otherwise_unrenderable_op() - test_verify_renderability_shim_is_between_lower_scan_and_cuda_render() + test_verify_renderability_shim_is_between_lower_kernel_body_and_render() test_verify_renderability_shim_is_a_pass_through() test_default_kernel_pipeline_runs_end_to_end_with_gate() test_kernel_pipeline_with_injected_unrenderable_op_raises_at_gate() From 7cf52126a37842ab4ae814196911559520be044f Mon Sep 17 00:00:00 2001 From: ysun67 Date: Tue, 19 May 2026 16:28:32 -0400 Subject: [PATCH 2/2] chore: fix I001 import sort in complete_runner.py (CI gate) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One-line mechanical re-sort — ep_has_work_stealing import moves into the alphabetical block. Pre-existing ruff failure on design/redesign-package blocks PR-1b CI; inlined here so the PR goes CLEAN without a separate chore-PR dependency. No behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/srdatalog/ir/codegen/cuda/complete_runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/srdatalog/ir/codegen/cuda/complete_runner.py b/src/srdatalog/ir/codegen/cuda/complete_runner.py index 039ebf2..e3c2237 100644 --- a/src/srdatalog/ir/codegen/cuda/complete_runner.py +++ b/src/srdatalog/ir/codegen/cuda/complete_runner.py @@ -43,7 +43,6 @@ has_tiled_cartesian_eligible, ) from srdatalog.ir.codegen.cuda.plugin import plugin_gen_host_view_setup, plugin_view_count -from srdatalog.ir.mir.passes import ep_has_work_stealing # Pure-template phase emitters now live in the dialect's runner module. # Local aliases preserve the legacy call sites until the rest of this @@ -75,6 +74,7 @@ compute_total_view_count, source_spec_key, ) +from srdatalog.ir.mir.passes import ep_has_work_stealing # ----------------------------------------------------------------------------- # Source spec extraction helpers (mirror Nim's inline lambdas)