diff --git a/doc/source/api-reference/qibo.rst b/doc/source/api-reference/qibo.rst index a0dabf7abf..5e376e58ca 100644 --- a/doc/source/api-reference/qibo.rst +++ b/doc/source/api-reference/qibo.rst @@ -1615,6 +1615,23 @@ or the complete set of :math:`d = 2^{n}` stabilizers operators can be extracted The destabilizers can be extracted analogously with :meth:`qibo.quantum_info.clifford.Clifford.destabilizers`. +We provide integration with the `stim `_ package. +It is possible to run Clifford circuits using `stim` as an engine: + +.. code-block:: python + from qibo.backends import CliffordBackend + from qibo.quantum_info import Clifford, random_clifford + + clifford_backend = CliffordBackend(engine="stim") + + circuit = random_clifford(nqubits) + result = clifford_backend.execute_circuit(circuit) + + ## Note that the execution above is equivalent to the one below + + result = Clifford.from_circuit(circuit, engine="stim") + + .. autoclass:: qibo.quantum_info.clifford.Clifford :members: :member-order: bysource diff --git a/poetry.lock b/poetry.lock index b951643fb7..29758d7b16 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "absl-py" @@ -1517,11 +1517,11 @@ files = [ google-auth = ">=2.14.1,<3.0.dev0" googleapis-common-protos = ">=1.56.2,<2.0.dev0" grpcio = [ - {version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, + {version = ">=1.33.2,<2.0dev", optional = true, markers = "extra == \"grpc\""}, {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, ] grpcio-status = [ - {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""}, + {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "extra == \"grpc\""}, {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, ] protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" @@ -2491,9 +2491,9 @@ files = [ [package.dependencies] numpy = [ - {version = ">=1.23.3", markers = "python_version > \"3.10\""}, - {version = ">=1.21.2", markers = "python_version > \"3.9\" and python_version <= \"3.10\""}, {version = ">1.20", markers = "python_version <= \"3.9\""}, + {version = ">=1.23.3", markers = "python_version > \"3.10\""}, + {version = ">=1.21.2", markers = "python_version > \"3.9\""}, ] [package.extras] @@ -2579,6 +2579,7 @@ files = [ {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, ] [[package]] @@ -4604,6 +4605,49 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +[[package]] +name = "stim" +version = "1.12.1" +description = "A fast library for analyzing with quantum stabilizer circuits." +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "stim-1.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:be50861d1b4219a12264f0bbebb04900ccdd56819f51136283a1e03962d133b1"}, + {file = "stim-1.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4e066aaed805364bf27ffb2bc9d275111f5b0828156f599c2ab82b02f96134e6"}, + {file = "stim-1.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14cb6400f49387ddc94c599556fec3f97a8f4c7d57300f984f3ca0cec838e00f"}, + {file = "stim-1.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:0d62aee6b9265268c728eaefa971215454f9c93cf69bf04c24d1e78231124371"}, + {file = "stim-1.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c2d674621ddce52bb0b0e54aaa2bd390707287454fbb0d6a03dc043eb16f752a"}, + {file = "stim-1.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c26565a81096fb688190ffbbeae51d60289b49753f6c8dcf2ee9beeafc617a2"}, + {file = "stim-1.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:475d91d3357d6f29baf08550b29e7fe5678c4ab3863e4ba25782e38f5b945790"}, + {file = "stim-1.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:c07f41ac40a0be6edeea03d50242d273e95d4590461a4b7599bab4e8dd29aa6d"}, + {file = "stim-1.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ebece3d630362516c39139dae0c321d2a6353fab78884b41a3f436ed923c1876"}, + {file = "stim-1.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61957d5cbb633a4efe5a9dc21b350fcd03a5767c441137e257517b223ec289be"}, + {file = "stim-1.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1904dd8779dae758eb4fa95f2b881a6c7903a949e709f9b995f115a6f2ac8f86"}, + {file = "stim-1.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:2bd9e04046e5b398499d74a94a9abacde70c9f2c3442d5f6a5f193f5f137025f"}, + {file = "stim-1.12.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7cb52db06fe5b1e33f100dd07fbf9f4cf6acb83a40115177cc6b5b483b88cecc"}, + {file = "stim-1.12.1-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f2d3da1d369e2eae45112caf80d4370a896f2caacfecae25393f030f76ca01b"}, + {file = "stim-1.12.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78ba6371e3102e4c3dc40cb648c7e7dc4d2b53a8ff41b970253f3883b3bf439b"}, + {file = "stim-1.12.1-cp36-cp36m-win32.whl", hash = "sha256:10fca3e2a4c07310d94710f29d42a808d0b4e0fbc9b6a80a69d37a6d188b60cb"}, + {file = "stim-1.12.1-cp36-cp36m-win_amd64.whl", hash = "sha256:ee9d04f820164ac748f8fe999ecdda7dc3d4c0d3564805b522464ab0b1183e1e"}, + {file = "stim-1.12.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3783158200ec395f9c40ecf4999b84fec7b8b31f9276993785d64847fa64a1f2"}, + {file = "stim-1.12.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48b40f8748f21a12dfa1f40209706dc8dc4d4713d83a61f838361e6309ec97aa"}, + {file = "stim-1.12.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcde7ba4c91496b4d610df1db5976c3e153411a953e4e4969464cb7303a545f1"}, + {file = "stim-1.12.1-cp37-cp37m-win32.whl", hash = "sha256:985757b1d25b7b9b626c8cf646178dd931500820991832c82cff7ea0f6fa3665"}, + {file = "stim-1.12.1-cp37-cp37m-win_amd64.whl", hash = "sha256:cf12de3f5ef03d3c248ff37df920aadec828b2f42c99687f0bdb54646ea9eb3a"}, + {file = "stim-1.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2e479614da248d95c98656985d2d132ca124259664a35a58f7d03b60cd4708ae"}, + {file = "stim-1.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c17d95d54d5bd163d22558369e67c1a4daeb21f4724c3cbd7f5dc954e5e90519"}, + {file = "stim-1.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0587aeaa9791bf5b2b64c993c3211213fdfa247afffdbca5e8d6b329f1ee3926"}, + {file = "stim-1.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:ef6c69f9d222381e241af8f97ffe596a02a27eaa01a223b815b3350279515deb"}, + {file = "stim-1.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fdb3fb321a0d9f576f3655b525f34f1efccaccc57a1c21840b3f0cda0c93dce4"}, + {file = "stim-1.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bdd744bca925fd4f78dd01a5068ebeb090d30d7bae9c4e379526838b8f5881fc"}, + {file = "stim-1.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0f2fe8c5a0906a8eb3ee3b3c840026912828e98a0dc44aace800e4d1d1b2b9b"}, + {file = "stim-1.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:86da45f618d5e8866a5197f10dd74ab23516865da2dbdc95edb54628195f67ff"}, + {file = "stim-1.12.1.tar.gz", hash = "sha256:71a8b5ee740e07c888a0676a5ca465c94a3e588de907806db303d607106da7b2"}, +] + +[package.dependencies] +numpy = "*" + [[package]] name = "sympy" version = "1.12" @@ -5140,85 +5184,6 @@ files = [ {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - [[package]] name = "zipp" version = "3.17.0" @@ -5237,4 +5202,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "0b472a931fa1b4631a6ba4549b02bda9ec9a6f0d5a7fff28c52d97263a1499ef" +content-hash = "9b1a14610acdd1973b166e3ded5200acbf457c194bca19dd6afa49aff7775e22" diff --git a/pyproject.toml b/pyproject.toml index d5014700ef..adb0d8f125 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,7 @@ matplotlib = "^3.7.0" qibojit = { git = "https://github.com/qiboteam/qibojit.git" } tensorflow = { version = "^2.14.1,<2.16", markers = "sys_platform == 'linux'" } qibotn = { git = "https://github.com/qiboteam/qibotn.git" } +stim = "^1.12.0" [tool.poe.tasks] test = "pytest" diff --git a/src/qibo/backends/clifford.py b/src/qibo/backends/clifford.py index e2d68800bf..2830fd9ef7 100644 --- a/src/qibo/backends/clifford.py +++ b/src/qibo/backends/clifford.py @@ -8,7 +8,6 @@ import numpy as np from qibo import gates -from qibo.backends import _clifford_operations from qibo.backends.numpy import NumpyBackend from qibo.config import raise_error @@ -28,12 +27,19 @@ class CliffordBackend(NumpyBackend): def __init__(self, engine=None): super().__init__() - if engine is None: - from qibo.backends import _check_backend + if engine == "stim": + import stim # pylint: disable=C0415 - engine = _get_engine_name(_check_backend(engine)) + engine = "numpy" + self.platform = "stim" + self._stim = stim + else: + if engine is None: + from qibo.backends import _check_backend # pylint: disable=C0415 + + engine = _get_engine_name(_check_backend(engine)) - self.platform = engine + self.platform = engine spec = find_spec("qibo.backends._clifford_operations") self.engine = module_from_spec(spec) @@ -49,7 +55,9 @@ def __init__(self, engine=None): for method in dir(clifford_operations_cpu): setattr(self.engine, method, getattr(clifford_operations_cpu, method)) elif engine == "cupy": # pragma: no cover - from qibojit.backends import clifford_operations_gpu + from qibojit.backends import ( # pylint: disable=C0415 + clifford_operations_gpu, + ) for method in dir(clifford_operations_gpu): setattr(self.engine, method, getattr(clifford_operations_gpu, method)) @@ -90,38 +98,43 @@ def zero_state(self, nqubits: int): Returns: (ndarray): Symplectic matrix for the zero state. """ - I = self.np.eye(nqubits) + identity = self.np.eye(nqubits) symplectic_matrix = self.np.zeros( (2 * nqubits + 1, 2 * nqubits + 1), dtype=bool ) - symplectic_matrix[:nqubits, :nqubits] = self.np.copy(I) - symplectic_matrix[nqubits:-1, nqubits : 2 * nqubits] = self.np.copy(I) + symplectic_matrix[:nqubits, :nqubits] = self.np.copy(identity) + symplectic_matrix[nqubits:-1, nqubits : 2 * nqubits] = self.np.copy(identity) return symplectic_matrix def _clifford_pre_execution_reshape(self, state): """Reshape the symplectic matrix to the shape needed by the engine before circuit execution. Args: - state (ndarray): The input state. + state (ndarray): Input state. Returns: - (ndarray): The reshaped state. + ndarray: Reshaped state. """ - return self.engine._clifford_pre_execution_reshape(state) + return self.engine._clifford_pre_execution_reshape( # pylint: disable=protected-access + state + ) def _clifford_post_execution_reshape(self, state, nqubits): """Reshape the symplectic matrix to the shape needed by the engine after circuit execution. Args: - state (ndarray): The input state. + state (ndarray): Input state. nqubits (int): Number of qubits. Returns: - (ndarray): The reshaped state. + ndarray: Reshaped state. """ - return self.engine._clifford_post_execution_reshape(state, nqubits) + return self.engine._clifford_post_execution_reshape( # pylint: disable=protected-access + state, nqubits + ) def apply_gate_clifford(self, gate, symplectic_matrix, nqubits): + """Apply a gate to a symplectic matrix.""" operation = getattr(self.engine, gate.__class__.__name__) kwargs = ( {"theta": gate.init_kwargs["theta"]} if "theta" in gate.init_kwargs else {} @@ -137,7 +150,9 @@ def apply_channel(self, channel, state, nqubits): state = gate.apply_clifford(self, state, nqubits) return state - def execute_circuit(self, circuit, initial_state=None, nshots: int = 1000): + def execute_circuit( # pylint: disable=R1710 + self, circuit, initial_state=None, nshots: int = 1000 + ): """Execute a Clifford circuits. Args: @@ -150,6 +165,28 @@ def execute_circuit(self, circuit, initial_state=None, nshots: int = 1000): Returns: :class:`qibo.quantum_info.clifford.Clifford`: Object storing to the final results. """ + from qibo.quantum_info.clifford import Clifford # pylint: disable=C0415 + + if self.platform == "stim": + circuit_stim = self._stim.Circuit() # pylint: disable=E1101 + for gate in circuit.queue: + circuit_stim.append(gate.__class__.__name__, list(gate.qubits)) + + x_destab, z_destab, x_stab, z_stab, x_phases, z_phases = ( + self._stim.Tableau.from_circuit( # pylint: disable=no-member + circuit_stim + ).to_numpy() + ) + symplectic_matrix = np.block([[x_destab, z_destab], [x_stab, z_stab]]) + symplectic_matrix = np.c_[symplectic_matrix, np.r_[x_phases, z_phases]] + + return Clifford( + symplectic_matrix, + measurements=circuit.measurements, + nshots=nshots, + _backend=self, + ) + for gate in circuit.queue: if ( not gate.clifford @@ -159,11 +196,9 @@ def execute_circuit(self, circuit, initial_state=None, nshots: int = 1000): raise_error(RuntimeError, "Circuit contains non-Clifford gates.") if circuit.repeated_execution and nshots != 1: - return self.execute_circuit_repeated(circuit, initial_state, nshots) + return self.execute_circuit_repeated(circuit, nshots, initial_state) try: - from qibo.quantum_info.clifford import Clifford - nqubits = circuit.nqubits state = self.zero_state(nqubits) if initial_state is None else initial_state @@ -192,7 +227,7 @@ def execute_circuit(self, circuit, initial_state=None, nshots: int = 1000): "different one using ``qibo.set_device``.", ) - def execute_circuit_repeated(self, circuit, initial_state=None, nshots: int = 1000): + def execute_circuit_repeated(self, circuit, nshots: int = 1000, initial_state=None): """Execute a Clifford circuits ``nshots`` times. This is used for all the simulations that involve repeated execution. @@ -209,6 +244,8 @@ def execute_circuit_repeated(self, circuit, initial_state=None, nshots: int = 10 Returns: :class:`qibo.quantum_info.clifford.Clifford`: Object storing to the final results. """ + from qibo.quantum_info.clifford import Clifford # pylint: disable=C0415 + circuit_copy = circuit.copy() samples = [] for _ in range(nshots): @@ -218,10 +255,8 @@ def execute_circuit_repeated(self, circuit, initial_state=None, nshots: int = 10 samples.append(res.samples()) samples = self.np.vstack(samples) - for m in circuit.measurements: - m.result.register_samples(samples[:, m.target_qubits], self) - - from qibo.quantum_info.clifford import Clifford + for meas in circuit.measurements: + meas.result.register_samples(samples[:, meas.target_qubits], self) result = Clifford( self.zero_state(circuit.nqubits), @@ -240,7 +275,7 @@ def sample_shots( nqubits: int, nshots: int, collapse: bool = False, - ): + ): # pylint: disable=W0221 """Sample shots by measuring selected ``qubits`` in symplectic matrix of a ``state``. Args: diff --git a/src/qibo/quantum_info/clifford.py b/src/qibo/quantum_info/clifford.py index 7b89a36326..11d1b4e9ec 100644 --- a/src/qibo/quantum_info/clifford.py +++ b/src/qibo/quantum_info/clifford.py @@ -30,11 +30,11 @@ class Clifford: Defaults to ``None``. nshots (int, optional): number of shots used for sampling the measurements. Defaults to :math:`1000`. - engine (:class:`qibo.backends.abstract.Backend`, optional): engine to use in the execution - of the :class:`qibo.backends.CliffordBackend`. - It accepts all ``qibo`` backends besides the :class:`qibo.backends.TensorflowBackend`, - which is not supported. If ``None``, defaults to :class:`qibo.backends.NumpyBackend` - Defaults to ``None``. + engine (str, optional): engine to use in the execution of the + :class:`qibo.backends.CliffordBackend`. It accepts ``"numpy"``, ``"numba"``, + ``"cupy"``, and ``"stim"`` (see `stim `_). + If ``None``, defaults to the corresponding engine + from :class:`qibo.backends.GlobalBackend`. Defaults to ``None``. """ symplectic_matrix: np.ndarray = field(init=False) @@ -85,12 +85,11 @@ def from_circuit( Defaults to ``None``. nshots (int, optional): number of measurement shots to perform if ``circuit`` has measurement gates. Defaults to :math:`10^{3}`. - engine (:class:`qibo.backends.abstract.Backend`, optional): engine to use in the - execution of the :class:`qibo.backends.CliffordBackend`. - It accepts all ``qibo`` backends besides the - :class:`qibo.backends.TensorflowBackend`, which is not supported. - If ``None``, defaults to :class:`qibo.backends.NumpyBackend`. - Defaults to ``None``. + engine (str, optional): engine to use in the execution of the + :class:`qibo.backends.CliffordBackend`. It accepts ``"numpy"``, ``"numba"``, + ``"cupy"``, and ``"stim"`` (see `stim `_). + If ``None``, defaults to the corresponding engine + from :class:`qibo.backends.GlobalBackend`. Defaults to ``None``. Returns: (:class:`qibo.quantum_info.clifford.Clifford`): Object storing the result of the circuit execution. diff --git a/tests/test_backends_clifford.py b/tests/test_backends_clifford.py index 7ea9c7c7c3..6ee566e52a 100644 --- a/tests/test_backends_clifford.py +++ b/tests/test_backends_clifford.py @@ -223,20 +223,26 @@ def test_set_backend(backend): assert global_platform == platform -def test_noise_channels(backend): +@pytest.mark.parametrize("seed", [2024]) +def test_noise_channels(backend, seed): clifford_bkd = construct_clifford_backend(backend) - nqubits = 3 - c = random_clifford(nqubits, backend=backend) - c.density_matrix = True - c_copy = c.copy() - c.add(gates.M(*range(nqubits))) - c_copy.add(gates.M(*range(nqubits))) + backend.set_seed(seed) + clifford_bkd.set_seed(seed) + noise = NoiseModel() noise.add(PauliError([("X", 0.5)]), gates.X) noise.add(DepolarizingError(0.1), gates.CZ) + + nqubits = 3 + + c = random_clifford(nqubits, density_matrix=True, seed=seed, backend=backend) + c.add(gates.M(*range(nqubits))) + c_copy = c.copy() + c = noise.apply(c) c_copy = noise.apply(c_copy) + numpy_result = numpy_bkd.execute_circuit(c) clifford_result = clifford_bkd.execute_circuit(c_copy) @@ -245,3 +251,18 @@ def test_noise_channels(backend): clifford_result.probabilities(), atol=1e-1, ) + + +def test_stim(backend): + clifford_bkd = construct_clifford_backend(backend) + clifford_stim = CliffordBackend(engine="stim") + + nqubits = 3 + circuit = random_clifford(nqubits, backend=backend) + + result_qibo = clifford_bkd.execute_circuit(circuit) + result_stim = clifford_stim.execute_circuit(circuit) + + backend.assert_allclose( + result_stim.symplectic_matrix, result_qibo.symplectic_matrix + )