Skip to content

Commit 84b5ce9

Browse files
Merge branch 'main' into port-hls-to-rust
2 parents a0c0857 + cd2bd52 commit 84b5ce9

File tree

68 files changed

+2986
-1898
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2986
-1898
lines changed

.azure/test-linux.yml

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ jobs:
120120
popd
121121
env:
122122
QISKIT_PARALLEL: FALSE
123+
QISKIT_IGNORE_USER_SETTINGS: TRUE
123124
RUST_BACKTRACE: 1
124125
displayName: 'Run Python tests'
125126

.azure/test-macos.yml

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ jobs:
6565
stestr run
6666
env:
6767
QISKIT_PARALLEL: FALSE
68+
QISKIT_IGNORE_USER_SETTINGS: TRUE
6869
RUST_BACKTRACE: 1
6970
displayName: "Run tests"
7071

.azure/test-windows.yml

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ jobs:
6868
LANG: 'C.UTF-8'
6969
PYTHONIOENCODING: 'utf-8:backslashreplace'
7070
QISKIT_PARALLEL: FALSE
71+
QISKIT_IGNORE_USER_SETTINGS: TRUE
7172
RUST_BACKTRACE: 1
7273
displayName: 'Run tests'
7374

.github/workflows/coverage.yml

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ jobs:
6161
env:
6262
QISKIT_TEST_CAPTURE_STREAMS: 1
6363
QISKIT_PARALLEL: FALSE
64+
QISKIT_IGNORE_USER_SETTINGS: TRUE
6465
PYTHON: "coverage run --source qiskit --parallel-mode"
6566

6667
- name: Convert to lcov and combine data

.github/workflows/qpy.yml

+2
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@ jobs:
3737
- name: Run QPY backwards compatibility tests
3838
working-directory: test/qpy_compat
3939
run: ./run_tests.sh
40+
env:
41+
QISKIT_IGNORE_USER_SETTINGS: TRUE

.github/workflows/randomized_tests.yml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ jobs:
2828
run: make test_randomized
2929
env:
3030
RUST_BACKTRACE: 1
31+
QISKIT_IGNORE_USER_SETTINGS: TRUE
3132
- name: Create comment on failed test run
3233
if: ${{ failure() }}
3334
uses: peter-evans/create-or-update-comment@v4

.github/workflows/slow.yml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
env:
2727
RUST_BACKTRACE: 1
2828
QISKIT_TESTS: "run_slow"
29+
QISKIT_IGNORE_USER_SETTINGS: TRUE
2930
- name: Create comment on failed test run
3031
if: ${{ failure() }}
3132
uses: peter-evans/create-or-update-comment@v4

.github/workflows/tests.yml

+3
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,6 @@ jobs:
4848
if: matrix.python-version == '3.9'
4949
- name: 'Run tests'
5050
run: stestr run
51+
env:
52+
QISKIT_PARALLEL: FALSE
53+
QISKIT_IGNORE_USER_SETTINGS: TRUE

pyproject.toml

+4
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ sk = "qiskit.transpiler.passes.synthesis.solovay_kitaev_synthesis:SolovayKitaevS
101101
"qft.line" = "qiskit.transpiler.passes.synthesis.hls_plugins:QFTSynthesisLine"
102102
"qft.default" = "qiskit.transpiler.passes.synthesis.hls_plugins:QFTSynthesisFull"
103103
"permutation.token_swapper" = "qiskit.transpiler.passes.synthesis.hls_plugins:TokenSwapperSynthesisPermutation"
104+
"IntComp.default" = "qiskit.transpiler.passes.synthesis.hls_plugins:IntComparatorSynthesisDefault"
105+
"IntComp.noaux" = "qiskit.transpiler.passes.synthesis.hls_plugins:IntComparatorSynthesisNoAux"
106+
"IntComp.twos" = "qiskit.transpiler.passes.synthesis.hls_plugins:IntComparatorSynthesis2s"
107+
"WeightedSum.default" = "qiskit.transpiler.passes.synthesis.hls_plugins:WeightedSumSynthesisDefault"
104108
"ModularAdder.default" = "qiskit.transpiler.passes.synthesis.hls_plugins:ModularAdderSynthesisDefault"
105109
"ModularAdder.ripple_c04" = "qiskit.transpiler.passes.synthesis.hls_plugins:ModularAdderSynthesisC04"
106110
"ModularAdder.ripple_v95" = "qiskit.transpiler.passes.synthesis.hls_plugins:ModularAdderSynthesisV95"

qiskit/circuit/library/__init__.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@
259259
:template: autosummary/class_no_inherited_members.rst
260260
261261
LinearAmplitudeFunction
262+
LinearAmplitudeFunctionGate
262263
263264
Functional Pauli Rotations
264265
--------------------------
@@ -269,10 +270,15 @@
269270
270271
FunctionalPauliRotations
271272
LinearPauliRotations
273+
LinearPauliRotationsGate
272274
PolynomialPauliRotations
275+
PolynomialPauliRotationsGate
273276
PiecewiseLinearPauliRotations
277+
PiecewiseLinearPauliRotationsGate
274278
PiecewisePolynomialPauliRotations
279+
PiecewisePolynomialPauliRotationsGate
275280
PiecewiseChebyshev
281+
PiecewiseChebyshevGate
276282
277283
Adders
278284
------
@@ -284,7 +290,6 @@
284290
DraperQFTAdder
285291
CDKMRippleCarryAdder
286292
VBERippleCarryAdder
287-
WeightedAdder
288293
ModularAdderGate
289294
HalfAdderGate
290295
FullAdderGate
@@ -308,6 +313,7 @@
308313
:template: autosummary/class_no_inherited_members.rst
309314
310315
IntegerComparator
316+
IntegerComparatorGate
311317
312318
Functions on binary variables
313319
-----------------------------
@@ -317,6 +323,7 @@
317323
:template: autosummary/class_no_inherited_members.rst
318324
319325
QuadraticForm
326+
QuadraticFormGate
320327
321328
Other arithmetic functions
322329
--------------------------
@@ -326,6 +333,9 @@
326333
:template: autosummary/class_no_inherited_members.rst
327334
328335
ExactReciprocal
336+
ExactReciprocalGate
337+
WeightedAdder
338+
WeightedSumGate
329339
330340
Particular Quantum Circuits
331341
===========================
@@ -621,20 +631,30 @@
621631
MultiplierGate,
622632
FunctionalPauliRotations,
623633
LinearPauliRotations,
634+
LinearPauliRotationsGate,
624635
PiecewiseLinearPauliRotations,
636+
PiecewiseLinearPauliRotationsGate,
625637
PiecewisePolynomialPauliRotations,
638+
PiecewisePolynomialPauliRotationsGate,
626639
PolynomialPauliRotations,
640+
PolynomialPauliRotationsGate,
627641
IntegerComparator,
642+
IntegerComparatorGate,
628643
WeightedAdder,
644+
WeightedSumGate,
629645
QuadraticForm,
646+
QuadraticFormGate,
630647
LinearAmplitudeFunction,
648+
LinearAmplitudeFunctionGate,
631649
VBERippleCarryAdder,
632650
CDKMRippleCarryAdder,
633651
DraperQFTAdder,
634652
PiecewiseChebyshev,
653+
PiecewiseChebyshevGate,
635654
HRSCumulativeMultiplier,
636655
RGQFTMultiplier,
637656
ExactReciprocal,
657+
ExactReciprocalGate,
638658
)
639659

640660
from .n_local import (

qiskit/circuit/library/arithmetic/__init__.py

+16-10
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,22 @@
1313
"""The arithmetic circuit library."""
1414

1515
from .functional_pauli_rotations import FunctionalPauliRotations
16-
from .integer_comparator import IntegerComparator
17-
from .linear_pauli_rotations import LinearPauliRotations
18-
from .piecewise_linear_pauli_rotations import PiecewiseLinearPauliRotations
19-
from .piecewise_polynomial_pauli_rotations import PiecewisePolynomialPauliRotations
20-
from .polynomial_pauli_rotations import PolynomialPauliRotations
21-
from .weighted_adder import WeightedAdder
22-
from .quadratic_form import QuadraticForm
23-
from .linear_amplitude_function import LinearAmplitudeFunction
16+
from .integer_comparator import IntegerComparator, IntegerComparatorGate
17+
from .linear_pauli_rotations import LinearPauliRotations, LinearPauliRotationsGate
18+
from .piecewise_linear_pauli_rotations import (
19+
PiecewiseLinearPauliRotations,
20+
PiecewiseLinearPauliRotationsGate,
21+
)
22+
from .piecewise_polynomial_pauli_rotations import (
23+
PiecewisePolynomialPauliRotations,
24+
PiecewisePolynomialPauliRotationsGate,
25+
)
26+
from .polynomial_pauli_rotations import PolynomialPauliRotations, PolynomialPauliRotationsGate
27+
from .weighted_adder import WeightedAdder, WeightedSumGate
28+
from .quadratic_form import QuadraticForm, QuadraticFormGate
29+
from .linear_amplitude_function import LinearAmplitudeFunction, LinearAmplitudeFunctionGate
30+
from .piecewise_chebyshev import PiecewiseChebyshev, PiecewiseChebyshevGate
31+
from .exact_reciprocal import ExactReciprocal, ExactReciprocalGate
2432
from .adders import (
2533
VBERippleCarryAdder,
2634
CDKMRippleCarryAdder,
@@ -29,6 +37,4 @@
2937
HalfAdderGate,
3038
FullAdderGate,
3139
)
32-
from .piecewise_chebyshev import PiecewiseChebyshev
3340
from .multipliers import HRSCumulativeMultiplier, RGQFTMultiplier, MultiplierGate
34-
from .exact_reciprocal import ExactReciprocal

qiskit/circuit/library/arithmetic/exact_reciprocal.py

+64-21
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from math import isclose
1515
import numpy as np
16-
from qiskit.circuit import QuantumCircuit, QuantumRegister
16+
from qiskit.circuit import QuantumCircuit, QuantumRegister, Gate
1717
from qiskit.circuit.library.generalized_gates import UCRYGate
1818

1919

@@ -46,43 +46,86 @@ def __init__(
4646
"""
4747
qr_state = QuantumRegister(num_state_qubits, "state")
4848
qr_flag = QuantumRegister(1, "flag")
49-
circuit = QuantumCircuit(qr_state, qr_flag, name=name)
49+
super().__init__(qr_state, qr_flag, name=name)
50+
51+
reciprocal = ExactReciprocalGate(num_state_qubits, scaling, neg_vals, label=name)
52+
self.append(reciprocal, self.qubits)
53+
54+
55+
class ExactReciprocalGate(Gate):
56+
r"""Implements an exact reciprocal function.
57+
58+
For a state :math:`|x\rangle` and a scaling factor :math:`s`, this gate implements the operation
59+
60+
.. math::
61+
62+
|x\rangle |0\rangle \mapsto
63+
\cos\left(\arcsin\left(s\frac{2^n}{x}\right)\right)|x\rangle|0\rangle +
64+
\left(s\frac{2^n}{x}\right)|x\rangle|1\rangle.
65+
66+
States representing :math:`x = 0` or :math:`s 2^n / x \geq 1` are left unchanged, since
67+
this function would not be defined.
68+
"""
69+
70+
def __init__(
71+
self, num_state_qubits: int, scaling: float, neg_vals: bool = False, label: str = "1/x"
72+
) -> None:
73+
r"""
74+
Args:
75+
num_state_qubits: The number of qubits representing the value to invert.
76+
scaling: Scaling factor :math:`s` of the reciprocal function, i.e. to compute
77+
:math:`s / x`.
78+
neg_vals: Whether :math:`x` might represent negative values. In this case the first
79+
qubit is the sign, with :math:`|1\rangle` for negative and :math:`|0\rangle` for
80+
positive. For the negative case it is assumed that the remaining string represents
81+
:math:`1 - x`. This is because :math:`e^{-2 \pi i x} = e^{2 \pi i (1 - x)}` for
82+
:math:`x \in [0,1)`.
83+
label: The label of the object.
84+
85+
.. note::
86+
87+
It is assumed that the binary string :math:`x` represents a number < 1.
88+
"""
89+
super().__init__("ExactReciprocal", num_state_qubits + 1, [], label=label)
90+
91+
self.scaling = scaling
92+
self.neg_vals = neg_vals
93+
94+
def _define(self):
95+
num_state_qubits = self.num_qubits - 1
96+
qr_state = QuantumRegister(num_state_qubits, "state")
97+
qr_flag = QuantumRegister(1, "flag")
98+
circuit = QuantumCircuit(qr_state, qr_flag)
5099

51100
angles = [0.0]
52-
nl = 2 ** (num_state_qubits - 1) if neg_vals else 2**num_state_qubits
101+
nl = 2 ** (num_state_qubits - 1) if self.neg_vals else 2**num_state_qubits
53102

54103
# Angles to rotate by scaling / x, where x = i / nl
55104
for i in range(1, nl):
56-
if isclose(scaling * nl / i, 1, abs_tol=1e-5):
105+
if isclose(self.scaling * nl / i, 1, abs_tol=1e-5):
57106
angles.append(np.pi)
58-
elif scaling * nl / i < 1:
59-
angles.append(2 * np.arcsin(scaling * nl / i))
107+
elif self.scaling * nl / i < 1:
108+
angles.append(2 * np.arcsin(self.scaling * nl / i))
60109
else:
61110
angles.append(0.0)
62111

63-
circuit.compose(
64-
UCRYGate(angles), [qr_flag[0]] + qr_state[: len(qr_state) - neg_vals], inplace=True
65-
)
112+
circuit.append(UCRYGate(angles), [qr_flag[0]] + qr_state[: len(qr_state) - self.neg_vals])
66113

67-
if neg_vals:
68-
circuit.compose(
114+
if self.neg_vals:
115+
circuit.append(
69116
UCRYGate([-theta for theta in angles]).control(),
70117
[qr_state[-1]] + [qr_flag[0]] + qr_state[:-1],
71-
inplace=True,
72118
)
73119
angles_neg = [0.0]
74120
for i in range(1, nl):
75-
if isclose(scaling * (-1) / (1 - i / nl), -1, abs_tol=1e-5):
121+
if isclose(self.scaling * (-1) / (1 - i / nl), -1, abs_tol=1e-5):
76122
angles_neg.append(-np.pi)
77-
elif np.abs(scaling * (-1) / (1 - i / nl)) < 1:
78-
angles_neg.append(2 * np.arcsin(scaling * (-1) / (1 - i / nl)))
123+
elif np.abs(self.scaling * (-1) / (1 - i / nl)) < 1:
124+
angles_neg.append(2 * np.arcsin(self.scaling * (-1) / (1 - i / nl)))
79125
else:
80126
angles_neg.append(0.0)
81-
circuit.compose(
82-
UCRYGate(angles_neg).control(),
83-
[qr_state[-1]] + [qr_flag[0]] + qr_state[:-1],
84-
inplace=True,
127+
circuit.append(
128+
UCRYGate(angles_neg).control(), [qr_state[-1]] + [qr_flag[0]] + qr_state[:-1]
85129
)
86130

87-
super().__init__(*circuit.qregs, name=name)
88-
self.compose(circuit.to_gate(), qubits=self.qubits, inplace=True)
131+
self.definition = circuit

0 commit comments

Comments
 (0)