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: ModulePass

Lower 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.

Parameters:
  • ctx (Context) – The active xDSL context. It is currently unused, but required by the ModulePass interface.

  • op (ModuleOp) – The module containing pulse kernels and their call sites.

Return type:

None

Returns:

None. The module is rewritten in place.

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 to replace_op(). operations is 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.