catalyst icon indicating copy to clipboard operation
catalyst copied to clipboard

Document the semantics of the QuantumDevice interface

Open dime10 opened this issue 6 months ago • 3 comments

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 shots from MP signatures, since that was officially deprecated.
    • I would say removing the One/Zero can 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.

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!
 */

dime10 avatar Apr 23 '25 18:04 dime10