Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
run: |
python -m pip install -U pip setuptools wheel pybind11
cat requirements.txt
python -m pip install -r requirements.txt --prefer-binary
python -m pip install -r requirements.txt --prefer-binary --no-build-isolation
python -m pip install coveralls

- name: Setup annotations on Linux
Expand Down Expand Up @@ -254,11 +254,12 @@ jobs:
/var/cache/dnf/
key: ${{ runner.os }}-centos${{ matrix.centos }}-yum-${{ secrets.yum_cache }}

- name: Fix repository URLs (CentOS 8 only)
if: matrix.centos == 8
- name: Fix repository URLs
run: |
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
sed -i 's|mirror.centos.org|vault.centos.org|g' /etc/yum.repos.d/CentOS-*
sed -i 's|^#baseurl|baseurl|g' /etc/yum.repos.d/CentOS-*

- name: Update YUM/DNF
run: yum update -y
Expand All @@ -267,6 +268,9 @@ jobs:
if: matrix.centos == 7
run: |
yum install -y centos-release-scl-rh
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|mirror.centos.org|vault.centos.org|g' /etc/yum.repos.d/CentOS-*
sed -i 's|^#baseurl|baseurl|g' /etc/yum.repos.d/CentOS-*
yum -y install https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm
echo '/opt/rh/rh-python38/root/usr/bin' >> $GITHUB_PATH

Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ jobs:
- uses: actions/checkout@v3

- name: Prepare env
run: >
apt-get update && apt-get install -y python3-dev python3-pip python3-setuptools python3-wheel
--no-install-recommends
run: |
sed -i 's|deb.debian.org/debian-security|archive.debian.org/debian-security|g' /etc/apt/sources.list
apt-get update -o Acquire::Retries=3
apt-get install -y python3-dev python3-pip python3-setuptools python3-wheel --no-install-recommends

- name: Upgrade pybind11 and setuptools
run: python3 -m pip install --upgrade pybind11 "setuptools>=61.0.0" --prefer-binary
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fixed some typos (thanks to @eltociear, @Darkdragon84)
- Fixed support for Python 3.12
- Fixed `ComparatorQuantum` decomposition so input registers are properly restored (#491)

### Removed

Expand All @@ -23,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Repository

- Update GitHub workflows to work with merge queues
- Fix Clang-Tidy Debian security package source URL in GitHub workflow
- Fix setuptools >= 70 compatibility in compiler configuration and build commands
- Update GitHub workflow action versions: `actions/cache@v3`, `actions/checkout@v3`, `actions/setup-python@v4`, `thomaseizinger/create-pull-request`
- Update pre-commit hook versions
- Fix failing GitHub workflows (Clang-10)
Expand Down
4 changes: 2 additions & 2 deletions projectq/libs/math/_quantummath.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,11 @@ def comparator(eng, quint_a, quint_b, comp):
with Control(eng, [quint_a[n_qubits - 2], quint_b[n_qubits - 2]]):
X | comp

for k in range(0, n_qubits - 2):
for k in range(n_qubits - 3, -1, -1):
with Control(eng, [quint_a[k], quint_b[k]]):
X | (quint_a[k + 1])

for j in range(n_qubits - 3, 0, -1):
for j in range(1, n_qubits - 2):
CNOT | (quint_a[j], quint_a[j + 1])

for i in range(1, n_qubits - 1):
Expand Down
88 changes: 87 additions & 1 deletion projectq/libs/math/_quantummath_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
import projectq.libs.math
from projectq import MainEngine
from projectq.backends import Simulator
from projectq.cengines import AutoReplacer, DecompositionRuleSet, InstructionFilter
from projectq.cengines import (
AutoReplacer,
BasicEngine,
DecompositionRuleSet,
InstructionFilter,
)
from projectq.libs.math import (
AddQuantum,
ComparatorQuantum,
Expand Down Expand Up @@ -249,6 +254,8 @@ def test_comparator(eng):

ComparatorQuantum | (qureg_a, qureg_b, compare_qubit)

assert 1.0 == pytest.approx(eng.backend.get_probability([1, 0, 1], qureg_a))
assert 1.0 == pytest.approx(eng.backend.get_probability([1, 1, 0], qureg_b))
assert 1.0 == pytest.approx(eng.backend.get_probability([1], compare_qubit))

# Size mismatch in qubit registers
Expand All @@ -264,6 +271,85 @@ def test_comparator(eng):
Measure | compare_qubit


class _BasisBackend(BasicEngine):
"""Exact basis-state backend accepting only multi-controlled X and lifecycle gates."""

def __init__(self):
super().__init__()
self.state = {}

def is_available(self, cmd):
return cmd.gate.__class__.__name__ in (
'XGate',
'AllocateQubitGate',
'DeallocateQubitGate',
'FlushGate',
'MeasureGate',
)

def receive(self, commands):
for cmd in commands:
name = cmd.gate.__class__.__name__
if name == 'AllocateQubitGate':
self.state[cmd.qubits[0][0].id] = 0
elif name == 'XGate' and all(self.state[c.id] for c in cmd.control_qubits):
self.state[cmd.qubits[0][0].id] ^= 1


def _run_comparator_decomposition(a_val, b_val, c_val, n_bits=3):
backend = _BasisBackend()
rules = DecompositionRuleSet(modules=[projectq.libs.math])
engine = MainEngine(backend=backend, engine_list=[AutoReplacer(rules)])
reg_a = engine.allocate_qureg(n_bits)
reg_b = engine.allocate_qureg(n_bits)
reg_c = engine.allocate_qureg(1)
for i, qubit in enumerate(reg_a):
if (a_val >> i) & 1:
X | qubit
for i, qubit in enumerate(reg_b):
if (b_val >> i) & 1:
X | qubit
if c_val:
X | reg_c[0]
ComparatorQuantum | (reg_a, reg_b, reg_c)
All(Measure) | (reg_a + reg_b + reg_c)
engine.flush()
res_a = sum(backend.state[q.id] << i for i, q in enumerate(reg_a))
res_b = sum(backend.state[q.id] << i for i, q in enumerate(reg_b))
res_c = backend.state[reg_c[0].id]
return res_a, res_b, res_c


@pytest.mark.parametrize(
'a, b, c_in, expected_c',
[
(1, 0, 0, 1),
(0, 1, 0, 0),
(2, 2, 0, 0),
(1, 0, 1, 0),
(0, 1, 1, 1),
(7, 0, 0, 1),
(0, 7, 0, 0),
(7, 7, 1, 1),
],
)
def test_comparator_decomposition_restore_registers(a, b, c_in, expected_c):
res_a, res_b, res_c = _run_comparator_decomposition(a, b, c_in, n_bits=3)
assert res_a == a
assert res_b == b
assert res_c == expected_c


def test_comparator_decomposition_all_3bit_cases():
for a in range(8):
for b in range(8):
for c_in in (0, 1):
res_a, res_b, res_c = _run_comparator_decomposition(a, b, c_in, n_bits=3)
assert res_a == a
assert res_b == b
assert res_c == c_in ^ int(a > b)


@pytest.mark.parametrize('qubit_idx', (0, 1, 2))
def test_quantumdivision_size_mismatch(eng, qubit_idx):
qureg_a = eng.allocate_qureg(4 if qubit_idx != 0 else 3)
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ dynamic = ["version"]
dependencies = [
'matplotlib >= 2.2.3',
'networkx >= 2.4',
'numpy>=1.21.5',
'numpy>=1.21.5, <2',
'requests>=2.25.1',
'scipy>=1.8.0'
]
Expand All @@ -44,7 +44,7 @@ dependencies = [
[project.optional-dependencies]

azure-quantum = [
'azure-quantum'
'azure-quantum < 3.10'
]

braket = [
Expand Down
11 changes: 7 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,9 @@ def _get_compilation_commands(self, ext):

def _configure_compiler(self):
# Force dry_run = False to allow for compiler feature testing
dry_run_old = self.compiler.dry_run
self.compiler.dry_run = False
dry_run_old = getattr(self.compiler, 'dry_run', False)
if hasattr(self.compiler, 'dry_run'):
self.compiler.dry_run = False

if (
int(os.environ.get('PROJECTQ_CLEANUP_COMPILER_FLAGS', 0))
Expand Down Expand Up @@ -472,7 +473,8 @@ def _configure_compiler(self):
if compiler_type == 'unix' and compiler_test(self.compiler, '-fvisibility=hidden'):
self.opts.append('-fvisibility=hidden')

self.compiler.dry_run = dry_run_old
if hasattr(self.compiler, 'dry_run'):
self.compiler.dry_run = dry_run_old
status_msgs('Finished configuring compiler!')

def _configure_openmp(self):
Expand Down Expand Up @@ -680,7 +682,8 @@ def run(self):
command.append('--warnings-as-errors=*')
for ext in self.distribution.ext_modules:
command.extend(os.path.abspath(p) for p in ext.sources)
spawn(command, dry_run=self.dry_run)
if not self.dry_run:
spawn(command)


# ------------------------------------------------------------------------------
Expand Down
Loading