You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Now that we are moving simulation based targets to runtime-only library mode (no MLIR compilation), we need to revisit how we enable sampling of dynamic circuits (those circuits with mid-circuit measurement + conditional feedback). An example circuit for this is
structkernel {
voidoperator()() __qpu__ {
cudaq::qreg<3> q;
// Initial state preparationx(q[0]);
// Create Bell pairh(q[1]);
x<cudaq::ctrl>(q[1], q[2]);
x<cudaq::ctrl>(q[0], q[1]);
h(q[0]);
auto b0 = mz(q[0]);
auto b1 = mz(q[1]);
if (b1)
x(q[2]);
if (b0)
z(q[2]);
mz(q[2]);
}
};
For a standard kernel with no measurements or measurements appended at the end of the function, backend simulations can simulate the circuit a single time and sample the final state, thereby producing the histogram of bit strings and counts. In the presence of non-trivial control flow with conditional statements like above, we cannot do that, and instead must invoke the circuit numShots times, collecting measured bit strings each time. The question becomes, in a purely runtime model, how does one indicate or know that a CUDA Quantum kernel has conditional statements on measurement results, and thus switch to this second model of sampling (invoking the kernel numShots times)? In the MLIR compilation mode, this is straightforward because we have the MLIR representation of the kernel at runtime and can look and see if it has cc.if() operations on values coming from a quake.mz() operation.
Potential solutions
Tracing the kernel
The first solution here is to borrow from the tracer PR (#92) with the addition of a defined type for measurement results. Imagine a measure_result type with the following structure
One could implement the implicit bool conversion operator on a type like this to trip some sort of flag indicating that the current kernel execution has conditional statements on measurement results (if (b0) invokes measure_result::operator bool()). With this in place, cudaq::sample(...) could be updated to first trace the function (no execution), and pick up any flag that was tripped by an implicit operator bool conversion on a measurement result.
This approach is nice because it requires no change to the language specification or the structure of kernel expressions / cudaq::sample(). I have a prototype for this here.
Kernel function indicator
Another approach could rely on some sort of helper function + user input on when a kernel has a mid-circuit measurement + conditional statement. Something like
structkernel {
voidoperator()() __qpu__ {
cudaq::qreg<3> q;
// For simulation / library mode, programmers // have to indicate this is a dynamic circuit, // and provide the names of any classical registers // we'll createcudaq::is_dynamic_kernel("b0", "b1");
// Initial state preparationx(q[0]);
// Create Bell pairh(q[1]);
x<cudaq::ctrl>(q[1], q[2]);
x<cudaq::ctrl>(q[0], q[1]);
h(q[0]);
auto b0 = mz(q[0]);
auto b1 = mz(q[1]);
if (b1)
x(q[2]);
if (b0)
z(q[2]);
mz(q[2]);
}
};
... sampling invoked via
auto counts = cudaq::sample({nShots, /* is dynamic circuit */true}, kernel{});
This is not as preferable to me, in that we have a different sample signature for physical vs simulated backends. I'd like those to stay the same. Moreover, it makes kernels targeting physical vs simulated backends different, with the addition of some kind of indicator function.
The text was updated successfully, but these errors were encountered:
Background
Now that we are moving simulation based targets to runtime-only library mode (no MLIR compilation), we need to revisit how we enable sampling of dynamic circuits (those circuits with mid-circuit measurement + conditional feedback). An example circuit for this is
For a standard kernel with no measurements or measurements appended at the end of the function, backend simulations can simulate the circuit a single time and sample the final state, thereby producing the histogram of bit strings and counts. In the presence of non-trivial control flow with conditional statements like above, we cannot do that, and instead must invoke the circuit
numShots
times, collecting measured bit strings each time. The question becomes, in a purely runtime model, how does one indicate or know that a CUDA Quantum kernel has conditional statements on measurement results, and thus switch to this second model of sampling (invoking the kernelnumShots
times)? In the MLIR compilation mode, this is straightforward because we have the MLIR representation of the kernel at runtime and can look and see if it hascc.if()
operations on values coming from aquake.mz()
operation.Potential solutions
Tracing the kernel
The first solution here is to borrow from the
tracer
PR (#92) with the addition of a defined type for measurement results. Imagine ameasure_result
type with the following structureOne could implement the implicit
bool
conversion operator on a type like this to trip some sort of flag indicating that the current kernel execution has conditional statements on measurement results (if (b0)
invokesmeasure_result::operator bool()
). With this in place,cudaq::sample(...)
could be updated to first trace the function (no execution), and pick up any flag that was tripped by an implicit operator bool conversion on a measurement result.This approach is nice because it requires no change to the language specification or the structure of kernel expressions /
cudaq::sample()
. I have a prototype for this here.Kernel function indicator
Another approach could rely on some sort of helper function + user input on when a kernel has a mid-circuit measurement + conditional statement. Something like
This is not as preferable to me, in that we have a different
sample
signature for physical vs simulated backends. I'd like those to stay the same. Moreover, it makes kernels targeting physical vs simulated backends different, with the addition of some kind of indicator function.The text was updated successfully, but these errors were encountered: