CUDA Quantum C++ API

Operators

class spin_op

The spin_op represents a general sum of pauli tensor products. It exposes the typical algebraic operations that allow programmers to define primitive pauli operators and use them to compose larger, more complex pauli tensor products and sums thereof.

Public Functions

spin_op()

Constructor, creates the identity term.

spin_op(const spin_op &o)

Copy constructor.

spin_op(std::vector<double> &data_rep, std::size_t nQubits)

Construct this spin_op from a serialized representation. Specifically, this encoding is via a vector of doubles. The encoding is as follows: for each term, a list of doubles where the ith element is a 3.0 for a Y, a 1.0 for a X, and a 2.0 for a Z on qubit i, followed by the real and imag part of the coefficient. Each term is appended to the array forming one large 1d array of doubles. The array is ended with the total number of terms represented as a double.

~spin_op() = default

The destructor.

spin_op &operator=(const spin_op&)

Set the provided spin_op equal to this one and return *this.

spin_op &operator+=(const spin_op &v) noexcept

Add the given spin_op to this one and return *this.

spin_op &operator-=(const spin_op &v) noexcept

Subtract the given spin_op from this one and return *this.

spin_op &operator*=(const spin_op &v) noexcept

Multiply the given spin_op with this one and return *this.

bool operator==(const spin_op &v) const noexcept

Return true if this spin_op is equal to the given one. Equality here does not consider the coefficients.

spin_op &operator*=(const double v) noexcept

Multiply this spin_op by the given double.

spin_op &operator*=(const std::complex<double> v) noexcept

Multiply this spin_op by the given complex value.

spin_op operator[](const std::size_t termIdx) const

Return the ith term of this spin_op (by value).

std::size_t n_qubits() const

Return the number of qubits this spin_op is on.

std::size_t n_terms() const

Return the number of terms in this spin_op.

std::complex<double> get_term_coefficient(const std::size_t idx) const

Return the coefficient on the ith term in this spin_op.

BinarySymplecticForm get_bsf() const

Return the binary symplectic form data.

bool is_identity()

Is this spin_op == to the identity.

void dump() const

Dump a string representation of this spin_op to standard out.

std::string to_string(bool printCoefficients = true) const

Return a string representation of this spin_op.

std::vector<double> getDataRepresentation()

Return the vector<double> serialized representation of this spin_op. (see the constructor for the encoding)

std::vector<std::complex<double>> get_coefficients() const

Return all term coefficients in this spin_op.

spin_op slice(const std::size_t startIdx, const std::size_t count)

Return a new spin_op made up of a sum of spin_op terms where the first term is the one at startIdx, and the remaining terms are the next count terms.

void for_each_term(std::function<void(spin_op&)>&&)

Apply the give functor on each term of this spin_op. This method can enable general reductions via lambda capture variables.

void for_each_pauli(std::function<void(pauli, std::size_t)>&&)

Apply the functor on each pauli in this 1-term spin_op. An exception is thrown if there are more than 1 terms. Users should pass a functor that takes the pauli type and the qubit index.

Public Static Functions

static inline spin_op from_binary_symplectic(BinarySymplecticForm &data, std::vector<std::complex<double>> &coeffs)

Return a new spin_op from the user-provided binary symplectic data.

static spin_op random(std::size_t nQubits, std::size_t nTerms)

Return a random spin_op on nQubits composed of nTerms.

Quantum

constexpr auto cudaq::dyn = std::dynamic_extent
template<std::size_t Levels>
class qudit

The qudit models a general d-level quantum system. This type is templated on the number of levels d.

Public Functions

inline qudit()

Construct a qudit, will allocated a new unique index.

template<std::size_t N = dyn, std::size_t Levels = 2>
class qreg

A qreg is a container for qudits. This container can be dynamic or compile-time-size specified. By default, the qreg is constructed as a dynamic register (vector-like) of qubits (2-level). This can be changed via the qreg type template parameters.

Public Types

using value_type = qudit<Levels>

Useful typedef indicating the underlying qudit type.

Public Functions

inline qreg(std::size_t size)

Construct a qreg with size qudits in the |0> state. Can only be used for dyn sized qregs.

inline qreg()

Nullary constructor can only be used for qreg<N> q;

qreg(qreg const&) = delete

qregs cannot be copied

qreg(qreg&&) = delete

qregs cannot be moved

inline auto begin()

Iterator interface, begin.

inline value_type &operator[](const std::size_t idx)

Returns the qudit at idx.

inline qspan<dyn, Levels> front(std::size_t count)

Returns the [0, count) qudits.

inline value_type &front()

Returns the first qudit.

inline qspan<dyn, Levels> back(std::size_t count)

Returns the [count, size()) qudits.

inline value_type &back()

Returns the last qudit.

inline qspan<dyn, Levels> slice(std::size_t start, std::size_t size)

Returns the [start, start+size) qudits.

inline std::size_t size() const

Returns the number of contained qudits.

inline void clear()

Destroys all contained qudits. Postcondition: size() == 0.

template<std::size_t N = dyn, std::size_t Levels = 2>
class qspan
using cudaq::qubit = qudit<2>

Common

class observe_result

The observe_result encapsulates all data generated from a cudaq”::”observe call. This includes all measurement counts from the execution of each ansatz + measure circuit, and the global expected value of the spin_op passed to observe.

Public Functions

inline observe_result(double &e, spin_op &H)

Constructor, takes the pre-computed exp val for <psi(x) | H | psi(x)> for the given spin_op.

inline observe_result(double &e, spin_op &H, sample_result counts)

Constructor, takes the pre-computed exp val for <psi(x) | H | psi(x)> for the given spin_op. If this execution was shots based, also provide the sample_result data containing counts for each term in H.

inline sample_result raw_data()

Return the raw counts data for all terms.

Returns:

inline operator double()

Conversion operator for this observe_result to double. Simply returns the pre-computed expectation value for the given spin_op. This.

the expected value: double exp = cudaq”::”observe(…); as opposed to cudaq”::”observe_data data = cudaq::observe(…); auto exp = data.exp_val_z();

inline double exp_val_z()

Return the expected value for the provided spin_op.

Returns:

template<typename SpinOpType>
inline double exp_val_z(SpinOpType term)

Return the expectation value for a sub-term in the provided spin_op.

template<typename SpinOpType>
inline sample_result counts(SpinOpType term)

Return the counts data for the given spin_op.

Parameters:

term

Returns:

inline double id_coefficient()

Return the coefficient of the identity term.

Returns:

inline void dump()

Dump the counts data to standard out.

class ExecutionContext

The ExecutionContext is an abstraction to indicate how a CUDA Quantum kernel should be executed.

Public Functions

inline ExecutionContext(const std::string n)

The Constructor, takes the name of the context.

Parameters:

n – The name of the context

inline ExecutionContext(const std::string n, std::size_t shots_)

The constructor, takes the name and the number of shots.

Parameters:
  • n – The name of the context

  • shots_ – The number of shots

Public Members

const std::string name

The name of the context ({basic, sampling, observe})

std::size_t shots = 0

The number of execution shots.

std::optional<cudaq::spin_op*> spin

An optional spin operator.

sample_result result

Measurement counts for a CUDA Quantum kernel invocation.

std::optional<double> expectationValue = std::nullopt

A computed expectation value.

bool hasConditionalsOnMeasureResults = false

The kernel being executed in this context has conditional statements on measure results.

noise_model *noiseModel = nullptr

Noise model to apply to the current execution.

bool canHandleObserve = false

Flag to indicate if backend can handle spin_op observe task under this ExecutionContext.

bool asyncExec = false

Flag indicating that the current execution should occur asynchronously.

details::future futureResult

When execution asynchronously, store the expected results as a cudaq::future here.

State simulationData

simulationData provides a mechanism for simulation clients to extract the underlying simulation data.

class future

The future type models the expected result of a CUDA Quantum kernel execution under a specific execution context. This type is returned from asynchronous execution calls. It encapsulates the job-specific circuit execution identifiers, the name of the qpu the job executed on, and any extra configuration information needed to retrieve the results later from the server. This type can be persisted to file and read in later to retrieve execution results. It also optionally wraps a std::future<T> type, and in this case, persistence to file is not allowed, .get() must be invoked at some later point within the same runtime context.

Public Functions

future() = default

The constructor.

future(future&&) = default

move constructor

inline future(std::vector<Job> &_jobs, std::string &qpuNameIn, std::map<std::string, std::string> &config)

The constructor, takes all info required to be able to retrieve results at a later date, even after file persistence.

template<typename T>
class async_result

the async_result type is a user facing, future-like type that is returned from CUDA Quantum public asynchronous API functions. It wraps a details::future type, which can itself be constructed from a std::future or a collection of data pertinent to remote QPU REST invocation.

Public Functions

inline T get()

Return the asynchronously computed data, will wait until the data is ready.

struct ExecutionResult

The ExecutionResult models the result of a typical quantum state sampling task. It will contain the observed measurement bit strings and corresponding number of times observed, as well as an expected value with respect to the Z…Z operator.

Public Functions

std::vector<std::size_t> serialize()

Serialize this sample result to a vector of integers. Encoding: 1st element is size of the register name N, then next N represent register name, next is the number of Bitstrings M, then for each bit string a triple {stringMappedToLong, bit string length, count}.

Returns:

void deserialize(std::vector<std::size_t> &data)

Deserialize a vector of integers to a ExecutionResult.

Parameters:

data – The data with encoding discussed in the serialize() brief.

ExecutionResult() = default

Constructor.

ExecutionResult(CountsDictionary c)

Construct from a CountsDictionary, assumes registerName == global

Parameters:

c – the counts

ExecutionResult(std::string name)

Construct from a register name.

ExecutionResult(double expVal)

Construct from a precomputed expectation value.

ExecutionResult(CountsDictionary c, std::string name)

Construct from a CountsDictionary, specify the register name.

Parameters:
  • c – the counts

  • name – the register name

ExecutionResult(CountsDictionary c, double e)

Construct from a CountsDictionary and expected value.

Parameters:
  • c – The counts

  • e – The pre-computed expected value

ExecutionResult(const ExecutionResult &other)

Copy constructor.

Parameters:

other

ExecutionResult &operator=(ExecutionResult &other)

Set this ExecutionResult equal to the provided one.

Parameters:

other

Returns:

bool operator==(const ExecutionResult &result) const

Return true if the given ExecutionResult is the same as this one.

Parameters:

result

Returns:

void appendResult(std::string bitString, std::size_t count)

Append the bitstring and count to this ExecutionResult.

Parameters:
  • bitString

  • count

Public Members

std::string registerName = GlobalRegisterName

Register name for the classicla bits.

std::vector<std::string> sequentialData

Sequential bit strings observed (not collated into a map)

class sample_result

The sample_result abstraction wraps a set of ExecutionResults for a single quantum kernel execution under the sampling or observation ExecutionContext. Each ExecutionResult is mapped to a register name, with a default ExecutionResult with name global representing the observed measurement results holistically for the quantum kernel.

Public Functions

sample_result() = default

Nullary constructor.

sample_result(ExecutionResult &result)

The constructor, sets the global sample result.

Parameters:

result

sample_result(std::vector<ExecutionResult> &results)

The constructor, appends all provided ExecutionResults.

sample_result(double preComputedExp, std::vector<ExecutionResult> &results)

The constructor, takes a pre-computed expectation value and stores it with the global ExecutionResult.

sample_result(const sample_result&)

Copy Constructor.

~sample_result() = default

The destructor.

bool has_expectation(const std::string_view registerName = GlobalRegisterName)

Return true if the given ExecutionResult with registerName has a pre-computed expectation value.

void append(ExecutionResult &result)

Add another ExecutionResult to this pre-constructed sample_result.

Parameters:

result

std::vector<std::string> register_names()

Return all register names. Can be used in tandem with sample_result::to_map(regName : string) to retrieve the counts for each register.

Returns:

sample_result &operator=(sample_result &counts)

Set this sample_result equal to the provided one.

Parameters:

counts

Returns:

sample_result &operator+=(sample_result &other)

Append all the data from other to this sample_result. Merge when necessary.

Parameters:

other

Returns:

std::vector<std::size_t> serialize()

Serialize this sample_result. Encoding is [(ExecutionResult0_Encoding) (ExecutionResult1_Encoding)…(ExecutionResultN_Encoding)] (see ExecutionResult::serialize() docs for encoding).

Returns:

void deserialize(std::vector<std::size_t> &data)

Create this sample_result from the serialized data.

Parameters:

data

bool operator==(const sample_result &counts) const

Return true if this sample_result is the same as the given one.

Parameters:

counts

Returns:

double exp_val_z(const std::string_view registerName = GlobalRegisterName)

Return the expected value <Z…Z>

Returns:

double probability(std::string_view bitString, const std::string_view registerName = GlobalRegisterName)

Return the probability of observing the given bit string.

Parameters:

bitString

Returns:

std::string most_probable(const std::string_view registerName = GlobalRegisterName)

Return the most probable bit string.

Parameters:

registerName

Returns:

std::size_t count(std::string_view bitString, const std::string_view registerName = GlobalRegisterName)

Return the number of times the given bitstring was observed.

Parameters:

bitString

Returns:

std::size_t size(const std::string_view registerName = GlobalRegisterName) noexcept

Return the number of observed bit strings.

Returns:

void dump()

Dump this sample_result to standard out.

void dump(std::ostream &os)

Dump this sample_result to the given output stream.

void clear()

Clear this sample_result.

CountsDictionary to_map(const std::string_view registerName = GlobalRegisterName)

Extract the ExecutionResults as a std::unordered<string, size_t> map.

Parameters:

registerName

Returns:

inline sample_result get_marginal(const std::vector<std::size_t> &&marginalIndices, const std::string_view registerName = GlobalRegisterName)

Extract marginal counts, ie those counts for a subset of measured qubits.

Parameters:
  • marginalIndices – The qubit indices as an rvalue

  • registerName

Returns:

sample_result get_marginal(const std::vector<std::size_t> &marginalIndices, const std::string_view registerName = GlobalRegisterName)

Extract marginal counts, ie those counts for a subset of measured qubits.

Parameters:
  • marginalIndices – The qubit indices as an reference

  • registerName

Returns:

CountsDictionary::iterator begin()

Range-based iterator begin function.

Returns:

CountsDictionary::iterator end()

Range-based iterator end function.

Returns:

CountsDictionary::const_iterator cbegin() const

Range-based const iterator begin function.

Returns:

CountsDictionary::const_iterator cend() const

Range-based const iterator end function.

Returns:

inline CountsDictionary::const_iterator begin() const

Range-based const iterator begin function.

Returns:

inline CountsDictionary::const_iterator end() const

Range-based const iterator end function.

Returns:

using cudaq::State = std::tuple<std::vector<std::size_t>, std::vector<std::complex<double>>>
template<typename T>
class RegisteredType

RegisteredType allows interface types to declare themselves as plugin interfaces. Used as follows class MyInterface : public RegisteredType<MyInterface> {…};.

Noise Modeling

using cudaq::complex = std::complex<double>
struct kraus_op

A kraus_op represents a single Kraus operation, described as a complex matrix of specific size. The matrix is represented here as a 1d array (specifically a std::vector).

Public Functions

kraus_op(const kraus_op&) = default

Copy constructor.

inline kraus_op(std::vector<complex> d)

Constructor, initialize from vector data.

template<typename T>
inline kraus_op(std::initializer_list<T> &&initList)

Constructor, initialize from initializer_list.

kraus_op &operator=(const kraus_op &other)

Set this kraus_op equal to the other.

kraus_op adjoint()

Return the adjoint of this kraus_op.

Public Members

std::vector<std::complex<double>> data

Matrix data, represented as a 1d flattened.

std::size_t nRows = 0

The number of rows in the matrix.

std::size_t nCols = 0

The number of columns in the matrix NOTE we currently assume nRows == nCols.

class kraus_channel

A kraus_channel represents a quantum noise channel on specific qubits. The action of the noise channel is described by a vector of kraus operations - matrices with size equal to 2**nQubits x 2**nQubits, where the number of qubits is the number of provided qubit indices at construction.

Subclassed by cudaq::amplitude_damping_channel, cudaq::bit_flip_channel, cudaq::depolarization_channel, cudaq::phase_flip_channel

Public Functions

kraus_channel() = default

The nullary constructor.

kraus_channel(const kraus_channel &other)

The copy constructor.

Parameters:

other

template<typename ...T>
inline kraus_channel(std::initializer_list<T>&&... inputLists)

The constructor, initializes kraus_ops internally from the provided initializer_lists.

kraus_channel(std::vector<kraus_op> &ops)

The constructor, take qubits and channel kraus_ops as lvalue reference.

inline kraus_channel(std::vector<kraus_op> &&ops)

The constructor, take qubits and channel kraus_ops as rvalue reference.

std::size_t size() const

Return the number of kraus_ops that make up this channel.

bool empty() const

Return true if there are no ops in this channel.

kraus_op &operator[](const std::size_t idx)

Return the kraus_op at the given index.

kraus_channel &operator=(const kraus_channel &other)

Set this kraus_channel equal to the given one.

std::vector<kraus_op> get_ops()

Return all kraus_ops in this channel.

void push_back(kraus_op op)

Add a kraus_op to this channel.

class amplitude_damping_channel : public cudaq::kraus_channel

amplitude_damping_channel is a kraus_channel that automates the creation of the kraus_ops that make up a single-qubit amplitude damping error channel.

class bit_flip_channel : public cudaq::kraus_channel

bit_flip_channel is a kraus_channel that automates the creation of the kraus_ops that make up a single-qubit bit flipping error channel.

class phase_flip_channel : public cudaq::kraus_channel

phase_flip_channel is a kraus_channel that automates the creation of the kraus_ops that make up a single-qubit phase flip error channel.

class depolarization_channel : public cudaq::kraus_channel

depolarization_channel is a kraus_channel that automates the creation of the kraus_ops that make up a single-qubit depolarization error channel.

class noise_model

The noise_model type keeps track of a set of kraus_channels to be applied after the execution of quantum operations. Each quantum operation maps to a kraus channel containing a number of kraus_ops to be applied to the density matrix representation of the state.

Public Functions

noise_model() = default

default constructor

inline bool empty() const

Return true if there are no kraus_channels in this noise model.

Returns:

void add_channel(const std::string &quantumOp, const std::vector<std::size_t> &qubits, const kraus_channel &channel)

Add the Kraus channel to the specified one-qubit quantum operation. It applies to the quantumOp operation for the specified qubits in the kraus_channel.

template<typename ...QuantumOp>
inline void add_channel(const std::vector<std::size_t> &qubits, const kraus_channel &channel)

Add the provided kraus_channel to all specified quantum operations.

std::vector<kraus_channel> get_channels(const std::string &quantumOp, const std::vector<std::size_t> &qubits)

Return relevant kraus_channels on the specified qubits for.

template<typename QuantumOp>
inline std::vector<kraus_channel> get_channels(const std::vector<std::size_t> &qubits)

Get all kraus_channels on the given qubits.

Kernel Builder

template<typename ...Args>
class kernel_builder : public cudaq::details::kernel_builder_base

The kernel_builder.

Public Functions

inline kernel_builder(std::vector<details::KernelBuilderType> &types)

The constructor, takes the input KernelBuilderTypes which is used to create the MLIR Function Type.

inline auto &getArguments()

Return the QuakeValue arguments.

Returns:

inline bool isArgStdVec(std::size_t idx)

Return true if the argument to the kernel is a std::vector, false otherwise.

inline std::string name()

Return the name of this kernel.

inline std::size_t getNumParams()

Return the number of function arguments.

Returns:

inline QuakeValue qalloc(const std::size_t nQubits = 1)

Return a QuakeValue representing the allocated QVec.

inline QuakeValue qalloc(QuakeValue size)

Return a QuakeValue representing the allocated QVec, size is from a pre-allocated size QuakeValue or BlockArgument.

inline void c_if(QuakeValue result, std::function<void()> &&thenFunctor)

Apply a conditional statement on a measure result, if true apply the thenFunctor.

template<typename OtherKernelBuilder>
inline void call(OtherKernelBuilder &kernel, std::vector<QuakeValue> &values)

Apply the given otherKernel with the provided QuakeValue arguments.

template<typename OtherKernelBuilder, typename ...QuakeValues>
inline void call(OtherKernelBuilder &&kernel, QuakeValues&... values)

Apply the given otherKernel with the provided QuakeValue arguments.

template<typename OtherKernelBuilder>
inline void control(OtherKernelBuilder &kernel, QuakeValue &control, std::vector<QuakeValue> &args)

Apply the given kernel controlled on the provided qubit value. This overload takes a vector of QuakeValues and is primarily meant to be used internally.

template<typename OtherKernelBuilder, typename ...QuakeValues>
inline void control(OtherKernelBuilder &kernel, QuakeValue &ctrl, QuakeValues&... values)

Apply the given kernel controlled on the provided qubit value.

template<typename OtherKernelBuilder>
inline void adjoint(OtherKernelBuilder &kernel, std::vector<QuakeValue> &args)

Apply the adjoint of the given kernel. This overload takes a vector of QuakeValues and is primarily meant to be used internally.

template<typename OtherKernelBuilder, typename ...QuakeValues>
inline void adjoint(OtherKernelBuilder &kernel, QuakeValues&... values)

Apply the adjoint of the given kernel.

inline virtual std::string to_quake() const override

Return the string representation of the quake code.

inline virtual void jitCode(std::vector<std::string> extraLibPaths = {}) override

Lower the Quake code to the LLVM Dialect, call PassManager.

inline void jitAndInvoke(void **argsArray, std::vector<std::string> extraLibPaths = {})

Invoke jitCode and extract a function pointer and execute.

inline void operator()(Args... args)

The call operator for the kernel_builder, takes as input the constructed function arguments.

inline void operator()(void **argsArray)

Call operator that takes an array of opaque pointers for the function arguments.

template<std::size_t N>
inline decltype(auto) get()

Expose the get<N>() method necessary for enabling structured bindings on a custom type

class QuakeValue

A QuakeValue is meant to provide a thin wrapper around an mlir::Value instance. These QuakeValues represent handles to function arguments and return values from MLIR Operations, specifically Quake Dialect operations. The QuakeValue also exposes and algebraic API enabling one to negate, add, subtract, and multiply QuakeValues with each other as well as with primitive arithmetic types, e.g. double.

Public Functions

mlir::Value getValue()

Return the actual MLIR Value.

QuakeValue(mlir::ImplicitLocOpBuilder &builder, mlir::Value v)

The constructor, takes the builder and the value to wrap.

QuakeValue(mlir::ImplicitLocOpBuilder &builder, double v)

The constructor, takes the builder and a constant double value, which will map to an arith::ConstantFloatOp Value.

QuakeValue slice(const std::size_t startIdx, const std::size_t count)

For a subscriptable QuakeValue, extract a sub set of the elements starting at the given startIdx and including the following count elements.

bool isStdVec()

Return true if this QuakeValue is of type StdVec.

Returns:

std::size_t getRequiredElements()

For a QuakeValue of type StdVec, return the number of required elements, i.e. the number of unique extractions observed.

QuakeValue operator[](const std::size_t idx)

Return a new QuakeValue when the current value is indexed, specifically for QuakeValues of type StdVecType and QVecType.

QuakeValue operator-()

Negate this QuakeValue.

QuakeValue operator*(const double)

Multiply this QuakeValue by the given double.

QuakeValue operator*(QuakeValue other)

Multiply this QuakeValue by the given QuakeValue.

QuakeValue operator+(const double)

Add this QuakeValue with the given double.

QuakeValue operator+(QuakeValue other)

Add this QuakeValue with the given QuakeValue.

QuakeValue operator-(const double)

Subtract the given double from this QuakeValue.

QuakeValue operator-(QuakeValue other)

Subtract the given QuakeValue from this QuakeValue.

class kernel_builder_base

The kernel_builder_base provides a base type for the templated kernel builder so that we can get a single handle on an instance within the runtime.

Subclassed by cudaq::kernel_builder< Args >

class KernelBuilderType

The kernel_builder::Type allows us to track input C++ types representing the quake function argument types in a way that does not expose MLIR Type to the CUDA Quantum code. This type keeps track of a functor that generates the MLIR Type in implementation code when create() is invoked.

Public Functions

KernelBuilderType(std::function<mlir::Type(mlir::MLIRContext *ctx)> &&f)

The constructor, take the Type generation functor.

mlir::Type create(mlir::MLIRContext *ctx)

Create the MLIR Type.

Algorithms

class optimizer

The cudaq::optimizer provides a high-level interface for general optimization of user-specified objective functions. This is meant to serve an interface for clients working with concrete subtypes providing specific optimization algorithms possibly delegating to third party libraries. This interface provides an optimize(…) method that takes the number of objective function input parameters (the dimension), and a user-specified objective function that takes the function input parameters as a immutable (const) vector<double> reference and a mutable vector<double> reference modeling the current iteration gradient vector (df / dx_i, for all i parameters). This function must return a scalar double, the value of this function at the current input parameters. The optimizer also exposes a method for querying whether the current optimization strategy requires gradients or not. Parameterizing optimization strategies is left as a task for sub-types (things like initial parameters, max function evaluations, etc.).

cudaq::optimizers::cobyla opt;
assert(!opt.requiresGradients() && "Cobyla algo does not use gradients.");
auto [opt_val, opt_params] = opt.optimize(2,
              [&](const std::vector<double>& x, std::vector<double>& dx) {
                  ... use x, modify dx, return scalar double ...
              }
            );

Public Functions

virtual bool requiresGradients() = 0

Returns true if this optimization strategy requires gradients to achieve its optimization goals.

virtual optimization_result optimize(const int dim, optimizable_function &&opt_function) = 0

Run the optimization strategy defined by concrete sub-type implementations. Takes the number of variational parameters, and a custom objective function that takes the function input parameters as a immutable (const) vector<double> reference and a mutable vector<double> reference modeling the current iteration gradient vector (df / dx_i, for all i parameters). This function must return a scalar double, the value of this function at the current input parameters.

class optimizable_function

An optimizable_function wraps a user-provided objective function to be optimized.

using cudaq::optimization_result = std::tuple<double, std::vector<double>>

Typedef modeling the result of an optimization strategy, a double representing the optimal value and the corresponding optimal parameters.

class state

The cudaq::state encapsulate backend simulation state vector or density matrix data.

Public Functions

inline state(State d)

The constructor, takes the simulation data.

std::complex<double> operator[](std::size_t idx)

Return the data element at the given indices.

void dump()

Dump the state to standard out.

double overlap(state &other)

Compute the overlap of this state with the other one.

class gradient

The cudaq::gradient represents a base type for all gradient strategies leveraged by variational algorithms.

The cudaq::gradient tracks a std::function with signature void(std::vector<double>) representing the parameterized kernel ansatz. For ansatzae that do not follow this signature, a separate Argument Mapper must be provided which takes std::vector<double> to a tuple of custom function arguments. All gradient subtypes should inherit the base class constructors (using gradient::gradient), but provide a concrete implementation of gradient::compute(). The compute method takes as input the current iteration parameters, a reference to the gradient vector which compute() must update, the cudaq::spin_op for this variational algorithm, and the expected value of the spin_op at the current iteration’s parameters. Subtypes can leverage the protected gradient::getExpectedValue() method to compute <psi(x) | H | psi(x)> at the provided set of variational parameters.

Subclassed by cudaq::gradients::central_difference, cudaq::gradients::parameter_shift

Public Functions

inline gradient(std::function<void(std::vector<double>)> &&kernel)

Constructor, takes the quantum kernel with prescribed signature.

gradient() = default

Empty constructor.

template<typename KernelT, typename ArgsMapper>
inline gradient(KernelT &kernel, ArgsMapper &&argsMapper)

Constructor, takes a callable with non-standard signature the Argument Mapper function object that maps the parameters to concrete arguments for the quantum kernel.

template<typename KernelT>
inline gradient(KernelT &kernel)

Constructor, takes a callable that must have the prescribed call signature (void(std::vector<double>))

template<typename QuantumKernel, typename ArgsMapper>
inline gradient(QuantumKernel &&kernel, ArgsMapper &&argsMapper)

Constructor, takes the quantum kernel with non-standard signature the Argument Mapper function object that maps the parameters to concrete arguments for the quantum kernel.

virtual void compute(const std::vector<double> &x, std::vector<double> &dx, spin_op &h, double exp_h) = 0

Compute the current iterations gradient vector and update the provided vector<double reference (dx).

virtual std::vector<double> compute(const std::vector<double> &x, std::function<double(std::vector<double>)> &func) = 0

Compute the gradient vector for the provided objective function, func, at the given set of parameters, x.

class central_difference : public cudaq::gradient

Public Functions

inline virtual void compute(const std::vector<double> &x, std::vector<double> &dx, spin_op &h, double exp_h) override

Compute the current iterations gradient vector and update the provided vector<double reference (dx).

inline virtual std::vector<double> compute(const std::vector<double> &x, std::function<double(std::vector<double>)> &func) override

Compute the central_difference gradient for the arbitary function, func, passed in by the user.

inline gradient(std::function<void(std::vector<double>)> &&kernel)

Constructor, takes the quantum kernel with prescribed signature.

gradient() = default

Empty constructor.

template<typename KernelT, typename ArgsMapper>
inline gradient(KernelT &kernel, ArgsMapper &&argsMapper)

Constructor, takes a callable with non-standard signature the Argument Mapper function object that maps the parameters to concrete arguments for the quantum kernel.

template<typename KernelT>
inline gradient(KernelT &kernel)

Constructor, takes a callable that must have the prescribed call signature (void(std::vector<double>))

template<typename QuantumKernel, typename ArgsMapper>
inline gradient(QuantumKernel &&kernel, ArgsMapper &&argsMapper)

Constructor, takes the quantum kernel with non-standard signature the Argument Mapper function object that maps the parameters to concrete arguments for the quantum kernel.

class parameter_shift : public cudaq::gradient

Public Functions

inline virtual void compute(const std::vector<double> &x, std::vector<double> &dx, spin_op &h, double exp_h) override

Compute the current iterations gradient vector and update the provided vector<double reference (dx).

inline virtual std::vector<double> compute(const std::vector<double> &x, std::function<double(std::vector<double>)> &func) override

Compute the parameter_shift gradient for the arbitrary function, func, passed in by the user.

inline gradient(std::function<void(std::vector<double>)> &&kernel)

Constructor, takes the quantum kernel with prescribed signature.

gradient() = default

Empty constructor.

template<typename KernelT, typename ArgsMapper>
inline gradient(KernelT &kernel, ArgsMapper &&argsMapper)

Constructor, takes a callable with non-standard signature the Argument Mapper function object that maps the parameters to concrete arguments for the quantum kernel.

template<typename KernelT>
inline gradient(KernelT &kernel)

Constructor, takes a callable that must have the prescribed call signature (void(std::vector<double>))

template<typename QuantumKernel, typename ArgsMapper>
inline gradient(QuantumKernel &&kernel, ArgsMapper &&argsMapper)

Constructor, takes the quantum kernel with non-standard signature the Argument Mapper function object that maps the parameters to concrete arguments for the quantum kernel.

Platform

class QPU : public cudaq::registry::RegisteredType<QPU>

A CUDA Quantum QPU is an abstraction on the quantum processing unit which executes quantum kernel expressions. The QPU exposes certain information about the QPU being targeting, such as the number of available qubits, the logical ID for this QPU in a set of available QPUs, and its qubit connectivity. The QPU keeps track of an execution queue for enqueuing asynchronous tasks that execute quantum kernel expressions. The QPU also tracks the client-provided execution context to enable quantum kernel related tasks such as sampling and observation.

This type is meant to be subtyped by concrete quantum_platform subtypes.

Public Functions

inline QPU()

The constructor, initializes the execution queue.

inline QPU(std::size_t _qpuId)

The constructor, sets the current QPU Id and initializes the execution queue

QPU(QPU&&) = default

Move constructor.

virtual ~QPU() = default

The destructor.

inline std::size_t getNumQubits()

Return the number of qubits.

inline auto getConnectivity()

Return the qubit connectivity.

inline virtual bool isSimulator()

Is this QPU a simulator ?

inline virtual bool supportsConditionalFeedback()

Return whether this qpu has conditional feedback support.

inline virtual void setShots(int _nShots)

Base class handling of shots is do-nothing, subclasses can handle as they wish

virtual void enqueue(QuantumTask &task) = 0

Enqueue a quantum task on the asynchronous execution queue.

virtual void setExecutionContext(ExecutionContext *context) = 0

Set the execution context, meant for subtype specification.

virtual void resetExecutionContext() = 0

Reset the execution context, meant for subtype specification.

virtual void launchKernel(const std::string &name, void (*kernelFunc)(void*), void *args, std::uint64_t, std::uint64_t) = 0

Launch the kernel with given name (to extract its Quake representation). The raw function pointer is also provided, as are the runtime arguments, as a struct-packed void pointer and its corresponding size.

class quantum_platform

The quantum_platform corresponds to a specific quantum architecture. The quantum_platform exposes a public API for programmers to query specific information about the targeted QPU(s) (e.g. number of qubits, qubit connectivity, etc.). This type is meant to be subclassed for concrete realizations of quantum platforms, which are intended to populate this platformQPUs member of this base class.

Public Functions

std::optional<QubitConnectivity> connectivity()

Fetch the connectivity info.

std::size_t get_num_qubits()

Get the number of qubits for the current QPU.

std::size_t get_num_qubits(std::size_t qpu_id)

Get the number of qubits for the QPU with ID qpu_id.

inline std::optional<int> get_shots()

Getter for the shots.

inline virtual void set_shots(int numShots)

Setter for the shots.

inline void clear_shots()

Reset shots.

void set_exec_ctx(cudaq::ExecutionContext *ctx, std::size_t qpu_id = 0)

Specify the execution context for this platform.

void reset_exec_ctx(std::size_t qpu_id = 0)

Reset the execution context for this platform.

inline std::size_t num_qpus() const

Get the number of QPUs available with this platform.

bool is_simulator(const std::size_t qpu_id = 0) const

Return whether this platform is simulating the architecture.

bool supports_conditional_feedback(const std::size_t qpu_id = 0) const

Return whether the qpu has conditional feedback support.

inline std::string name() const

The name of the platform, which also corresponds to the name of the platform file.

std::size_t get_current_qpu()

Get the ID of the current QPU.

void set_current_qpu(const std::size_t device_id)

Set the current QPU via its device ID.

std::future<sample_result> enqueueAsyncTask(const std::size_t qpu_id, KernelExecutionTask &t)

Enqueue an asynchronous sampling task.

void launchKernel(std::string kernelName, void (*kernelFunc)(void*), void *args, std::uint64_t voidStarSize, std::uint64_t resultOffset)

Enqueue an asynchronous observation task.

inline virtual void setTargetBackend(const std::string &name)

Set the target backend, by default do nothing, let subclasses override.

Parameters:

name

Public Static Functions

static std::vector<std::string> list_platforms()

List all available platforms, which correspond to .qplt files in the platform directory.

using cudaq::QuantumTask = std::function<void()>

The QuantumTask is ultimately what gets added to the execution queue. It is meant to wrap any Sampling or Observe task with an appropriate std::promise instance being provided and set.

using cudaq::QubitConnectivity = std::vector<QubitEdge>
using cudaq::QubitEdge = std::pair<std::size_t, std::size_t>

Typedefs for defining the connectivity structure of a QPU.

using cudaq::KernelExecutionTask = std::function<sample_result()>

A sampling tasks takes no input arguments and returns a sample_result instance.

Namespaces

namespace cudaq
namespace details
namespace registry