Measuring Kernels¶
import cudaq
#include <cudaq.h>
Kernel measurement can be specified in the Z, X, or Y basis using mz
, mx
, and my
. Measurement occurs in the Z basis by default.
@cudaq.kernel
def kernel():
qubits = cudaq.qvector(2)
mz(qubits)
__qpu__ void kernel0() {
cudaq::qvector qubits(2);
mz(qubits[0]);
}
Specific qubits or registers can be measured rather than the entire kernel.
@cudaq.kernel
def kernel():
qubits_a = cudaq.qvector(2)
qubit_b = cudaq.qubit()
mz(qubits_a)
mx(qubit_b)
__qpu__ void kernel1() {
cudaq::qvector qubits_a(2);
cudaq::qubit qubits_b;
mz(qubits_a);
mx(qubits_b);
}
Mid-circuit Measurement and Conditional Logic¶
In certain cases, it is helpful for some operations in a quantum kernel to depend on measurement results following previous operations. This is accomplished in the following example by performing a Hadamard on qubit 0, then measuring qubit 0 and saving the result as b0
. Then, qubit 0 can be reset and used later in the computation. In this case it is flipped to a 1. Finally, an if statement performs a Hadamard on qubit 1 if b0
is 1.
The results show qubit 0 is one, indicating the reset worked, and qubit 1 has a 75/25 distribution, demonstrating the mid-circuit measurement worked as expected.
@cudaq.kernel
def kernel():
q = cudaq.qvector(2)
h(q[0])
b0 = mz(q[0])
reset(q[0])
x(q[0])
if b0:
h(q[1])
print(cudaq.sample(kernel))
__qpu__ void kernel2() {
cudaq::qvector q(2);
h(q[0]);
auto b0 = mz(q[0]);
cudaq::reset(q[0]);
x(q[0]);
if (b0) {
h(q[1]);
}
}
int main() {
auto result = cudaq::sample(kernel2);
result.dump();
return 0;
}
Output
{
__global__ : { 10:728 11:272 }
b0 : { 0:505 1:495 }
}
{
__global__ : { 10:728 11:272 }
b0 : { 0:505 1:495 }
}