Skip to content

Support mutable fixed size arrays in Adaptive Profile QIR emission - #3706

Open
Stefan J. Wernli (swernli) wants to merge 1 commit into
mainfrom
swernli/mutable-arrays
Open

Support mutable fixed size arrays in Adaptive Profile QIR emission#3706
Stefan J. Wernli (swernli) wants to merge 1 commit into
mainfrom
swernli/mutable-arrays

Conversation

@swernli

Copy link
Copy Markdown
Contributor

This change adds support for mutable fixed size arrays in Adaptive Profile. It adds new RIR instructions to correspond to array copy, slice, and store index instructions and updates Partial Evaluation to emit these instructions when needed. To minimize extraneous propagation of variables and only emit the new instructions when required by the program, the implementation carefully tracks the usage of mutable fixed size arrays throughout the program, the change also updates Runtime Capabilities Analysis to mark those arrays who are dynamically updated and propagate those results as part of analysis. This allows Partial Eval to identify these arrays when they are initialized and emit the expected store instructions, tracking the resulting variable rather than the array contents (since emitting at first array update is too late). The new instructions generate multiple lines of QIR each, rather than emitting to a loop, to preserve block linearity and avoid introducing new control flow where it is unexpected. Changes are validated in Partial Eval and Codegen unit tests, as well as Python integration testing.

This change adds support for mutable fixed size arrays in Adaptive Profile. It adds new RIR instructions to correspond to array copy, slice, and store index instructions and updates Partial Evaluation to emit these instructions when needed. To minimize extraneous propagation of variables and only emit the new instructions when required by the program, the implementation carefully tracks the usage of mutable fixed size arrays throughout the program, the change also updates Runtime Capabilities Analysis to mark those arrays who are dynamically updated and propagate those results as part of analysis. This allows Partial Eval to identify these arrays when they are initialized and emit the expected store instructions, tracking the resulting variable rather than the array contents (since emitting at first array update is too late). The new instructions generate multiple lines of QIR each, rather than emitting to a loop, to preserve block linearity and avoid introducing new control flow where it is unexpected. Changes are validated in Partial Eval and Codegen unit tests, as well as Python integration testing.
@swernli

Copy link
Copy Markdown
Contributor Author

As an example of code that this change now supports, consider:

@EntryPoint(Adaptive)
operation Main() : Bool[] {
    use q = Qubit[2];
    mutable redo = true;
    mutable results = [false, false];
    mutable loop_count = 0;
    repeat {
        // Psuedo "X with noise" operation
        Rx(2.5, q[0]);
        Rx(2.5, q[1]);
        let r0 = MResetZ(q[0]);
        let r1 = MResetZ(q[1]);
        results[0] = not IsLossResult(r0) and r0 == One;
        results[1] = not IsLossResult(r1) and r1 == One;
        loop_count += 1;
    } until (results[0] and results[1]) or loop_count > 100;
    results
}

This used to fail because it involved mutating the array of Bool values:

image

It now produces valid Adaptive QIR:

image

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