Support mutable fixed size arrays in Adaptive Profile QIR emission - #3706
Stefan J. Wernli (swernli) wants to merge 1 commit into
Conversation
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.
@EntryPoint(Adaptive)
operation Main() : Int {
mutable values = [0];
if 2 < 3 {
values[0] = 136;
}
use qubit = Qubit();
H(qubit);
if MResetZ(qubit) == One {
values[0] += 1;
}
return values[0];
}I would expect this to evaluate to either 136 or 137, but it actually evaluates to 0 or 137 - looks like the static if is getting dropped. Quoth Copilot: Mutable fixed-size array updates nested inside statically evaluated control flow are lost during Adaptive QIR emission. In Expected output: The partial evaluator’s classical and hybrid states become desynchronized. The synchronization logic predates #3706, but the PR exposes it through newly supported mutable fixed-size arrays and lacks coverage for static control flow followed by dynamic use. |
|
I can't generate QIR for this: @EntryPoint(Adaptive)
operation Main() : Int {
mutable matrix = [
[9, 1, 7],
[3, 5, 2],
[8, 4, 6]
];
use q = Qubit();
H(q);
if (MResetZ(q) == One) {
matrix[0][1] = 2;
}
return matrix[1][2];
} |
|
Ooo, both good finds, Andrew Casey (@amcasey)! For the first one, I need to ensure that expressions that include an update of a dynamic, mutable, fixed size array are themselves considered dynamic. Then for the second, at the very least this should be a graceful failure at QIR generation time, but I'd like to look into whether or not this can be detected at analysis time so the user gets feedback sooner that it isn't supported. |


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.