Struct QuantumDevice

Struct Documentation

struct QuantumDevice

struct API for backend quantum devices.

This device API contains,

  • a set of methods to manage qubit allocations and deallocations, device shot noise, and quantum tape recording as well as reference values for the result data-type; these are used to implement Quantum Runtime (QR) instructions.

  • a set of methods for quantum operations, observables, measurements, and gradient of the device; these are used to implement Quantum Instruction Set (QIS) instructions.

Public Functions

QuantumDevice() = default
virtual ~QuantumDevice() = default
QuantumDevice &operator=(const QuantumDevice&) = delete
QuantumDevice(const QuantumDevice&) = delete
QuantumDevice(QuantumDevice&&) = delete
QuantumDevice &operator=(QuantumDevice&&) = delete
virtual auto AllocateQubit() -> QubitIdType = 0

Allocate a qubit.

Returns

QubitIdType

virtual auto AllocateQubits(size_t num_qubits) -> std::vector<QubitIdType> = 0

Allocate a vector of qubits.

Parameters

num_qubits – The number of qubits to allocate.

Returns

std::vector<QubitIdType>

virtual void ReleaseQubit(QubitIdType qubit) = 0

Release a qubit.

Parameters

qubit – The id of the qubit

virtual void ReleaseAllQubits() = 0

Release all qubits.

virtual auto GetNumQubits() const -> size_t = 0

Get the number of allocated qubits.

Returns

size_t

virtual void SetDeviceShots(size_t shots) = 0

Set the number of device shots.

Parameters

shots – The number of noise shots

virtual auto GetDeviceShots() const -> size_t = 0

Get the number of device shots.

Returns

size_t

inline virtual void SetDevicePRNG([[maybe_unused]] std::mt19937 *gen)

Set the PRNG of the device.

The Catalyst runtime enables seeded program execution on non-hardware devices. A random number generator instance is managed by the runtime to predictably generate results for non-deterministic programs, such as those involving Measure calls. Devices implementing support for this feature do not need to use the provided PRNG instance as their sole source of random numbers, but it is expected that the the same instance state will predictable and reproducibly generate the same program results. It is also expected that the provided PRNG state is evolved sufficiently so that two device executions sharing the same instance do not produce identical results. The provided PRNG instance is not thread-locked, and devices wishing to share it across threads will need to provide their own thread-safety.

Parameters

gen – The std::mt19937 PRNG object.

virtual void StartTapeRecording() = 0

Start recording a quantum tape if provided.

Note

This is backed by the Catalyst::Runtime::CacheManager<ComplexT> property in the device implementation.

virtual void StopTapeRecording() = 0

Stop recording a quantum tape if provided.

Note

This is backed by the Catalyst::Runtime::CacheManager<ComplexT> property in the device implementation.

virtual auto Zero() const -> Result = 0

Result value for “Zero” used in the measurement process.

Returns

Result

virtual auto One() const -> Result = 0

Result value for “One” used in the measurement process.

Returns

Result

virtual void PrintState() = 0

A helper method to print the state vector of a device.

inline virtual void SetState([[maybe_unused]] DataView<std::complex<double>, 1> &state, [[maybe_unused]] std::vector<QubitIdType> &wires)

Prepare subsystems using the given ket vector in the computational basis.

Parameters
  • state – A state vector of size 2**len(wires)

  • wires – The wire(s) the operation acts on

inline virtual void SetBasisState([[maybe_unused]] DataView<int8_t, 1> &n, [[maybe_unused]] std::vector<QubitIdType> &wires)

Prepares a single computational basis state.

Parameters
  • n – Prepares the basis state |n>, where n is an array of integers from the set {0, 1}

  • wires – The wire(s) the operation acts on

virtual void NamedOperation(const std::string &name, const std::vector<double> &params, const std::vector<QubitIdType> &wires, [[maybe_unused]] bool inverse = false, [[maybe_unused]] const std::vector<QubitIdType> &controlled_wires = {}, [[maybe_unused]] const std::vector<bool> &controlled_values = {}) = 0

Apply a single gate to the state vector of a device with its name if this is supported.

Parameters
  • name – The name of the gate to apply

  • params – Optional parameter list for parametric gates

  • wires – Wires to apply gate to

  • inverse – Indicates whether to use inverse of gate

  • controlled_wires – Optional controlled wires applied to the operation

  • controlled_values – Optional controlled values applied to the operation

virtual void MatrixOperation(const std::vector<std::complex<double>> &matrix, const std::vector<QubitIdType> &wires, [[maybe_unused]] bool inverse = false, [[maybe_unused]] const std::vector<QubitIdType> &controlled_wires = {}, [[maybe_unused]] const std::vector<bool> &controlled_values = {}) = 0

Apply a given matrix directly to the state vector of a device.

Parameters
  • matrix – The matrix of data in row-major format

  • wires – Wires to apply gate to

  • inverse – Indicates whether to use inverse of gate

  • controlled_wires – Controlled wires applied to the operation

  • controlled_values – Controlled values applied to the operation

virtual auto Observable(ObsId id, const std::vector<std::complex<double>> &matrix, const std::vector<QubitIdType> &wires) -> ObsIdType = 0

Construct a named (Identity, PauliX, PauliY, PauliZ, and Hadamard) or Hermitian observable.

Parameters
  • id – The type of the observable

  • matrix – The matrix of data to construct a hermitian observable

  • wires – Wires to apply observable to

Returns

ObsIdType Index of the constructed observable

virtual auto TensorObservable(const std::vector<ObsIdType> &obs) -> ObsIdType = 0

Construct a tensor product of observables.

Parameters

obs – The vector of observables indices of type ObsIdType

Returns

ObsIdType Index of the constructed observable

virtual auto HamiltonianObservable(const std::vector<double> &coeffs, const std::vector<ObsIdType> &obs) -> ObsIdType = 0

Construct a Hamiltonian observable.

Parameters
  • coeffs – The vector of coefficients

  • obs – The vector of observables indices of size coeffs

Returns

ObsIdType Index of the constructed observable

virtual auto Expval(ObsIdType obsKey) -> double = 0

Compute the expected value of an observable.

Parameters

obsKey – The index of the constructed observable

Returns

double The expected value

virtual auto Var(ObsIdType obsKey) -> double = 0

Compute the variance of an observable.

Parameters

obsKey – The index of the constructed observable

Returns

double The variance

virtual void State(DataView<std::complex<double>, 1> &state) = 0

Get the state-vector of a device.

Parameters

state – The pre-allocated DataView<complex<double>, 1>

virtual void Probs(DataView<double, 1> &probs) = 0

Compute the probabilities of each computational basis state.

Parameters

probs – The pre-allocated DataView<double, 1>

virtual void PartialProbs(DataView<double, 1> &probs, const std::vector<QubitIdType> &wires) = 0

Compute the probabilities for a subset of the full system.

Parameters
  • probs – The pre-allocated DataView<double, 1>

  • wires – Wires will restrict probabilities to a subset of the full system

virtual void Sample(DataView<double, 2> &samples, size_t shots) = 0

Compute samples with the number of shots on the entire wires, returing raw samples.

Parameters
  • samples – The pre-allocated DataView<double, 2>representing a matrix of shape shots * numQubits. The built-in iterator in DataView<double, 2> iterates over all elements of samples row-wise.

  • shots – The number of shots

virtual void PartialSample(DataView<double, 2> &samples, const std::vector<QubitIdType> &wires, size_t shots) = 0

Compute partial samples with the number of shots on wires, returing raw samples.

Parameters
  • samples – The pre-allocated DataView<double, 2>representing a matrix of shape shots * numWires. The built-in iterator in DataView<double, 2> iterates over all elements of samples row-wise.

  • wires – Wires to compute samples on

  • shots – The number of shots

virtual void Counts(DataView<double, 1> &eigvals, DataView<int64_t, 1> &counts, size_t shots) = 0

Sample with the number of shots on the entire wires, returning the number of counts for each sample.

Parameters
  • eigvals – The pre-allocated DataView<double, 1>

  • counts – The pre-allocated DataView<int64_t, 1>

  • shots – The number of shots

virtual void PartialCounts(DataView<double, 1> &eigvals, DataView<int64_t, 1> &counts, const std::vector<QubitIdType> &wires, size_t shots) = 0

Partial sample with the number of shots on wires, returning the number of counts for each sample.

Parameters
  • eigvals – The pre-allocated DataView<double, 1>

  • counts – The pre-allocated DataView<int64_t, 1>

  • wires – Wires to compute samples on

  • shots – The number of shots

virtual auto Measure(QubitIdType wire, std::optional<int32_t> postselect) -> Result = 0

A general measurement method that acts on a single wire.

Parameters
  • wire – The wire to compute Measure on

  • postselect – Which basis state to postselect after a mid-circuit measurement (-1 denotes no post-selection)

Returns

Result The measurement result

virtual void Gradient(std::vector<DataView<double, 1>> &gradients, const std::vector<size_t> &trainParams) = 0

Compute the gradient of a quantum tape, that is cached using Catalyst::Runtime::Simulator::CacheManager, for a specific set of trainable parameters.

Parameters
  • gradients – The vector of pre-allocated DataView<double, 1>* to store gradients resutls for the list of cached observables.

  • trainParams – The vector of trainable parameters; if none, all parameters would be assumed trainable