Closed jfraxanet closed 2 months ago
The difference between prepare_state
and initialize
is because Aer supports initialize
natively as an instruction, so transpile
doesn't need to do anything to it. Aer can short-circuit evaluation of initialize
to simply set the statevector to the correct value (including relevant partial traces, etc), but prepare_state
is a unitary operation that has a defined action on the $\lvert 0\rangle$ state, and undefined but still fixed actions on all other basis states, so in general, it can't. Obviously here, if you reset the qubits first, the action will be the same, but we don't have a peephole optimisation pass that combines these.
The point of prepare_state
is that you can take the adjoint of it, so you can use it as a kernel to implement arbitrary $\lvert \psi\rangle \to \lvert \phi\rangle$ transitions by applying $U\phi U\psi^\dagger$ to a state.
I'm not sure what's causing peaks in the measured runtime - off the top of my head, I can't think of what it might be in the transpiler, though it's possible that those are garbage-collection spikes.
I see, thank you so much for the quick response and the clarification!
It's good to know, since using qc.prepare_state()
in an optimization workflow can increase the time to a point in which it becomes difficult to get a converged result, but by switching to qc.initialize()
it is easily solved!
Thanks! I'll close this issue now, but feel free to re-open if there's more to discuss.
Environment
What is happening?
We realized that the transpilation time using the AerSimulator for the instructions
takes much longer than
even though the two instructions should be equivalent. This is specially relevant for iterative processes such as variational algorithms, in which the circuit is built several times, since we see structured peaks in the transpilation time for each iterative step.
When comparing the two classes, we realized that for the
qc.prepare_state()
instruction, theqc.append(StatePreparation)
is called with "copy=False" while forqc.initialize()
, the default value is "copy=True". Even though it seems thatqc.prepare_state()
might be slower because it creates a circuit from scratch each time, we were not able to reproduce the results usingqc.initialize()
differently, and this would not explain the peaks.How can we reproduce the issue?
What should happen?
The following instructions should be equivalent:
Any suggestions?
Probably
qc.prepare_state()
is implementing some step which is not needed, or redefining the circuit at some point.