From b53293cf1c4ea280aa9986e9e3d9287a04b84105 Mon Sep 17 00:00:00 2001 From: Anurudh Peduri Date: Sat, 25 Jan 2025 23:18:20 +0100 Subject: [PATCH 1/5] clean --- qualtran/simulation/tensor/_quimb.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qualtran/simulation/tensor/_quimb.py b/qualtran/simulation/tensor/_quimb.py index d4957e4778..c626b389c0 100644 --- a/qualtran/simulation/tensor/_quimb.py +++ b/qualtran/simulation/tensor/_quimb.py @@ -69,11 +69,8 @@ def cbloq_to_quimb(cbloq: CompositeBloq) -> qtn.TensorNetwork: # the tensor network. Add an identity tensor acting on this register to make sure the # tensor network has variables corresponding to all input / output registers. - n = cxn.left.reg.bitsize for j in range(cxn.left.reg.bitsize): - placeholder = Soquet(None, Register('simulation_placeholder', QBit())) # type: ignore - Connection(cxn.left, placeholder) tn.add( qtn.Tensor( data=np.eye(2), From 36c7b8e38d62846fe7fb02a3bc80f7187583d15b Mon Sep 17 00:00:00 2001 From: Anurudh Peduri Date: Fri, 7 Feb 2025 22:31:41 +0100 Subject: [PATCH 2/5] add `pyzx` dependency --- dev_tools/requirements/deps/runtime.txt | 3 + dev_tools/requirements/envs/dev.env.txt | 66 ++++++++++++--------- dev_tools/requirements/envs/docs.env.txt | 66 +++++++++++++-------- dev_tools/requirements/envs/format.env.txt | 62 ++++++++++++------- dev_tools/requirements/envs/pylint.env.txt | 64 +++++++++++++------- dev_tools/requirements/envs/pytest.env.txt | 64 +++++++++++++------- dev_tools/requirements/envs/runtime.env.txt | 62 ++++++++++++------- 7 files changed, 246 insertions(+), 141 deletions(-) diff --git a/dev_tools/requirements/deps/runtime.txt b/dev_tools/requirements/deps/runtime.txt index 43bd16aa40..810be55e8d 100644 --- a/dev_tools/requirements/deps/runtime.txt +++ b/dev_tools/requirements/deps/runtime.txt @@ -34,6 +34,9 @@ qsharp-widgets qref==0.9.0 bartiq==0.9.0 +# pyzx interop +pyzx + # serialization protobuf diff --git a/dev_tools/requirements/envs/dev.env.txt b/dev_tools/requirements/envs/dev.env.txt index d3f4f8efb1..b7f7e58790 100644 --- a/dev_tools/requirements/envs/dev.env.txt +++ b/dev_tools/requirements/envs/dev.env.txt @@ -36,7 +36,7 @@ asttokens==3.0.0 # via stack-data async-lru==2.0.4 # via jupyterlab -attrs==24.3.0 +attrs==25.1.0 # via # -r deps/runtime.txt # cirq-core @@ -47,7 +47,7 @@ autoray==0.7.0 # via # cotengra # quimb -babel==2.16.0 +babel==2.17.0 # via # jupyterlab-server # pydata-sphinx-theme @@ -56,7 +56,7 @@ backports-tarfile==1.2.0 # via jaraco-context bartiq==0.9.0 # via -r deps/runtime.txt -beautifulsoup4==4.12.3 +beautifulsoup4==4.13.3 # via # nbconvert # pydata-sphinx-theme @@ -70,7 +70,7 @@ build==1.2.2.post1 # via pip-tools cachetools==5.5.1 # via -r deps/runtime.txt -certifi==2024.12.14 +certifi==2025.1.31 # via # httpcore # httpx @@ -155,7 +155,7 @@ flask==3.0.3 # via dash flynt==0.78 # via -r deps/format.txt -fonttools==4.55.4 +fonttools==4.56.0 # via matplotlib fqdn==1.5.1 # via jsonschema @@ -167,9 +167,9 @@ graphviz==0.20.3 # via qref greenlet==3.1.1 # via sqlalchemy -grpcio==1.69.0 +grpcio==1.70.0 # via grpcio-tools -grpcio-tools==1.69.0 +grpcio-tools==1.70.0 # via -r deps/packaging.txt h11==0.14.0 # via httpcore @@ -204,7 +204,7 @@ ipykernel==6.29.5 # -r deps/pytest.txt # jupyterlab # myst-nb -ipython==8.31.0 +ipython==8.32.0 # via # -r deps/runtime.txt # ipykernel @@ -215,6 +215,7 @@ ipywidgets==8.1.5 # -r deps/docs.txt # -r deps/runtime.txt # anywidget + # pyzx isoduration==20.11.0 # via jsonschema isort==5.10.1 @@ -278,7 +279,7 @@ jupyter-core==5.7.2 # nbclient # nbconvert # nbformat -jupyter-events==0.11.0 +jupyter-events==0.12.0 # via jupyter-server jupyter-lsp==2.2.5 # via jupyterlab @@ -291,7 +292,7 @@ jupyter-server==2.15.0 # notebook-shim jupyter-server-terminals==0.5.3 # via jupyter-server -jupyterlab==4.3.4 +jupyterlab==4.3.5 # via notebook jupyterlab-pygments==0.3.0 # via nbconvert @@ -305,6 +306,8 @@ keyring==25.6.0 # via twine kiwisolver==1.4.8 # via matplotlib +lark==1.2.2 + # via pyzx llvmlite==0.44.0 # via numba markdown-it-py==3.0.0 @@ -332,7 +335,7 @@ mdit-py-plugins==0.4.2 # via myst-parser mdurl==0.1.2 # via markdown-it-py -mistune==3.1.0 +mistune==3.1.1 # via nbconvert ml-dtypes==0.5.1 # via @@ -344,7 +347,7 @@ more-itertools==10.6.0 # jaraco-functools mpmath==1.3.0 # via sympy -mypy==1.14.1 +mypy==1.15.0 # via -r deps/mypy.txt mypy-extensions==1.0.0 # via @@ -352,16 +355,18 @@ mypy-extensions==1.0.0 # mypy mypy-protobuf==3.6.0 # via -r deps/mypy.txt -myst-nb==1.1.2 +myst-nb==1.2.0 # via -r deps/docs.txt myst-parser==4.0.0 # via myst-nb +narwhals==1.25.2 + # via plotly nbclient==0.10.2 # via # jupyter-cache # myst-nb # nbconvert -nbconvert==7.16.5 +nbconvert==7.16.6 # via # -r deps/docs.txt # -r deps/runtime.txt @@ -416,6 +421,7 @@ numpy==1.26.4 # openfermion # pandas # pyscf + # pyzx # quimb # scipy openfermion[resources]==1.6.1 @@ -432,6 +438,7 @@ packaging==24.2 # build # deprecation # ipykernel + # jupyter-events # jupyter-server # jupyterlab # jupyterlab-server @@ -461,7 +468,7 @@ platformdirs==4.3.6 # jupyter-core # pylint # virtualenv -plotly==5.24.1 +plotly==6.0.0 # via # -r deps/runtime.txt # dash @@ -481,7 +488,7 @@ psutil==6.1.1 # via # ipykernel # quimb -psygnal==0.11.1 +psygnal==0.12.0 # via anywidget ptyprocess==0.7.0 # via @@ -493,7 +500,7 @@ pure-eval==0.2.3 # via stack-data pycparser==2.22 # via cffi -pydantic==2.10.5 +pydantic==2.10.6 # via # bartiq # qref @@ -512,13 +519,15 @@ pygments==2.19.1 # readme-renderer # rich # sphinx -pylint==3.3.3 +pylint==3.3.4 # via -r deps/pylint.txt pyparsing==3.1.4 # via # bartiq # matplotlib # pydot +pyperclip==1.9.0 + # via pyzx pyproject-hooks==1.2.0 # via # build @@ -532,7 +541,7 @@ pytest==8.3.4 # pytest-asyncio # pytest-cov # pytest-xdist -pytest-asyncio==0.25.2 +pytest-asyncio==0.25.3 # via -r deps/pytest.txt pytest-cov==6.0.0 # via -r deps/pytest.txt @@ -546,7 +555,7 @@ python-dateutil==2.9.0.post0 # pandas python-json-logger==3.2.1 # via jupyter-events -pytz==2024.2 +pytz==2025.1 # via pandas pyyaml==6.0.2 # via @@ -555,24 +564,26 @@ pyyaml==6.0.2 # myst-nb # myst-parser # tensorflow-docs -pyzmq==26.2.0 +pyzmq==26.2.1 # via # ipykernel # jupyter-client # jupyter-server +pyzx==0.9.0 + # via -r deps/runtime.txt qref==0.9.0 # via # -r deps/runtime.txt # bartiq -qsharp==1.12.1 +qsharp==1.13.2 # via -r deps/runtime.txt -qsharp-widgets==1.12.1 +qsharp-widgets==1.13.2 # via -r deps/runtime.txt quimb==1.10.0 # via -r deps/runtime.txt readme-renderer==44.0 # via twine -referencing==0.36.1 +referencing==0.36.2 # via # jsonschema # jsonschema-specifications @@ -651,7 +662,7 @@ sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx -sqlalchemy==2.0.37 +sqlalchemy==2.0.38 # via jupyter-cache stack-data==0.6.3 # via ipython @@ -664,8 +675,6 @@ sympy==1.12.1 # openfermion tabulate==0.9.0 # via jupyter-cache -tenacity==9.0.0 - # via plotly tensorflow-docs==2023.5.24.56664 # via # -r deps/docs.txt @@ -703,6 +712,7 @@ tornado==6.4.2 tqdm==4.67.1 # via # cirq-core + # pyzx # quimb traitlets==5.14.3 # via @@ -732,6 +742,7 @@ typing-extensions==4.12.2 # anywidget # astroid # async-lru + # beautifulsoup4 # black # cirq-core # dash @@ -743,6 +754,7 @@ typing-extensions==4.12.2 # pydantic # pydantic-core # pydata-sphinx-theme + # pyzx # referencing # rich # sqlalchemy diff --git a/dev_tools/requirements/envs/docs.env.txt b/dev_tools/requirements/envs/docs.env.txt index fc77866bc1..df8008c787 100644 --- a/dev_tools/requirements/envs/docs.env.txt +++ b/dev_tools/requirements/envs/docs.env.txt @@ -53,7 +53,7 @@ async-lru==2.0.4 # via # -c envs/dev.env.txt # jupyterlab -attrs==24.3.0 +attrs==25.1.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -66,7 +66,7 @@ autoray==0.7.0 # -c envs/dev.env.txt # cotengra # quimb -babel==2.16.0 +babel==2.17.0 # via # -c envs/dev.env.txt # jupyterlab-server @@ -76,7 +76,7 @@ bartiq==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -beautifulsoup4==4.12.3 +beautifulsoup4==4.13.3 # via # -c envs/dev.env.txt # nbconvert @@ -93,7 +93,7 @@ cachetools==5.5.1 # via # -c envs/dev.env.txt # -r deps/runtime.txt -certifi==2024.12.14 +certifi==2025.1.31 # via # -c envs/dev.env.txt # httpcore @@ -192,7 +192,7 @@ flask==3.0.3 # via # -c envs/dev.env.txt # dash -fonttools==4.55.4 +fonttools==4.56.0 # via # -c envs/dev.env.txt # matplotlib @@ -250,7 +250,7 @@ ipykernel==6.29.5 # -c envs/dev.env.txt # jupyterlab # myst-nb -ipython==8.31.0 +ipython==8.32.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -263,6 +263,7 @@ ipywidgets==8.1.5 # -r deps/docs.txt # -r deps/runtime.txt # anywidget + # pyzx isoduration==20.11.0 # via # -c envs/dev.env.txt @@ -324,7 +325,7 @@ jupyter-core==5.7.2 # nbclient # nbconvert # nbformat -jupyter-events==0.11.0 +jupyter-events==0.12.0 # via # -c envs/dev.env.txt # jupyter-server @@ -344,7 +345,7 @@ jupyter-server-terminals==0.5.3 # via # -c envs/dev.env.txt # jupyter-server -jupyterlab==4.3.4 +jupyterlab==4.3.5 # via # -c envs/dev.env.txt # notebook @@ -365,6 +366,10 @@ kiwisolver==1.4.8 # via # -c envs/dev.env.txt # matplotlib +lark==1.2.2 + # via + # -c envs/dev.env.txt + # pyzx llvmlite==0.44.0 # via # -c envs/dev.env.txt @@ -398,7 +403,7 @@ mdurl==0.1.2 # via # -c envs/dev.env.txt # markdown-it-py -mistune==3.1.0 +mistune==3.1.1 # via # -c envs/dev.env.txt # nbconvert @@ -406,7 +411,7 @@ mpmath==1.3.0 # via # -c envs/dev.env.txt # sympy -myst-nb==1.1.2 +myst-nb==1.2.0 # via # -c envs/dev.env.txt # -r deps/docs.txt @@ -414,13 +419,17 @@ myst-parser==4.0.0 # via # -c envs/dev.env.txt # myst-nb +narwhals==1.25.2 + # via + # -c envs/dev.env.txt + # plotly nbclient==0.10.2 # via # -c envs/dev.env.txt # jupyter-cache # myst-nb # nbconvert -nbconvert==7.16.5 +nbconvert==7.16.6 # via # -c envs/dev.env.txt # -r deps/docs.txt @@ -472,6 +481,7 @@ numpy==1.26.4 # matplotlib # numba # pandas + # pyzx # quimb # scipy overrides==7.7.0 @@ -482,6 +492,7 @@ packaging==24.2 # via # -c envs/dev.env.txt # ipykernel + # jupyter-events # jupyter-server # jupyterlab # jupyterlab-server @@ -513,7 +524,7 @@ platformdirs==4.3.6 # via # -c envs/dev.env.txt # jupyter-core -plotly==5.24.1 +plotly==6.0.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -536,7 +547,7 @@ psutil==6.1.1 # -c envs/dev.env.txt # ipykernel # quimb -psygnal==0.11.1 +psygnal==0.12.0 # via # -c envs/dev.env.txt # anywidget @@ -553,7 +564,7 @@ pycparser==2.22 # via # -c envs/dev.env.txt # cffi -pydantic==2.10.5 +pydantic==2.10.6 # via # -c envs/dev.env.txt # bartiq @@ -584,6 +595,10 @@ pyparsing==3.1.4 # bartiq # matplotlib # pydot +pyperclip==1.9.0 + # via + # -c envs/dev.env.txt + # pyzx python-dateutil==2.9.0.post0 # via # -c envs/dev.env.txt @@ -595,7 +610,7 @@ python-json-logger==3.2.1 # via # -c envs/dev.env.txt # jupyter-events -pytz==2024.2 +pytz==2025.1 # via # -c envs/dev.env.txt # pandas @@ -607,22 +622,26 @@ pyyaml==6.0.2 # myst-nb # myst-parser # tensorflow-docs -pyzmq==26.2.0 +pyzmq==26.2.1 # via # -c envs/dev.env.txt # ipykernel # jupyter-client # jupyter-server +pyzx==0.9.0 + # via + # -c envs/dev.env.txt + # -r deps/runtime.txt qref==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt # bartiq -qsharp==1.12.1 +qsharp==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt -qsharp-widgets==1.12.1 +qsharp-widgets==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -630,7 +649,7 @@ quimb==1.10.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -referencing==0.36.1 +referencing==0.36.2 # via # -c envs/dev.env.txt # jsonschema @@ -723,7 +742,7 @@ sphinxcontrib-serializinghtml==2.0.0 # via # -c envs/dev.env.txt # sphinx -sqlalchemy==2.0.37 +sqlalchemy==2.0.38 # via # -c envs/dev.env.txt # jupyter-cache @@ -741,10 +760,6 @@ tabulate==0.9.0 # via # -c envs/dev.env.txt # jupyter-cache -tenacity==9.0.0 - # via - # -c envs/dev.env.txt - # plotly tensorflow-docs==2023.5.24.56664 # via # -c envs/dev.env.txt @@ -780,6 +795,7 @@ tqdm==4.67.1 # via # -c envs/dev.env.txt # cirq-core + # pyzx # quimb traitlets==5.14.3 # via @@ -808,6 +824,7 @@ typing-extensions==4.12.2 # anyio # anywidget # async-lru + # beautifulsoup4 # cirq-core # dash # galois @@ -817,6 +834,7 @@ typing-extensions==4.12.2 # pydantic # pydantic-core # pydata-sphinx-theme + # pyzx # referencing # sqlalchemy tzdata==2025.1 diff --git a/dev_tools/requirements/envs/format.env.txt b/dev_tools/requirements/envs/format.env.txt index 55bfdaacfa..44a10b8f48 100644 --- a/dev_tools/requirements/envs/format.env.txt +++ b/dev_tools/requirements/envs/format.env.txt @@ -41,7 +41,7 @@ async-lru==2.0.4 # via # -c envs/dev.env.txt # jupyterlab -attrs==24.3.0 +attrs==25.1.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -53,7 +53,7 @@ autoray==0.7.0 # -c envs/dev.env.txt # cotengra # quimb -babel==2.16.0 +babel==2.17.0 # via # -c envs/dev.env.txt # jupyterlab-server @@ -61,7 +61,7 @@ bartiq==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -beautifulsoup4==4.12.3 +beautifulsoup4==4.13.3 # via # -c envs/dev.env.txt # nbconvert @@ -81,7 +81,7 @@ cachetools==5.5.1 # via # -c envs/dev.env.txt # -r deps/runtime.txt -certifi==2024.12.14 +certifi==2025.1.31 # via # -c envs/dev.env.txt # httpcore @@ -178,7 +178,7 @@ flynt==0.78 # via # -c envs/dev.env.txt # -r deps/format.txt -fonttools==4.55.4 +fonttools==4.56.0 # via # -c envs/dev.env.txt # matplotlib @@ -225,7 +225,7 @@ ipykernel==6.29.5 # via # -c envs/dev.env.txt # jupyterlab -ipython==8.31.0 +ipython==8.32.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -236,6 +236,7 @@ ipywidgets==8.1.5 # -c envs/dev.env.txt # -r deps/runtime.txt # anywidget + # pyzx isoduration==20.11.0 # via # -c envs/dev.env.txt @@ -294,7 +295,7 @@ jupyter-core==5.7.2 # nbclient # nbconvert # nbformat -jupyter-events==0.11.0 +jupyter-events==0.12.0 # via # -c envs/dev.env.txt # jupyter-server @@ -314,7 +315,7 @@ jupyter-server-terminals==0.5.3 # via # -c envs/dev.env.txt # jupyter-server -jupyterlab==4.3.4 +jupyterlab==4.3.5 # via # -c envs/dev.env.txt # notebook @@ -335,6 +336,10 @@ kiwisolver==1.4.8 # via # -c envs/dev.env.txt # matplotlib +lark==1.2.2 + # via + # -c envs/dev.env.txt + # pyzx llvmlite==0.44.0 # via # -c envs/dev.env.txt @@ -355,7 +360,7 @@ matplotlib-inline==0.1.7 # -c envs/dev.env.txt # ipykernel # ipython -mistune==3.1.0 +mistune==3.1.1 # via # -c envs/dev.env.txt # nbconvert @@ -367,11 +372,15 @@ mypy-extensions==1.0.0 # via # -c envs/dev.env.txt # black +narwhals==1.25.2 + # via + # -c envs/dev.env.txt + # plotly nbclient==0.10.2 # via # -c envs/dev.env.txt # nbconvert -nbconvert==7.16.5 +nbconvert==7.16.6 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -418,6 +427,7 @@ numpy==1.26.4 # matplotlib # numba # pandas + # pyzx # quimb # scipy overrides==7.7.0 @@ -429,6 +439,7 @@ packaging==24.2 # -c envs/dev.env.txt # black # ipykernel + # jupyter-events # jupyter-server # jupyterlab # jupyterlab-server @@ -464,7 +475,7 @@ platformdirs==4.3.6 # -c envs/dev.env.txt # black # jupyter-core -plotly==5.24.1 +plotly==6.0.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -486,7 +497,7 @@ psutil==6.1.1 # -c envs/dev.env.txt # ipykernel # quimb -psygnal==0.11.1 +psygnal==0.12.0 # via # -c envs/dev.env.txt # anywidget @@ -503,7 +514,7 @@ pycparser==2.22 # via # -c envs/dev.env.txt # cffi -pydantic==2.10.5 +pydantic==2.10.6 # via # -c envs/dev.env.txt # bartiq @@ -527,6 +538,10 @@ pyparsing==3.1.4 # bartiq # matplotlib # pydot +pyperclip==1.9.0 + # via + # -c envs/dev.env.txt + # pyzx python-dateutil==2.9.0.post0 # via # -c envs/dev.env.txt @@ -538,7 +553,7 @@ python-json-logger==3.2.1 # via # -c envs/dev.env.txt # jupyter-events -pytz==2024.2 +pytz==2025.1 # via # -c envs/dev.env.txt # pandas @@ -546,22 +561,26 @@ pyyaml==6.0.2 # via # -c envs/dev.env.txt # jupyter-events -pyzmq==26.2.0 +pyzmq==26.2.1 # via # -c envs/dev.env.txt # ipykernel # jupyter-client # jupyter-server +pyzx==0.9.0 + # via + # -c envs/dev.env.txt + # -r deps/runtime.txt qref==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt # bartiq -qsharp==1.12.1 +qsharp==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt -qsharp-widgets==1.12.1 +qsharp-widgets==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -569,7 +588,7 @@ quimb==1.10.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -referencing==0.36.1 +referencing==0.36.2 # via # -c envs/dev.env.txt # jsonschema @@ -636,10 +655,6 @@ sympy==1.12.1 # -r deps/runtime.txt # bartiq # cirq-core -tenacity==9.0.0 - # via - # -c envs/dev.env.txt - # plotly terminado==0.18.1 # via # -c envs/dev.env.txt @@ -672,6 +687,7 @@ tqdm==4.67.1 # via # -c envs/dev.env.txt # cirq-core + # pyzx # quimb traitlets==5.14.3 # via @@ -700,6 +716,7 @@ typing-extensions==4.12.2 # anyio # anywidget # async-lru + # beautifulsoup4 # black # cirq-core # dash @@ -708,6 +725,7 @@ typing-extensions==4.12.2 # mistune # pydantic # pydantic-core + # pyzx # referencing tzdata==2025.1 # via diff --git a/dev_tools/requirements/envs/pylint.env.txt b/dev_tools/requirements/envs/pylint.env.txt index baea6183ac..dd89ad53e7 100644 --- a/dev_tools/requirements/envs/pylint.env.txt +++ b/dev_tools/requirements/envs/pylint.env.txt @@ -57,7 +57,7 @@ async-lru==2.0.4 # via # -c envs/dev.env.txt # jupyterlab -attrs==24.3.0 +attrs==25.1.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -69,7 +69,7 @@ autoray==0.7.0 # -c envs/dev.env.txt # cotengra # quimb -babel==2.16.0 +babel==2.17.0 # via # -c envs/dev.env.txt # jupyterlab-server @@ -78,7 +78,7 @@ bartiq==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -beautifulsoup4==4.12.3 +beautifulsoup4==4.13.3 # via # -c envs/dev.env.txt # nbconvert @@ -94,7 +94,7 @@ cachetools==5.5.1 # via # -c envs/dev.env.txt # -r deps/runtime.txt -certifi==2024.12.14 +certifi==2025.1.31 # via # -c envs/dev.env.txt # httpcore @@ -204,7 +204,7 @@ flask==3.0.3 # via # -c envs/dev.env.txt # dash -fonttools==4.55.4 +fonttools==4.56.0 # via # -c envs/dev.env.txt # matplotlib @@ -264,7 +264,7 @@ ipykernel==6.29.5 # via # -c envs/dev.env.txt # jupyterlab -ipython==8.31.0 +ipython==8.32.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -275,6 +275,7 @@ ipywidgets==8.1.5 # -c envs/dev.env.txt # -r deps/runtime.txt # anywidget + # pyzx isoduration==20.11.0 # via # -c envs/dev.env.txt @@ -344,7 +345,7 @@ jupyter-core==5.7.2 # nbclient # nbconvert # nbformat -jupyter-events==0.11.0 +jupyter-events==0.12.0 # via # -c envs/dev.env.txt # jupyter-server @@ -364,7 +365,7 @@ jupyter-server-terminals==0.5.3 # via # -c envs/dev.env.txt # jupyter-server -jupyterlab==4.3.4 +jupyterlab==4.3.5 # via # -c envs/dev.env.txt # notebook @@ -385,6 +386,10 @@ kiwisolver==1.4.8 # via # -c envs/dev.env.txt # matplotlib +lark==1.2.2 + # via + # -c envs/dev.env.txt + # pyzx llvmlite==0.44.0 # via # -c envs/dev.env.txt @@ -410,7 +415,7 @@ mccabe==0.7.0 # via # -c envs/dev.env.txt # pylint -mistune==3.1.0 +mistune==3.1.1 # via # -c envs/dev.env.txt # nbconvert @@ -423,11 +428,15 @@ mpmath==1.3.0 # via # -c envs/dev.env.txt # sympy +narwhals==1.25.2 + # via + # -c envs/dev.env.txt + # plotly nbclient==0.10.2 # via # -c envs/dev.env.txt # nbconvert -nbconvert==7.16.5 +nbconvert==7.16.6 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -483,6 +492,7 @@ numpy==1.26.4 # openfermion # pandas # pyscf + # pyzx # quimb # scipy openfermion[resources]==1.6.1 @@ -502,6 +512,7 @@ packaging==24.2 # -c envs/dev.env.txt # deprecation # ipykernel + # jupyter-events # jupyter-server # jupyterlab # jupyterlab-server @@ -535,7 +546,7 @@ platformdirs==4.3.6 # -c envs/dev.env.txt # jupyter-core # pylint -plotly==5.24.1 +plotly==6.0.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -562,7 +573,7 @@ psutil==6.1.1 # -c envs/dev.env.txt # ipykernel # quimb -psygnal==0.11.1 +psygnal==0.12.0 # via # -c envs/dev.env.txt # anywidget @@ -583,7 +594,7 @@ pycparser==2.22 # via # -c envs/dev.env.txt # cffi -pydantic==2.10.5 +pydantic==2.10.6 # via # -c envs/dev.env.txt # bartiq @@ -602,7 +613,7 @@ pygments==2.19.1 # ipython # nbconvert # sphinx -pylint==3.3.3 +pylint==3.3.4 # via # -c envs/dev.env.txt # -r deps/pylint.txt @@ -612,6 +623,10 @@ pyparsing==3.1.4 # bartiq # matplotlib # pydot +pyperclip==1.9.0 + # via + # -c envs/dev.env.txt + # pyzx pyscf==2.8.0 # via # -c envs/dev.env.txt @@ -631,7 +646,7 @@ python-json-logger==3.2.1 # via # -c envs/dev.env.txt # jupyter-events -pytz==2024.2 +pytz==2025.1 # via # -c envs/dev.env.txt # pandas @@ -640,22 +655,26 @@ pyyaml==6.0.2 # -c envs/dev.env.txt # jupyter-events # tensorflow-docs -pyzmq==26.2.0 +pyzmq==26.2.1 # via # -c envs/dev.env.txt # ipykernel # jupyter-client # jupyter-server +pyzx==0.9.0 + # via + # -c envs/dev.env.txt + # -r deps/runtime.txt qref==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt # bartiq -qsharp==1.12.1 +qsharp==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt -qsharp-widgets==1.12.1 +qsharp-widgets==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -663,7 +682,7 @@ quimb==1.10.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -referencing==0.36.1 +referencing==0.36.2 # via # -c envs/dev.env.txt # jsonschema @@ -770,10 +789,6 @@ sympy==1.12.1 # bartiq # cirq-core # openfermion -tenacity==9.0.0 - # via - # -c envs/dev.env.txt - # plotly tensorflow-docs==2023.5.24.56664 # via # -c envs/dev.env.txt @@ -815,6 +830,7 @@ tqdm==4.67.1 # via # -c envs/dev.env.txt # cirq-core + # pyzx # quimb traitlets==5.14.3 # via @@ -844,6 +860,7 @@ typing-extensions==4.12.2 # anywidget # astroid # async-lru + # beautifulsoup4 # cirq-core # dash # galois @@ -851,6 +868,7 @@ typing-extensions==4.12.2 # mistune # pydantic # pydantic-core + # pyzx # referencing tzdata==2025.1 # via diff --git a/dev_tools/requirements/envs/pytest.env.txt b/dev_tools/requirements/envs/pytest.env.txt index 4842e0748b..3ddd3c5e72 100644 --- a/dev_tools/requirements/envs/pytest.env.txt +++ b/dev_tools/requirements/envs/pytest.env.txt @@ -41,7 +41,7 @@ async-lru==2.0.4 # via # -c envs/dev.env.txt # jupyterlab -attrs==24.3.0 +attrs==25.1.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -53,7 +53,7 @@ autoray==0.7.0 # -c envs/dev.env.txt # cotengra # quimb -babel==2.16.0 +babel==2.17.0 # via # -c envs/dev.env.txt # jupyterlab-server @@ -61,7 +61,7 @@ bartiq==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -beautifulsoup4==4.12.3 +beautifulsoup4==4.13.3 # via # -c envs/dev.env.txt # nbconvert @@ -77,7 +77,7 @@ cachetools==5.5.1 # via # -c envs/dev.env.txt # -r deps/runtime.txt -certifi==2024.12.14 +certifi==2025.1.31 # via # -c envs/dev.env.txt # httpcore @@ -187,7 +187,7 @@ flask==3.0.3 # via # -c envs/dev.env.txt # dash -fonttools==4.55.4 +fonttools==4.56.0 # via # -c envs/dev.env.txt # matplotlib @@ -244,7 +244,7 @@ ipykernel==6.29.5 # -c envs/dev.env.txt # -r deps/pytest.txt # jupyterlab -ipython==8.31.0 +ipython==8.32.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -255,6 +255,7 @@ ipywidgets==8.1.5 # -c envs/dev.env.txt # -r deps/runtime.txt # anywidget + # pyzx isoduration==20.11.0 # via # -c envs/dev.env.txt @@ -318,7 +319,7 @@ jupyter-core==5.7.2 # nbclient # nbconvert # nbformat -jupyter-events==0.11.0 +jupyter-events==0.12.0 # via # -c envs/dev.env.txt # jupyter-server @@ -338,7 +339,7 @@ jupyter-server-terminals==0.5.3 # via # -c envs/dev.env.txt # jupyter-server -jupyterlab==4.3.4 +jupyterlab==4.3.5 # via # -c envs/dev.env.txt # notebook @@ -359,6 +360,10 @@ kiwisolver==1.4.8 # via # -c envs/dev.env.txt # matplotlib +lark==1.2.2 + # via + # -c envs/dev.env.txt + # pyzx llvmlite==0.44.0 # via # -c envs/dev.env.txt @@ -380,7 +385,7 @@ matplotlib-inline==0.1.7 # -c envs/dev.env.txt # ipykernel # ipython -mistune==3.1.0 +mistune==3.1.1 # via # -c envs/dev.env.txt # nbconvert @@ -393,11 +398,15 @@ mpmath==1.3.0 # via # -c envs/dev.env.txt # sympy +narwhals==1.25.2 + # via + # -c envs/dev.env.txt + # plotly nbclient==0.10.2 # via # -c envs/dev.env.txt # nbconvert -nbconvert==7.16.5 +nbconvert==7.16.6 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -452,6 +461,7 @@ numpy==1.26.4 # openfermion # pandas # pyscf + # pyzx # quimb # scipy openfermion[resources]==1.6.1 @@ -471,6 +481,7 @@ packaging==24.2 # -c envs/dev.env.txt # deprecation # ipykernel + # jupyter-events # jupyter-server # jupyterlab # jupyterlab-server @@ -502,7 +513,7 @@ platformdirs==4.3.6 # via # -c envs/dev.env.txt # jupyter-core -plotly==5.24.1 +plotly==6.0.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -528,7 +539,7 @@ psutil==6.1.1 # -c envs/dev.env.txt # ipykernel # quimb -psygnal==0.11.1 +psygnal==0.12.0 # via # -c envs/dev.env.txt # anywidget @@ -549,7 +560,7 @@ pycparser==2.22 # via # -c envs/dev.env.txt # cffi -pydantic==2.10.5 +pydantic==2.10.6 # via # -c envs/dev.env.txt # bartiq @@ -573,6 +584,10 @@ pyparsing==3.1.4 # bartiq # matplotlib # pydot +pyperclip==1.9.0 + # via + # -c envs/dev.env.txt + # pyzx pyscf==2.8.0 # via # -c envs/dev.env.txt @@ -584,7 +599,7 @@ pytest==8.3.4 # pytest-asyncio # pytest-cov # pytest-xdist -pytest-asyncio==0.25.2 +pytest-asyncio==0.25.3 # via # -c envs/dev.env.txt # -r deps/pytest.txt @@ -607,7 +622,7 @@ python-json-logger==3.2.1 # via # -c envs/dev.env.txt # jupyter-events -pytz==2024.2 +pytz==2025.1 # via # -c envs/dev.env.txt # pandas @@ -615,22 +630,26 @@ pyyaml==6.0.2 # via # -c envs/dev.env.txt # jupyter-events -pyzmq==26.2.0 +pyzmq==26.2.1 # via # -c envs/dev.env.txt # ipykernel # jupyter-client # jupyter-server +pyzx==0.9.0 + # via + # -c envs/dev.env.txt + # -r deps/runtime.txt qref==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt # bartiq -qsharp==1.12.1 +qsharp==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt -qsharp-widgets==1.12.1 +qsharp-widgets==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -638,7 +657,7 @@ quimb==1.10.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -referencing==0.36.1 +referencing==0.36.2 # via # -c envs/dev.env.txt # jsonschema @@ -712,10 +731,6 @@ sympy==1.12.1 # bartiq # cirq-core # openfermion -tenacity==9.0.0 - # via - # -c envs/dev.env.txt - # plotly terminado==0.18.1 # via # -c envs/dev.env.txt @@ -748,6 +763,7 @@ tqdm==4.67.1 # via # -c envs/dev.env.txt # cirq-core + # pyzx # quimb traitlets==5.14.3 # via @@ -776,6 +792,7 @@ typing-extensions==4.12.2 # anyio # anywidget # async-lru + # beautifulsoup4 # cirq-core # dash # galois @@ -783,6 +800,7 @@ typing-extensions==4.12.2 # mistune # pydantic # pydantic-core + # pyzx # referencing tzdata==2025.1 # via diff --git a/dev_tools/requirements/envs/runtime.env.txt b/dev_tools/requirements/envs/runtime.env.txt index 3a5e632db5..7f55987f09 100644 --- a/dev_tools/requirements/envs/runtime.env.txt +++ b/dev_tools/requirements/envs/runtime.env.txt @@ -37,7 +37,7 @@ async-lru==2.0.4 # via # -c envs/dev.env.txt # jupyterlab -attrs==24.3.0 +attrs==25.1.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -49,7 +49,7 @@ autoray==0.7.0 # -c envs/dev.env.txt # cotengra # quimb -babel==2.16.0 +babel==2.17.0 # via # -c envs/dev.env.txt # jupyterlab-server @@ -57,7 +57,7 @@ bartiq==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -beautifulsoup4==4.12.3 +beautifulsoup4==4.13.3 # via # -c envs/dev.env.txt # nbconvert @@ -73,7 +73,7 @@ cachetools==5.5.1 # via # -c envs/dev.env.txt # -r deps/runtime.txt -certifi==2024.12.14 +certifi==2025.1.31 # via # -c envs/dev.env.txt # httpcore @@ -165,7 +165,7 @@ flask==3.0.3 # via # -c envs/dev.env.txt # dash -fonttools==4.55.4 +fonttools==4.56.0 # via # -c envs/dev.env.txt # matplotlib @@ -212,7 +212,7 @@ ipykernel==6.29.5 # via # -c envs/dev.env.txt # jupyterlab -ipython==8.31.0 +ipython==8.32.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -223,6 +223,7 @@ ipywidgets==8.1.5 # -c envs/dev.env.txt # -r deps/runtime.txt # anywidget + # pyzx isoduration==20.11.0 # via # -c envs/dev.env.txt @@ -277,7 +278,7 @@ jupyter-core==5.7.2 # nbclient # nbconvert # nbformat -jupyter-events==0.11.0 +jupyter-events==0.12.0 # via # -c envs/dev.env.txt # jupyter-server @@ -297,7 +298,7 @@ jupyter-server-terminals==0.5.3 # via # -c envs/dev.env.txt # jupyter-server -jupyterlab==4.3.4 +jupyterlab==4.3.5 # via # -c envs/dev.env.txt # notebook @@ -318,6 +319,10 @@ kiwisolver==1.4.8 # via # -c envs/dev.env.txt # matplotlib +lark==1.2.2 + # via + # -c envs/dev.env.txt + # pyzx llvmlite==0.44.0 # via # -c envs/dev.env.txt @@ -338,7 +343,7 @@ matplotlib-inline==0.1.7 # -c envs/dev.env.txt # ipykernel # ipython -mistune==3.1.0 +mistune==3.1.1 # via # -c envs/dev.env.txt # nbconvert @@ -346,11 +351,15 @@ mpmath==1.3.0 # via # -c envs/dev.env.txt # sympy +narwhals==1.25.2 + # via + # -c envs/dev.env.txt + # plotly nbclient==0.10.2 # via # -c envs/dev.env.txt # nbconvert -nbconvert==7.16.5 +nbconvert==7.16.6 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -397,6 +406,7 @@ numpy==1.26.4 # matplotlib # numba # pandas + # pyzx # quimb # scipy overrides==7.7.0 @@ -407,6 +417,7 @@ packaging==24.2 # via # -c envs/dev.env.txt # ipykernel + # jupyter-events # jupyter-server # jupyterlab # jupyterlab-server @@ -437,7 +448,7 @@ platformdirs==4.3.6 # via # -c envs/dev.env.txt # jupyter-core -plotly==5.24.1 +plotly==6.0.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -459,7 +470,7 @@ psutil==6.1.1 # -c envs/dev.env.txt # ipykernel # quimb -psygnal==0.11.1 +psygnal==0.12.0 # via # -c envs/dev.env.txt # anywidget @@ -476,7 +487,7 @@ pycparser==2.22 # via # -c envs/dev.env.txt # cffi -pydantic==2.10.5 +pydantic==2.10.6 # via # -c envs/dev.env.txt # bartiq @@ -500,6 +511,10 @@ pyparsing==3.1.4 # bartiq # matplotlib # pydot +pyperclip==1.9.0 + # via + # -c envs/dev.env.txt + # pyzx python-dateutil==2.9.0.post0 # via # -c envs/dev.env.txt @@ -511,7 +526,7 @@ python-json-logger==3.2.1 # via # -c envs/dev.env.txt # jupyter-events -pytz==2024.2 +pytz==2025.1 # via # -c envs/dev.env.txt # pandas @@ -519,22 +534,26 @@ pyyaml==6.0.2 # via # -c envs/dev.env.txt # jupyter-events -pyzmq==26.2.0 +pyzmq==26.2.1 # via # -c envs/dev.env.txt # ipykernel # jupyter-client # jupyter-server +pyzx==0.9.0 + # via + # -c envs/dev.env.txt + # -r deps/runtime.txt qref==0.9.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt # bartiq -qsharp==1.12.1 +qsharp==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt -qsharp-widgets==1.12.1 +qsharp-widgets==1.13.2 # via # -c envs/dev.env.txt # -r deps/runtime.txt @@ -542,7 +561,7 @@ quimb==1.10.0 # via # -c envs/dev.env.txt # -r deps/runtime.txt -referencing==0.36.1 +referencing==0.36.2 # via # -c envs/dev.env.txt # jsonschema @@ -609,10 +628,6 @@ sympy==1.12.1 # -r deps/runtime.txt # bartiq # cirq-core -tenacity==9.0.0 - # via - # -c envs/dev.env.txt - # plotly terminado==0.18.1 # via # -c envs/dev.env.txt @@ -643,6 +658,7 @@ tqdm==4.67.1 # via # -c envs/dev.env.txt # cirq-core + # pyzx # quimb traitlets==5.14.3 # via @@ -671,6 +687,7 @@ typing-extensions==4.12.2 # anyio # anywidget # async-lru + # beautifulsoup4 # cirq-core # dash # galois @@ -678,6 +695,7 @@ typing-extensions==4.12.2 # mistune # pydantic # pydantic-core + # pyzx # referencing tzdata==2025.1 # via From 52ccf6749ee8965048bdcafba4896e18ffbf6b3b Mon Sep 17 00:00:00 2001 From: Anurudh Peduri Date: Fri, 10 Jan 2025 16:58:57 +0100 Subject: [PATCH 3/5] cbloq to pyzx graph --- qualtran/_infra/bloq.py | 8 ++ qualtran/bloqs/basic_gates/x_basis.py | 10 ++ qualtran/bloqs/basic_gates/z_basis.py | 32 +++++ qualtran/pyzx_interop/__init__.py | 14 +++ qualtran/pyzx_interop/bloq_to_pyzx_circuit.py | 115 ++++++++++++++++++ .../pyzx_interop/bloq_to_pyzx_circuit_test.py | 44 +++++++ 6 files changed, 223 insertions(+) create mode 100644 qualtran/pyzx_interop/__init__.py create mode 100644 qualtran/pyzx_interop/bloq_to_pyzx_circuit.py create mode 100644 qualtran/pyzx_interop/bloq_to_pyzx_circuit_test.py diff --git a/qualtran/_infra/bloq.py b/qualtran/_infra/bloq.py index ec5e2d7350..83bf0408b3 100644 --- a/qualtran/_infra/bloq.py +++ b/qualtran/_infra/bloq.py @@ -21,6 +21,8 @@ if TYPE_CHECKING: import cirq import networkx as nx + import numpy as np + import pyzx as zx import quimb.tensor as qtn import sympy from numpy.typing import NDArray @@ -39,6 +41,7 @@ from qualtran.cirq_interop import CirqQuregT from qualtran.cirq_interop.t_complexity_protocol import TComplexity from qualtran.drawing import WireSymbol + from qualtran.pyzx_interop.bloq_to_pyzx_circuit import ZXAncillaManager from qualtran.resource_counting import ( BloqCountDictT, BloqCountT, @@ -551,3 +554,8 @@ def wire_symbol( def __str__(self): return self.__class__.__name__ + + def as_zx_gates( + self, ancilla_manager: 'ZXAncillaManager', /, **qubits: 'NDArray[np.integer]' + ) -> tuple[list['zx.circuit.Gate'], dict[str, 'NDArray[np.integer]']]: + raise NotImplementedError(f"{self} does not declare a conversion to ZX gates.") diff --git a/qualtran/bloqs/basic_gates/x_basis.py b/qualtran/bloqs/basic_gates/x_basis.py index c215a4ad25..c50a28aec4 100644 --- a/qualtran/bloqs/basic_gates/x_basis.py +++ b/qualtran/bloqs/basic_gates/x_basis.py @@ -17,6 +17,7 @@ import numpy as np from attrs import frozen +from numpy.typing import NDArray from qualtran import ( AddControlledT, @@ -36,6 +37,7 @@ if TYPE_CHECKING: import cirq + import pyzx as zx import quimb.tensor as qtn from qualtran.cirq_interop import CirqQuregT @@ -263,3 +265,11 @@ def wire_symbol(self, reg: Register, idx: Tuple[int, ...] = tuple()) -> 'WireSym return Text('X') return ModPlus() + + def as_zx_gates( + self, ancilla_manager, /, q: NDArray[np.integer] + ) -> tuple[list['zx.circuit.Gate'], dict[str, NDArray[np.integer]]]: + import pyzx as zx + + (qubit,) = q + return [zx.circuit.NOT(qubit)], {'q': q} diff --git a/qualtran/bloqs/basic_gates/z_basis.py b/qualtran/bloqs/basic_gates/z_basis.py index 599acfc898..6c5a7c5c62 100644 --- a/qualtran/bloqs/basic_gates/z_basis.py +++ b/qualtran/bloqs/basic_gates/z_basis.py @@ -46,9 +46,11 @@ if TYPE_CHECKING: import cirq + import pyzx as zx import quimb.tensor as qtn from qualtran.cirq_interop import CirqQuregT + from qualtran.pyzx_interop.bloq_to_pyzx_circuit import ZXAncillaManager from qualtran.resource_counting import BloqCountDictT, SympySymbolAllocator _ZERO = np.array([1, 0], dtype=np.complex128) @@ -137,6 +139,28 @@ def wire_symbol( s = '1' if self.bit else '0' return directional_text_box(s, side=reg.side) + def as_zx_gates( + self, ancilla_manager: 'ZXAncillaManager', /, **qubits: NDArray[np.integer] + ) -> tuple[list['zx.circuit.Gate'], dict[str, NDArray[np.integer]]]: + import pyzx as zx + + if self.state: + qubit = ancilla_manager.allocate() + + gates = [zx.circuit.gates.InitAncilla(qubit), zx.circuit.gates.HAD(qubit)] + if self.bit: + gates = gates + [zx.circuit.gates.NOT(qubit)] + + return gates, {'q': np.array([qubit])} + else: + (qubit,) = qubits.pop('q') + + gates = [zx.circuit.gates.HAD(qubit), zx.circuit.gates.PostSelect(qubit)] + if self.bit: + gates = [zx.circuit.gates.NOT(qubit)] + gates + + return gates, {} + def _hide_base_fields(cls, fields): # for use in attrs `field_transformer`. @@ -285,6 +309,14 @@ def wire_symbol( return TextBox('Z') + def as_zx_gates( + self, ancilla_manager, /, q: NDArray[np.integer] + ) -> tuple[list['zx.circuit.Gate'], dict[str, NDArray[np.integer]]]: + import pyzx as zx + + (qubit,) = q + return [zx.circuit.Z(qubit)], {'q': q} + @bloq_example def _zgate() -> ZGate: diff --git a/qualtran/pyzx_interop/__init__.py b/qualtran/pyzx_interop/__init__.py new file mode 100644 index 0000000000..87ae1fbfa4 --- /dev/null +++ b/qualtran/pyzx_interop/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from .bloq_to_pyzx_circuit import bloq_to_pyzx_circuit diff --git a/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py b/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py new file mode 100644 index 0000000000..cff8ce24a0 --- /dev/null +++ b/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py @@ -0,0 +1,115 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from typing import Iterable + +import numpy as np +import pyzx as zx +from attrs import define +from numpy.typing import NDArray + +from qualtran import Bloq, CompositeBloq, LeftDangle, Register, RightDangle, Signature, Soquet + +ZXQubitMap = dict[str, NDArray[np.integer]] +"""A mapping from register names to an NDArray of ZX qubits""" + + +@define +class ZXAncillaManager: + n: int + + def allocate(self) -> int: + idx = self.n + self.n += 1 + return idx + + +def _empty_qubit_map_from_registers(registers: Iterable[Register]) -> ZXQubitMap: + return {reg.name: np.empty(reg.shape + (reg.bitsize,), dtype=int) for reg in registers} + + +def _initalize_zx_circuit_from_signature( + signature: Signature, +) -> tuple[zx.Circuit, ZXQubitMap, ZXAncillaManager]: + n_qubits: int = 0 + qubit_d: ZXQubitMap = {} + + for reg in signature.lefts(): + n = reg.total_bits() + idxs = np.arange(n) + n_qubits + shape = reg.shape + (reg.bitsize,) + qubit_d[reg.name] = idxs.reshape(shape) + n_qubits += n + + circ = zx.Circuit(qubit_amount=n_qubits) + return circ, qubit_d, ZXAncillaManager(n_qubits) + + +def _add_bloq_to_pyzx_circuit( + circ: zx.Circuit, bloq: Bloq, ancilla_manager: ZXAncillaManager, in_qubits: ZXQubitMap +) -> ZXQubitMap: + try: + gates, out_qubits = bloq.as_zx_gates(ancilla_manager, **in_qubits) + for gate in gates: + circ.add_gate(gate) + return out_qubits + except NotImplementedError: + pass + + cbloq = bloq.decompose_bloq() + return _add_cbloq_to_pyzx_circuit(circ, cbloq, ancilla_manager, in_qubits) + + +def _add_cbloq_to_pyzx_circuit( + circ: zx.Circuit, cbloq: CompositeBloq, ancilla_manager: ZXAncillaManager, in_qubits: ZXQubitMap +) -> ZXQubitMap: + soq_map: dict[Soquet, NDArray[np.integer]] = { + Soquet(binst=LeftDangle, reg=reg, idx=idx): in_qubits[reg.name][idx] + for reg in cbloq.signature.lefts() + for idx in reg.all_idxs() + } + + for binst, pred_cxns, succ_cxns in cbloq.iter_bloqnections(): + bloq = binst.bloq + + # compute the input qubits + bloq_in_qubits: ZXQubitMap = _empty_qubit_map_from_registers(bloq.signature.lefts()) + for cxn in pred_cxns: + bloq_soq = cxn.right + bloq_in_qubits[bloq_soq.reg.name][bloq_soq.idx] = soq_map.pop(cxn.left) + + out_qubits: ZXQubitMap = _add_bloq_to_pyzx_circuit( + circ, bloq, ancilla_manager, bloq_in_qubits + ) + + # forward the output qubits to their corresponding soqs + for cxn in succ_cxns: + bloq_soq = cxn.left + soq_map[bloq_soq] = out_qubits[bloq_soq.reg.name][bloq_soq.idx] + + # forward the soqs to the cbloq output soqs + for cxn in cbloq.connections: + if cxn.right.binst is RightDangle: + soq_map[cxn.right] = soq_map.pop(cxn.left) + + # get the output qubits + out_qubits = _empty_qubit_map_from_registers(cbloq.signature.rights()) + for soq, qubits in soq_map.items(): + out_qubits[soq.reg.name][soq.idx] = qubits + return out_qubits + + +def bloq_to_pyzx_circuit(bloq: Bloq) -> zx.Circuit: + circ, in_qubits, ancilla_manager = _initalize_zx_circuit_from_signature(bloq.signature) + _ = _add_bloq_to_pyzx_circuit(circ, bloq, ancilla_manager, in_qubits) + return circ diff --git a/qualtran/pyzx_interop/bloq_to_pyzx_circuit_test.py b/qualtran/pyzx_interop/bloq_to_pyzx_circuit_test.py new file mode 100644 index 0000000000..856c5a1a62 --- /dev/null +++ b/qualtran/pyzx_interop/bloq_to_pyzx_circuit_test.py @@ -0,0 +1,44 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import numpy as np +import pyzx as zx + +from qualtran import Bloq, BloqBuilder, Signature, Soquet, SoquetT +from qualtran.bloqs.basic_gates import OneEffect, XGate, ZeroState, ZGate +from qualtran.pyzx_interop.bloq_to_pyzx_circuit import bloq_to_pyzx_circuit + + +class TestBloq(Bloq): + @property + def signature(self) -> 'Signature': + return Signature.build(q=1) + + def build_composite_bloq(self, bb: 'BloqBuilder', q: 'Soquet') -> dict[str, 'SoquetT']: + q = bb.add(ZGate(), q=q) + q = bb.add(XGate(), q=q) + + a = bb.add(ZeroState()) + a = bb.add(XGate(), q=a) + bb.add(OneEffect(), q=a) + + return {'q': q} + + +def test_bloq_to_pyzx_circuit(): + bloq = TestBloq() + circ = bloq_to_pyzx_circuit(bloq) + tensor = bloq.tensor_contract() + + assert zx.compare_tensors(circ, tensor) + np.testing.assert_allclose(np.imag(zx.find_scalar_correction(circ, tensor)), 0, atol=1e-7) From 8c5764263d691b3d1e87018a34c44ba3dfc41a82 Mon Sep 17 00:00:00 2001 From: Anurudh Peduri Date: Tue, 18 Feb 2025 16:59:32 +0100 Subject: [PATCH 4/5] docs --- qualtran/pyzx_interop/bloq_to_pyzx_circuit.py | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py b/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py index cff8ce24a0..86e9897d9f 100644 --- a/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py +++ b/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py @@ -26,21 +26,52 @@ @define class ZXAncillaManager: + """A simple ancilla qubit manager for generating pyzx Circuits. + + Args: + n: number of existing qubits in the starting circuit. + """ + n: int def allocate(self) -> int: + """Allocate an uninitialized ancilla qubit. + + This returns the index of a new ancilla qubit for use. + Note that it must be manually initialized, e.g. using the `InitAncilla` gate. + """ idx = self.n self.n += 1 return idx + def free(self, q: int): + """Free an ancilla qubit. + + Discard an ancilla qubit. For now, this operation does nothing. + """ + pass + def _empty_qubit_map_from_registers(registers: Iterable[Register]) -> ZXQubitMap: + """For each register, creates an empty NDArray of the appropriate shape to store the zx qubits.""" return {reg.name: np.empty(reg.shape + (reg.bitsize,), dtype=int) for reg in registers} def _initalize_zx_circuit_from_signature( signature: Signature, ) -> tuple[zx.Circuit, ZXQubitMap, ZXAncillaManager]: + """Initalize a pyzx circuit from a bloq signature. + + This enumerates the qubits in the same order as the registers in the signature. + + Args: + signature: the signature of the bloq. + + Returns: + A tuple of the pyzx circuit, the mapping from register names to qubits, and an + ancilla manager for the circuit. + """ + n_qubits: int = 0 qubit_d: ZXQubitMap = {} @@ -58,6 +89,17 @@ def _initalize_zx_circuit_from_signature( def _add_bloq_to_pyzx_circuit( circ: zx.Circuit, bloq: Bloq, ancilla_manager: ZXAncillaManager, in_qubits: ZXQubitMap ) -> ZXQubitMap: + """Add a single bloq acting on the given input qubits to a pyzx circuit. + + Args: + circ: the pyzx circuit. + bloq: the bloq to add. + ancilla_manager: the ancilla manager for `circ`. + in_qubits: the input qubits to the bloq. + + Returns: + A mapping of output register names to output qubits. + """ try: gates, out_qubits = bloq.as_zx_gates(ancilla_manager, **in_qubits) for gate in gates: @@ -73,6 +115,21 @@ def _add_bloq_to_pyzx_circuit( def _add_cbloq_to_pyzx_circuit( circ: zx.Circuit, cbloq: CompositeBloq, ancilla_manager: ZXAncillaManager, in_qubits: ZXQubitMap ) -> ZXQubitMap: + """Add a composite bloq acting on the given input qubits to a pyzx circuit. + + This iterates through the `cbloq` graph in topologically-sorted order, and adds each + bloq instance. + + Args: + circ: the pyzx circuit. + cbloq: the composite bloq to add. + ancilla_manager: the ancilla manager for `circ`. + in_qubits: the input qubits to the bloq. + + Returns: + A mapping of output register names to output qubits. + """ + # initialize the soquets corresponding to the `cbloq` inputs soq_map: dict[Soquet, NDArray[np.integer]] = { Soquet(binst=LeftDangle, reg=reg, idx=idx): in_qubits[reg.name][idx] for reg in cbloq.signature.lefts() @@ -110,6 +167,14 @@ def _add_cbloq_to_pyzx_circuit( def bloq_to_pyzx_circuit(bloq: Bloq) -> zx.Circuit: + """Build a pyzx circuit of a bloq. + + Args: + bloq: the bloq to convert. + + Returns: + A pyzx circuit corresponding to `bloq`. + """ circ, in_qubits, ancilla_manager = _initalize_zx_circuit_from_signature(bloq.signature) _ = _add_bloq_to_pyzx_circuit(circ, bloq, ancilla_manager, in_qubits) return circ From 562323d747f3669168c4a90934c8ad841893b07c Mon Sep 17 00:00:00 2001 From: Anurudh Peduri Date: Tue, 18 Feb 2025 17:02:02 +0100 Subject: [PATCH 5/5] simplify --- qualtran/_infra/bloq.py | 2 +- qualtran/bloqs/basic_gates/z_basis.py | 2 +- qualtran/pyzx_interop/__init__.py | 2 +- qualtran/pyzx_interop/bloq_to_pyzx_circuit.py | 9 ++++----- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/qualtran/_infra/bloq.py b/qualtran/_infra/bloq.py index 83bf0408b3..9e04ed867f 100644 --- a/qualtran/_infra/bloq.py +++ b/qualtran/_infra/bloq.py @@ -41,7 +41,7 @@ from qualtran.cirq_interop import CirqQuregT from qualtran.cirq_interop.t_complexity_protocol import TComplexity from qualtran.drawing import WireSymbol - from qualtran.pyzx_interop.bloq_to_pyzx_circuit import ZXAncillaManager + from qualtran.pyzx_interop import ZXAncillaManager from qualtran.resource_counting import ( BloqCountDictT, BloqCountT, diff --git a/qualtran/bloqs/basic_gates/z_basis.py b/qualtran/bloqs/basic_gates/z_basis.py index 6c5a7c5c62..8f3cea1d8a 100644 --- a/qualtran/bloqs/basic_gates/z_basis.py +++ b/qualtran/bloqs/basic_gates/z_basis.py @@ -50,7 +50,7 @@ import quimb.tensor as qtn from qualtran.cirq_interop import CirqQuregT - from qualtran.pyzx_interop.bloq_to_pyzx_circuit import ZXAncillaManager + from qualtran.pyzx_interop import ZXAncillaManager from qualtran.resource_counting import BloqCountDictT, SympySymbolAllocator _ZERO = np.array([1, 0], dtype=np.complex128) diff --git a/qualtran/pyzx_interop/__init__.py b/qualtran/pyzx_interop/__init__.py index 87ae1fbfa4..2e276c7e28 100644 --- a/qualtran/pyzx_interop/__init__.py +++ b/qualtran/pyzx_interop/__init__.py @@ -11,4 +11,4 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from .bloq_to_pyzx_circuit import bloq_to_pyzx_circuit +from .bloq_to_pyzx_circuit import bloq_to_pyzx_circuit, ZXAncillaManager diff --git a/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py b/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py index 86e9897d9f..611f7f9153 100644 --- a/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py +++ b/qualtran/pyzx_interop/bloq_to_pyzx_circuit.py @@ -28,7 +28,7 @@ class ZXAncillaManager: """A simple ancilla qubit manager for generating pyzx Circuits. - Args: + Attributes: n: number of existing qubits in the starting circuit. """ @@ -49,7 +49,6 @@ def free(self, q: int): Discard an ancilla qubit. For now, this operation does nothing. """ - pass def _empty_qubit_map_from_registers(registers: Iterable[Register]) -> ZXQubitMap: @@ -131,9 +130,9 @@ def _add_cbloq_to_pyzx_circuit( """ # initialize the soquets corresponding to the `cbloq` inputs soq_map: dict[Soquet, NDArray[np.integer]] = { - Soquet(binst=LeftDangle, reg=reg, idx=idx): in_qubits[reg.name][idx] - for reg in cbloq.signature.lefts() - for idx in reg.all_idxs() + soq: in_qubits[soq.reg.name][soq.idx] + for soq in cbloq.all_soquets + if soq.binst is LeftDangle } for binst, pred_cxns, succ_cxns in cbloq.iter_bloqnections():