qat.experimental.conversion.pulse.lower_kernels_to_arrays module
Lower pulse kernels from collection-typed results to array-typed results.
This module provides the inter-dialect pass that rewrites each
KernelOp signature from
ResultsCollectionType values to ResultsArrayType values, then updates all call
sites to match the expanded kernel signature.
The pass depends on the generic results conversion pass to lower the kernel body before rewriting the kernel signature and its callers.
- class LowerKernelsToResultsArrays
Bases:
ModulePassLower pulse kernel bodies, signatures, and call sites to arrays.
The pass first rewrites collection-typed values inside each kernel body, then updates the kernel signature and every call site to match the lowered array-based form.
Example:
// Before module { pulse.kernel @accumulate() -> (!results.collection<"a": i32, "b": i64>[2]) { %c0 = arith.constant 0 : index %c1 = arith.constant 1 : index %acc = results.create : !results.collection<"a": i32, "b": i64>[2] scf.for %i = %c0 to %c1 step %c1 iter_args(%current = %acc) -> (!results.collection<"a": i32, "b": i64>[2]) { %a = arith.constant 1 : i32 %b = arith.constant 2 : i64 %next = results.store %current[%i] with %a : !results.collection<"a": i32, "b": i64>[2] %next2 = results.store %next[%i] with %b : !results.collection<"a": i32, "b": i64>[2] scf.yield %next2 : !results.collection<"a": i32, "b": i64>[2] } pulse.return %acc : !results.collection<"a": i32, "b": i64>[2] } func.func @main() -> (!results.collection<"a": i32, "b": i64>[2]) { %result = pulse.call_kernel @accumulate() : () -> (!results.collection<"a": i32, "b": i64>[2]) func.return %result : !results.collection<"a": i32, "b": i64>[2] } } // After module { pulse.kernel @accumulate() -> (!results.array<i32>[2], !results.array<i64>[2]) { %c0 = arith.constant 0 : index %c2 = arith.constant 2 : index %c1 = arith.constant 1 : index %a = results.create : !results.array<i32>[2] %b = results.create : !results.array<i64>[2] %a_final, %b_final = scf.for %i = %c0 to %c2 step %c1 iter_args(%a_current = %a, %b_current = %b) -> (!results.array<i32>[2], !results.array<i64>[2]) { %a_value = arith.constant 1 : i32 %b_value = arith.constant 2 : i64 %a_next = results.store %a_current[%i] with %a_value : !results.array<i32>[2] %b_next = results.store %b_current[%i] with %b_value : !results.array<i64>[2] scf.yield %a_next, %b_next : !results.array<i32>[2], !results.array<i64>[2] } pulse.return %a_final, %b_final : !results.array<i32>[2], !results.array<i64>[2] } func.func @main() -> (!results.collection<"a": i32, "b": i64>[2]) { %a, %b = pulse.call_kernel @accumulate() : () -> (!results.array<i32>[2], !results.array<i64>[2]) %result = results.create %a, %b : !results.collection<"a": i32, "b": i64>[2] func.return %result : !results.collection<"a": i32, "b": i64>[2] } }- apply(ctx, op)
Rewrite kernel signatures and all matching call sites in
op.
- name: ClassVar[str] = 'lower-kernels-to-results-arrays'
- expand_call_site(expansion, call_site)
Builds the replacement operations and result SSA values for
call_site.Returns a tuple of
(operations, replacement_results)suitable for passing directly toreplace_op().operationsis ordered as: extract ops → new call op → reassembly create ops.- Parameters:
expansion¶ (
_KernelSignatureExpansion) – The precomputed kernel signature expansion.call_site¶ (
CallKernelOp) – The call site to expand.
- Return type:
tuple[list[CallKernelOp|CreateOp|ExtractOp],list[SSAValue]]- Returns:
Replacement operations and SSA values in original result order.