Comments (10)
Are switch statements supported on the backend? It is not listed in the feature table.
Maybe that's the problem? I'm moving this to qiskit-ibm-runtime
. Consider updating to 0.46/1.0 and extend on your example.
from qiskit.
Hi @1ucian0
I'm unsure if the runtime repo is the right place for this since, on the surface, the trouble looks like a part of qiskit
.
Maybe that's the problem?
I did try replacing the switch
statement with if
, but the issue persists.
Consider updating to 0.46/1.0 and extend on your example.
The issue is present in Qiskit 1.0
Also, the issue happens with both qiskit-ibm-provider
and qiskit-ibm-runtime
(which doesn't support transpiling dynamic circuits out of the box - Qiskit/qiskit-ibm-runtime#1253).
from qiskit.
Patrick, from the IBM Quantum Support Team, shared the following concise code snippets, which raise the same error:
qr = QuantumRegister(4, "q")
cr = ClassicalRegister(3, "cr")
qc = QuantumCircuit(qr, cr)
with qc.if_test((cr[1], 1)) as _else:
qc.x(0, label="X1111i").c_if(cr, 4)
with _else:
qr1 = QuantumRegister(2, "qr1")
cr1 = ClassicalRegister(2, "cr1")
inst = QuantumCircuit(2, 2, name='t').to_instruction()
qc.append(inst, [qr[0], qr[1]], [cr[0], cr[1]])
# qc.draw('mpl')
qc.draw(style={"showindex": True})
from qiskit.circuit import QuantumCircuit, Qubit, Clbit
q_bits = [Qubit(), Qubit(), Qubit()]
c_bits = ClassicalRegister(2,'cr')
qc = QuantumCircuit(q_bits, c_bits)
with qc.if_test((c_bits[1], 0)) as else_:
qc.x(0, label="pat").c_if(c_bits, 4)
with else_:
inst = QuantumCircuit(1, 1, name='t').to_instruction()
qc.append(inst, [0],[1])
from qiskit.
I had to readjust the snippets, but they both worked when I ran them on qiskit 1.0.1
and qiskit 0.46.0
:
from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister
q_bits = QuantumRegister(2, 'qr')
c_bits = ClassicalRegister(2,'cr')
qc = QuantumCircuit(q_bits, c_bits)
with qc.if_test((c_bits[1], 0)) as else_:
qc.x(0, label="pat").c_if(c_bits, 4)
with else_:
inst = QuantumCircuit(1, 1, name='t').to_instruction()
qc.append(inst, [0],[1])
from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister
qr = QuantumRegister(4, "q")
cr = ClassicalRegister(3, "cr")
qc = QuantumCircuit(qr, cr)
with qc.if_test((cr[1], 1)) as _else:
qc.x(0, label="X1111i").c_if(cr, 4)
with _else:
qr1 = QuantumRegister(2, "qr1")
cr1 = ClassicalRegister(2, "cr1")
inst = QuantumCircuit(2, 2, name='t').to_instruction()
qc.append(inst, [qr[0], qr[1]], [cr[0], cr[1]])
qc.draw(style={"showindex": True}) # or qc.draw('mpl')
from qiskit.
but they both worked when I ran them on
qiskit 1.0.1
andqiskit 0.46.0
Could you clarify if by "running" you mean the circuit builds or that it runs on the hardware? The former always worked, and the latter is where the issue pops up.
from qiskit.
@prakharb10: apologies for the slow reply from us. It's no excuse, this issue just happened to come in right in the middle of the Qiskit 1.0 final release push, and I think it got missed.
I can reproduce your issue when running on our hardware with this most minimal reproducer:
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
qr = QuantumRegister(27, "q")
cr = ClassicalRegister(3, "cr")
qc = QuantumCircuit(qr, cr)
with qc.if_test((cr[1], 1)):
with qc.if_test((cr, 4)):
qc.x(0)
That said, I got that reproducer from one of our internal support team, not from your QPY file, and then minimised it myself, so it might not be exactly the same problem you're seeing.
With my minimal reproducer, the problem seems to enter the circuit in our internal code that prepares the circuits to run. That said, I think the actual root cause might be the "nested" issue I was foreseeing in this comment on Qiskit #10108 (comment) rearing its head (but I'm not certain).
In your QPY file, it looks like you're using a lot of nested classical instructions that act on classical data, with a lot of nested conditionals that act on registers, so the second part of that definitely appears to be an effect of what I mentioned in #10108 (comment), which is triggered by our internal code.
We're looking into how we reach that error state internally, but for right now, the status is that nested control-flow with register conditions will fail with this error.
It will look very ugly, but as a very temporary workaround, if you can write your conditions in terms of bitwise expressions, you might be able to get something working successfully. Looking at your QPY file, that might be quite tricky (and certainly I don't love that I need to make this suggestion), but here I've written a function that converts conditions on registers to bitwise conditions. If you replace all (register, value)
tuples in your if_test
calls with condition_to_expr(register, value)
, I think you should get something working:
from qiskit.circuit.classical import expr
def condition_to_expr(reg, value):
def bit_compare(bit, value):
return expr.lift(bit) if value else expr.logic_not(bit)
new_condition = bit_compare(reg[0], value & 1)
value >>= 1
for bit in reg[1:]:
new_condition = expr.logic_and(new_condition, bit_compare(bit, value & 1))
value >>= 1
return new_condition
So as an example, I modified my example above to this:
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
qr = QuantumRegister(27, "q")
cr = ClassicalRegister(3, "cr")
qc = QuantumCircuit(qr, cr)
with qc.if_test(condition_to_expr(cr, 1)):
with qc.if_test(condition_to_expr(cr, 4)):
qc.x(0)
and that executed successfully on hardware.
from qiskit.
Luciano: can you transfer this back to Qiskit for now, because at a minimum I think there's issues we need to solve on our side, and there's a separate tracking issue on the internal code base as well. (I don't have write on this repo, so can't transfer it back.)
(edit: I also just noticed that you're using the base of the same reproducer I was haha.)
from qiskit.
Thank you for highlighting the root cause, @jakelishman. The fact that you could foresee this brings a degree of comfort, in some sense.
The workaround will undoubtedly help when running shallow circuits with nested control-flow instructions. For now, I will hold off on using it for the initial dense circuit. I'm already doing a "bit shift" for the current circuit in parts where I only want to condition on a subset of the classical register, e.g., bits 2-4. I ran into another error when using conditionals on multiple classical registers (details in the footer of the original comment).
I don't know if you already have an agreed design for tackling this, but please let me know if I can help with the implementation or any other way.
from qiskit.
Oh, I missed those comments at the bottom, sorry. In general, you can't wrap up conditions on registers into an Instruction
(which is what happens if you try to QuantumCircuit.append
with a QuantumCircuit
argument); the Instruction
data model is not designed to close over classical registers at all, so any places where it works are unexpected (and I'd take care with).
switch
is supported on all IBM backends that support if
. The IBM hardware requires (or at least used to require) a default
branch in the switch
statement, whether or not it was reachable, in case you're running into problems.
from qiskit.
(which is what happens if you try to
QuantumCircuit.append
with aQuantumCircuit
argument)
I ran into dissonating behavior between QuantumCircuit.append
and QuantumCircuit.compose
. Is there a particular scenario when either should be used? I ended up using QuantumCircuit.compose
(with inplace=True
) throughout.
In general, you can't wrap up conditions on registers into an
Instruction
Is that what happens when you try to run such a circuit (one with conditionals on multiple classical registers) on the simulator - the circuit is converted to an instruction?
My methodology was to build parts of the circuit piecewise and then compose
them together. I'm wondering if I need to switch to building a single circuit at the start and imperatively add operations to it.
The IBM hardware requires (or at least used to require) a
default
branch in theswitch
statement, whether or not it was reachable, in case you're running into problems.
The issue with the nested control-flow instructions is the only message I saw. My initial concern was to check if errors with switch
statements might be bubbling up as the context
error message. I do not think that is the case after your explanation.
from qiskit.
Related Issues (20)
- preset_passmanager transpilation bug if used >2 times with optimisation level 3: transpiled circuit is different and refers to unknown registers
- add `graphviz` to the visualization tool dependency HOT 3
- OpenQASM3 parser incorrectly identifies bit literals as uint literals HOT 6
- qiskit.provider.back_compat.convert_to_target doesn't add control flow instructions to the target HOT 5
- Add QPY support for timing information
- Add "layout" to the `SparsePauliOp` (and related operators)
- Support "direct" `Instruction -> SparsePauliOp` conversion HOT 5
- Collapse measurements when drawing HOT 2
- generate_preset_pass_manager as a user-facing function HOT 3
- When i use quantum lab by default it import some libraries from qiskit import QuantumCircuit, transpile from qiskit.tools.jupyter import * from qiskit.visualization import * from ibm_quantum_widgets import *.When i run this getting error Traceback (most recent call last): Cell In[1], line 3 from qiskit.tools.jupyter import * ModuleNotFoundError: No module named 'qiskit.tools'.help me to solve it HOT 1
- plugin support for circuit drawer
- dynamic circuit fail to transpile without a backend HOT 3
- preset passmanagers should perform gate optimization before routing HOT 3
- Faster `CouplingMap` initialization when `couplinglist` is a numpy array. HOT 4
- Runtime recursion depth reached in classical expresssion while implementing stress test HOT 3
- Primitive estimator with shots number fails with complex valued averages HOT 2
- Allow QuantumCircuit to contain non-CPTP channels HOT 2
- KeyError: Clbit(ClassicalRegister(2, 'cr'), 1) during transpile of a conditional circuit HOT 2
- OpenQASM3 dumper does not work with repeated conditionals HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from qiskit.