diff --git a/poetry.lock b/poetry.lock index be45cd53..8bd8dfb1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. [[package]] name = "appnope" version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -15,6 +16,7 @@ files = [ name = "astroid" version = "2.15.8" description = "An abstract syntax tree for Python with inference support." +category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -34,6 +36,7 @@ wrapt = [ name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" +category = "dev" optional = false python-versions = "*" files = [ @@ -45,6 +48,7 @@ files = [ name = "cloudpickle" version = "3.0.0" description = "Pickler class to extend the standard pickle.Pickler functionality" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -56,6 +60,7 @@ files = [ name = "cma" version = "3.3.0" description = "CMA-ES, Covariance Matrix Adaptation Evolution Strategy for non-linear numerical optimization in Python" +category = "main" optional = false python-versions = "*" files = [ @@ -74,6 +79,7 @@ plotting = ["matplotlib"] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -83,63 +89,64 @@ files = [ [[package]] name = "coverage" -version = "7.4.1" +version = "7.4.3" description = "Code coverage measurement for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7"}, - {file = "coverage-7.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b"}, - {file = "coverage-7.4.1-cp310-cp310-win32.whl", hash = "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016"}, - {file = "coverage-7.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018"}, - {file = "coverage-7.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295"}, - {file = "coverage-7.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6"}, - {file = "coverage-7.4.1-cp311-cp311-win32.whl", hash = "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5"}, - {file = "coverage-7.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968"}, - {file = "coverage-7.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581"}, - {file = "coverage-7.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc"}, - {file = "coverage-7.4.1-cp312-cp312-win32.whl", hash = "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74"}, - {file = "coverage-7.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448"}, - {file = "coverage-7.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218"}, - {file = "coverage-7.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad"}, - {file = "coverage-7.4.1-cp38-cp38-win32.whl", hash = "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042"}, - {file = "coverage-7.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d"}, - {file = "coverage-7.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54"}, - {file = "coverage-7.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35"}, - {file = "coverage-7.4.1-cp39-cp39-win32.whl", hash = "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c"}, - {file = "coverage-7.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a"}, - {file = "coverage-7.4.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166"}, - {file = "coverage-7.4.1.tar.gz", hash = "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04"}, + {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, + {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, + {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, + {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, + {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, + {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, + {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, + {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, + {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, + {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, + {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, + {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, + {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, + {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, + {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, + {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, + {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, + {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, + {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, + {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, + {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, + {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, ] [package.dependencies] @@ -152,6 +159,7 @@ toml = ["tomli"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -163,6 +171,7 @@ files = [ name = "dill" version = "0.3.8" description = "serialize all of Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -178,6 +187,7 @@ profile = ["gprof2dot (>=2022.7.29)"] name = "exceptiongroup" version = "1.2.0" description = "Backport of PEP 654 (exception groups)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -190,18 +200,21 @@ test = ["pytest (>=6)"] [[package]] name = "future" -version = "0.18.3" +version = "1.0.0" description = "Clean single-source support for Python 3 and 2" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ - {file = "future-0.18.3.tar.gz", hash = "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307"}, + {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, + {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, ] [[package]] name = "hyperopt" version = "0.2.7" description = "Distributed Asynchronous Hyperparameter Optimization" +category = "main" optional = false python-versions = "*" files = [ @@ -229,6 +242,7 @@ sparktrials = ["pyspark"] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -240,6 +254,7 @@ files = [ name = "ipython" version = "7.34.0" description = "IPython: Productive Interactive Computing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -276,6 +291,7 @@ test = ["ipykernel", "nbformat", "nose (>=0.10.1)", "numpy (>=1.17)", "pygments" name = "isort" version = "5.13.2" description = "A Python utility / library to sort Python imports." +category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -290,6 +306,7 @@ colors = ["colorama (>=0.4.6)"] name = "jedi" version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -309,6 +326,7 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "joblib" version = "1.3.2" description = "Lightweight pipelining with Python functions" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -320,6 +338,7 @@ files = [ name = "lazy-object-proxy" version = "1.10.0" description = "A fast and thorough lazy object proxy." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -366,6 +385,7 @@ files = [ name = "llvmlite" version = "0.42.0" description = "lightweight wrapper around basic LLVM functionality" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -396,6 +416,7 @@ files = [ name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -410,6 +431,7 @@ traitlets = "*" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -421,6 +443,7 @@ files = [ name = "mpmath" version = "1.3.0" description = "Python library for arbitrary-precision floating-point arithmetic" +category = "main" optional = false python-versions = "*" files = [ @@ -438,6 +461,7 @@ tests = ["pytest (>=4.6)"] name = "networkx" version = "3.2.1" description = "Python package for creating and manipulating graphs and networks" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -456,6 +480,7 @@ test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] name = "numba" version = "0.59.0" description = "compiling Python code using LLVM" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -483,13 +508,14 @@ files = [ ] [package.dependencies] -llvmlite = "==0.42.*" +llvmlite = ">=0.42.0dev0,<0.43" numpy = ">=1.22,<1.27" [[package]] name = "numpy" version = "1.26.4" description = "Fundamental package for array computing in Python" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -535,6 +561,7 @@ files = [ name = "packaging" version = "23.2" description = "Core utilities for Python packages" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -546,6 +573,7 @@ files = [ name = "parso" version = "0.8.3" description = "A Python Parser" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -561,6 +589,7 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pexpect" version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." +category = "dev" optional = false python-versions = "*" files = [ @@ -575,6 +604,7 @@ ptyprocess = ">=0.5" name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" +category = "dev" optional = false python-versions = "*" files = [ @@ -586,6 +616,7 @@ files = [ name = "platformdirs" version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -601,6 +632,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest- name = "pluggy" version = "1.4.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -616,6 +648,7 @@ testing = ["pytest", "pytest-benchmark"] name = "prompt-toolkit" version = "3.0.43" description = "Library for building powerful interactive command lines in Python" +category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -630,6 +663,7 @@ wcwidth = "*" name = "psutil" version = "5.9.8" description = "Cross-platform lib for process and system monitoring in Python." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -658,6 +692,7 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" +category = "dev" optional = false python-versions = "*" files = [ @@ -669,6 +704,7 @@ files = [ name = "py4j" version = "0.10.9.7" description = "Enables Python programs to dynamically access arbitrary Java objects" +category = "main" optional = false python-versions = "*" files = [ @@ -680,6 +716,7 @@ files = [ name = "pygments" version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -695,6 +732,7 @@ windows-terminal = ["colorama (>=0.4.6)"] name = "pylint" version = "2.17.7" description = "python code static checker" +category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -724,6 +762,7 @@ testutils = ["gitpython (>3)"] name = "pytest" version = "7.4.4" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -746,6 +785,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -764,6 +804,7 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-env" version = "0.8.2" description = "py.test plugin that allows you to add environment variables." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -781,6 +822,7 @@ test = ["coverage (>=7.2.7)", "pytest-mock (>=3.10)"] name = "qibo" version = "0.2.4" description = "A framework for quantum computing with hardware acceleration." +category = "main" optional = false python-versions = ">=3.9,<3.12" files = [ @@ -800,6 +842,7 @@ tabulate = ">=0.9.0,<0.10.0" name = "scipy" version = "1.12.0" description = "Fundamental algorithms for scientific computing in Python" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -840,24 +883,26 @@ test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", [[package]] name = "setuptools" -version = "69.1.0" +version = "69.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.1.0-py3-none-any.whl", hash = "sha256:c054629b81b946d63a9c6e732bc8b2513a7c3ea645f11d0139a2191d735c60c6"}, - {file = "setuptools-69.1.0.tar.gz", hash = "sha256:850894c4195f09c4ed30dba56213bf7c3f21d86ed6bdaafb5df5972593bfc401"}, + {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, + {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -869,6 +914,7 @@ files = [ name = "sympy" version = "1.12" description = "Computer algebra system (CAS) in Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -883,6 +929,7 @@ mpmath = ">=0.19" name = "tabulate" version = "0.9.0" description = "Pretty-print tabular data" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -897,6 +944,7 @@ widechars = ["wcwidth"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -908,6 +956,7 @@ files = [ name = "tomlkit" version = "0.12.3" description = "Style preserving TOML library" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -919,6 +968,7 @@ files = [ name = "tqdm" version = "4.66.2" description = "Fast, Extensible Progress Meter" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -939,6 +989,7 @@ telegram = ["requests"] name = "traitlets" version = "5.14.1" description = "Traitlets Python configuration system" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -952,19 +1003,21 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, [[package]] name = "typing-extensions" -version = "4.9.0" +version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, - {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] [[package]] name = "wcwidth" version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" +category = "dev" optional = false python-versions = "*" files = [ @@ -976,6 +1029,7 @@ files = [ name = "wrapt" version = "1.16.0" description = "Module for decorators, wrappers and monkey patching." +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1053,5 +1107,5 @@ files = [ [metadata] lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "24eb1e151039a5ba7908579cf8e18b7175c9b385adcbcc36322f600c1a8f1b50" +python-versions = ">=3.9.0,<3.12" +content-hash = "889aec5a74487e201285450cca34b04384003b283433ad0338418a39634ec96d" diff --git a/pyproject.toml b/pyproject.toml index 31509c6f..ee61ec9f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,9 +20,9 @@ classifiers = [ ] [tool.poetry.dependencies] -python = "^3.9,<3.12" -numba = ">=0.51.0" -qibo = ">=0.2.3" +python=">=3.9.0,<3.12" +numba=">=0.51.0" +qibo=">=0.2.4" scipy = "^1.10.1" psutil = "^5.9.5" @@ -49,6 +49,11 @@ output-format = "colorized" [tool.pylint.reports] output-format = "colorized" +[tool.coverage.run] +omit = [ + "src/qibojit/backends/clifford_operations*", +] + [tool.pytest.ini_options] testpaths = ['src/qibojit/tests/'] addopts = ['--cov=qibojit', '--cov-report=xml'] diff --git a/src/qibojit/backends/clifford_operations_cpu.py b/src/qibojit/backends/clifford_operations_cpu.py new file mode 100644 index 00000000..9d595165 --- /dev/null +++ b/src/qibojit/backends/clifford_operations_cpu.py @@ -0,0 +1,311 @@ +"""Set of custom Numba operations for the Clifford backend.""" + +import numpy as np +from numba import njit, prange, uint64 + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def H(symplectic_matrix, q, nqubits): + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ (x[i, q] & z[i, q]) + tmp = symplectic_matrix[i, q] + symplectic_matrix[i, q] = symplectic_matrix[i, nqubits + q] + symplectic_matrix[i, nqubits + q] = tmp + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True) +def CNOT(symplectic_matrix, control_q, target_q, nqubits): + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ (x[i, control_q] & z[i, target_q]) & ( + x[i, target_q] ^ ~z[i, control_q] + ) + symplectic_matrix[i, target_q] = x[i, target_q] ^ x[i, control_q] + symplectic_matrix[i, nqubits + control_q] = z[i, control_q] ^ z[i, target_q] + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True) +def CZ(symplectic_matrix, control_q, target_q, nqubits): + """Decomposition --> H-CNOT-H""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = ( + r[i] + ^ (x[i, target_q] & z[i, target_q]) + ^ (x[i, control_q] & x[i, target_q] & (z[i, target_q] ^ ~z[i, control_q])) + ^ (x[i, target_q] & (z[i, target_q] ^ x[i, control_q])) + ) + z_control_q = x[i, target_q] ^ z[i, control_q] + z_target_q = z[i, target_q] ^ x[i, control_q] + symplectic_matrix[i, nqubits + control_q] = z_control_q + symplectic_matrix[i, nqubits + target_q] = z_target_q + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def S(symplectic_matrix, q, nqubits): + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ (x[i, q] & z[i, q]) + symplectic_matrix[i, nqubits + q] = z[i, q] ^ x[i, q] + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def Z(symplectic_matrix, q, nqubits): + """Decomposition --> S-S""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ ( + (x[i, q] & z[i, q]) ^ x[i, q] & (z[i, q] ^ x[i, q]) + ) + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def X(symplectic_matrix, q, nqubits): + """Decomposition --> H-S-S-H""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = ( + r[i] ^ (z[i, q] & (z[i, q] ^ x[i, q])) ^ (z[i, q] & x[i, q]) + ) + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def Y(symplectic_matrix, q, nqubits): + """Decomposition --> S-S-H-S-S-H""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = ( + r[i] ^ (z[i, q] & (z[i, q] ^ x[i, q])) ^ (x[i, q] & (z[i, q] ^ x[i, q])) + ) + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def SX(symplectic_matrix, q, nqubits): + """Decomposition --> H-S-H""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ (z[i, q] & (z[i, q] ^ x[i, q])) + symplectic_matrix[i, q] = z[i, q] ^ x[i, q] + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def SDG(symplectic_matrix, q, nqubits): + """Decomposition --> S-S-S""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ (x[i, q] & (z[i, q] ^ x[i, q])) + symplectic_matrix[i, nqubits + q] = z[i, q] ^ x[i, q] + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def SXDG(symplectic_matrix, q, nqubits): + """Decomposition --> H-S-S-S-H""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ (z[i, q] & x[i, q]) + symplectic_matrix[i, q] = z[i, q] ^ x[i, q] + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def RY_pi(symplectic_matrix, q, nqubits): + """Decomposition --> H-S-S""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ (x[i, q] & (z[i, q] ^ x[i, q])) + zq = symplectic_matrix[i, nqubits + q] + symplectic_matrix[i, nqubits + q] = symplectic_matrix[i, q] + symplectic_matrix[i, q] = zq + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True) +def RY_3pi_2(symplectic_matrix, q, nqubits): + """Decomposition --> H-S-S""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = r[i] ^ (z[i, q] & (z[i, q] ^ x[i, q])) + zq = symplectic_matrix[i, nqubits + q] + symplectic_matrix[i, nqubits + q] = symplectic_matrix[i, q] + symplectic_matrix[i, q] = zq + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True) +def SWAP(symplectic_matrix, control_q, target_q, nqubits): + """Decomposition --> CNOT-CNOT-CNOT""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = ( + r[i] + ^ (x[i, control_q] & z[i, target_q] & (x[i, target_q] ^ ~z[i, control_q])) + ^ ( + (x[i, target_q] ^ x[i, control_q]) + & (z[i, target_q] ^ z[i, control_q]) + & (z[i, target_q] ^ ~x[i, control_q]) + ) + ^ ( + x[i, target_q] + & z[i, control_q] + & (x[i, control_q] ^ x[i, target_q] ^ z[i, control_q] ^ ~z[i, target_q]) + ) + ) + x_cq = symplectic_matrix[i, control_q] + x_tq = symplectic_matrix[i, target_q] + z_cq = symplectic_matrix[i, nqubits + control_q] + z_tq = symplectic_matrix[i, nqubits + target_q] + symplectic_matrix[i, control_q] = x_tq + symplectic_matrix[i, target_q] = x_cq + symplectic_matrix[i, nqubits + control_q] = z_tq + symplectic_matrix[i, nqubits + target_q] = z_cq + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True) +def iSWAP(symplectic_matrix, control_q, target_q, nqubits): + """Decomposition --> H-CNOT-CNOT-H-S-S""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = ( + r[i] + ^ (x[i, target_q] & z[i, target_q]) + ^ (x[i, control_q] & z[i, control_q]) + ^ (x[i, control_q] & (z[i, control_q] ^ x[i, control_q])) + ^ ( + (z[i, control_q] ^ x[i, control_q]) + & (z[i, target_q] ^ x[i, target_q]) + & (x[i, target_q] ^ ~x[i, control_q]) + ) + ^ ( + (x[i, target_q] ^ z[i, control_q] ^ x[i, control_q]) + & (x[i, target_q] ^ z[i, target_q] ^ x[i, control_q]) + & (x[i, target_q] ^ z[i, target_q] ^ x[i, control_q] ^ ~z[i, control_q]) + ) + ^ (x[i, control_q] & (x[i, target_q] ^ x[i, control_q] ^ z[i, control_q])) + ) + z_control_q = x[i, target_q] ^ z[i, target_q] ^ x[i, control_q] + z_target_q = x[i, target_q] ^ z[i, control_q] ^ x[i, control_q] + symplectic_matrix[i, nqubits + control_q] = z_control_q + symplectic_matrix[i, nqubits + target_q] = z_target_q + tmp = symplectic_matrix[i, control_q] + symplectic_matrix[i, control_q] = symplectic_matrix[i, target_q] + symplectic_matrix[i, target_q] = tmp + return symplectic_matrix + + +@njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True) +def CY(symplectic_matrix, control_q, target_q, nqubits): + """Decomposition --> S-CNOT-SDG""" + r = symplectic_matrix[:-1, -1] + x = symplectic_matrix[:-1, :nqubits] + z = symplectic_matrix[:-1, nqubits:-1] + for i in prange(symplectic_matrix.shape[0]): # pylint: disable=not-an-iterable + symplectic_matrix[i, -1] = ( + r[i] + ^ (x[i, target_q] & (z[i, target_q] ^ x[i, target_q])) + ^ ( + x[i, control_q] + & (x[i, target_q] ^ z[i, target_q]) + & (z[i, control_q] ^ ~x[i, target_q]) + ) + ^ ((x[i, target_q] ^ x[i, control_q]) & (z[i, target_q] ^ x[i, target_q])) + ) + x_target_q = x[i, control_q] ^ x[i, target_q] + z_control_q = z[i, control_q] ^ z[i, target_q] ^ x[i, target_q] + z_target_q = z[i, target_q] ^ x[i, control_q] + symplectic_matrix[i, target_q] = x_target_q + symplectic_matrix[i, nqubits + control_q] = z_control_q + symplectic_matrix[i, nqubits + target_q] = z_target_q + return symplectic_matrix + + +@njit( + [ + "b1[:,:](b1[:,:], u8[:], u8[:], u8, b1)", + "b1[:,:](b1[:,:], u4[:], u4[:], u4, b1)", + ], + parallel=True, + cache=True, + fastmath=True, +) +def _rowsum(symplectic_matrix, h, i, nqubits, determined=False): + xi, xh = symplectic_matrix[i, :nqubits], symplectic_matrix[h, :nqubits] + zi, zh = symplectic_matrix[i, nqubits:-1], symplectic_matrix[h, nqubits:-1] + if determined: + g_r = np.array([False for _ in range(h.shape[0])]) + g_xi_xh = xi.copy() + g_zi_zh = xi.copy() + for j in prange(len(h)): # pylint: disable=not-an-iterable + exp = np.zeros(nqubits, dtype=uint64) + x1_eq_z1 = (xi[j] ^ zi[j]) == False + x1_neq_z1 = ~x1_eq_z1 + x1_eq_0 = xi[j] == False + x1_eq_1 = ~x1_eq_0 + ind2 = x1_eq_z1 & x1_eq_1 + ind3 = x1_eq_1 & x1_neq_z1 + ind4 = x1_eq_0 & x1_neq_z1 + exp[ind2] = zh[j, ind2].astype(uint64) - xh[j, ind2].astype(uint64) + exp[ind3] = zh[j, ind3].astype(uint64) * (2 * xh[j, ind3].astype(uint64) - 1) + exp[ind4] = xh[j, ind4].astype(uint64) * (1 - 2 * zh[j, ind4].astype(uint64)) + + r = ( + 2 * symplectic_matrix[h[j], -1] + + 2 * symplectic_matrix[i[j], -1] + + np.sum(exp) + ) % 4 != 0 + xi_xh = xi[j] ^ xh[j] + zi_zh = zi[j] ^ zh[j] + if determined: # for some reason xor reduction fails here + g_r[j] = r # thus, I cannot do g_r += r here + g_xi_xh[j] = xi_xh + g_zi_zh[j] = zi_zh + else: + symplectic_matrix[h[j], -1] = r + symplectic_matrix[h[j], :nqubits] = xi_xh + symplectic_matrix[h[j], nqubits:-1] = zi_zh + if determined: + for j in prange(len(g_r)): # pylint: disable=not-an-iterable + symplectic_matrix[h[0], -1] ^= g_r[j] + symplectic_matrix[h[0], :nqubits] ^= g_xi_xh[j] + symplectic_matrix[h[0], nqubits:-1] ^= g_zi_zh[j] + return symplectic_matrix diff --git a/src/qibojit/backends/clifford_operations_gpu.py b/src/qibojit/backends/clifford_operations_gpu.py new file mode 100644 index 00000000..1039c2bc --- /dev/null +++ b/src/qibojit/backends/clifford_operations_gpu.py @@ -0,0 +1,727 @@ +"""Set of custom CuPy operations for the Clifford backend.""" + +from functools import cache + +import cupy as cp # pylint: disable=E0401 +from scipy import sparse + +np = cp + +GRIDDIM, BLOCKDIM = 1024, 128 +GRIDDIM_2D = (1024, 1024) + + +@cache +def _get_dim(nqubits): + return 2 * nqubits + 1 + + +apply_one_qubit_kernel = """ +extern "C" +__global__ void apply_{}(bool* symplectic_matrix, const int q, const int nqubits, const int qz, const int dim) {{ + _apply_{}(symplectic_matrix, q, nqubits, qz, dim); +}} +""" + +apply_two_qubits_kernel = """ +extern "C" +__global__ void apply_{}(bool* symplectic_matrix, const int control_q, const int target_q, const int nqubits, const int cqz, const int tqz, const int dim) {{ + _apply_{}(symplectic_matrix, control_q, target_q, nqubits, cqz, tqz, dim); +}} +""" + + +def one_qubit_kernel_launcher(kernel, symplectic_matrix, q, nqubits): + qz = nqubits + q + dim = _get_dim(nqubits) + return kernel((GRIDDIM,), (BLOCKDIM,), (symplectic_matrix, q, nqubits, qz, dim)) + + +def two_qubits_kernel_launcher(kernel, symplectic_matrix, control_q, target_q, nqubits): + cqz = nqubits + control_q + tqz = nqubits + target_q + dim = _get_dim(nqubits) + return kernel( + (GRIDDIM,), + (BLOCKDIM,), + (symplectic_matrix, control_q, target_q, nqubits, cqz, tqz, dim), + ) + + +apply_H = """ +__device__ void _apply_H(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ (symplectic_matrix[i * dim + q] & symplectic_matrix[i * dim + qz]); + const bool tmp = symplectic_matrix[i * dim + q]; + symplectic_matrix[i * dim + q] = symplectic_matrix[i * dim + qz]; + symplectic_matrix[i * dim + qz] = tmp; + }; +} +""" + apply_one_qubit_kernel.format( + "H", "H" +) + +apply_H = cp.RawKernel(apply_H, "apply_H", options=("--std=c++11",)) + + +def H(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_H, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_CNOT = """ +__device__ void _apply_CNOT(bool* symplectic_matrix, const int& control_q, const int& target_q, const int& nqubits, const int& cqz, const int& tqz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ ( + symplectic_matrix[i * dim + control_q] & symplectic_matrix[i * dim + tqz] + ) & (symplectic_matrix[i * dim + target_q] ^ symplectic_matrix[i * dim + cqz] ^ 1); + symplectic_matrix[i * dim + target_q] = ( + symplectic_matrix[i * dim + target_q] ^ symplectic_matrix[i * dim + control_q] + ); + symplectic_matrix[i * dim + cqz] = ( + symplectic_matrix[i * dim + cqz] ^ symplectic_matrix[i * dim + tqz] + ); + }; +} +""" + apply_two_qubits_kernel.format( + "CNOT", "CNOT" +) + +apply_CNOT = cp.RawKernel(apply_CNOT, "apply_CNOT", options=("--std=c++11",)) + + +def CNOT(symplectic_matrix, control_q, target_q, nqubits): + two_qubits_kernel_launcher( + apply_CNOT, symplectic_matrix, control_q, target_q, nqubits + ) + return symplectic_matrix + + +apply_CZ = """ +__device__ void _apply_CZ(bool* symplectic_matrix, const int& control_q, const int& target_q, const int& nqubits, const int& cqz, const int& tqz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = ( + symplectic_matrix[i * dim + last] + ^ (symplectic_matrix[i * dim + target_q] & symplectic_matrix[i * dim + tqz]) + ^ ( + symplectic_matrix[i * dim + control_q] + & symplectic_matrix[i * dim + target_q] + & (symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + cqz] ^ 1) + ) + ^ ( + symplectic_matrix[i * dim + target_q] + & (symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + control_q]) + ) + ); + const bool z_control_q = symplectic_matrix[i * dim + target_q] ^ symplectic_matrix[i * dim + cqz]; + const bool z_target_q = symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + control_q]; + symplectic_matrix[i * dim + cqz] = z_control_q; + symplectic_matrix[i * dim + tqz] = z_target_q; + }; +} +""" + apply_two_qubits_kernel.format( + "CZ", "CZ" +) + +apply_CZ = cp.RawKernel(apply_CZ, "apply_CZ", options=("--std=c++11",)) + + +def CZ(symplectic_matrix, control_q, target_q, nqubits): + two_qubits_kernel_launcher( + apply_CZ, symplectic_matrix, control_q, target_q, nqubits + ) + return symplectic_matrix + + +apply_S = """ +__device__ void _apply_S(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ ( + symplectic_matrix[i * dim + q] & symplectic_matrix[i * dim + qz] + ); + symplectic_matrix[i * dim + qz] = symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]; + }; +} +""" + apply_one_qubit_kernel.format( + "S", "S" +) + +apply_S = cp.RawKernel(apply_S, "apply_S", options=("--std=c++11",)) + + +def S(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_S, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_Z = """ +__device__ void _apply_Z(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ ( + (symplectic_matrix[i * dim + q] & symplectic_matrix[i * dim + qz]) + ^ symplectic_matrix[i * dim + q] + & (symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]) + ); + }; +} +""" + apply_one_qubit_kernel.format( + "Z", "Z" +) + +apply_Z = cp.RawKernel(apply_Z, "apply_Z", options=("--std=c++11",)) + + +def Z(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_Z, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_X = """ +__device__ void _apply_X(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = ( + symplectic_matrix[i * dim + last] + ^ ( + symplectic_matrix[i * dim + qz] + & (symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]) + ) + ^ (symplectic_matrix[i * dim + qz] & symplectic_matrix[i * dim + q]) + ); + }; +} +""" + apply_one_qubit_kernel.format( + "X", "X" +) + +apply_X = cp.RawKernel(apply_X, "apply_X", options=("--std=c++11",)) + + +def X(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_X, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_Y = """ +__device__ void _apply_Y(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = ( + symplectic_matrix[i * dim + last] + ^ ( + symplectic_matrix[i * dim + qz] + & (symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]) + ) + ^ ( + symplectic_matrix[i * dim + q] + & (symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]) + ) + ); + }; +} +""" + apply_one_qubit_kernel.format( + "Y", "Y" +) + +apply_Y = cp.RawKernel(apply_Y, "apply_Y", options=("--std=c++11",)) + + +def Y(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_Y, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_SX = """ +__device__ void _apply_SX(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ ( + symplectic_matrix[i * dim + qz] + & (symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]) + ); + symplectic_matrix[i * dim + q] = symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]; + }; +} +""" + apply_one_qubit_kernel.format( + "SX", "SX" +) + +apply_SX = cp.RawKernel(apply_SX, "apply_SX", options=("--std=c++11",)) + + +def SX(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_SX, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_SDG = """ +__device__ void _apply_SDG(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ ( + symplectic_matrix[i * dim + q] + & (symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]) + ); + symplectic_matrix[i * dim + qz] = symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]; + }; +} +""" + apply_one_qubit_kernel.format( + "SDG", "SDG" +) + +apply_SDG = cp.RawKernel(apply_SDG, "apply_SDG", options=("--std=c++11",)) + + +def SDG(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_SDG, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_SXDG = """ +__device__ void _apply_SXDG(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ ( + symplectic_matrix[i * dim + qz] & symplectic_matrix[i * dim + q] + ); + symplectic_matrix[i * dim + q] = symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]; + }; +} +""" + apply_one_qubit_kernel.format( + "SXDG", "SXDG" +) + +apply_SXDG = cp.RawKernel(apply_SXDG, "apply_SXDG", options=("--std=c++11",)) + + +def SXDG(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_SXDG, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_RY_pi = """ +__device__ void _apply_RY_pi(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ ( + symplectic_matrix[i * dim + q] + & (symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]) + ); + const bool zq = symplectic_matrix[i * dim + qz]; + symplectic_matrix[i * dim + qz] = symplectic_matrix[i * dim + q]; + symplectic_matrix[i * dim + q] = zq; + }; +} +""" + apply_one_qubit_kernel.format( + "RY_pi", "RY_pi" +) + +apply_RY_pi = cp.RawKernel(apply_RY_pi, "apply_RY_pi", options=("--std=c++11",)) + + +def RY_pi(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_RY_pi, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_RY_3pi_2 = """ +__device__ void _apply_RY_3pi_2(bool* symplectic_matrix, const int& q, const int& nqubits, const int& qz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = symplectic_matrix[i * dim + last] ^ ( + symplectic_matrix[i * dim + qz] + & (symplectic_matrix[i * dim + qz] ^ symplectic_matrix[i * dim + q]) + ); + const bool zq = symplectic_matrix[i * dim + qz]; + symplectic_matrix[i * dim + qz] = symplectic_matrix[i * dim + q]; + symplectic_matrix[i * dim + q] = zq; + }; +} +""" + apply_one_qubit_kernel.format( + "RY_3pi_2", "RY_3pi_2" +) + +apply_RY_3pi_2 = cp.RawKernel( + apply_RY_3pi_2, "apply_RY_3pi_2", options=("--std=c++11",) +) + + +def RY_3pi_2(symplectic_matrix, q, nqubits): + one_qubit_kernel_launcher(apply_RY_3pi_2, symplectic_matrix, q, nqubits) + return symplectic_matrix + + +apply_SWAP = """ +__device__ void _apply_SWAP(bool* symplectic_matrix, const int& control_q, const int& target_q, const int& nqubits, const int& cqz, const int& tqz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = ( + symplectic_matrix[i * dim + last] + ^ ( + symplectic_matrix[i * dim + control_q] + & symplectic_matrix[i * dim + tqz] + & (symplectic_matrix[i * dim + target_q] ^ symplectic_matrix[i * dim + cqz] ^ 1) + ) + ^ ( + (symplectic_matrix[i * dim + target_q] ^ symplectic_matrix[i * dim + control_q]) + & (symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + cqz]) + & (symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + control_q] ^ 1) + ) + ^ ( + symplectic_matrix[i * dim + target_q] + & symplectic_matrix[i * dim + cqz] + & ( + symplectic_matrix[i * dim + control_q] + ^ symplectic_matrix[i * dim + target_q] + ^ symplectic_matrix[i * dim + cqz] + ^ symplectic_matrix[i * dim + tqz] ^ 1 + ) + ) + ); + const bool x_cq = symplectic_matrix[i * dim + control_q]; + const bool x_tq = symplectic_matrix[i * dim + target_q]; + const bool z_cq = symplectic_matrix[i * dim + cqz]; + const bool z_tq = symplectic_matrix[i * dim + tqz]; + symplectic_matrix[i * dim + control_q] = x_tq; + symplectic_matrix[i * dim + target_q] = x_cq; + symplectic_matrix[i * dim + cqz] = z_tq; + symplectic_matrix[i * dim + tqz] = z_cq; + }; +} +""" + apply_two_qubits_kernel.format( + "SWAP", "SWAP" +) + +apply_SWAP = cp.RawKernel(apply_SWAP, "apply_SWAP", options=("--std=c++11",)) + + +def SWAP(symplectic_matrix, control_q, target_q, nqubits): + two_qubits_kernel_launcher( + apply_SWAP, symplectic_matrix, control_q, target_q, nqubits + ) + return symplectic_matrix + + +apply_iSWAP = """ +__device__ void _apply_iSWAP(bool* symplectic_matrix, const int& control_q, const int& target_q, const int& nqubits, const int& cqz, const int& tqz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = ( + symplectic_matrix[i * dim + last] + ^ (symplectic_matrix[i * dim + target_q] & symplectic_matrix[i * dim + tqz]) + ^ (symplectic_matrix[i * dim + control_q] & symplectic_matrix[i * dim + cqz]) + ^ ( + symplectic_matrix[i * dim + control_q] + & (symplectic_matrix[i * dim + cqz] ^ symplectic_matrix[i * dim + control_q]) + ) + ^ ( + (symplectic_matrix[i * dim + cqz] ^ symplectic_matrix[i * dim + control_q]) + & (symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + target_q]) + & (symplectic_matrix[i * dim + target_q] ^ symplectic_matrix[i * dim + control_q] ^ 1) + ) + ^ ( + ( + symplectic_matrix[i * dim + target_q] + ^ symplectic_matrix[i * dim + cqz] + ^ symplectic_matrix[i * dim + control_q] + ) + & ( + symplectic_matrix[i * dim + target_q] + ^ symplectic_matrix[i * dim + tqz] + ^ symplectic_matrix[i * dim + control_q] + ) + & ( + symplectic_matrix[i * dim + target_q] + ^ symplectic_matrix[i * dim + tqz] + ^ symplectic_matrix[i * dim + control_q] + ^ symplectic_matrix[i * dim + cqz] ^ 1 + ) + ) + ^ ( + symplectic_matrix[i * dim + control_q] + & ( + symplectic_matrix[i * dim + target_q] + ^ symplectic_matrix[i * dim + control_q] + ^ symplectic_matrix[i * dim + cqz] + ) + ) + ); + const bool z_control_q = ( + symplectic_matrix[i * dim + target_q] + ^ symplectic_matrix[i * dim + tqz] + ^ symplectic_matrix[i * dim + control_q] + ); + const bool z_target_q = ( + symplectic_matrix[i * dim + target_q] + ^ symplectic_matrix[i * dim + cqz] + ^ symplectic_matrix[i * dim + control_q] + ); + symplectic_matrix[i * dim + cqz] = z_control_q; + symplectic_matrix[i * dim + tqz] = z_target_q; + const bool tmp = symplectic_matrix[i * dim + control_q]; + symplectic_matrix[i * dim + control_q] = symplectic_matrix[i * dim + target_q]; + symplectic_matrix[i * dim + target_q] = tmp; + }; +} +""" + apply_two_qubits_kernel.format( + "iSWAP", "iSWAP" +) + +apply_iSWAP = cp.RawKernel(apply_iSWAP, "apply_iSWAP", options=("--std=c++11",)) + + +def iSWAP(symplectic_matrix, control_q, target_q, nqubits): + two_qubits_kernel_launcher( + apply_iSWAP, symplectic_matrix, control_q, target_q, nqubits + ) + return symplectic_matrix + + +apply_CY = """ +__device__ void _apply_CY(bool* symplectic_matrix, const int& control_q, const int& target_q, const int& nqubits, const int& cqz, const int& tqz, const int& dim) { + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + const int ntid = gridDim.x * blockDim.x; + const int last = dim - 1; + for(int i = tid; i < last; i += ntid) { + symplectic_matrix[i * dim + last] = ( + symplectic_matrix[i * dim + last] + ^ ( + symplectic_matrix[i * dim + target_q] + & (symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + target_q]) + ) + ^ ( + symplectic_matrix[i * dim + control_q] + & (symplectic_matrix[i * dim + target_q] ^ symplectic_matrix[i * dim + tqz]) + & (symplectic_matrix[i * dim + cqz] ^ symplectic_matrix[i * dim + target_q] ^ 1) + ) + ^ ( + (symplectic_matrix[i * dim + target_q] ^ symplectic_matrix[i * dim + control_q]) + & (symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + target_q]) + ) + ); + const bool x_target_q = symplectic_matrix[i * dim + control_q] ^ symplectic_matrix[i * dim + target_q]; + const bool z_control_q = ( + symplectic_matrix[i * dim + cqz] + ^ symplectic_matrix[i * dim + tqz] + ^ symplectic_matrix[i * dim + target_q] + ); + const bool z_target_q = symplectic_matrix[i * dim + tqz] ^ symplectic_matrix[i * dim + control_q]; + symplectic_matrix[i * dim + target_q] = x_target_q; + symplectic_matrix[i * dim + cqz] = z_control_q; + symplectic_matrix[i * dim + tqz] = z_target_q; + }; +} +""" + apply_two_qubits_kernel.format( + "CY", "CY" +) + +apply_CY = cp.RawKernel(apply_CY, "apply_CY", options=("--std=c++11",)) + + +def CY(symplectic_matrix, control_q, target_q, nqubits): + two_qubits_kernel_launcher( + apply_CY, symplectic_matrix, control_q, target_q, nqubits + ) + return symplectic_matrix + + +_apply_rowsum = """ +__device__ void _apply_rowsum(bool* symplectic_matrix, const long* h, const long* i, const int& nqubits, const bool& determined, const int& nrows, long* g_exp, const int& dim) { + unsigned int tid_x = blockIdx.x * blockDim.x + threadIdx.x; + unsigned int bid_y = blockIdx.y; + unsigned int ntid_x = gridDim.x * blockDim.x; + unsigned int nbid_y = gridDim.y; + const int last = dim - 1; + __shared__ int exp; + if (threadIdx.x == 0) { + exp = 0; + } + for(int j = bid_y; j < nrows; j += nbid_y) { + for(int k = tid_x; k < nqubits; k += ntid_x) { + unsigned int kz = nqubits + k; + bool x1_eq_z1 = symplectic_matrix[i[j] * dim + k] == symplectic_matrix[i[j] * dim + kz]; + bool x1_eq_0 = symplectic_matrix[i[j] * dim + k] == false; + if (x1_eq_z1) { + if (not x1_eq_0) { + exp += ((int) symplectic_matrix[h[j] * dim + kz]) - + (int) symplectic_matrix[h[j] * dim + k]; + } + } else { + if (x1_eq_0) { + exp += ((int) symplectic_matrix[h[j] * dim + k]) * ( + 1 - 2 * (int) symplectic_matrix[h[j] * dim + kz] + ); + } else { + exp += ((int) symplectic_matrix[h[j] * dim + kz]) * ( + 2 * (int) symplectic_matrix[h[j] * dim + k] - 1 + ); + } + } + } + if (threadIdx.x == 0 && tid_x < nqubits) { + g_exp[j] += exp; + } + __syncthreads(); + if (threadIdx.x == 0 && blockIdx.x == 0) { + symplectic_matrix[h[j] * dim + last] = ( + 2 * symplectic_matrix[h[j] * dim + last] + 2 * symplectic_matrix[i[j] * dim + last] + g_exp[j] + ) % 4 != 0; + } + for(int k = tid_x; k < nqubits; k += ntid_x) { + unsigned int kz = nqubits + k; + unsigned int row_i = i[j] * dim; + unsigned int row_h = h[j] * dim; + bool xi_xh = ( + symplectic_matrix[row_i + k] ^ symplectic_matrix[row_h + k] + ); + bool zi_zh = ( + symplectic_matrix[row_i + kz] ^ symplectic_matrix[row_h + kz] + ); + if (determined) { + symplectic_matrix[row_h + k] ^= xi_xh; + symplectic_matrix[row_h + kz] ^= zi_zh; + } else { + symplectic_matrix[row_h + k] = xi_xh; + symplectic_matrix[row_h + kz] = zi_zh; + } + } + } +} +""" + +apply_rowsum = f""" +{_apply_rowsum} +extern "C" +__global__ void apply_rowsum(bool* symplectic_matrix, const long* h, const long* i, const int nqubits, const bool determined, const int nrows, long* g_exp, const int dim) {{ + _apply_rowsum(symplectic_matrix, h, i, nqubits, determined, nrows, g_exp, dim); +}} +""" + +apply_rowsum = cp.RawKernel(apply_rowsum, "apply_rowsum", options=("--std=c++11",)) + + +def _rowsum(symplectic_matrix, h, i, nqubits, determined=False): + dim = _get_dim(nqubits) + nrows = len(h) + exp = cp.zeros(len(h), dtype=int) + apply_rowsum( + GRIDDIM_2D, + (BLOCKDIM,), + (symplectic_matrix, h, i, nqubits, determined, nrows, exp, dim), + ) + return symplectic_matrix + + +def _get_p(state, q, nqubits): + dim = _get_dim(nqubits) + return state.reshape(dim, dim)[nqubits:-1, q].nonzero()[0] + + +def _random_outcome(state, p, q, nqubits): + dim = _get_dim(nqubits) + p = p[0] + nqubits + idx_pq = p * dim + q + tmp = state[idx_pq].copy() + state[idx_pq] = False + h = state.reshape(dim, dim)[:-1, q].nonzero()[0] + state[idx_pq] = tmp + if h.shape[0] > 0: + state = _rowsum( + state, + h, + p.astype(cp.uint) * cp.ones(h.shape[0], dtype=np.uint), + nqubits, + False, + ) + state = state.reshape(dim, dim) + state[p - nqubits, :] = state[p, :] + outcome = cp.random.randint(2, size=None, dtype=cp.uint) + state[p, :] = False + state[p, -1] = outcome.astype(bool) + state[p, nqubits + q] = True + return state.ravel(), outcome + + +def _determined_outcome(state, q, nqubits): + dim = _get_dim(nqubits) + state = state.reshape(dim, dim) + state[-1, :] = False + idx = state[:nqubits, q].nonzero()[0] + nqubits + state = _rowsum( + state.ravel(), + (2 * nqubits * cp.ones(idx.shape, dtype=np.uint)).astype(np.uint), + idx.astype(np.uint), + nqubits, + True, + ) + return state, state[dim * dim - 1].astype(cp.uint) + + +def cast(x, dtype=None, copy=False): + if dtype is None: + dtype = "complex128" + + if cp.sparse.issparse(x): + if dtype != x.dtype: + return x.astype(dtype) + return x + + if sparse.issparse(x): + cls = getattr(cp.sparse, x.__class__.__name__) + return cls(x, dtype=dtype) + + if isinstance(x, cp.ndarray) and copy: + return cp.copy(cp.asarray(x, dtype=dtype)) + + return cp.asarray(x, dtype=dtype) + + +def _clifford_pre_execution_reshape(state): + return state.ravel() + + +def _clifford_post_execution_reshape(state, nqubits): + dim = _get_dim(nqubits) + return state.reshape(dim, dim) + + +def identity_density_matrix(nqubits, normalize: bool = True): + n = 1 << nqubits + state = cp.eye(n, dtype="complex128") + cp.cuda.stream.get_current_stream().synchronize() + if normalize: + state /= 2**nqubits + return state.reshape((n, n))