diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0297b3a..3767349 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ name: pytest on: pull_request: branches: [ "master" ] + schedule: + # Every Monday at 0AM UTC + - cron: "0 0 * * 1" permissions: contents: read diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..a807275 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,20 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +build: + os: ubuntu-20.04 + tools: + python: "3.9" + +sphinx: + configuration: docs/source/conf.py + +python: + install: + - requirements: docs/requirements.txt + - method: pip + path: . \ No newline at end of file diff --git a/README.md b/README.md index 48b87c1..d7c683c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Graphix Perceval interface - +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/graphix-perceval) Provides an interface to run MBQC pattern (`graphix.Pattern`) on Quandela's optical quantum devices as well as Perceval's simulator backends. @@ -22,4 +22,4 @@ install with `pip` ## License -[Apache License 2.0](LICENSE) +[Apache License 2.0](LICENSE) \ No newline at end of file diff --git a/docs/logo/black_with_name.png b/docs/logo/black_with_name.png new file mode 100644 index 0000000..04d5bfd Binary files /dev/null and b/docs/logo/black_with_name.png differ diff --git a/docs/logo/black_with_text.png b/docs/logo/black_with_text.png new file mode 100644 index 0000000..af32b3c Binary files /dev/null and b/docs/logo/black_with_text.png differ diff --git a/docs/logo/graphix-logo.pptx b/docs/logo/graphix-logo.pptx new file mode 100644 index 0000000..85b7779 Binary files /dev/null and b/docs/logo/graphix-logo.pptx differ diff --git a/docs/logo/white.png b/docs/logo/white.png new file mode 100644 index 0000000..dd36995 Binary files /dev/null and b/docs/logo/white.png differ diff --git a/docs/logo/white_with_text.png b/docs/logo/white_with_text.png new file mode 100644 index 0000000..5469371 Binary files /dev/null and b/docs/logo/white_with_text.png differ diff --git a/docs/source/_static/img/ghz_circuit.svg b/docs/source/_static/img/ghz_circuit.svg new file mode 100644 index 0000000..f055d95 --- /dev/null +++ b/docs/source/_static/img/ghz_circuit.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + +GHZ + + + + + + + + + + + + + + +LOCALCLIFFORDID:6 + + +LOCALCLIFFORDID:6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0 +1 +2 +3 +4 +5 +0 +1 +2 +3 +4 +5 + \ No newline at end of file diff --git a/docs/source/_static/img/ghz_pattern.png b/docs/source/_static/img/ghz_pattern.png new file mode 100644 index 0000000..4715a96 Binary files /dev/null and b/docs/source/_static/img/ghz_pattern.png differ diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..1dfec95 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,62 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html +import os +import sys + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "graphix-perceval" +copyright = "2023, Team Graphix" +author = "Kazuki Tsuoka, Shinichi Sunami" +release = "0.0.1" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.viewcode", + "sphinx.ext.autosummary", + "sphinx.ext.autosectionlabel", + "sphinx.ext.napoleon", + "sphinx_gallery.gen_gallery", +] + +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +autosectionlabel_prefix_document = True + + +sys.path.insert(0, os.path.abspath("../..")) + + +def skip(app, what, name, obj, would_skip, options): + if name == "__init__": + return False + return would_skip + + +def setup(app): + app.connect("autodoc-skip-member", skip) + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + + +html_theme = "sphinx_rtd_theme" +html_static_path = ["_static"] +html_logo = "../logo/white_with_text.png" +html_theme_options = { + "logo_only": True, + "display_version": False, +} + +sphinx_gallery_conf = { + "examples_dirs": "../../examples", # path to your example scripts + "gallery_dirs": "gallery", # path to where to save gallery generated output + "filename_pattern": "/", +} diff --git a/docs/source/converter.rst b/docs/source/converter.rst new file mode 100644 index 0000000..89a63f4 --- /dev/null +++ b/docs/source/converter.rst @@ -0,0 +1,11 @@ +Pattern converter +================== + +:mod:`graphix_perceval.converter` module ++++++++++++++++++++++++++++++++++++++++++ + +.. automodule:: graphix_perceval.converter + :members: + +.. autoclass:: PercevalCircuitConstructor + :members: diff --git a/docs/source/experiment.rst b/docs/source/experiment.rst new file mode 100644 index 0000000..9897c79 --- /dev/null +++ b/docs/source/experiment.rst @@ -0,0 +1,16 @@ +Device interface +================ + +:mod:`graphix_perceval.experiment` module ++++++++++++++++++++++++++++++++++++++++++ + +.. automodule:: graphix_perceval.experiment + +.. autoclass:: PercevalExperiment + :members: + +.. autoclass:: PhotonCount + :members: + +.. autoclass:: PhotonDistribution + :members: diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..dc19856 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,13 @@ +.. graphix-perceval documentation master file, created by + sphinx-quickstart on Mon Oct 16 05:34:14 2023. + +Graphix-perceval - executing MBQC patterns on Perceval devices +============================================================== + +.. toctree:: + :maxdepth: 1 + :caption: Documentation + + tutorial + gallery/index + reference diff --git a/docs/source/reference.rst b/docs/source/reference.rst new file mode 100644 index 0000000..26191fb --- /dev/null +++ b/docs/source/reference.rst @@ -0,0 +1,8 @@ +Module reference +================ + +.. toctree:: + :maxdepth: 2 + + converter + experiment diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst new file mode 100644 index 0000000..66b600b --- /dev/null +++ b/docs/source/tutorial.rst @@ -0,0 +1,135 @@ +Tutorial +======== + +In this tutorial, we will learn how to use the `graphix-perceval` library to convert +`graphix.Pattern `_ +objects into `perceval.Circuit `_ objects. + +Installation +------------ + +First, we need to install the `graphix-perceval` library. This can be done using `pip`: + +.. code-block:: bash + + pip install graphix-perceval + +If you have not installed `graphix` yet, you can install it using `pip` as well: + +.. code-block:: bash + + pip install graphix + +Generating MBQC Pattern +----------------------- + +We first generate a MBQC pattern using ``graphix`` library. +We create GHZ state as an example. + +First, let us import relevant modules and define function we will use: + +.. code-block:: python + + from graphix import Circuit + import numpy as np + import matplotlib.pyplot as plt + import networkx as nx + + + # define the functions required for GHZ state generation + def ghz(circuit: Circuit): + """generate GHZ circuit""" + circuit.h(1) + circuit.h(2) + circuit.cnot(0, 1) + circuit.cnot(0, 2) + +Then we define a circuit to create GHZ state. + +.. code-block:: python + + # generate the GHZ state generation pattern + circuit = Circuit(3) + ghz(circuit) + pattern = circuit.transpile() + + # plot the pattern + nodes, edges = pattern.get_graph() + g = nx.Graph() + g.add_nodes_from(nodes) + g.add_edges_from(edges) + np.random.seed(100) + nx.draw(g) + plt.show() + + +.. figure:: ./_static/img/ghz_pattern.png + :scale: 85 % + :alt: 2-qubit GHZ pattern visualization + +Pattern-to-circuit conversion +----------------------------- + +Now let us convert the pattern into a circuit using the `graphix-perceval` library: + +.. code-block:: python + + from graphix_perceval import to_perceval + from perceval import pdisplay + + exp = to_perceval(pattern) + pdisplay(exp.circ) + +.. figure:: ./_static/img/ghz_circuit.svg + :scale: 85 % + :alt: 2-qubit GHZ circuit visualization + +Running pattern on Perceval simulator +------------------------------------- + +By running the Perceval's computing backends, We can obtain the probability distribution of the measurement outcomes + +.. code-block:: python + + exp.set_local_processor("SLOS") + dist = exp.get_probability_distribution() + dist.draw() + +.. raw:: html + + + + + + + + + +
state probability
|000> 0.5
|111> 0.5
+
+ +or sampling distribution with a given number of samples: + +.. code-block:: python + + exp.set_local_processor("SLOS") + dist = exp.sample(num_samples=1000) + dist.draw() + +.. raw:: html + + + + + + + + + +
state counts
|000> 499
|111> 501
+
+ +.. note:: + Note that the current implementation only supports ``SLOS`` and ``Naive`` as local Perceval processors. + See `Perceval documentation `_ for more details. + diff --git a/examples/readme.rst b/examples/readme.rst new file mode 100644 index 0000000..1076f50 --- /dev/null +++ b/examples/readme.rst @@ -0,0 +1,4 @@ +Graphix-perceval examples +========================= + +Here are examples of pattern-to-circuit conversion and simulation using Perceval simulator. diff --git a/graphix_perceval/converter.py b/graphix_perceval/converter.py index 098a575..214dc16 100644 --- a/graphix_perceval/converter.py +++ b/graphix_perceval/converter.py @@ -61,7 +61,7 @@ def to_perceval(pattern: graphix.Pattern) -> PercevalExperiment: pcc = PercevalCircuitConstructor() for ResourceGraph in ResourceGraphs: - pcc.add_ResourceGraph(ResourceGraph, phasedict, output_nodes) + pcc.add_resourcegraph(ResourceGraph, phasedict, output_nodes) pcc.add_fusions() @@ -85,7 +85,7 @@ def __init__(self): self._is_fused: bool = False self._clifford_applied: bool = False - def add_ResourceGraph(self, ResourceGraph: ResourceGraph, phasedict: dict[int, float], readouts: list) -> None: + def add_resourcegraph(self, ResourceGraph: ResourceGraph, phasedict: dict[int, float], readouts: list) -> None: if self._is_fused: raise RuntimeError("Cannot add ResourceGraph after fusion") for node_id in ResourceGraph.graph.nodes: @@ -132,7 +132,7 @@ def add_fusions(self) -> None: self._is_fused = True - def get_all_ResourceGraphs(self) -> list[ResourceGraph]: + def get_all_resourcegraphs(self) -> list[ResourceGraph]: return self.ghz_ResourceGraphs | self.linear_ResourceGraphs def setup_perceval_circuit(self, name: str | None = None, merge: bool = False) -> pcvl.Circuit: diff --git a/graphix_perceval/experiment.py b/graphix_perceval/experiment.py index 873212a..4d070e6 100644 --- a/graphix_perceval/experiment.py +++ b/graphix_perceval/experiment.py @@ -65,8 +65,10 @@ def __init__(self, circuit: pcvl.Circuit, photons: list[Photon]): Parameters ---------- - pattern: :class:`graphix.Pattern` object - MBQC pattern to be run on the Quandela device or Perceval simulator. + circuit : :class:`perceval.Circuit` object + Perceval circuit corresponding to the pattern. + photons : list[:class:`Photon` object] + List of photons. """ self.circ = circuit self.photons = photons @@ -75,7 +77,7 @@ def __init__(self, circuit: pcvl.Circuit, photons: list[Photon]): self.output_states: dict[str, str] | None = None def set_local_processor(self, backend: str, source: pcvl.Source = pcvl.Source(), name: str = None): - """Set the local computing backend. + r"""Set the local computing backend. Parameters ---------- @@ -98,7 +100,7 @@ def set_local_processor(self, backend: str, source: pcvl.Source = pcvl.Source(), self.set_output_states() def set_remote_processor(self, backend: str, token: str): - """Set the remote computing backend. + r"""Set the remote computing backend. Parameters ---------- @@ -120,8 +122,8 @@ def set_remote_processor(self, backend: str, token: str): self.set_output_states() def set_input_state(self): - """Set the input states for the processor. - The default input state is |{P:H}> for each photon and |0> for each ancillary mode. + r"""Set the input states for the processor. + The default input state is ``|{P:H}>`` for each photon and ``|0>`` for each ancillary mode. """ if self.processor is None: raise Exception( @@ -141,9 +143,9 @@ def set_output_states(self): Currently, Perceval does not support feed-forward opetations, so we postselect the output states where - - The witness photons are in |{P:H}> and translated to |0,1> - - The computing photons are in |{P:H}> and translated to |0,1> - - The readout photons are in |{P:H}> or |{P:V}> + - The witness photons are in ``|{P:H}>`` and translated to ``|0,1>`` + - The computing photons are in ``|{P:H}>`` and translated to ``|0,1>`` + - The readout photons are in ``|{P:H}>`` or ``|{P:V}>`` """ if self.processor is None: raise Exception( @@ -171,7 +173,9 @@ def set_output_states(self): x = x + 1 self.output_states = out_states - def get_probability_distribution(self, format_result=True, postselection=True) -> PhotonDistribution: + def get_probability_distribution( + self, format_result: bool = True, postselection: bool = True + ) -> PhotonDistribution: r"""Get the probability distribution of the measurement results. Parameters @@ -201,7 +205,7 @@ def get_probability_distribution(self, format_result=True, postselection=True) - return probs - def sample(self, num_samples=1024, format_result=True, postselection=True) -> PhotonCount: + def sample(self, num_samples=1024, format_result: bool = True, postselection: bool = True) -> PhotonCount: """Run the MBQC pattern on IBMQ devices Parameters @@ -286,6 +290,7 @@ def items(self) -> dict_items: def draw(self, sort: bool = True): """Draw the counts result in a table. + If the code is run in a Jupyter notebook, the table will be displayed in HTML format. If the code is run in a terminal, the table will be displayed in ASCII format. diff --git a/readme.md b/readme.md deleted file mode 100644 index 48b87c1..0000000 --- a/readme.md +++ /dev/null @@ -1,25 +0,0 @@ -# Graphix Perceval interface - - -Provides an interface to run MBQC pattern (`graphix.Pattern`) on Quandela's optical quantum devices as well as Perceval's simulator backends. - -Requires [graphix](https://github.com/TeamGraphix/graphix) to generate the measurement pattern. - -## Installation - -install with `pip` - -```bash - $ pip install graphix-perceval -``` - - - -## License - -[Apache License 2.0](LICENSE) diff --git a/tests/test_converter.py b/tests/test_converter.py index 3847507..dbd16b6 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -20,7 +20,7 @@ def test_sampling_circuit_wo_postselection(self): exp.set_local_processor("SLOS") dist = exp.sample(num_samples=1000, format_result=False, postselection=False) counts = 0 - for k, v in dist.items(): + for _, v in dist.items(): counts += v self.assertEqual(counts, 1000) diff --git a/tox.ini b/tox.ini index eae2186..cccfb8f 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ description = Run the unit tests deps = -r {toxinidir}/requirements.txt commands = - pip install --upgrade pip + python -m pip install --upgrade pip pip install pytest pytest {toxinidir} extras = test