-
Notifications
You must be signed in to change notification settings - Fork 179
Enable PrepareArbitraryState to use state injection on Quantum Simulator #370
Conversation
|
It looks like
|
cgranade
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not had a chance to do a complete review yet, sorry; please treat these comments as provisional for now. Thanks for your patience!
Since My suggestion would thus be to add a check similar to the |
In general we cannot check the register for being in zero state, can we? I can change the API on the native side to return bool and return Note: Before I update the runtime not to throw, added a catch so we can run all tests and discover other potential problems. This is not meant to be final. |
I think there's already a native API for that, used to implement double JointEnsembleProbability(std::vector<Gates::Basis> bs, std::vector<logical_qubit_id> qs)
{
removeIdentities(bs, qs);
if (bs.empty())
{
return 0.0;
}
recursive_lock_type l(mutex());
changebasis(bs, qs, true);
double p = psi.jointprobability(qs);
changebasis(bs, qs, false);
return p;
}
That makes a lot of sense, yeah. Hopefully should be able to see performance implications of that unpacking in end-to-end benchmarks.
Makes sense, agreed; if it turns out from benchmarks that we need to grow the C-API surface further, maybe we could generalize slightly to allow checking registers of qubits against |00…0⟩, then do the check from the C# side?
Sounds good! |
I meant to say, that there is no generic Q# way to check the state of the register because only specific simulators can do this, for example the full state simulator. And as long as we have to ping the simulator anyway, we can do the check inside InjectState API or in an additional call as I described above. Also, to guarantee the prereq, AssertMeasurementProbability has to be done on each qubit separately, right? So if we do it on Q# side it will have to make n roundtrips to the simulator rather than a single call if we do the check inside InjectState. Note: Considered not doing the check at all and allowing to inject the state anyway. Unfortunately, in the current implementation of partial state injection this might not end up being a unitary operation so cannot go that route.
Even if we do see the impact, I'm not sure it's worth optimizing here, because the result of the behaviour is going to be undefined anyway, no? However, there is one more concern I have now. If I understand your previous explanations correctly, we must provide precise emulation of adjoint as well, otherwise base*adjoint might not yield identity. UPD: discussed with @alexeib2 -- there is no known efficient way to uncompute state injection so the discrepancy is unavoidable. QML scenarios shouldn't need the adjoint, and for those scenarios that do apply it there probably should be a way to configure the libraries (or the simulator) to never emulate. |
cgranade
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good, thanks for doing this! Note that we won't see improvements in QML performance until we port that library to use _PrepareAmplitudesFromZeroState.
a typo in comment Co-authored-by: Chris Granade <chgranad@microsoft.com>
Added new non-Adj/non-Ctr operation
_PrepareAmplitudesFromZeroStatethat will emulate state preparation if running on a simulator that supports it and the prerequisites are met.Had to move onto SDK 0.14.20111301-pull to pick up the new functionality in the Quantum Simulator.