forked from Qiskit/qiskit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path__init__.py
1384 lines (1034 loc) · 60.9 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
r"""
=============================================
Quantum circuit model (:mod:`qiskit.circuit`)
=============================================
.. currentmodule:: qiskit.circuit
The fundamental element of quantum computing is the *quantum circuit*. This is a computational
routine that can be run, one shot at a time, on a quantum processing unit (QPU). A circuit will act
on a predefined amount of quantum data (in Qiskit, we only directly support qubits) with unitary
operations (gates), measurements and resets. In addition, a quantum circuit can contain operations
on classical data, including real-time computations and control-flow constructs, which are executed
by the controllers of the QPU.
.. note::
You may wish to skip the introductory material and jump directly to:
* :ref:`the API overview of the whole circuit module <circuit-module-api>`
* :ref:`the detailed discussion about how circuits are represented <circuit-repr>`
* the core :class:`QuantumCircuit` class for how to build and query circuits
* :ref:`information on construction custom instructions <circuit-custom-gates>`
* :ref:`ways to work with circuit-level objects <circuit-working-with>`
* :ref:`discussion of Qiskit conventions for circuits, matrices and state labelling
<circuit-conventions>`
Circuits are at a low level of abstraction when building up quantum programs. They are the
construct that is used to build up to higher levels of abstraction, such as the :ref:`primitives of
quantum computation <qiskit-primitives>`, which accumulate data from many shots of quantum-circuit
execution, along with advanced error-mitigation techniques and measurement optimizations, into
well-typed classical data and error statistics.
In Qiskit, circuits can be defined in one of two regimes:
* an *abstract* circuit, which is defined in terms of *virtual qubits* and arbitrary high-level
operations, like encapsulated algorithms and user-defined gates.
* a *physical* circuit, which is defined in terms of the *hardware qubits* of one particular
backend, and contains only operations that this backend natively supports. You might also see
this concept referred to as an *ISA circuit*.
You convert from an abstract circuit to a physical circuit by using :ref:`Qiskit's transpilation
package <qiskit-transpiler>`, of which the top-level access point is :func:`.transpile`.
In Qiskit, a quantum circuit is represented by the :class:`QuantumCircuit` class. Below is an
example of a quantum circuit that makes a three-qubit Greenberger–Horne–Zeilinger (GHZ) state
defined as:
.. math::
|\psi\rangle = \left( |000\rangle + |111\rangle \right) / \sqrt{2}
.. plot::
:include-source:
from qiskit import QuantumCircuit
# Create a circuit with a register of three qubits
circ = QuantumCircuit(3)
# H gate on qubit 0, putting this qubit in a superposition of |0> + |1>.
circ.h(0)
# A CX (CNOT) gate on control qubit 0 and target qubit 1 generating a Bell state.
circ.cx(0, 1)
# CX (CNOT) gate on control qubit 0 and target qubit 2 resulting in a GHZ state.
circ.cx(0, 2)
# Draw the circuit
circ.draw('mpl')
.. _circuit-definitions:
Circuit concepts and definitions
================================
There is a lot of specialized terminology around quantum circuits. Much of this is common in
quantum-computing literature, while some is more specific to quantum software packages, and a small
amount specific to Qiskit. This is an alphabetical listing of some of the important concepts as a
quick reference, but does not go into detail of the foundational concepts. Consider using the `IBM
Quantum Learning platform <https://learning.quantum.ibm.com/>`_ if you want to start from the
beginning.
abstract circuit
A *circuit* defined in terms of abstract mathematical operations and *virtual qubits*. This is
typically how you think about quantum algorithms; an abstract circuit can be made up of
completely arbitrary unitary operations, measurements, and potentially *real-time classical
computation*, with no restrictions about which qubits can interact with each other.
You turn an abstract circuit into a *physical circuit* by using :ref:`Qiskit's transpilation
package <qiskit-transpiler>`.
ancilla qubit
An extra qubit that is used to help implement operations on other qubits, but whose final state
is not important for the program.
circuit
A computational routine the defines a single execution to be taken on a QPU. This can either be
an *abstract circuit* or a *physical circuit*.
clbit
A Qiskit-specific abbreviation meaning a single classical bit of data.
gate
A *unitary operation* on one or more qubits.
hardware qubit
The representation of a single qubit on a particular *QPU*. A hardware qubit has some physical
quantum-mechanical system backing it, such as superconducting circuits; unlike a *virtual
qubit*, it has particular coupling constraints and only certain gates can be applied to certain
groups of hardware qubits.
Qiskit does not distinguish *logical qubits* from any individual *physical qubits* when talking
about hardware qubits. A QPU may implement its hardware qubits as logical qubits, where each
hardware qubit comprises many physical qubits that are controlled and error-corrected opaquely
to Qiskit by the control electronics. More likely, for near-term applications, a QPU will be
directly exposing its physical qubits as the hardware qubits for Qiskit to reason about.
Both physical and logical qubits will have coupling constraints between them, only permit
certain quantum operations on them, and have scheduling concerns between them. Qiskit abstracts
these concerns together in the concept of hardware qubits. In the early days of quantum error
correction, particular backends may let you access their qubit resources either as high-level
logical qubits or as low-level physical qubits through Qiskit.
instruction set architecture (ISA)
The abstract model of which operations are available on which sets of *hardware qubits* on one
particular *QPU*. For example, one QPU may allow :math:`\sqrt X` and :math:`R_Z` operations on
all single hardware qubits, and :math:`CX` operations on certain pairs of hardware qubits.
logical qubit
A collection of several *physical qubits* that are controlled together by a QPU (from the user's
perspective) to apply real-time quantum error correction. A logical qubit is a type of
*hardware qubit* for Qiskit.
measurement
The act of extracting one classical bit of a data from a single qubit state. This is an
irreversible operation, and usually destroys entanglement and phase coherence between the target
qubit and the rest of the system.
physical circuit
A *circuit* defined in terms of *hardware qubits* and only the quantum operations available in a
particular *QPU's* *ISA*. Physical circuits are tied to one particular QPU architecture, and
will not run on other incompatible architectures. You may also hear this referred to as an *ISA
circuit*.
You typically get a physical circuit by using :ref:`Qiskit's transpilation routines
<qiskit-transpiler>` on an *abstract circuit* that you constructed.
physical qubit
A controllable two-level quantum system. This is literally one "physics" qubit, such as a
transmon or the electronic state of a trapped ion. A QPU may expose this directly as its
*hardware qubit*, or combine several physical qubits into a *logical qubit*.
quantum processing unit (QPU)
Analogous to a CPU in classical computing or a GPU in graphics processing, a QPU is the hardware
that runs quantum operations on quantum data. You can always expect a QPU that uses the
*circuit* model of computation to be able to perform some set of *gates*, and *measurement*
operations. Depending on the particular technology, they also may be able to run some real-time
classical computations as well, such as classical control flow and bitwise calculations on
classical data.
qubit
The basic unit of quantum information.
real-time classical computation
Any classical computation that can happen within the execution of a single shot of a *circuit*,
where the results of the classical computation can affect later execution of the circuit. The
amount of real-time classical computation available with particular *QPU*\ s will vary
significantly dependent on many factors, such as the controlling electronics and the qubit
technology in use. You should consult your hardware vendor's documentation for more information
on this.
unitary operation
A reversible operation on a quantum state. All quantum *gates* are unitary operations (by
definition).
virtual qubit
An abstract, mathematical *qubit* used to build an *abstract circuit*. Virtual qubits are how
one typically thinks about quantum algorithms at a high level; we assume that all quantum gates
are valid on all virtual qubits, and all virtual qubits are always connected to every other
virtual qubit.
When mapping to hardware, virtual qubits must be assigned to *hardware qubits*. This mapping
need not be one-to-one. Typically, one virtual qubit will need to be swapped from one hardware
qubit to another over the course of a circuit execution in order to satisfy coupling constraints
of the underlying QPU. It is not strictly necessary for all virtual qubits used in a circuit to
be mapped to a physical qubit at any given point in a *physical circuit*; it could be that a
virtual qubit is measured (collapsing its state) and then never used again, so a new virtual
qubit could take its place. Evaluating these conditions to map a virtual circuit to a physical
circuit is the job of :ref:`Qiskit's transpilation package <qiskit-transpiler>`.
.. _circuit-module-api:
API overview of :mod:`qiskit.circuit`
=====================================
All objects here are described in more detail, and in their greater context in the following
sections. This section provides an overview of the API elements documented here.
..
TODO: actually write the "in-depth section on building circuits and cross-ref to it.
The principal class is :class:`.QuantumCircuit`, which has its own documentation page, including
an in-depth section on building circuits. Quantum data and the simplest classical data are
represented by "bits" and "registers":
* :class:`Bit`, an atom of data
* :class:`Qubit`
* :class:`Clbit`
* :class:`AncillaQubit`
* :class:`Register`, a collection of bits
* :class:`QuantumRegister`
* :class:`ClassicalRegister`
* :class:`AncillaRegister`
Within a circuit, each complete :class:`CircuitInstruction` is made up of an :class:`Operation`
(which might be an :class:`Instruction`, a :class:`Gate`, or some other subclass) and the qubit
and clbit operands. The core base classes here are:
* :class:`CircuitInstruction`, an operation and its operands
* :class:`InstructionSet`, a temporary handle to a slice of circuit data
* :class:`Operation`, any abstract mathematical object or hardware instruction
* :class:`AnnotatedOperation`, a subclass with applied abstract modifiers
* :class:`InverseModifier`
* :class:`ControlModifier`
* :class:`PowerModifier`
The most common concrete subclass of the minimal, abstract :class:`Operation` interface is the
:class:`Instruction`. While :class:`Operation` can include abstract mathematical objects,
an :class:`Instruction` is something that could conceivably run directly on hardware. This is in
turn subclassed by :class:`Gate` and :class:`ControlledGate` that further add unitarity and
controlled semantics on top:
* :class:`Instruction`, representing a hardware-based instruction
* :class:`Gate`, representing a hardware instruction that is unitary
* :class:`ControlledGate`, representing a gate with control structure.
Qiskit includes a large library of standard gates and circuits, which is documented in
:mod:`qiskit.circuit.library`. Many of these are declared as Python-object singletons. The
machinery for this is described in detail in :mod:`qiskit.circuit.singleton`, of which the main
classes are each a singleton form of the standard instruction–gate hierarchy:
* :class:`~singleton.SingletonInstruction`
* :class:`~singleton.SingletonGate`
* :class:`~singleton.SingletonControlledGate`
Some instructions are particularly special in that they affect the control flow or data flow of the
circuit. The top-level ones are:
* :class:`Barrier`, to mark parts of the circuit that should be optimized independently
* :class:`Delay`, to insert a real-time wait period
* :class:`Measure`, to measure a :class:`Qubit` into a :class:`Clbit`
* :class:`Reset`, to irreversibly reset a qubit to the :math:`\lvert0\rangle` state
* :class:`Store`, to write a real-time classical expression to a storage location
* :class:`ControlFlowOp`, which has specific subclasses:
* :class:`BreakLoopOp`, to break out of the nearest containing loop
* :class:`ContinueLoopOp`, to move immediately to the next iteration of the containing loop
* :class:`ForLoopOp`, to loop over a fixed range of values
* :class:`IfElseOp`, to conditionally enter one of two subcircuits
* :class:`SwitchCaseOp`, to conditionally enter one of many subcicuits
* :class:`WhileLoopOp`, to repeat a subcircuit until a condition is falsified.
:ref:`Circuits can include classical expressions that are evaluated in real time
<circuit-repr-real-time-classical>`, while the QPU is executing a single shot of the circuit. These
are primarily documented in the module documentation of :mod:`qiskit.circuit.classical`. You might
be particularly interested in the base classes (which are not exposed from the :mod:`qiskit.circuit`
root):
* :class:`~classical.expr.Var`, a typed classical storage location in a circuit
* :class:`~classical.expr.Expr`, a real-time-evaluated expression
* :class:`~classical.types.Type`, the classical type of an expression.
In addition to this real-time expression evaluation, which is limited by classical hardware
representations of data, Qiskit has the concept of "compile-time" parametrization, which is done in
abstract symbolic algebra. These are typically used to represent gate angles in high-level
algorithms that might want to perform numerical derivatives, but they are an older part of Qiskit
than the real-time evaluation, so are still used in some places to do general parametrization. The
main related classes are:
* :class:`Parameter`, the atom of compile-time expressions
* :class:`ParameterExpression`, a symbolic calculation on parameters
* :class:`ParameterVector`, a convenience collection of many :class:`Parameter`\ s
The :mod:`qiskit.circuit` module also exposes some calculation classes that work with circuits to
assist compilation workflows. These include:
* :class:`EquivalenceLibrary`, a database of decomposition relations between gates and circuits
* :data:`SessionEquivalenceLibrary`, a mutable instance of :class:`EquivalenceLibrary` which is used
by default by the compiler's :class:`.BasisTranslator`.
There is also a utility for generating random circuits:
* :func:`random.random_circuit`
Finally, the circuit module has its own exception class, to indicate when things went wrong in
circuit-specific manners:
* :exc:`CircuitError`
.. _circuit-repr:
Representation of circuits in Qiskit
====================================
The main user-facing class for representing circuits is :class:`QuantumCircuit`. This can be either
an abstract circuit or a physical circuit. There is much more information about the
:class:`QuantumCircuit` class itself and the multitude of available methods on it in its class
documentation.
..
TODO: the intention is to replace this `autosummary` directive with a proper entry in the API
toctree once the `QuantumCircuit` class-level documentation has been completely rewritten into
more of this style. For now, this just ensures it gets *any* page generated.
.. autosummary::
:toctree: ../stubs/
QuantumCircuit
Internally, a :class:`QuantumCircuit` contains the qubits, classical bits, compile-time parameters,
real-time variables, and other tracking information about the data it acts on and how it is
parametrized. It then contains a sequence of :class:`CircuitInstruction`\ s, which contain
the particular operation (gate, measurement, etc) and its operands (the qubits and classical bits).
Bits and registers
------------------
Qubits and classical bits are represented by a shared base :class:`Bit` type, which is just intended
to be a "type tag"; the classes have no behavior other than being immutable objects:
.. autoclass:: Bit
.. autoclass:: Qubit
:show-inheritance:
:class-doc-from: class
.. autoclass:: Clbit
:show-inheritance:
:class-doc-from: class
Qubits and clbits are instantiated by users with no arguments, such as by ``Qubit()``. Bits compare
equal if they are the same Python object, or if they were both created by a register of the same
name and size, and they refer to the same index within that register. There is also a special type
tag for "ancilla" qubits, but this is little used in the current state
of Qiskit:
.. autoclass:: AncillaQubit
:show-inheritance:
:class-doc-from: class
A collection bits of the same type can be encapsulated in a register of the matching type. The base
functionality is in a base class that is not directly instantiated:
.. autoclass:: Register
:members:
Each of the defined bit subtypes has an associated register, which have the same constructor
signatures, methods and properties as the base class:
.. autoclass:: QuantumRegister
:show-inheritance:
:class-doc-from: class
.. autoclass:: ClassicalRegister
:show-inheritance:
:class-doc-from: class
.. autoclass:: AncillaRegister
:show-inheritance:
:class-doc-from: class
A common way to instantiate several bits at once is to create a register, such as by
``QuantumRegister("my_qreg", 5)``. This has the advantage that you can give that collection of bits
a name, which will appear during circuit visualizations (:meth:`QuantumCircuit.draw`) and exports to
interchange languages (see :mod:`.qasm2` and :mod:`.qasm3`). You can also pass a name and a list of
pre-constructed bits, but this creates an "aliasing register", which are very poorly supported on
hardware.
Circuits track registers, but registers themselves impart almost no behavioral differences on
circuits. The only exception is that :class:`ClassicalRegister`\ s can be implicitly cast to
unsigned integers for use in conditional comparisons of :ref:`control flow operations
<circuit-control-flow>`.
Classical registers and bits were the original way of representing classical data in Qiskit, and
remain the most supported currently. Longer term, the data model is moving towards a more complete
and strongly typed representation of a range of classical data (see
:ref:`circuit-repr-real-time-classical`), but you will still very commonly use classical bits in
current Qiskit.
Instruction contexts
--------------------
The scalar type of the :attr:`QuantumCircuit.data` sequence is the "instruction context" object,
:class:`CircuitInstruction`. This is essentially just a data class that contains a representation
of what is to be done (its :attr:`~CircuitInstruction.operation`), and the data it acts on (the
:attr:`~CircuitInstruction.qubits` and :attr:`~CircuitInstruction.clbits`).
.. autosummary::
:toctree: ../stubs/
CircuitInstruction
Programmatically, this class is actually implemented in Rust and is a constructed handle to internal
data within Rust space. Mutations to instances of this class will not be reflected in the circuit.
In general, you cannot mutate instruction contexts that are already in the circuit directly; the
:class:`QuantumCircuit` interface is designed for storing and building circuits, while the
:ref:`transpiler and its passes <qiskit-transpiler>`, and its intermediate :class:`.DAGCircuit`
representation, are where you should look for an interface to mutate circuits.
The :class:`QuantumCircuit` methods that add instructions to circuits (such as
:meth:`~QuantumCircuit.append`, and all the helper standard-gate methods) return an
:class:`InstructionSet`, which is a handle to several :class:`CircuitInstruction`\ s simultaneously.
.. autosummary::
:toctree: ../stubs/
InstructionSet
This :class:`InstructionSet` is now little used in Qiskit. It provides a very minimal set of
methods to perform post-append mutations on instructions (which *will* be propagated to the
circuit), but these are now discouraged and you should use the alternatives noted in those methods.
Operations, instructions and gates
----------------------------------
Within a :class:`CircuitInstruction`, the minimal interface that any operation must fulfill is
:class:`Operation`. This is a *very* high level view, and only usable for abstract circuits. The
main purpose of treating operations as :class:`Operation` is to allow arbitrary mathematical
objects (such as :class:`.quantum_info.Operator`) to be added to abstract circuits directly.
.. autosummary::
:toctree: ../stubs/
Operation
Most operations, including all operations on physical circuits, are instances of the more concretely
defined :class:`Instruction`. This represents any instruction that some QPU might be able to carry
out natively, such as :class:`Measure`. :class:`Instruction` need not be unitary (much as
:class:`Measure` isn't); an instruction is specifically unitary if it is a :class:`Gate`.
.. autosummary::
:toctree: ../stubs/
Instruction
:class:`Instruction`\ s can be near arbitrary, provided they only act on :class:`Qubit`\ s and
:class:`Clbit`\ s, and are parametrized by their :attr:`~Instruction.params`; they should not
attempt to "close over" outer circuit registers, or use hidden parameters inside themselves.
:class:`Instruction`\ s can be related to other circuits to provide a decompositions by using
their :attr:`Instruction.definition` attribute, which provides a local, one-off decomposition. This
can be in whatever basis set of operations is most convenient to you, as long as the definitions of
all contained gates have some topological order; that is, you cannot use a gate in a definition it
its own definition depends on the parent. If the :class:`Instruction` should be considered entirely
opaque to optimizers, its :attr:`~Instruction.definition` can be ``None``. See
:ref:`circuit-custom-gates` for more detail.
The :attr:`~Instruction.params` of an instruction can technically be arbitrary, but in general you
should attempt to stick to parametrizations in terms of real numbers, wherever possible. Qiskit
itself breaks this rule in many places, and you will find all sorts of unusual types in
:attr:`Instruction.params` fields, but these are an annoying source of bugs because they often imply
the need for type-aware special casing. If your instruction is parametrized in terms of angles, you
will be able to reliably use :ref:`compile-time parametrization in it
<circuit-compile-time-parameters>`, and it will integrate well with
:meth:`QuantumCircuit.assign_parameters`.
While :class:`Instruction` is not necessarily unitary, its subclass :class:`Gate` implies unitarity,
and adds :meth:`~Gate.to_matrix` and :meth:`~Gate.control` methods to all the methods inherited from
:class:`Instruction`.
.. autosummary::
:toctree: ../stubs/
Gate
:class:`Gate` inherits all the methods for :class:`Instruction` and all the same considerations
about its :attr:`~Instruction.params` and :attr:`~Instruction.definition` field, except of course
that :class:`Gate`\ s cannot act on any classical resources.
:class:`Gate` instances can (and should) have a base :attr:`~Instruction.definition`, but you can
also specify several different decompositions in different bases by using an
:class:`EquivalenceLibrary`.
Subclassing :class:`Gate`, Qiskit has a special :class:`ControlledGate` class as well. This class
is the base of many standard-library gates that are controlled (such as :class:`CXGate`), which is
where you are most likely to encounter it:
.. autosummary::
:toctree: ../stubs/
ControlledGate
Each of :class:`Instruction`, :class:`Gate` and :class:`ControlledGate` has a corresponding
singleton type, built using the machinery described in :mod:`qiskit.circuit.singleton`. The
module-level documentation contains full details, along with descriptions of
:class:`.SingletonInstruction`, :class:`.SingletonGate` and :class:`.SingletonControlledGate`. From
a user's perspective, little changes based on whether the base class is a singleton or not; the
intention always remains that you should call :meth:`~Instruction.to_mutable` first if you need to
get a safe-to-mutate owned copy of an instruction (you cannot assume that an arbitrary instruction
is mutable), and while direct :class:`type` inspection is discouraged, if you do need it, the
reliable way to find the "base" type of a potentially singleton instruction is to use
:attr:`~Instruction.base_class`.
:class:`ControlledGate` uses the same mechanisms as :ref:`subclassing gates <circuit-custom-gates>`
to define a fixed, lazy synthesis for itself. This is naturally not hardware-aware, and harder to
hook into the synthesis routines of the compiler, but works better as a concrete
:class:`Instruction` that could potentially be run natively on hardware. For cases where synthesis
and abstract optimization is more important, Qiskit offers a composable class called
:class:`AnnotatedOperation`, which tracks "gate modifiers" (of which :class:`ControlModifier` is
one) to apply to the inner :attr:`~AnnotatedOperation.base_op`.
.. autosummary::
:toctree: ../stubs/
AnnotatedOperation
The available modifiers for :class:`AnnotatedOperation` are:
.. autoclass:: InverseModifier
.. autoclass:: ControlModifier
.. autoclass:: PowerModifier
For information on how to create custom gates and instructions, including how to build one-off
objects, and re-usable parametric gates via subclassing, see :ref:`circuit-custom-gates` below.
The Qiskit circuit library in :mod:`qiskit.circuit.library` contains many predefined gates and
circuits for you to use.
Built-in special instructions
-----------------------------
Qiskit contains a few :class:`Instruction` classes that are in some ways "special". These typically
have special handling in circuit code, in the transpiler, or the models of hardware. These are all
generally instructions you might already be familiar with.
Measurements in Qiskit are of a single :class:`Qubit` into a single :class:`Clbit`. These are the
two that the instruction is applied to. Measurements are in the computational basis.
.. autoclass:: Measure(label=None)
:show-inheritance:
Related to measurements, there is a :class:`Reset` operation, which produces no classical data but
instructs hardware to return the qubit to the :math:`\lvert0\rangle` state. This is assumed to
happen incoherently and to collapse any entanglement.
.. autoclass:: Reset(label=None)
:show-inheritance:
Hardware can be instructed to apply a real-time idle period on a given qubit. A scheduled circuit
(see :mod:`qiskit.transpiler`) will include all the idle times on qubits explicitly in terms of this
:class:`Delay`.
.. autoclass:: Delay
:show-inheritance:
The :class:`Barrier` instruction can span an arbitrary number of qubits and clbits, and is a no-op
in hardware. During transpilation and optimization, however, it blocks any optimizations from
"crossing" the barrier; that is, in::
from qiskit.circuit import QuantumCircuit
qc = QuantumCircuit(1)
qc.x(0)
qc.barrier()
qc.x(0)
it is forbidden for the optimizer to cancel out the two :math:`X` instructions.
.. autoclass:: Barrier
:show-inheritance:
The :class:`Store` instruction is particularly special, in that it allows writing the result of a
:ref:`real-time classical computation expression <circuit-repr-real-time-classical>` (an
:class:`.expr.Expr`) in a local classical variable (a :class:`.expr.Var`). It takes *neither*
:class:`Qubit` nor :class:`Clbit` operands, but has an explicit :attr:`~Store.lvalue` and
:attr:`~Store.rvalue`.
.. autoclass:: Store
:show-inheritance:
:members:
:no-inherited-members:
.. _circuit-repr-real-time-classical:
Real-time classical computation
-------------------------------
.. note::
The primary documentation for real-time classical computation is in the module-level
documentation of :mod:`qiskit.circuit.classical`.
You might also want to read about the circuit methods for working with real-time variables on
the :class:`QuantumCircuit` class page.
..
TODO: write a section in the QuantumCircuit-level guide about real-time-variable methods and
cross-ref to it.
Qiskit has rudimentary low-level support for representing real-time classical computations, which
happen during the QPU execution and affect the results. We are still relatively early into hardware
support for these concepts as well, so beware that you will need to work closely with your hardware
provider's documentation to get the best use out of any real-time classical computation.
These real-time calculations are represented by the expression and type system in
:mod:`qiskit.circuit.classical`. At a high level, all real-time expressions are represented by an
:class:`.Expr` node, which is part of an expression "tree" representation, which has a well-defined
:class:`~.classical.Type` associated with it at every level. See the module-level documentation for
much more detail on the internal representations of these classes.
The result of a real-time :class:`.Expr` can be used directly in certain places. Currently this is
limited to conditions of :class:`.IfElseOp` and :class:`.WhileLoopOp`, and the target of
:class:`.SwitchCaseOp`. The result can also be stored in a typed classical storage location, using
the :class:`.Store` instruction (or its :meth:`QuantumCircuit.store` constructor), backed by a
:class:`.expr.Var` node.
A circuit can contain manual classical storage locations, represented internally by the
:class:`~.expr.Var` node of the :class:`.Expr` tree. These have an attached classical type (like
any other expression). These can either be declared and initialized within each execution of the
circuit (:meth:`~QuantumCircuit.add_var`), or be inputs to the circuit
(:meth:`~QuantumCircuit.add_input`).
.. _circuit-compile-time-parameters:
Compile-time parametrization
----------------------------
Various parametric :class:`Instruction` instances in Qiskit can be parametrized in ways that are
designed to be resolved at compile time. These are characterized by the use of the
:class:`Parameter` and :class:`ParameterExpression` classes.
.. autosummary::
:toctree: ../stubs/
Parameter
ParameterExpression
The main way that this differs from the :class:`expr.Var` variables used in real-time classical
computation is that :class:`ParameterExpression` is a symbolic representation of a mathematical
expression. The semantics of the expression are those of regular mathematics over the continuous
real numbers (and, in limited cases, over the complex numbers). In contrast, :class:`.Var` is a
handle to a variable stored on a classical computer, such as a floating-point value or an
fixed-width integer, which are always discrete.
In other words, you can expect :class:`ParameterExpression` to do symbolic simplifications that are
valid in mathematics, such as simplifying :math:`(x + y - x) / y \to 1`. Such a simplification is
not valid in floating-point arithmetic, and :class:`.expr.Expr` will not do this.
The "compile-time" part of these parameters means that you typically will want to "assign" values to
the parameters before sending the circuit for execution. These parameters can typically be used
anywhere that expects a mathematical angle (like a rotation gate's parameters), with the caveat that
hardware will usually require them to be assigned to a proper classically typed value before
execution. You can do this assignment using :meth:`QuantumCircuit.assign_parameters`.
You may want to use many parameters that are related to each other. To make this easier (and to
avoid you needing to come up with many names), you can use the convenience constructor
:class:`ParameterVector`. The elements of the vector are all valid :class:`Parameter` instances.
.. autosummary::
:toctree: ../stubs/
ParameterVector
.. _circuit-control-flow:
Control flow in circuits
------------------------
Within :class:`QuantumCircuit`, classical control flow is represented by specific
:class:`Instruction`\ s, which are subclasses of :class:`ControlFlowOp`.
.. autosummary::
:toctree: ../stubs/
ControlFlowOp
These control-flow operations (:class:`IfElseOp`, :class:`WhileLoopOp`,
:class:`SwitchCaseOp` and :class:`ForLoopOp`) all have specific state that defines the branching
conditions and strategies, but contain all the different subcircuit blocks that might be entered in
their :attr:`~ControlFlowOp.blocks` property.
.. autosummary::
:toctree: ../stubs/
IfElseOp
WhileLoopOp
SwitchCaseOp
ForLoopOp
The :class:`.SwitchCaseOp` also understands a special value:
.. autodata:: CASE_DEFAULT
In addition to the block-structure control-flow operations, there are also two special instructions
that affect the flow of control when within loops. These correspond to typical uses of the
``break`` and ``continue`` statements in classical programming languages.
.. autosummary::
:toctree: ../stubs/
BreakLoopOp
ContinueLoopOp
.. note::
The classes representations are documented here, but please note that manually constructing
these classes is a low-level operation that we do not expect users to need to do frequently.
..
TODO: make this below statement valid, and reinsert.
Users should read :ref:`circuit-creating-control-flow` for the recommended workflows for
building control-flow-enabled circuits.
Since :class:`ControlFlowOp` subclasses are also :class:`Instruction` subclasses, this means that
the way they are stored in :class:`CircuitInstruction` instances has them "applied" to a sequence of
qubits and clbits in its :attr:`~CircuitInstruction.qubits` and :attr:`~CircuitInstruction.clbits`
attributes. This can lead to subtle data-coherence problems: the :class:`Qubit` and :class:`Clbit`
objects used inside the subcircuit blocks of the control-flow ops will not necessarily be identical
to the corresponding objects in the :class:`CircuitInstruction`. Any code that consumes
control-flow operations in Qiskit needs to be aware of this; within a subcircuit, you should treat
``subcircuit.qubits[i]`` as if it were really ``outer_instruction.qubits[i]``, and so on. You can
generate an easy lookup table for this by doing::
cf_instruction: CircuitInstruction = ...
cf_operation: ControlFlowOp = cf_instruction.operation
for block in blocks:
# Mappings of "inner" qubits/clbits to the outer ones.
qubit_map = dict(zip(block.qubits, cf_instruction.qubits))
clbit_map = dict(zip(block.clbits, cf_instruction.clbits))
# ... do something with `block` ...
Remember that you will need to propagate this information if you recurse into subblocks of
control-flow operations.
..
TODO: insert cross-ref to control-flow builder guide into below paragraph once written.
All the subcircuit blocks in a :class:`ControlFlowOp` are required to contain the same numbers of
:class:`Qubit`\ s and :class:`Clbit`\ s, referring to the same outer bits in the same order, such
that the :class:`zip` loop given in the code block above works. The inner-circuit :class:`Bit`
objects do not need to be literally the same objects. When using the control-flow builder interface
(which, it cannot be stressed enough, is *highly* recommended for users), the builders will arrange
that the inner bit objects *are* identical to the outer bit objects; the ``qubit_map`` in the code
block above will always be a mapping ``{x: x}``, but if you are consuming the blocks, you should be
prepared for the case that the mapping is required.
Any :class:`ClassicalRegister`\ s used in a control-flow subcircuit must also be present in all
containing blocks (*i.e.* any containing control-flow operations, and the outermost circuit), and
all blocks in the same :class:`ControlFlowOp` need to contain the same registers. Again, the
builder interface will arrange for this to be the case (or produce an eager error if they cannot).
When the low-level construction is being used the inner :class:`QuantumCircuit` blocks must
manually close over any outer-scope :ref:`real-time classical computation variables
<circuit-repr-real-time-classical>` that they use. This is marked by these being in the
:meth:`~QuantumCircuit.iter_captured_vars` iterator for that block. Libraries constructing these
blocks manually will need to track these captures when building control-flow circuit blocks and add
them to the block using :meth:`~QuantumCircuit.add_capture` (or the ``captures`` constructor
argument), but user code will typically use the control-flow builder interface, which handles this
automatically.
..
TODO: make the below sentence valid, then re-insert.
Consult :ref:`the control-flow construction documentation <circuit-creating-control-flow>` for
more information on how to build circuits with control flow.
.. _circuit-custom-gates:
Creating custom instructions
============================
If you wish to create simple one-off instructions or gates that will be added to a circuit, and the
blocks are just being used for visualization or grouping purposes, the easiest way to create a
custom instruction or gate is simply to build its definition as a :class:`QuantumCircuit`, and then
use its :meth:`~QuantumCircuit.to_instruction` or :meth:`~QuantumCircuit.to_gate` method as
appropriate. The results can be given directly to :meth:`QuantumCircuit.append` on the larger
circuit. These methods will create base :class:`Instruction` or :class:`Gate` instances whose
:attr:`~Instruction.definition` attribute is the circuit as supplied, meaning it will automatically
be accessible to the transpiler, and to other Qiskit functions that attempt to decompose circuits.
Note that standalone instructions and gates should act only on qubits and clbits; instructions that
need to use complex control-flow will need to be inlined onto the :class:`QuantumCircuit` using
:meth:`~QuantumCircuit.compose`.
Creating instruction subclasses
-------------------------------
The base classes :class:`Instruction`, :class:`Gate` and :class:`ControlledGate` are all designed to
be safe to subclass, and have hook points for subclasses to implement. If your custom gate is
parameterless and stateless, you may also want to derive from the corresponding singleton class in
:mod:`qiskit.circuit.singleton`, such as :class:`SingletonGate`. You should consult the
documentation in :mod:`qiskit.circuit.singleton` for additional methods and hook points for the
singleton machinery.
Subclasses should typically define a default constructor that calls the :class`super` constructor
with the correct arguments for your instruction. It is permissible to have extra state in the
class, but your subclasses will most reliably integrate with the rest of the Qiskit machinery if you
depend only on your :attr:`Instruction.params`, and these parameters are purely gate angles.
Subclasses of :class:`Instruction` (or one of its subclasses) should implement the private
:meth:`Instruction._define` method, which lazily populates the hidden ``_definition`` cache that
backs the public :attr:`~Instruction.definition` method.
.. automethod:: Instruction._define
In subclasses of :class:`ControlledGate`, the :meth:`~Instruction._define` method should implement
the decomposition only for the all-ones control state. The :attr:`ControlledGate.definition
<Instruction.definition>` machinery will modify this to handle the actual control state.
If the subclass is using the singleton machinery, beware that :meth:`~Instruction._define` will be
called eagerly immediately after the class-body statement has been executed, in order to produce the
definition object for the canonical singleton object. This means that your definition must only use
gates that are already defined; if you are writing a library with many singleton gates, you will
have to order your files and imports to ensure that this is possible.
Subclasses of :class:`Gate` will also likely wish to override `the Numpy array-protocol instance
method <https://numpy.org/devdocs/user/basics.interoperability.html#the-array-method>`__,
``__array__``. This is used by :meth:`Gate.to_matrix`, and has the signature:
.. currentmodule:: None
.. py:method:: __array__(dtype=None, copy=None)
Return a Numpy array representing the gate. This can use the gate's :attr:`~Instruction.params`
field, and may assume that these are numeric values (assuming the subclass expects that) and not
:ref:`compile-time parameters <circuit-compile-time-parameters>`.
For greatest efficiency, the returned array should default to a dtype of :class:`complex`.
.. currentmodule:: qiskit.circuit
If your custom subclass has natural representations of its controlled or inverse forms, you may also
wish to override the :meth:`~Instruction.inverse` and :meth:`~Gate.control` methods.
As an example of defining a custom :math:`R_{xz}` gate; that is, a single-angle rotation about the
:math:`XZ` axis. This is essentially :class:`RZXGate`, if the qubits were the other way around, so
we will write our definition in terms of that. We are parametric, so cannot be a singleton, but we
are unitary, so should be a :class:`Gate`::
import math
import numpy as np
from qiskit.circuit import Gate, QuantumCircuit
class RXZGate(Gate):
def __init__(self, theta):
# Initialize with our name, number of qubits and parameters.
super().__init__("rxz", 2, [theta])
def _define(self):
# Our base definition is an RZXGate, applied "backwards".
defn = QuantumCircuit(2)
defn.rzx(1, 0)
self._definition = defn
def inverse(self, annotated = False):
# We have an efficient representation of our inverse,
# so we'll override this method.
return RXZGate(-self.params[0])
def power(self, exponent: float):
# Also we have an efficient representation of power.
return RXZGate(exponent * self.params[0])
def __array__(self, dtype=None, copy=None):
if copy is False:
raise ValueError("unable to avoid copy while creating an array as requested")
cos = math.cos(0.5 * self.params[0])
isin = 1j * math.sin(0.5 * self.params[0])
return np.array([
[cos, -isin, 0, 0],
[-isin, cos, 0, 0],
[0, 0, cos, isin],
[0, 0, isin, cos],
], dtype=dtype)
In this example, we defined a base definition in terms of :class:`RZXGate`, but to enable faster
decompositions to a range of bases, we might want to add some more equivalences to
:data:`SessionEquivalenceLibrary`. Note that the :class:`.BasisTranslator` translation search will
search through all possible equivalences at all possible depths, so providing an equivalence in
terms of (say) :class:`.XGate` will automatically make decompositions in terms of :class:`.RXGate`
available as well.
Let us add an equivalence in terms of :math:`H`, :math:`CX` and :math:`R_z` for an arbitrary symbolic
parameter::
from qiskit.circuit import SessionEquivalenceLibrary, Parameter
theta = Parameter("theta")
equiv = QuantumCircuit(2)
equiv.h(0)
equiv.cx(1, 0)
equiv.rz(theta, 0)
equiv.cx(1, 0)
equiv.h(0)
SessionEquivalenceLibrary.add_equivalence(RZXGate(theta), equiv)
After this, for the duration of the Python interpreter session, translators like
:class:`.BasisTranslator` will find our new definition in their search.
.. _circuit-working-with:
Working with circuit-level objects
==================================
Circuit properties
------------------
..
TODO: rewrite this section and move it into the `QuantumCircuit` class-level overview of its
functions.
When constructing quantum circuits, there are several properties that help quantify
the "size" of the circuits, and their ability to be run on a noisy quantum device.
Some of these, like number of qubits, are straightforward to understand, while others
like depth and number of tensor components require a bit more explanation. Here we will
explain all of these properties, and, in preparation for understanding how circuits change
when run on actual devices, highlight the conditions under which they change.
Consider the following circuit:
.. plot::
:include-source:
from qiskit import QuantumCircuit
qc = QuantumCircuit(12)
for idx in range(5):
qc.h(idx)
qc.cx(idx, idx+5)
qc.cx(1, 7)
qc.x(8)
qc.cx(1, 9)
qc.x(7)
qc.cx(1, 11)
qc.swap(6, 11)
qc.swap(6, 9)
qc.swap(6, 10)
qc.x(6)
qc.draw('mpl')
From the plot, it is easy to see that this circuit has 12 qubits, and a collection of
Hadamard, CNOT, X, and SWAP gates. But how to quantify this programmatically? Because we
can do single-qubit gates on all the qubits simultaneously, the number of qubits in this
circuit is equal to the **width** of the circuit:
.. code-block::
qc.width()
.. parsed-literal::
12
We can also just get the number of qubits directly:
.. code-block::
qc.num_qubits
.. parsed-literal::
12
.. important::
For a quantum circuit composed from just qubits, the circuit width is equal
to the number of qubits. This is the definition used in quantum computing. However,
for more complicated circuits with classical registers, and classically controlled gates,
this equivalence breaks down. As such, from now on we will not refer to the number of
qubits in a quantum circuit as the width.
It is also straightforward to get the number and type of the gates in a circuit using
:meth:`QuantumCircuit.count_ops`:
.. code-block::
qc.count_ops()
.. parsed-literal::
OrderedDict([('cx', 8), ('h', 5), ('x', 3), ('swap', 3)])