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() -> list[bool]:
    q = cudaq.qvector(2)

    h(q[0])
    b0 = mz(q[0])
    reset(q[0])
    x(q[0])

    if b0:
        h(q[1])

    return mz(q)


from collections import Counter

results = cudaq.run(kernel, shots_count=1000)
# Convert results to bitstrings and count
bitstring_counts = Counter(
    ''.join('1' if bit else '0' for bit in result) for result in results)

print(f"Bitstring counts: {dict(bitstring_counts)}")

__qpu__ auto 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]);
  }
  return mz(q);
}

int main() {
  auto results = cudaq::run(1000, kernel2);
  // Count occurrences of each bitstring
  std::map<std::string, std::size_t> bitstring_counts;
  for (const auto &result : results) {
    std::string bits = std::to_string(static_cast<int>(result[0])) +
                       std::to_string(static_cast<int>(result[1]));
    bitstring_counts[bits]++;
  }

  printf("Bitstring counts:\n{\n");
  for (const auto &[bits, count] : bitstring_counts) {
    printf("  %s: %zu\n", bits.c_str(), count);
  }
  printf("}\n");

  return 0;
}

Output

Bitstring counts: {'11': 247, '10': 753}
Bitstring counts:
{
  10: 771
  11: 229
}