catalyst
catalyst copied to clipboard
Document the semantics of the QuantumDevice interface
This PR adds detailed descriptions of the semantics of each method in the QuantumDevice interface used by runtime plugins. Looking for feedback on:
- whether the semantics make sense as written (mostly they are describing the existing behaviour in particular w.r.t to the lighting devices)
- which methods should be considered optional - I gave it my best guest about what a "minimal" working device would need to support
- whether anything is missing
- whether any TODOs should be implemented right now
- At the very least I would say we should remove
shotsfrom MP signatures, since that was officially deprecated. - I would say removing the
One/Zerocan also be at the top of the list, since we already don't use them, and the functions to make use of them are already gone (like__quantum__rt__compare_result), so they really don't make any sense anymore. - Some of the type restructuring might also be nice.
- At the very least I would say we should remove
closes #1512 [sc-81294]
While writing these, I identified the following TODOs to improve the interface (possibly at a later date):
////////////////////
////// TODO //////
////////////////////
/*
* - Remove the `shots` parameter from sample and counts methods, as that has already been
* deprecated in #1310.
* - Revisit confusing or inconsistent type usage and/or naming in the runtime/device interface:
* - QUBIT type: `QUBIT` (undefined struct) vs `QUBIT*` vs `QubitIdType`
* - RESULT type: `RESULT` (bool) vs `Result` (RESULT*)
* - OBS type: `ObsId` vs `ObsIdType`
* - Remove default argument values from the interface.
* - Include types only where they are needed:
* - CAPI types in the CAPI header
* - Runtime types in CAPI implementation or QuantumDevice header
* - Also: Should the QuantumDevice interface use the concrete C++ types instead of the type aliases?
* The former might make it clearer for any implementers what types are used.
* - Revisit instructions in the QuantumDevice interface:
* - move `PrintState` into the runtime or eliminate entirely?
* Seems unnecessary as a dedicated function since one can just call `State` + print.
* - remove `Result` specific functions (`One`, `Zero`, `compare_result` - already gone I guess)?
* With results being forced as `bool*`, there is no reason to keep these functions.
* Originally they were meant to allow an arbitrary representation of measurement results,
* and would thus require special runtime functions, but this is not the case.
* - revisit qubit management functions
* - ideally as part of dynamic allocation or multiple register support
* - several inconsistencies here, but first and foremost `AllocateQubits` has no counterpart,
* only `ReleaseAllQubits`
* - QubitUnitary / Hermitian: why creating `vector<complex>` instead of forwarding a `DataView`?
* - Why is Jacobian in `Gradient` a `vector<buffer>` instead of a 2D buffer?
* - With `Probs` / `PartialProbs` and similar ops, there are separate instructions for acting on a subsystem,
* but with `Gradient` the same function is reused for both (dictated by the `trainParams` argument`).
*
* Important: All devices need to be updated after such interface changes!
*/