Required prerequisites
Describe the feature
This is my team's single most important request. I'm available to discuss and help with this!
After running a kernel, we'd like to be able to get the result (the return value from the kernel) and also carry the resulting state forward for the next kernel.
Currently:
- If we call
cudaq.run(kernel, state, args) on our kernel, we get the return value from the kernel, but not the resulting state.
- If we call
cudaq.get_state(kernel, state, args) on our kernel, we get the resulting state, but not the return value.
- We'd really like both.
What we'd like, specifically:
- Call a kernel, and get the return values.
- Call another kernel, using the resulting state from the previous kernel, and get the return values.
- ...repeat thousands of times
Note that we don't actually need to get the state after each kernel call; if there's a way to just let it persist for the next kernel (like it would in the physical FTQC machine), that's great.
Why this is needed:
- In FTQC, mid-circuit measurements are essential. For example (see diagram), we compute a QROM (hundreds of gates), and then to uncompute it we measure the ancilla qubits and do some phase fixup which depends on the measurement results. This may happen thousands of times in a single program.
Our current workaround:
We have a solution, but it's not great.
- We call
state = cudaq.get_state(initial_state_kernel, num_qubits) to create the state
- Then we call
state = cudaq.get_state(ops_kernel, state, ops_list) with a list of QPU ops (X gates and such) to evolve the state.
- Repeat step 2 as needed with more ops.
- When the ops list includes measurements, then RIGHT after them we call
results = cudaq.run(fetch_result_kernel, state, ops_list, shots_count=1) which re-measures the same qubits (this is wasteful but doesn't change the state), return the results.
- Goto step 2
- Step 2 is potentially wasteful, if the state vector is copied from CPU to GPU, because we're not actually going to need to inspect it.
- Step 4 is definitely wasteful, because we wouldn't need to stop and do another kernel call to re-measure, if only we could get the return values (which contain the measurement results) the first time the instructions are run.
The good part
From the user's point of view, our workaround makes mid-circuit measurements easy, allowing users to branch their code and issue more gates on the same live state, based on measurement results. It's just messy under the hood at the moment.
Required prerequisites
Describe the feature
This is my team's single most important request. I'm available to discuss and help with this!
After running a kernel, we'd like to be able to get the result (the return value from the kernel) and also carry the resulting state forward for the next kernel.
Currently:
cudaq.run(kernel, state, args)on our kernel, we get the return value from the kernel, but not the resulting state.cudaq.get_state(kernel, state, args)on our kernel, we get the resulting state, but not the return value.What we'd like, specifically:
Note that we don't actually need to get the state after each kernel call; if there's a way to just let it persist for the next kernel (like it would in the physical FTQC machine), that's great.
Why this is needed:
Our current workaround:
We have a solution, but it's not great.
state = cudaq.get_state(initial_state_kernel, num_qubits)to create the statestate = cudaq.get_state(ops_kernel, state, ops_list)with a list of QPU ops (X gates and such) to evolve the state.results = cudaq.run(fetch_result_kernel, state, ops_list, shots_count=1)which re-measures the same qubits (this is wasteful but doesn't change the state), return the results.The good part
From the user's point of view, our workaround makes mid-circuit measurements easy, allowing users to branch their code and issue more gates on the same live state, based on measurement results. It's just messy under the hood at the moment.