From b5107262fed6df9a0fb4266c973ff91c1d111d58 Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:13:05 +0900 Subject: [PATCH 1/9] :fire: Remove unmaintained benchmarks --- benchmarks/graphsim.py | 135 ---------------------------- benchmarks/readme.rst | 4 - benchmarks/requirements.txt | 0 benchmarks/statevec.py | 169 ------------------------------------ 4 files changed, 308 deletions(-) delete mode 100644 benchmarks/graphsim.py delete mode 100644 benchmarks/readme.rst delete mode 100644 benchmarks/requirements.txt delete mode 100644 benchmarks/statevec.py diff --git a/benchmarks/graphsim.py b/benchmarks/graphsim.py deleted file mode 100644 index 9f6921e2a..000000000 --- a/benchmarks/graphsim.py +++ /dev/null @@ -1,135 +0,0 @@ -""" -Graph state simulator backends -======================================= - -Here we benchmark our graph state simulator for MBQC with different backends. - -Currently, we have two backends: `networkx `_ -and `rustworkx `_. -Both Python packages are used to manipulate graphs. -While networkx is a pure Python package, rustworkx is a Rust package with Python bindings, which is faster than networkx. -""" - -# %% -# Firstly, let us import relevant modules: - -from copy import copy -from time import perf_counter - -import matplotlib.pyplot as plt -import numpy as np - -from graphix import Circuit - -# %% -# Next, define a function to generate random Clifford circuits. - - -def genpair(n_qubits, count, rng): - pairs = [] - for _ in range(count): - choice = [j for j in range(n_qubits)] - x = rng.choice(choice) - choice.pop(x) - y = rng.choice(choice) - pairs.append((x, y)) - return pairs - - -def random_clifford_circuit(nqubits, depth, seed=42): - rng = np.random.default_rng(seed) - circuit = Circuit(nqubits) - gate_choice = list(range(5)) - for _ in range(depth): - for j, k in genpair(nqubits, 2, rng): - circuit.cnot(j, k) - for j in range(nqubits): - k = rng.choice(gate_choice) - if k == 0: # H - circuit.h(j) - elif k == 1: # S - circuit.s(j) - elif k == 2: # X - circuit.x(j) - elif k == 3: # Z - circuit.z(j) - elif k == 4: # Y - circuit.y(j) - else: - pass - return circuit - - -# %% -# We generate a set of random Clifford circuits with different widths. - -DEPTH = 3 -test_cases = [i for i in range(2, 300, 10)] -graphix_patterns = {} - -for i in test_cases: - circuit = random_clifford_circuit(i, DEPTH) - pattern = circuit.transpile() - pattern.standardize() - pattern.shift_signals() - nodes, edges = pattern.get_graph() - graphix_patterns[i] = (circuit, pattern, len(nodes)) - - -# %% -# We then run simulations. -# First, we run the pattern optimization using networkx. -networkx_time = [] -networkx_node = [] - -for width, (_, pattern, num_nodes) in graphix_patterns.items(): - pattern_copy = copy(pattern) - start = perf_counter() - pattern_copy.perform_pauli_measurements() - end = perf_counter() - networkx_node.append(num_nodes) - print(f"width: {width}, number of nodes: {num_nodes}, depth: {DEPTH}, time: {end - start}") - networkx_time.append(end - start) - - -# %% -# Next, we run the pattern optimization using rustworkx. -rustworkx_time = [] -rustworkx_node = [] - -for width, (_, pattern, num_nodes) in graphix_patterns.items(): - pattern_copy = copy(pattern) - start = perf_counter() - pattern_copy.perform_pauli_measurements(use_rustworkx=True) - end = perf_counter() - rustworkx_node.append(num_nodes) - print(f"width: {width}, number of nodes: {num_nodes}, depth: {DEPTH}, time: {end - start}") - rustworkx_time.append(end - start) - -# %% -# Lastly, we compare the simulation times. -assert networkx_node == rustworkx_node - -fig = plt.figure() -ax = fig.add_subplot(111) - -ax.scatter(networkx_node, networkx_time, label="networkx", color="blue") -ax.scatter(rustworkx_node, rustworkx_time, label="rustworkx", color="red") -ax.set( - xlabel="Number of nodes in the graph state", - xscale="log", - ylabel="Time (s)", - yscale="log", - title="Time to perform Pauli measurements on the graph state", -) -ax.legend() -fig.show() - -# %% -# Performing pattern optimization using rustworkx is slightly faster than networkx. - -import importlib.metadata # noqa: E402 - -# print package versions. -for pkg in ["graphix", "networkx", "rustworkx"]: - print(f"{pkg} - {importlib.metadata.version(pkg)}") diff --git a/benchmarks/readme.rst b/benchmarks/readme.rst deleted file mode 100644 index 068c3a629..000000000 --- a/benchmarks/readme.rst +++ /dev/null @@ -1,4 +0,0 @@ -Graphix benchmarks -================== - -Here are some benchmark of Graphix and related packages. diff --git a/benchmarks/requirements.txt b/benchmarks/requirements.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/benchmarks/statevec.py b/benchmarks/statevec.py deleted file mode 100644 index 200c04562..000000000 --- a/benchmarks/statevec.py +++ /dev/null @@ -1,169 +0,0 @@ -""" -Statevector simulation of MBQC patterns -======================================= - -Here we benchmark our statevector simulator for MBQC. - -The methods and modules we use are the followings: - 1. :meth:`graphix.pattern.Pattern.simulate_pattern` - Pattern simulator with statevector backend. - 2. :mod:`paddle_quantum.mbqc` - Pattern simulation using :mod:`paddle_quantum.mbqc`. -""" - -# %% -# Firstly, let us import relevant modules: - -from time import perf_counter - -import matplotlib.pyplot as plt -import numpy as np -from paddle import to_tensor -from paddle_quantum.mbqc.qobject import Circuit as PaddleCircuit -from paddle_quantum.mbqc.simulator import MBQC as PaddleMBQC # noqa: N811 -from paddle_quantum.mbqc.transpiler import transpile as paddle_transpile - -from graphix import Circuit - -rng = np.random.default_rng() - -# %% -# Next, define a circuit to be transpiled into measurement pattern: - - -def simple_random_circuit(nqubit, depth): - r"""Generate a test circuit for benchmarking. - - This function generates a circuit with nqubit qubits and depth layers, - having layers of CNOT and Rz gates with random placements. - - Parameters - ---------- - nqubit : int - number of qubits - depth : int - number of layers - - Returns - ------- - circuit : graphix.transpiler.Circuit object - generated circuit - """ - qubit_index = [i for i in range(nqubit)] - circuit = Circuit(nqubit) - for _ in range(depth): - rng.shuffle(qubit_index) - for j in range(len(qubit_index) // 2): - circuit.cnot(qubit_index[2 * j], qubit_index[2 * j + 1]) - for j in range(len(qubit_index)): - circuit.rz(qubit_index[j], 2 * np.pi * rng.random()) - return circuit - - -# %% -# We define the test cases: shallow (depth=1) random circuits, only changing the number of qubits. - -DEPTH = 1 -test_cases = [i for i in range(2, 22)] -graphix_circuits = {} - -pattern_time = [] -circuit_time = [] - -# %% -# We then run simulations. -# First, we run the pattern simulation using `graphix`. -# For reference, we perform simple statevector simulation of the original gate network. -# Since transpilation into MBQC involves a significant increase in qubit number, -# the MBQC simulation is inherently slower as we will see. - -for width in test_cases: - circuit = simple_random_circuit(width, DEPTH) - graphix_circuits[width] = circuit - pattern = circuit.transpile() - pattern.standardize() - pattern.minimize_space() - nodes, edges = pattern.get_graph() - nqubit = len(nodes) - start = perf_counter() - pattern.simulate_pattern(max_qubit_num=30) - end = perf_counter() - print(f"width: {width}, nqubit: {nqubit}, depth: {DEPTH}, time: {end - start}") - pattern_time.append(end - start) - start = perf_counter() - circuit.simulate_statevector() - end = perf_counter() - circuit_time.append(end - start) - - -# %% -# Here we benchmark `paddle_quantum`, using the same original gate network and use `paddle_quantum.mbqc` module -# to transpile into a measurement pattern. - - -def translate_graphix_rc_into_paddle_quantum_circuit(graphix_circuit: Circuit) -> PaddleCircuit: - """Translate graphix circuit into paddle_quantum circuit. - - Parameters - ---------- - graphix_circuit : Circuit - graphix circuit - - Returns - ------- - paddle_quantum_circuit : PaddleCircuit - paddle_quantum circuit - """ - paddle_quantum_circuit = PaddleCircuit(graphix_circuit.width) - for instr in graphix_circuit.instruction: - if instr.name == "CNOT": - paddle_quantum_circuit.cnot(which_qubits=instr[1]) - elif instr.name == "RZ": - paddle_quantum_circuit.rz(which_qubit=instr[1], theta=to_tensor(instr[2], dtype="float64")) - return paddle_quantum_circuit - - -test_cases_for_paddle_quantum = [i for i in range(2, 22)] -paddle_quantum_time = [] - -for width in test_cases_for_paddle_quantum: - graphix_circuit = graphix_circuits[width] - paddle_quantum_circuit = translate_graphix_rc_into_paddle_quantum_circuit(graphix_circuit) - pat = paddle_transpile(paddle_quantum_circuit) - mbqc = PaddleMBQC() - mbqc.set_pattern(pat) - start = perf_counter() - mbqc.run_pattern() - end = perf_counter() - paddle_quantum_time.append(end - start) - - print(f"width: {width}, depth: {DEPTH}, time: {end - start}") - -# %% -# Lastly, we compare the simulation times. - -fig = plt.figure() -ax = fig.add_subplot(111) - -ax.scatter( - test_cases, circuit_time, label="direct statevector sim of original gate-based circuit (reference)", marker="x" -) -ax.scatter(test_cases, pattern_time, label="graphix pattern simulator") -ax.scatter(test_cases_for_paddle_quantum, paddle_quantum_time, label="paddle_quantum pattern simulator") -ax.set( - xlabel="Width of the original circuit", - ylabel="time (s)", - yscale="log", - title="Time to simulate random circuits", -) -fig.legend(bbox_to_anchor=(0.85, 0.9)) -fig.show() - -# %% -# MBQC simulation is a lot slower than the simulation of original gate network, since the number of qubit involved -# is significantly larger. - -import importlib.metadata # noqa: E402 - -# print package versions. -[print(f"{pkg} - {importlib.metadata.version(pkg)}") for pkg in ["numpy", "graphix", "paddlepaddle", "paddle-quantum"]] From 767b6f5d17105edb8a2522bc3cba5d1d4955a4ab Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:28:02 +0900 Subject: [PATCH 2/9] :fire: Remove doc requirements --- docs/requirements.txt | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 docs/requirements.txt diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 4f518e626..000000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,12 +0,0 @@ -sphinx>=5.0 -sphinx-gallery==0.11.1 -furo -sphinxawesome-theme==5.1.6 -numpy -graphix -matplotlib -scikit-learn -seaborn -ipython - --r ../benchmarks/requirements.txt From bda094395ca4373efdc5b4db4d82a66252307c1a Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:28:26 +0900 Subject: [PATCH 3/9] :technologist: Update requirements --- pyproject.toml | 1 + requirements-dev.txt | 8 -------- requirements-doc.txt | 8 ++++++++ requirements-extra.txt | 4 ++++ requirements.txt | 1 - 5 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 requirements-doc.txt diff --git a/pyproject.toml b/pyproject.toml index 40eeb707e..382b618b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ dependencies = { file = ["requirements.txt"] } [tool.setuptools.dynamic.optional-dependencies] dev = { file = ["requirements-dev.txt"] } +doc = { file = ["requirements-doc.txt"] } extra = { file = ["requirements-extra.txt"] } [tool.ruff] diff --git a/requirements-dev.txt b/requirements-dev.txt index 5a18f48f1..98684c73c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -13,11 +13,3 @@ pytest pytest-cov pytest-mock tox - -# Optional dependencies -qiskit>=1.0 -qiskit-aer -rustworkx - -# Optional dependency. Pinned due to version changes often being incompatible -pyzx==0.8.0 diff --git a/requirements-doc.txt b/requirements-doc.txt new file mode 100644 index 000000000..17c5c3a11 --- /dev/null +++ b/requirements-doc.txt @@ -0,0 +1,8 @@ +furo +ipython +matplotlib +scikit-learn +seaborn +sphinxawesome-theme +sphinx-gallery +sphinx>=5.0 diff --git a/requirements-extra.txt b/requirements-extra.txt index a87155897..c691ea6cc 100644 --- a/requirements-extra.txt +++ b/requirements-extra.txt @@ -1,2 +1,6 @@ graphix-ibmq graphix-perceval +pyzx==0.8.0 +qiskit-aer +qiskit>=1.0 +rustworkx diff --git a/requirements.txt b/requirements.txt index e84c035be..b1e63b312 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -autoray>=0.6.0 eval_type_backport galois>=0.3.0 matplotlib From 2f3213f2816c208315079fd11ab5dc9bc5cbb665 Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:28:42 +0900 Subject: [PATCH 4/9] :green_heart: Update CIs --- .github/workflows/cov.yml | 2 +- .github/workflows/doc.yml | 4 ++-- .github/workflows/typecheck.yml | 2 +- tox.ini | 5 ++--- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cov.yml b/.github/workflows/cov.yml index b86b59309..b5a66777e 100644 --- a/.github/workflows/cov.yml +++ b/.github/workflows/cov.yml @@ -22,7 +22,7 @@ jobs: run: python -m pip install --upgrade pip - name: Install graphix with dev deps. - run: pip install .[dev] + run: pip install .[dev,extra] - name: Run pytest run: pytest --cov=./graphix --cov-report=xml diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 9547c58b8..b5f4e7d26 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -31,7 +31,7 @@ jobs: run: python -m pip install --upgrade pip - name: Install requirements - run: pip install -r requirements.txt -r requirements-dev.txt -r docs/requirements.txt + run: pip install .[dev,doc] - name: Make docs - run: make -C docs html SPHINXOPTS="--fail-on-warning" + run: sphinx-build -M html docs/source docs/build diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index c105a9045..92736df27 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -25,7 +25,7 @@ jobs: - run: | python -m pip install --upgrade pip - pip install -e .[dev] + pip install -e .[dev,extra] - run: mypy diff --git a/tox.ini b/tox.ini index fb0869ba9..b69a47a8d 100644 --- a/tox.ini +++ b/tox.ini @@ -14,6 +14,7 @@ description = Run the unit tests deps = -r {toxinidir}/requirements.txt -r {toxinidir}/requirements-dev.txt + -r {toxinidir}/requirements-extra.txt commands = pytest {toxinidir} @@ -21,8 +22,6 @@ commands = description = Run the unit tests with minimum dependencies deps = -r {toxinidir}/requirements.txt - pytest - pytest-mock - psutil + -r {toxinidir}/requirements-dev.txt commands = pytest {toxinidir} From b4a5c77268db07feb4705b320349e7bdf9d2cfd3 Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:31:23 +0900 Subject: [PATCH 5/9] :poop: Comment out dead deps. --- requirements-extra.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements-extra.txt b/requirements-extra.txt index c691ea6cc..3304cd229 100644 --- a/requirements-extra.txt +++ b/requirements-extra.txt @@ -1,5 +1,5 @@ -graphix-ibmq -graphix-perceval +# graphix-ibmq +# graphix-perceval pyzx==0.8.0 qiskit-aer qiskit>=1.0 From 2bf4e569ddd3111cd13dc01d5414c5a954c80af0 Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:38:07 +0900 Subject: [PATCH 6/9] :construction_worker: Fail on error --- .github/workflows/doc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index b5f4e7d26..0e66dc704 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -34,4 +34,4 @@ jobs: run: pip install .[dev,doc] - name: Make docs - run: sphinx-build -M html docs/source docs/build + run: sphinx-build -M html docs/source docs/build --fail-on-warning From 25e31df596cd66223eec94923aadecf75eab8b64 Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:43:05 +0900 Subject: [PATCH 7/9] :wrench: Update rtd config --- .readthedocs.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index e4481b896..eb1aa776a 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -6,15 +6,17 @@ version: 2 build: - os: ubuntu-20.04 + os: ubuntu-22.04 tools: - python: "3.10" + python: "3.12" sphinx: configuration: docs/source/conf.py python: install: - - requirements: docs/requirements.txt + - requirements: requirements.txt + - requirements: requirements-extra.txt + - requirements: requirements-doc.txt - method: pip path: . From fdfa77527f884f72f6ef6ad7c28d89b11e36fd18 Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:46:06 +0900 Subject: [PATCH 8/9] :bug: Fix CI fail --- docs/source/conf.py | 1 - requirements-doc.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 7e49705eb..0b8d0f19b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -23,7 +23,6 @@ "sphinx.ext.autosectionlabel", "sphinx.ext.napoleon", "sphinx_gallery.gen_gallery", - "sphinxawesome_theme.highlighting", ] templates_path = ["_templates"] diff --git a/requirements-doc.txt b/requirements-doc.txt index 17c5c3a11..394a2341c 100644 --- a/requirements-doc.txt +++ b/requirements-doc.txt @@ -3,6 +3,5 @@ ipython matplotlib scikit-learn seaborn -sphinxawesome-theme sphinx-gallery sphinx>=5.0 From c5a3a5432194fafadc47e202f6386fc76b59cb1c Mon Sep 17 00:00:00 2001 From: SS <66886825+EarlMilktea@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:55:56 +0900 Subject: [PATCH 9/9] :construction_worker: Update noxfile --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 508ba024f..6f32db51f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -17,5 +17,5 @@ def tests_minimal(session: Session) -> None: @nox.session(python=["3.8", "3.9", "3.10", "3.11", "3.12"]) def tests(session: Session) -> None: """Run the test suite with full dependencies.""" - session.install("-e", ".[dev]") + session.install("-e", ".[extra]") session.run("pytest")