Hi everyone!
I built a small compilation pass that performs a transformation essentially amounting to repeating every instruction in a program + its ‘inverse’ (also called its adjoint) a bunch of times.
As a simple example, here is a small program:
module {
func.func @main(%arg0: !ensemble.qubit, %arg1: !ensemble.qubit) -> !ensemble.qubit {
%0 = ensemble.gate1q "H" %arg0 : (!ensemble.qubit) -> (!ensemble.qubit)
%1 = ensemble.gate1q "H" %arg1 : (!ensemble.qubit) -> (!ensemble.qubit)
%2 = ensemble.gate1q "X" %0 : (!ensemble.qubit) -> (!ensemble.qubit)
%3 = ensemble.gate1q "X" %1 : (!ensemble.qubit) -> (!ensemble.qubit)
return %3: !ensemble.qubit
}
}
And here is the output from the compiler pass I built (using a custom version of mlir-opt that I registered my dialect and pass with):
module {
func.func @main(%arg0: !ensemble.qubit, %arg1: !ensemble.qubit) -> !ensemble.qubit {
%0 = ensemble.gate1q "H" %arg0 {"zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
affine.for %arg2 = 0 to 10 {
%4 = ensemble.gate1q "H" %0 {"zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
%5 = ensemble.gate1q "H" %4 {adjoint, "zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
}
%1 = ensemble.gate1q "H" %arg1 {"zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
affine.for %arg2 = 0 to 10 {
%4 = ensemble.gate1q "H" %1 {"zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
%5 = ensemble.gate1q "H" %4 {adjoint, "zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
}
%2 = ensemble.gate1q "X" %0 {"zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
affine.for %arg2 = 0 to 10 {
%4 = ensemble.gate1q "X" %2 {"zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
%5 = ensemble.gate1q "X" %4 {adjoint, "zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
}
%3 = ensemble.gate1q "X" %1 {"zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
affine.for %arg2 = 0 to 10 {
%4 = ensemble.gate1q "X" %3 {"zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
%5 = ensemble.gate1q "X" %4 {adjoint, "zne-applied"} : (!ensemble.qubit) -> (!ensemble.qubit)
}
return %3 : !ensemble.qubit
}
}
Something that I noticed is that the names of the SSA values being assigned inside the for loops are repeated (%4 and %5).
Is there any way that I could change the names of these variables (programmatically)? I’m also not sure how the generated IR included multiple assignments to the same values - am I wrong in thinking that MLIR handles SSA value naming automatically to ensure that no value is assigned twice? Or do I need to take specific steps in my compiler passes to ensure this?
Thank you in advance!