5. Quantum Intrinsic Operations¶
In an effort to support low-level quantum programming and build foundational
quantum kernels for large-scale applications, CUDA Quantum defines the quantum
intrinsic operation as an abstraction
for device-specific single-qudit unitary operations. A quantum intrinsic
operation is modeled via a standard C++ function with a unique instruction name and
general function operands. These operands can model classical rotation
parameters or units of quantum information (e.g. the cudaq::qudit
).
The syntax for these operations is
void INST_NAME( PARAM...?, qudit<N>&...);
where INST_NAME
is the name of the instruction, qudit<N>&...
indicates one many
cudaq::qudit
instances, and PARAM...?
indicates optional parameters of
floating point type (e.g. double
, float
). All intrinsic operations should
start with a base declaration targeting a single cudaq::qudit
, and overloads
should be provided that take more than one cudaq::qudit
instances to model the application
of that instruction on all provided cudaq::qudits
, e.g. void x(cudaq::qubit&)
and
x(cudaq::qubit&, cudaq::qubit&, cudaq::qubit&)
, modeling the NOT operation on a single
cudaq::qubit
or on multiple cudaq::qubit
.
Implementations should provide overloads to support broadcasting of single-qubit
intrinsic operations across a register of cudaq::qudit
. For example,
x(cudaq::qvector<>&)
should apply a NOT operation on all
cudaq::qubit
in the provided cudaq::qvector
. A set of quantum
intrinsic operations for the cudaq::qubit
then for example looks as
follows, where NAME
, ROTATION_NAME
, and MEASURE_OP
stand
for the names of single-qubit operations, single-qubit rotations, and
measurement operations respectively:
namespace cudaq {
struct base;
struct ctrl;
struct adj;
// Single qubit operations, ctrl / adj variants, and broadcasting
template<typename mod = base, typename... QubitArgs>
void NAME(QubitArgs&... args) noexcept { ... }
template<typename mod = base>
void NAME(const qvector& qr) noexcept { ... }
template<typename mod = ctrl>
void NAME(qvector& ctrls, qubit& target) noexcept { ... }
// Single qubit rotation operations and ctrl / adj variants
template <typename mod = base, typename ScalarAngle, typename... QubitArgs>
void ROTATION_NAME(ScalarAngle angle, QubitArgs &...args) noexcept { ... }
bool MEASURE_OP(qubit &q) noexcept;
std::vector<bool> MEASURE_OP(qvector &q) noexcept;
double measure(cudaq::spin_op & term) noexcept { ... }
}
The set of gates that the official CUDA Quantum implementation supports can be found in the API documentation.