diff --git a/.gitignore b/.gitignore index 41d393a..6bb6a70 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ devenv.local.nix /.envrc /result *.snap.new +/.vscode/ diff --git a/Cargo.lock b/Cargo.lock index 7b8fde1..47a9ab3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,11 +11,75 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "approx" @@ -45,11 +109,33 @@ dependencies = [ "wyz", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cc" -version = "1.0.97" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +dependencies = [ + "jobserver", + "libc", +] [[package]] name = "cfg-if" @@ -68,6 +154,66 @@ dependencies = [ "serde", ] +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "clap" +version = "4.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + [[package]] name = "console" version = "0.15.8" @@ -92,6 +238,67 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + [[package]] name = "delegate" version = "0.12.0" @@ -100,20 +307,43 @@ checksum = "4e018fccbeeb50ff26562ece792ed06659b9c2dae79ece77c4456bb10d9bf79b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn", +] + +[[package]] +name = "dlopen2" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1297103d2bbaea85724fcee6294c2d50b1081f9ad47d0f6f6f61eda65315a6" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -124,9 +354,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "either" -version = "1.11.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" @@ -143,7 +373,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.63", + "syn", ] [[package]] @@ -230,7 +460,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn", ] [[package]] @@ -269,6 +499,26 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "glob" version = "0.3.1" @@ -283,9 +533,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "html-escape" @@ -298,9 +548,9 @@ dependencies = [ [[package]] name = "hugr" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bcfc2468cd2c63e86c562d491130a32d9a8e6f192dc67916818b9a3da02d7e0" +checksum = "39fe922e36cf43f807e83e3ae7265f5e60c47f5843bd3a9e92db718ea03270e0" dependencies = [ "hugr-core", "hugr-passes", @@ -308,9 +558,9 @@ dependencies = [ [[package]] name = "hugr-core" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7384f55699d0290a2d6d491518d0fe15f43d7c5d312814a112b8a17d5666d7c4" +checksum = "30162597f260dcbde8e63156fa7cd59f2b4d396c491664ea5355428799b69588" dependencies = [ "bitvec", "cgmath", @@ -343,6 +593,7 @@ version = "0.1.0" dependencies = [ "anyhow", "delegate", + "dlopen2", "downcast-rs", "hugr", "inkwell", @@ -354,14 +605,35 @@ dependencies = [ "petgraph", "portgraph", "rstest", + "serde", + "serde_json", + "strum", + "strum_macros", + "tket2", +] + +[[package]] +name = "hugr-llvm-exec" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "dlopen2", + "hugr", + "hugr-llvm", + "inkwell", + "lazy_static", + "pathsearch", + "qir-backend", "serde_json", + "tket2", ] [[package]] name = "hugr-passes" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9905dac38c839a5ea493dde57a3761d656fe782526b6e2d2a258f574a40799a" +checksum = "4449d424edfc728e86a22584c69d8b77eb216ed4aded27d2adb7859ce9fe44d4" dependencies = [ "hugr-core", "itertools 0.13.0", @@ -371,6 +643,29 @@ dependencies = [ "thiserror", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "indexmap" version = "2.2.6" @@ -403,7 +698,7 @@ checksum = "4fa4d8d74483041a882adaa9a29f633253a66dde85055f0495c121620ac484b2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn", ] [[package]] @@ -424,6 +719,12 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.12.1" @@ -448,17 +749,35 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "linked-hash-map" @@ -479,22 +798,60 @@ dependencies = [ "semver", ] +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "ndarray" +version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "rawpointer", +] [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -569,6 +926,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "portgraph" version = "0.12.2" @@ -584,15 +947,67 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "priority-queue" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70c501afe3a2e25c9bd219aa56ec1e04cdb3fcdd763055be268778c13fa82c1f" +dependencies = [ + "autocfg", + "equivalent", + "indexmap", +] + [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] +[[package]] +name = "qir-backend" +version = "0.7.4" +source = "git+https://github.com/qir-alliance/qir-runner#7b41f9313609f8309317ce91afccf0a2c7fe5a6f" +dependencies = [ + "bitvec", + "num-bigint", + "num-complex", + "qir-stdlib", + "quantum-sparse-sim", + "rand", +] + +[[package]] +name = "qir-stdlib" +version = "0.7.4" +source = "git+https://github.com/qir-alliance/qir-runner#7b41f9313609f8309317ce91afccf0a2c7fe5a6f" +dependencies = [ + "num-bigint", + "rand", +] + +[[package]] +name = "quantum-sparse-sim" +version = "0.7.4" +source = "git+https://github.com/qir-alliance/qir-runner#7b41f9313609f8309317ce91afccf0a2c7fe5a6f" +dependencies = [ + "ndarray", + "num-bigint", + "num-complex", + "num-traits", + "rand", + "rustc-hash", +] + [[package]] name = "quote" version = "1.0.36" @@ -608,11 +1023,67 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -622,9 +1093,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -633,9 +1104,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "relative-path" @@ -668,10 +1139,16 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.63", + "syn", "unicode-ident", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.0" @@ -701,29 +1178,29 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -745,9 +1222,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "slab" @@ -768,40 +1245,38 @@ dependencies = [ ] [[package]] -name = "strum" -version = "0.26.2" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "strum_macros" -version = "0.26.2" +name = "strum" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.63", + "strum_macros", ] [[package]] -name = "syn" -version = "1.0.109" +name = "strum_macros" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ + "heck", "proc-macro2", "quote", - "unicode-ident", + "rustversion", + "syn", ] [[package]] name = "syn" -version = "2.0.63" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -816,22 +1291,101 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tket-json-rs" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2609f8a0343065937000d8aa537a473aaab8591f7da1788d4d1bc3e792b3f293" +dependencies = [ + "serde", + "serde_json", + "strum", + "uuid", +] + +[[package]] +name = "tket2" +version = "0.1.0-alpha.2" +source = "git+https://github.com/CQCL/tket2.git#59c03c6a2e443b9f7c63555dc7fd494b8b993ca1" +dependencies = [ + "bytemuck", + "cgmath", + "chrono", + "crossbeam-channel", + "csv", + "delegate", + "derive_more", + "downcast-rs", + "fxhash", + "hugr", + "hugr-core", + "itertools 0.13.0", + "lazy_static", + "num-rational", + "petgraph", + "portgraph", + "priority-queue", + "rayon", + "serde", + "serde_json", + "serde_yaml", + "smol_str", + "strum", + "strum_macros", + "thiserror", + "tket-json-rs", + "tracing", + "typetag", + "zstd", +] + +[[package]] +name = "tracing" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", ] [[package]] @@ -861,7 +1415,7 @@ checksum = "ac73887f47b9312552aa90ef477927ff014d63d1920ca8037c6c1951eab64bb1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn", ] [[package]] @@ -882,6 +1436,112 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "serde", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -893,9 +1553,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -909,51 +1569,51 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wyz" @@ -963,3 +1623,31 @@ checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa556e971e7b568dc775c136fc9de8c779b1c2fc3a63defaafadffdbd3181afa" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.12+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index f26d718..8d5b5e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ categories = ["compilers"] [features] default = ["llvm14-0"] llvm14-0 = ["dep:llvm-sys-140", "inkwell/llvm14-0"] +tket2 = ["dep:tket2", "dep:dlopen2"] [dependencies] inkwell = { version = "0.4.0", default-features=false } @@ -29,6 +30,12 @@ delegate = "0.12.0" petgraph = "0.6.5" lazy_static = "1.4.0" downcast-rs= "1.2.1" +serde = "1.0" +serde_json = "1.0" +tket2 = { git = "https://github.com/CQCL/tket2.git", optional = true } +strum = "0.26" +strum_macros = "0.26" +dlopen2 = { version = "0.7" , optional = true} [dev-dependencies] insta = "1.39.0" @@ -41,3 +48,5 @@ serde_json = "1.0.117" insta.opt-level = 3 similar.opt-level = 3 +[workspace] +members = ["hugr-llvm-exec"] diff --git a/hugr-llvm-exec/Cargo.toml b/hugr-llvm-exec/Cargo.toml new file mode 100644 index 0000000..4c59817 --- /dev/null +++ b/hugr-llvm-exec/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "hugr-llvm-exec" +version = "0.1.0" +edition = "2021" + +[dependencies] +qir-backend = { git = "https://github.com/qir-alliance/qir-runner" } +clap = {version = "4.5", features = ["derive"] } +pathsearch = "*" +anyhow = "*" +hugr = "*" +hugr-llvm = { path = "../.", features = ["tket2"] } +tket2 = { git = "https://github.com/CQCL/tket2.git" } +serde_json = "*" +lazy_static = "*" +inkwell = { version = "0.4" } +dlopen2 = { version = "0.7" } diff --git a/hugr-llvm-exec/src/lib.rs b/hugr-llvm-exec/src/lib.rs new file mode 100644 index 0000000..3bf2a11 --- /dev/null +++ b/hugr-llvm-exec/src/lib.rs @@ -0,0 +1 @@ +pub use qir_backend::*; diff --git a/hugr-llvm-exec/src/main.rs b/hugr-llvm-exec/src/main.rs new file mode 100644 index 0000000..bae84d6 --- /dev/null +++ b/hugr-llvm-exec/src/main.rs @@ -0,0 +1,147 @@ +use std::{error::Error, fs::File, path::{Path, PathBuf}, process::{Command, Stdio}}; +use anyhow::{anyhow, Result}; + +use clap::Parser; +use hugr::{extension::{prelude, ExtensionRegistry}, std_extensions::arithmetic::{float_types, int_ops, int_types}, Hugr, HugrView}; +use hugr_llvm::{custom::{tket2_qir::QirFunc, CodegenExtsMap}, emit::{EmitHugr, Namer}, fat::FatExt as _}; +use inkwell::{context::Context, execution_engine, intrinsics::Intrinsic, module::{Linkage, Module}, targets::{Target, TargetMachine}, values::FunctionValue}; +use tket2::extension::TKET2_EXTENSION; +use lazy_static::lazy_static; + +lazy_static! { + static ref EXTENSION_REGISTRY: ExtensionRegistry = ExtensionRegistry::try_new([ + int_ops::EXTENSION.to_owned(), + int_types::EXTENSION.to_owned(), + prelude::PRELUDE.to_owned(), + float_types::EXTENSION.to_owned(), + TKET2_EXTENSION.to_owned(), + ]) + .unwrap(); +} + +#[derive(Parser)] +struct CliArgs { + guppy_file: PathBuf +} + +fn guppy(python_bin: impl AsRef, file: impl AsRef) -> Result { + let mut guppy_cmd = Command::new(python_bin.as_ref()); + guppy_cmd + .arg(file.as_ref()) + .stdout(Stdio::piped()); + let mut guppy_proc = guppy_cmd.spawn()?; + let mut hugr: Hugr = serde_json::from_reader(guppy_proc.stdout.take().unwrap())?; + if !guppy_proc.wait()?.success() { + Err(anyhow!("Guppy failed"))?; + } + hugr.update_validate(&EXTENSION_REGISTRY).unwrap(); + Ok(hugr) +} + +fn hugr_to_module<'c>(context: &'c Context, hugr: &'c impl HugrView) -> Result<(FunctionValue<'c>,Module<'c>)> { + let module = context.create_module("hugr_llvm_exec"); + let namer = Namer::new("_hugr_llvm_exec_.", false); + let exts = CodegenExtsMap::default() + .add_int_extensions() + .add_float_extensions() + .add_tket2_qir_exts(); + let root = hugr.fat_root().unwrap(); + let module = EmitHugr::new(&context, module, namer.into(), exts.into()) + .emit_module(root)? + .finish(); + let entry = { + let guppy_entry = module.get_function("_hugr_llvm_exec_.main").ok_or(anyhow!("No main function"))?; + let entry = module.add_function("main", context.void_type().fn_type(&[], false), Some(Linkage::External)); + let entry_block = context.append_basic_block(entry, "entry"); + let builder = context.create_builder(); + builder.position_at_end(entry_block); + let debugtrap = Intrinsic::find("llvm.debugtrap").ok_or(anyhow!("Failed to find llvm.debugtrap"))?; + let debugtrap = debugtrap.get_declaration(&module, &[]).ok_or(anyhow!("Failed to get declaration for llvm.debugtrap"))?; + builder.build_call(debugtrap, &[], "")?; + builder.build_call(guppy_entry, &[], "")?; + builder.build_return(None)?; + entry + }; + Ok((entry, module)) +} + +fn jit_hugr(hugr: &impl HugrView) -> Result<()> { + let context = inkwell::context::Context::create(); + let (entry, module) = hugr_to_module(&context, hugr)?; + let engine = module.create_execution_engine().map_err(|e| anyhow!("Failed to create execution engine: {e}"))?; + QirFunc::add_all_global_mappings(&engine, &module, |qir_func| { + use hugr_llvm_exec::*; + match qir_func { + QirFunc::H => __quantum__qis__h__body as usize, + QirFunc::RZ => __quantum__qis__rz__body as usize, + QirFunc::QAlloc => __quantum__rt__qubit_allocate as usize, + QirFunc::QFree => __quantum__rt__qubit_release as usize, + QirFunc::Measure => __quantum__qis__m__body as usize, + QirFunc::ReadResult => __quantum__qis__read_result__body as usize, + }} + )?; + + + unsafe { engine.run_function(entry, &[])} ; + Ok(()) +} + +// drives `hugr-llvm` to produce an LLVM module from a Hugr. +fn hugr_to_so<'c>(hugr: &'c Hugr) -> Result<()> { + let context = inkwell::context::Context::create(); + let module = context.create_module("hugr_llvm_exec"); + let namer = Namer::new("_hugr_llvm_exec_.", false); + let exts = CodegenExtsMap::default() + .add_int_extensions() + .add_float_extensions() + .add_tket2_qir_exts(); + let root = hugr.fat_root().unwrap(); + let module = EmitHugr::new(&context, module, namer.into(), exts.into()) + .emit_module(root)? + .finish(); + { + let guppy_entry = module.get_function("_hugr_llvm_exec_.main").ok_or(anyhow!("No main function"))?; + let entry = module.add_function("main", context.void_type().fn_type(&[], false), Some(Linkage::External)); + let entry_block = context.append_basic_block(entry, "entry"); + let builder = context.create_builder(); + builder.position_at_end(entry_block); + builder.build_call(guppy_entry, &[], "")?; + builder.build_return(None)?; + } + + Target::initialize_native(&Default::default()).map_err(|e| anyhow!("Failed to initialize native target: {}", e))?; + let triple = TargetMachine::get_default_triple(); + let target = Target::from_triple(&triple).map_err(|e| anyhow!("Failed to create target: {e}"))?; + let cpu = TargetMachine::get_host_cpu_name().to_string(); + let cpu_features = TargetMachine::get_host_cpu_features().to_string(); + let machine = target.create_target_machine(&triple, &cpu, &cpu_features, inkwell::OptimizationLevel::None, inkwell::targets::RelocMode::PIC, inkwell::targets::CodeModel::Default).ok_or(anyhow!("Failed to create target machine"))?; + + machine.write_to_file(&module, inkwell::targets::FileType::Object, &PathBuf::from("hugr_llvm_exec.o")).map_err(|e| anyhow!("Failed to write object file: {}", e))?; + + if !Command::new("gcc") + .arg("-Wl,-lhugr_llvm_exec") + .arg("hugr_llvm_exec.o") + .arg("-o") + .arg("hugr_llvm_exec") + .status()?.success() { + Err(anyhow!("Failed to link object file"))?; + } + Ok(()) +} + + +fn main_impl(args: CliArgs) -> Result<()> { + let python = pathsearch::find_executable_in_path("python3").ok_or(anyhow!("Failed to find python3 executable"))?; + if !args.guppy_file.exists() { + Err(anyhow!("Guppy file does not exist: {:?}", args.guppy_file))?; + } + let hugr = guppy(python, args.guppy_file)?; + jit_hugr(&hugr) +} + +fn main() { + if let Err(e) = main_impl(CliArgs::parse()) { + eprintln!("Error: {}", e); + std::process::exit(1); + } +} diff --git a/poetry.lock b/poetry.lock index b8f831d..fd2c7c9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -29,35 +29,39 @@ test = ["coverage", "pytest (>=7,<8.1)", "pytest-cov", "pytest-mock (>=3)"] [[package]] name = "guppylang" -version = "0.5.2" +version = "0.6.2" description = "Pythonic quantum-classical programming language" optional = false -python-versions = "<4.0,>=3.10" -files = [ - {file = "guppylang-0.5.2-py3-none-any.whl", hash = "sha256:fc7f397869c96280fb19ed1eb7ef55e6a3198235e73dabf937cea106e91ee1f4"}, - {file = "guppylang-0.5.2.tar.gz", hash = "sha256:a7716e5fa15190f9c3cadaec363f4f1a59660251cb7c45b180d96500cec9346f"}, -] +python-versions = "^3.10" +files = [] +develop = false [package.dependencies] -graphviz = ">=0.20.1,<0.21.0" -hugr = ">=0.2.1,<0.3.0" -networkx = ">=3.2.1,<4.0.0" -pydantic = ">=2.7.0b1,<3.0.0" -typing-extensions = ">=4.9.0,<5.0.0" +graphviz = "^0.20.1" +hugr = "^0.4.0" +networkx = "^3.2.1" +pydantic = "^2.7.0b1" +typing-extensions = "^4.9.0" + +[package.source] +type = "git" +url = "https://github.com/CQCL/guppy" +reference = "toy/debug-info" +resolved_reference = "a0232289e818830fcac9da868f63190f4d71f5ca" [[package]] name = "hugr" -version = "0.2.1" +version = "0.4.0" description = "Quantinuum's common representation for quantum programs" optional = false python-versions = ">=3.10" files = [ - {file = "hugr-0.2.1-py3-none-any.whl", hash = "sha256:9bed349f342740d1f7e92859f8c12553d494f39ff26216eadbbdfd92513f64e6"}, - {file = "hugr-0.2.1.tar.gz", hash = "sha256:899203ee02000a0ed3fe36ae1bf3f3ec5e06bddfa4d53bea15ab06aa8b452de5"}, + {file = "hugr-0.4.0-py3-none-any.whl", hash = "sha256:284f9a8eba8e638b3c2b0ed54b0cddfa84c527cdcb10bdc468cc70f9cd6c3f4d"}, + {file = "hugr-0.4.0.tar.gz", hash = "sha256:060693b1bc04a19c433eef262ff9574d909091851e73a4fc442887ee818257b1"}, ] [package.dependencies] -pydantic = ">=2.7.0,<2.8.0" +pydantic = ">=2.7,<2.9" [[package]] name = "networkx" @@ -79,109 +83,122 @@ test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "pydantic" -version = "2.7.4" +version = "2.8.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.7.4-py3-none-any.whl", hash = "sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"}, - {file = "pydantic-2.7.4.tar.gz", hash = "sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52"}, + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, ] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.18.4" -typing-extensions = ">=4.6.1" +pydantic-core = "2.20.1" +typing-extensions = [ + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, +] [package.extras] email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.18.4" +version = "2.20.1" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"}, - {file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"}, - {file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"}, - {file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"}, - {file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"}, - {file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"}, - {file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"}, - {file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"}, - {file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"}, - {file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"}, - {file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"}, - {file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"}, - {file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"}, - {file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"}, - {file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"}, - {file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"}, - {file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"}, - {file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"}, - {file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"}, - {file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"}, - {file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"}, - {file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"}, - {file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"}, - {file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"}, - {file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"}, - {file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"}, - {file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"}, - {file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"}, - {file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"}, - {file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, ] [package.dependencies] @@ -201,4 +218,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "28bbb18cdb8049833dc99fa0d64e65229ad6039b836e68e250e0b4271930a6ff" +content-hash = "8eb9682800e82924123017191e58eab2f4972ca590ac0ef24005a1c10481fe47" diff --git a/pyproject.toml b/pyproject.toml index be87909..7d4fd4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ package-mode = false [tool.poetry.dependencies] python = "^3.11" -guppylang= "^0.5.2" +guppylang= {git = "https://github.com/CQCL/guppy", branch = "toy/debug-info"} [build-system] diff --git a/src/custom.rs b/src/custom.rs index 5206938..1545188 100644 --- a/src/custom.rs +++ b/src/custom.rs @@ -24,6 +24,8 @@ use super::emit::EmitOp; pub mod float; pub mod int; pub mod prelude; +#[cfg(feature="tket2")] +pub mod tket2_qir; /// The extension point for lowering HUGR Extensions to LLVM. pub trait CodegenExtension<'c, H> { diff --git a/src/custom/tket2_qir.rs b/src/custom/tket2_qir.rs new file mode 100644 index 0000000..94da951 --- /dev/null +++ b/src/custom/tket2_qir.rs @@ -0,0 +1,261 @@ +use hugr::{extension::simple_op::MakeExtensionOp, ops::{CustomOp, NamedOp, Value}, HugrView}; +use inkwell::{builder::Builder, context::Context, execution_engine::ExecutionEngine, module::Module, types::{BasicType, FunctionType}, values::FunctionValue, AddressSpace}; +use anyhow::{anyhow,Result}; +use tket2::Tk2Op; +use strum_macros::EnumIter; +use strum::IntoEnumIterator; + +use crate::{emit::{emit_value, EmitFuncContext, EmitOp, EmitOpArgs}, types::TypingSession}; + +use super::{prelude::PreludeCodegen, CodegenExtension, CodegenExtsMap}; + +pub struct Tket2QIRPrelude; + +const QUBIT_NAME: &str = "Qubit"; +const RESULT_NAME: &str = "Result"; +fn qubit_t(context: &Context) -> impl BasicType<'_> { + context.get_struct_type(QUBIT_NAME).unwrap_or(context.opaque_struct_type(QUBIT_NAME)) + .ptr_type(AddressSpace::default()) +} + +fn result_t(context: &Context) -> impl BasicType<'_> { + context.get_struct_type(RESULT_NAME).unwrap_or(context.opaque_struct_type(RESULT_NAME)) + .ptr_type(AddressSpace::default()) +} + +impl PreludeCodegen for Tket2QIRPrelude { + fn qubit_type<'c,H: HugrView>(&self, session: &TypingSession<'c,H>) -> impl BasicType<'c> { + qubit_t(session.iw_context()) + } +} + +pub struct Tket2QIR; + +impl<'c, H: HugrView> CodegenExtension<'c,H> for Tket2QIR { + fn extension(&self) -> hugr::extension::ExtensionId { + tket2::extension::TKET2_EXTENSION_ID + } + + fn llvm_type( + &self, + _: &TypingSession<'c, H>, + hugr_type: &hugr::types::CustomType, + ) -> anyhow::Result> { + Err(anyhow::anyhow!( + "Type not supported by tket2 qir extension: {hugr_type:?}" + )) + } + + fn emitter<'a>( + &self, + context: &'a mut EmitFuncContext<'c, H>, + ) -> Box + 'a> { + Box::new(Tket2QIREmitter::new(context)) + } +} + +pub struct Tket2QIREmitter<'c,'d,H: HugrView> ( + &'d mut EmitFuncContext<'c, H>, +); + +#[derive(Copy,Clone,PartialEq, Eq, EnumIter)] +pub enum QirFunc { + H, + RZ, + QAlloc, + QFree, + Measure, + ReadResult, +} + +impl QirFunc { + pub fn symbol(self) -> &'static str { + match self { + QirFunc::H => "__quantum__qis__h__body", + QirFunc::RZ => "__quantum__qis__rz__body", + QirFunc::QAlloc => "__quantum__rt__qubit_allocate", + QirFunc::QFree => "__quantum__rt__qubit_release", + QirFunc::Measure => "__quantum__qis__m__body", + QirFunc::ReadResult => "__quantum__qis__read_result__body", + } + } + + pub fn func_type<'c>(self, context: &'c Context) -> FunctionType<'c> { + match self { + QirFunc::H => + context.void_type().fn_type( + &[context.f64_type().into(), qubit_t(context).as_basic_type_enum().into()], + false, + ), + QirFunc::RZ => context.void_type().fn_type( + &[context.f64_type().into(), qubit_t(context).as_basic_type_enum().into()], + false, + ), + QirFunc::QAlloc => qubit_t(context).fn_type( + &[], + false, + ), + QirFunc::QFree => context.void_type().fn_type( + &[qubit_t(context).as_basic_type_enum().into()], + false, + ), + QirFunc::Measure => result_t(context).fn_type( + &[qubit_t(context).as_basic_type_enum().into()], + false, + ), + QirFunc::ReadResult => context.bool_type().fn_type( + &[result_t(context).as_basic_type_enum().into()], + false, + ), + } + } + + pub fn add_global_mapping<'c>(self, engine: &ExecutionEngine<'c>, module: &Module<'c>, addr: usize) -> Result<()>{ + let Some(func) = module.get_function(self.symbol()) else { + return Ok(()); + }; + + engine.add_global_mapping(&func, addr); + Ok(()) + } + + pub fn add_all_global_mappings<'c>(engine: &ExecutionEngine<'c>, module: &Module<'c>, get_addr: impl Fn(Self) -> usize) -> Result<()> { + for x in Self::iter() { + x.add_global_mapping(engine, module, get_addr(x))?; + } + Ok(()) + + } + + fn get_func<'c,H: HugrView>(self, context: & EmitFuncContext<'c, H>) -> Result> { + context.get_extern_func(self.symbol(), self.func_type(context.iw_context())) + } +} + +impl<'c, 'd, H: HugrView> Tket2QIREmitter<'c, 'd, H> { + fn new(context: &'d mut EmitFuncContext<'c,H>) -> Self { Self(context) } + fn iw_context(&self) -> &'c Context { + self.0.iw_context() + } + + fn builder(&self) -> &Builder<'c> { + self.0.builder() + } + + fn get_func(&self, func:QirFunc) -> Result> { + func.get_func(self.0) + } +} + +impl<'c, H: HugrView> EmitOp<'c, CustomOp, H> for Tket2QIREmitter<'c, '_, H> { + /// Function to help lower the tket-2 extension. + fn emit(&mut self, args: EmitOpArgs<'c, CustomOp, H>) -> Result<()> { + match args + .node() + .as_extension_op() + .ok_or(anyhow!("Tket2Emitter: Unknown op: {}", args.node().name())) + .and_then(|x| Ok(MakeExtensionOp::from_extension_op(x)?))? + { + Tk2Op::H => { + let [qb] = args + .inputs + .try_into() + .map_err(|_| anyhow!("H expects one inputs"))?; + let func = self.get_func(QirFunc::H)?; + self.builder() + .build_call(func, &[qb.into()],"")?; + args.outputs.finish(self.builder(), [qb]) + } + Tk2Op::RzF64 => { + let [qb, angle] = args + .inputs + .try_into() + .map_err(|_| anyhow!("RzF64 expects two inputs"))?; + let func = self.get_func(QirFunc::RZ)?; + self.builder() + .build_call(func, &[angle.into(), qb.into()],"")?; + args.outputs.finish(self.builder(), [qb]) + } + // Tk2Op::ZZMax => { + // let [qb1, qb2] = args + // .inputs + // .try_into() + // .map_err(|_| anyhow!("ZZMax expects two inputs"))?; + // let zz = self.get_func_zz()?; + // self.builder() + // .build_call(zz, &[qb1.into(), qb2.into()], "zz")?; + // args.outputs.finish(self.builder(), [qb1, qb2]) + // } + // Tk2Op::ZZPhase => { + // let [qb1, qb2, angle] = args + // .inputs + // .try_into() + // .map_err(|_| anyhow!("ZZPhase expects three inputs"))?; + // let rzz = self.get_func_rzz()?; + // self.builder() + // .build_call(rzz, &[qb1.into(), qb2.into(), angle.into()], "rzz")?; + // args.outputs.finish(self.builder(), [qb1, qb2]) + // } + // Tk2Op::PhasedX => { + // let [qb, f1, f2] = args + // .inputs + // .try_into() + // .map_err(|_| anyhow!("PhasedX expects three inputs"))?; + // let rxy = self.get_func_rxy()?; + // self.builder() + // .build_call(rxy, &[qb.into(), f1.into(), f2.into()], "rxy")?; + // args.outputs.finish(self.builder(), [qb]) + // } + Tk2Op::QAlloc => { + let [] = args + .inputs + .try_into() + .map_err(|_| anyhow!("QAlloc expects no inputs"))?; + let qalloc = self.get_func(QirFunc::QAlloc)?; + let qb = self + .builder() + .build_call(qalloc, &[], "qalloc")? + .try_as_basic_value() + .unwrap_left(); + args.outputs.finish(self.builder(), [qb]) + } + Tk2Op::QFree => { + let [qb] = args + .inputs + .try_into() + .map_err(|_| anyhow!("QFree expects one inputs"))?; + let qfree = self.get_func(QirFunc::QFree)?; + self.builder().build_call(qfree, &[qb.into()], "qfree")?; + args.outputs.finish(self.builder(), []) + } + Tk2Op::Measure => { + let [qb] = args + .inputs + .try_into() + .map_err(|_| anyhow!("Measure expects one inputs"))?; + let measure = self.get_func(QirFunc::Measure)?; + let result = self + .builder() + .build_call(measure, &[qb.into()],"")? + .try_as_basic_value() + .unwrap_left(); + let read_result = self.get_func(QirFunc::ReadResult)?; + let result_i1 = self.builder().build_call(read_result, &[result.into()], "")?.try_as_basic_value().unwrap_left(); + let true_val = emit_value(&mut self.0, &Value::true_val())?; + let false_val = emit_value(&mut self.0, &Value::false_val())?; + let result = self + .builder() + .build_select(result_i1.into_int_value(), true_val, false_val, "measure")?; + args.outputs.finish(self.builder(), [qb, result]) + } + n => Err(anyhow!("Unknown op {:?}", n)), + } + } +} + +impl<'c,H: HugrView> CodegenExtsMap<'c,H> { + pub fn add_tket2_qir_exts(self) -> Self { + self.add_prelude_extensions(Tket2QIRPrelude) + .add_cge(Tket2QIR) + } +} diff --git a/src/debuginfo.rs b/src/debuginfo.rs new file mode 100644 index 0000000..3f3fa50 --- /dev/null +++ b/src/debuginfo.rs @@ -0,0 +1,123 @@ +use std::path::{Path, PathBuf}; + +use hugr::{ + ops::{FuncDefn, OpType}, + HugrView, Node, +}; +use inkwell::{ + context::Context, + debug_info::{DICompileUnit, DILocation, DIScope, DISubprogram, DebugInfoBuilder}, + module::Module, +}; +use serde::{Deserialize, Serialize}; + +use crate::{emit::Namer, fat::FatNode}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ModuleInfo { + file: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LocationInfo { + file: String, + line: u32, + col: u32, +} + +pub trait DebugHugrView: HugrView { + fn get_module_info(&self, node: Node) -> Option { + self.get_metadata(node, "di") + .and_then(|di| serde_json::from_value(di.clone()).ok()) + } + + fn get_location_info(&self, node: Node) -> Option { + self.get_metadata(node, "di") + .and_then(|di| serde_json::from_value(di.clone()).ok()) + } +} + +impl DebugHugrView for T {} + +fn split_path(path: impl AsRef) -> Option<(String, String)> { + let dir = path.as_ref().parent()?.to_str()?.to_owned(); + let file = path.as_ref().file_name()?.to_str()?.to_owned(); + Some((dir, file)) +} + +pub fn module_debug_info<'c, H: DebugHugrView>( + node: FatNode<'c, hugr::ops::Module, H>, + module: &Module<'c>, +) -> (DebugInfoBuilder<'c>, DICompileUnit<'c>) { + let (dir, file) = node + .hugr() + .get_module_info(node.node()) + .and_then(|mi| { + dbg!(&mi); + split_path(PathBuf::from(mi.file)) + }) + .unwrap_or(("".to_owned(), "".to_owned())); + module.create_debug_info_builder( + true, // allow_unresolved + inkwell::debug_info::DWARFSourceLanguage::C, // language + &file, // filename + &dir, // directory + "guppy", // produer + false, // is_optimised + "", //flags + 0, // runtime_ver + "", //split_name + inkwell::debug_info::DWARFEmissionKind::Full, + 0, // dwo_id + false, // split_debug_inlining + false, //debug_info_for_profiling + "", // sysroot + "", + ) // dk +} + +pub fn func_debug_info<'c, H: DebugHugrView>( + builder: &DebugInfoBuilder<'c>, + namer: &Namer, + scope: DIScope<'c>, + node: FatNode<'c, FuncDefn, H>, +) -> DISubprogram<'c> { + let (dir, filename, line, _) = node + .hugr() + .get_location_info(node.node()) + .and_then(|li| { + let (dir, file) = split_path(PathBuf::from(li.file))?; + Some((dir, file, li.line, li.col)) + }) + .unwrap_or(("".to_owned(), "".to_owned(), 0, 0)); + let di_file = builder.create_file(&filename, &dir); + let di_subroutine_type = builder.create_subroutine_type(di_file, None, &[], 0); + let linkage_name = namer.name_func(&node.name, node.node()); + builder.create_function( + scope, + &node.name, + Some(&linkage_name), + di_file, + line, + di_subroutine_type, + false, // is_local_to_unit + true, // is_definition + line, + inkwell::debug_info::DIFlags::default(), + false, // is_optimised + ) +} + +pub fn op_debug_location<'c, H: DebugHugrView>( + context: &'c Context, + builder: &DebugInfoBuilder<'c>, + scope: DIScope<'c>, + node: FatNode<'c, OpType, H>, +) -> DILocation<'c> { + let (line, col) = node + .hugr() + .get_location_info(node.node()) + .map(|li| (li.line, li.col)) + .unwrap_or((0, 0)); + builder.create_debug_location(context, line, col, scope, None) +} diff --git a/src/emit.rs b/src/emit.rs index 0a545cd..8b49ce5 100644 --- a/src/emit.rs +++ b/src/emit.rs @@ -6,15 +6,11 @@ use hugr::{ HugrView, Node, }; use inkwell::{ - builder::Builder, - context::Context, - module::{Linkage, Module}, - types::{AnyType, BasicType, BasicTypeEnum, FunctionType}, - values::{BasicValueEnum, CallSiteValue, FunctionValue, GlobalValue}, + builder::Builder, context::Context, debug_info::{AsDIScope, DICompileUnit, DIScope, DebugInfoBuilder}, module::{Linkage, Module}, types::{AnyType, BasicType, BasicTypeEnum, FunctionType}, values::{BasicValueEnum, CallSiteValue, FunctionValue, GlobalValue} }; -use std::{collections::HashSet, rc::Rc}; +use std::{collections::HashMap, rc::Rc}; -use crate::types::{HugrFuncType, HugrSumType, HugrType, TypingSession}; +use crate::{debuginfo::module_debug_info, types::{HugrFuncType, HugrSumType, HugrType, TypingSession}}; use crate::{ custom::CodegenExtsMap, @@ -32,6 +28,8 @@ pub use func::{EmitFuncContext, RowPromise}; pub use namer::Namer; pub use ops::emit_value; +type DI<'c> = (Rc>, DICompileUnit<'c>); + /// A trait used to abstract over emission. /// /// In particular a `Box` is returned by @@ -242,7 +240,7 @@ impl<'c, H> EmitModuleContext<'c, H> { } } -type EmissionSet<'c, H> = HashSet>; +type EmissionSet<'c, H> = HashMap, DIScope<'c>>; /// Emits [HugrView]s into an LLVM [Module]. pub struct EmitHugr<'c, H> { @@ -294,14 +292,20 @@ impl<'c, H: HugrView> EmitHugr<'c, H> { /// /// If any LLVM IR declaration which is to be emitted already exists in the /// [Module] and it differs from what would be emitted, then we fail. - pub fn emit_func(mut self, node: FatNode<'c, FuncDefn, H>) -> Result { - let mut worklist: EmissionSet<'c, H> = [node].into_iter().collect(); + pub fn emit_func(mut self, node: FatNode<'c, FuncDefn, H>, di: DI<'c>) -> Result { + let mut worklist: EmissionSet<'c, H> = [(node, di.1.clone().as_debug_info_scope())].into_iter().collect(); let pop = - |wl: &mut EmissionSet<'c, H>| wl.iter().next().cloned().map(|x| wl.take(&x).unwrap()); + |wl: &mut EmissionSet<'c, H>| { + let &k = wl.keys().next()?; + wl.remove_entry(&k) + }; - while let Some(x) = pop(&mut worklist) { - let (new_self, new_tasks) = self.emit_func_impl(x)?; - self = new_self; + while let Some((node, scope)) = pop(&mut worklist) { + if self.emitted.insert(node, scope.clone()).is_some() { + continue; + } + let (new_self, new_tasks) = func::emit_func(self.module_context, node, di.0.clone(), scope)?; + self.module_context = new_self; worklist.extend(new_tasks.into_iter()); } Ok(self) @@ -314,11 +318,14 @@ impl<'c, H: HugrView> EmitHugr<'c, H> { /// emission of ops with static edges from them. So [FuncDefn] are the only /// interesting children. pub fn emit_module(mut self, node: FatNode<'c, hugr::ops::Module, H>) -> Result { + let (di_builder, di_compile_unit) = module_debug_info(node, self.module()); + let di_builder = Rc::new(di_builder); for c in node.children() { match c.as_ref() { OpType::FuncDefn(ref fd) => { let fat_ot = c.into_ot(fd); - self = self.emit_func(fat_ot)?; + + self = self.emit_func(fat_ot, (di_builder.clone(), di_compile_unit))?; } // FuncDecls are allowed, but we don't need to do anything here. OpType::FuncDecl(_) => (), @@ -330,35 +337,6 @@ impl<'c, H: HugrView> EmitHugr<'c, H> { Ok(self) } - fn emit_func_impl( - mut self, - node: FatNode<'c, FuncDefn, H>, - ) -> Result<(Self, EmissionSet<'c, H>)> { - if !self.emitted.insert(node) { - return Ok((self, EmissionSet::default())); - } - let func = self.module_context.get_func_defn(node)?; - let mut func_ctx = EmitFuncContext::new(self.module_context, func)?; - let ret_rmb = func_ctx.new_row_mail_box(node.signature.body().output.iter(), "ret")?; - ops::emit_dataflow_parent( - &mut func_ctx, - EmitOpArgs { - node, - inputs: func.get_params(), - outputs: ret_rmb.promise(), - }, - )?; - let builder = func_ctx.builder(); - match &ret_rmb.read::>(builder, [])?[..] { - [] => builder.build_return(None)?, - [x] => builder.build_return(Some(x))?, - xs => builder.build_aggregate_return(xs)?, - }; - let (mctx, todos) = func_ctx.finish()?; - self.module_context = mctx; - Ok((self, todos)) - } - /// Consumes the `EmitHugr` and returns the internal [Module]. pub fn finish(self) -> Module<'c> { self.module_context.finish() diff --git a/src/emit/func.rs b/src/emit/func.rs index 2fd4ad0..e93a7b7 100644 --- a/src/emit/func.rs +++ b/src/emit/func.rs @@ -2,26 +2,22 @@ use std::{collections::HashMap, rc::Rc}; use anyhow::{anyhow, Result}; use hugr::{ - ops::{FuncDecl, FuncDefn}, + ops::{FuncDecl, FuncDefn, OpType}, types::Type, HugrView, NodeIndex, PortIndex, Wire, }; use inkwell::{ - basic_block::BasicBlock, - builder::Builder, - context::Context, - types::{BasicType, BasicTypeEnum, FunctionType}, - values::{FunctionValue, GlobalValue}, + basic_block::BasicBlock, builder::Builder, context::Context, debug_info::{AsDIScope, DIScope, DebugInfoBuilder}, types::{BasicType, BasicTypeEnum, FunctionType}, values::{FunctionValue, GlobalValue} }; -use itertools::zip_eq; +use itertools::{zip_eq, Itertools as _}; -use crate::types::{HugrFuncType, HugrSumType, HugrType, TypingSession}; +use crate::{debuginfo::{func_debug_info, op_debug_location}, types::{HugrFuncType, HugrSumType, HugrType, TypingSession}}; use crate::{custom::CodegenExtsMap, fat::FatNode, types::LLVMSumType}; use delegate::delegate; use self::mailbox::ValueMailBox; -use super::{EmissionSet, EmitModuleContext}; +use super::{EmissionSet, EmitModuleContext, EmitOpArgs}; mod mailbox; pub use mailbox::{RowMailBox, RowPromise}; @@ -51,6 +47,9 @@ pub struct EmitFuncContext<'c, H> { builder: Builder<'c>, prologue_bb: BasicBlock<'c>, launch_bb: BasicBlock<'c>, + scope: DIScope<'c>, + di_builder: Rc>, + } impl<'c, H: HugrView> EmitFuncContext<'c, H> { @@ -99,10 +98,19 @@ impl<'c, H: HugrView> EmitFuncContext<'c, H> { } } + pub fn clear_debug_location(&self) { + self.builder().unset_current_debug_location(); + } + + pub fn set_debug_location(&self, node: FatNode<'c, OpType, H>, scope: Option>) { + let location = op_debug_location(self.iw_context(), &self.di_builder, scope.unwrap_or(self.scope), node); + self.builder().set_current_debug_location(location); + } + /// Used when emitters encounter a scoped definition. `node` will be /// returned from [EmitFuncContext::finish]. pub fn push_todo_func(&mut self, node: FatNode<'c, FuncDefn, H>) { - self.todo.insert(node); + self.todo.insert(node, self.scope); } // TODO likely we don't need this @@ -148,6 +156,8 @@ impl<'c, H: HugrView> EmitFuncContext<'c, H> { pub fn new( emit_context: EmitModuleContext<'c, H>, func: FunctionValue<'c>, + di_builder: Rc>, + scope: DIScope<'c>, ) -> Result> { if func.get_first_basic_block().is_some() { Err(anyhow!( @@ -155,6 +165,7 @@ impl<'c, H: HugrView> EmitFuncContext<'c, H> { func.get_name() ))?; } + let prologue_bb = emit_context .iw_context() .append_basic_block(func, "alloca_block"); @@ -171,6 +182,8 @@ impl<'c, H: HugrView> EmitFuncContext<'c, H> { builder, prologue_bb, launch_bb, + scope, + di_builder }) } @@ -257,6 +270,12 @@ impl<'c, H: HugrView> EmitFuncContext<'c, H> { .out_value_types() .map(|(port, hugr_type)| self.map_wire(node, port, &hugr_type)) .collect::>()?; + #[cfg(debug_assertions)] + { + let ts1 = node.out_value_types().map(|x| self.llvm_type(&x.1).unwrap()).collect_vec(); + let ts2 = r.get_types().collect_vec(); + debug_assert_eq!(ts1,ts2); + } debug_assert!(zip_eq(node.out_value_types(), r.get_types()) .all(|((_, t), lt)| self.llvm_type(&t).unwrap() == lt)); Ok(r) @@ -286,6 +305,36 @@ impl<'c, H: HugrView> EmitFuncContext<'c, H> { pub fn finish(self) -> Result<(EmitModuleContext<'c, H>, EmissionSet<'c, H>)> { self.builder.position_at_end(self.prologue_bb); self.builder.build_unconditional_branch(self.launch_bb)?; + self.di_builder.finalize(); Ok((self.emit_context, self.todo)) } } + +pub fn emit_func<'c,H: HugrView>( + emit_context: EmitModuleContext<'c, H>, + node: FatNode<'c, FuncDefn, H>, + di_builder: Rc>, + scope: DIScope<'c>, +) -> Result<(EmitModuleContext<'c, H>, EmissionSet<'c, H>)> { + let func = emit_context.get_func_defn(node)?; + let di_subprogram = func_debug_info(&di_builder, &emit_context.namer, scope, node); + func.set_subprogram(di_subprogram); + + let mut func_ctx = EmitFuncContext::new(emit_context, func, di_builder, di_subprogram.as_debug_info_scope())?; + let ret_rmb = func_ctx.new_row_mail_box(node.signature.body().output.iter(), "ret")?; + super::ops::emit_dataflow_parent( + &mut func_ctx, + EmitOpArgs { + node, + inputs: func.get_params(), + outputs: ret_rmb.promise(), + }, + )?; + let builder = func_ctx.builder(); + match &ret_rmb.read::>(builder, [])?[..] { + [] => builder.build_return(None)?, + [x] => builder.build_return(Some(x))?, + xs => builder.build_aggregate_return(xs)?, + }; + func_ctx.finish() +} diff --git a/src/emit/ops.rs b/src/emit/ops.rs index 903d150..cf628a9 100644 --- a/src/emit/ops.rs +++ b/src/emit/ops.rs @@ -130,11 +130,15 @@ where let inputs_rmb = self.context.node_ins_rmb(node)?; let inputs = inputs_rmb.read(self.builder(), [])?; let outputs = self.context.node_outs_rmb(node)?.promise(); - self.emit(EmitOpArgs { + + self.context.set_debug_location(node,None); + let r = self.emit(EmitOpArgs { node, inputs, outputs, - }) + }); + self.context.clear_debug_location(); + r }) } } diff --git a/src/lib.rs b/src/lib.rs index fc08bc3..422ccdb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,6 +65,7 @@ pub mod custom; pub mod emit; pub mod fat; pub mod types; +pub mod debuginfo; #[allow(unreachable_code)] pub fn llvm_version() -> &'static str { diff --git a/tests/guppy_test_cases/planqc-1.py b/tests/guppy_test_cases/planqc-1.py index 1023a3f..6916f43 100644 --- a/tests/guppy_test_cases/planqc-1.py +++ b/tests/guppy_test_cases/planqc-1.py @@ -3,7 +3,7 @@ from guppylang.prelude import quantum from guppylang.prelude.quantum import measure, qubit, h, rz -mod = GuppyModule("main") +mod = GuppyModule("main", file = __file__) mod.load(quantum) @guppy(mod)