From e5ced83134bea77602c94acb91d1a26aa99d7691 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 17:07:51 +0100 Subject: [PATCH 01/16] Add Nix tools to Rust --- flake.lock | 39 +++++++++++++++++++++++++++++++++++++++ flake.nix | 9 +++++++++ 2 files changed, 48 insertions(+) diff --git a/flake.lock b/flake.lock index b4abd66bf..07ae0529b 100644 --- a/flake.lock +++ b/flake.lock @@ -21,6 +21,27 @@ "type": "github" } }, + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1705904706, + "narHash": "sha256-0aJfyNYWy6pS4GfOA+pmGOE+PgJZLG78T+sPh8zRJx8=", + "owner": "nix-community", + "repo": "fenix", + "rev": "8e7851239acf6bfb06637f4d3e180302f53ec542", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -267,11 +288,29 @@ "root": { "inputs": { "devenv": "devenv", + "fenix": "fenix", "nixpkgs": "nixpkgs_2", "nixpkgs-python": "nixpkgs-python", "systems": "systems_3" } }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1705864945, + "narHash": "sha256-ZATChFWHToTZQFLlzrzDUX8fjEbMHHBIyPaZU1JGmjI=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "d410d4a2baf9e99b37b03dd42f06238b14374bf7", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, "systems": { "locked": { "lastModified": 1681028828, diff --git a/flake.nix b/flake.nix index a0a8860eb..4cacbf960 100644 --- a/flake.nix +++ b/flake.nix @@ -7,6 +7,10 @@ url = "github:cachix/nixpkgs-python"; inputs.nixpkgs.follows = "nixpkgs"; }; + fenix = { + url = "github:nix-community/fenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = { @@ -57,6 +61,11 @@ }; version = "3.11"; }; + + languages.rust = { + enable = true; + channel = "stable"; + }; } ]; }; From dfefb5e5d99d2bc2457c8e5698f618490052989f Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 17:08:09 +0100 Subject: [PATCH 02/16] Add Rust bindings stub --- crate/Cargo.lock | 287 ++++++++++++++++++++++++++++++++++++++ crate/Cargo.toml | 12 ++ crate/examples/example.rs | 22 +++ crate/src/lib.rs | 17 +++ 4 files changed, 338 insertions(+) create mode 100644 crate/Cargo.lock create mode 100644 crate/Cargo.toml create mode 100644 crate/examples/example.rs create mode 100644 crate/src/lib.rs diff --git a/crate/Cargo.lock b/crate/Cargo.lock new file mode 100644 index 000000000..790404568 --- /dev/null +++ b/crate/Cargo.lock @@ -0,0 +1,287 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "indoc" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pyo3" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a89dc7a5850d0e983be1ec2a463a171d20990487c3cfcd68b5363f1ee3d6fe0" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset", + "parking_lot", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07426f0d8fe5a601f26293f300afd1a7b1ed5e78b2a705870c5f30893c5163be" +dependencies = [ + "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb7dec17e17766b46bca4f1a4215a85006b4c2ecde122076c562dd058da6cf1" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f738b4e40d50b5711957f142878cfa0f28e054aa0ebdfc3fd137a843f74ed3" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc910d4851847827daf9d6cdd4a823fbdaab5b8818325c5e97a86da79e8881f" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "qibolab" +version = "0.1.0" +dependencies = [ + "anyhow", + "pyo3", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-lexicon" +version = "0.12.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unindent" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/crate/Cargo.toml b/crate/Cargo.toml new file mode 100644 index 000000000..bae9d89a7 --- /dev/null +++ b/crate/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "qibolab" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +pyo3 = { version = "0.20.2", features = ["auto-initialize"] } + +[dev-dependencies] +anyhow = "1.0.79" diff --git a/crate/examples/example.rs b/crate/examples/example.rs new file mode 100644 index 000000000..a087c4a11 --- /dev/null +++ b/crate/examples/example.rs @@ -0,0 +1,22 @@ +use anyhow::Result; +use qibolab::execute_qasm; + +const CODE: &str = r#" +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[3]; +creg a[2]; +cx q[0],q[2]; +x q[1]; +swap q[0],q[1]; +cx q[1],q[0]; +measure q[0] -> a[0]; +measure q[2] -> a[1];, +"#; + +fn main() -> Result<()> { + let res = execute_qasm(CODE.to_owned(), "dummy".to_owned(), 10)?; + println!("{:#?}", res); + + Ok(()) +} diff --git a/crate/src/lib.rs b/crate/src/lib.rs new file mode 100644 index 000000000..c7ab8cc18 --- /dev/null +++ b/crate/src/lib.rs @@ -0,0 +1,17 @@ +use pyo3::prelude::*; + +pub fn execute_qasm(circuit: String, platform: String, nshots: u32) -> PyResult> { + // TODO: move to the example, here for debug + println!( + "---\nExecuting:\n'''{}'''\n\non: {}\nwith: {} shots\n---\n", + circuit, platform, nshots + ); + + Python::with_gil(|py| { + let qibolab = PyModule::import(py, "qibolab")?; + qibolab + .getattr("execute_qasm")? + .call1((circuit, platform, nshots))? + .extract() + }) +} From e3229571389d2b37f56bcb44aed1fdb733ab1999 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:13:34 +0000 Subject: [PATCH 03/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- crate/examples/example.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crate/examples/example.rs b/crate/examples/example.rs index a087c4a11..82d186ec7 100644 --- a/crate/examples/example.rs +++ b/crate/examples/example.rs @@ -2,15 +2,15 @@ use anyhow::Result; use qibolab::execute_qasm; const CODE: &str = r#" -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[3]; -creg a[2]; -cx q[0],q[2]; -x q[1]; -swap q[0],q[1]; -cx q[1],q[0]; -measure q[0] -> a[0]; +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[3]; +creg a[2]; +cx q[0],q[2]; +x q[1]; +swap q[0],q[1]; +cx q[1],q[0]; +measure q[0] -> a[0]; measure q[2] -> a[1];, "#; From 2b21cbe612a6a8ccff35cab2a915e1339141a0bf Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 18:15:21 +0100 Subject: [PATCH 04/16] Fix example and options passed --- crate/examples/example.rs | 4 ++-- crate/src/lib.rs | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/crate/examples/example.rs b/crate/examples/example.rs index 82d186ec7..35ec82d82 100644 --- a/crate/examples/example.rs +++ b/crate/examples/example.rs @@ -11,12 +11,12 @@ x q[1]; swap q[0],q[1]; cx q[1],q[0]; measure q[0] -> a[0]; -measure q[2] -> a[1];, +measure q[2] -> a[1]; "#; fn main() -> Result<()> { let res = execute_qasm(CODE.to_owned(), "dummy".to_owned(), 10)?; - println!("{:#?}", res); + println!("{:?}", res); Ok(()) } diff --git a/crate/src/lib.rs b/crate/src/lib.rs index c7ab8cc18..d36a426cc 100644 --- a/crate/src/lib.rs +++ b/crate/src/lib.rs @@ -1,4 +1,5 @@ use pyo3::prelude::*; +use pyo3::types::PyDict; pub fn execute_qasm(circuit: String, platform: String, nshots: u32) -> PyResult> { // TODO: move to the example, here for debug @@ -8,10 +9,17 @@ pub fn execute_qasm(circuit: String, platform: String, nshots: u32) -> PyResult< ); Python::with_gil(|py| { + let kwargs = PyDict::new(py); + kwargs.set_item("circuit", circuit)?; + kwargs.set_item("platform", platform)?; + kwargs.set_item("nshots", nshots)?; + let qibolab = PyModule::import(py, "qibolab")?; qibolab .getattr("execute_qasm")? - .call1((circuit, platform, nshots))? + .call((), Some(kwargs))? + .call_method0("samples")? + .call_method0("ravel")? .extract() }) } From e1445803b99b23be5f1066d0ab91888d108eef39 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 18:17:26 +0100 Subject: [PATCH 05/16] Move debug print into example report --- crate/examples/example.rs | 13 +++++++++++-- crate/src/lib.rs | 6 ------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/crate/examples/example.rs b/crate/examples/example.rs index 35ec82d82..80c805493 100644 --- a/crate/examples/example.rs +++ b/crate/examples/example.rs @@ -15,8 +15,17 @@ measure q[2] -> a[1]; "#; fn main() -> Result<()> { - let res = execute_qasm(CODE.to_owned(), "dummy".to_owned(), 10)?; - println!("{:?}", res); + let circuit = CODE.to_owned(); + let platform = "dummy".to_owned(); + let nshots = 10; + + println!( + "---\nExecuting:\n'''{}'''\n\non: {}\nwith: {} shots\n---\n", + circuit, platform, nshots + ); + + let res = execute_qasm(circuit, platform, nshots)?; + println!("\n{:?}", res); Ok(()) } diff --git a/crate/src/lib.rs b/crate/src/lib.rs index d36a426cc..912bb3f87 100644 --- a/crate/src/lib.rs +++ b/crate/src/lib.rs @@ -2,12 +2,6 @@ use pyo3::prelude::*; use pyo3::types::PyDict; pub fn execute_qasm(circuit: String, platform: String, nshots: u32) -> PyResult> { - // TODO: move to the example, here for debug - println!( - "---\nExecuting:\n'''{}'''\n\non: {}\nwith: {} shots\n---\n", - circuit, platform, nshots - ); - Python::with_gil(|py| { let kwargs = PyDict::new(py); kwargs.set_item("circuit", circuit)?; From 17d0a26335465fbdd59bbf40ce11912d508ee566 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 18:48:00 +0100 Subject: [PATCH 06/16] Switch return type to a proper array --- crate/Cargo.lock | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ crate/Cargo.toml | 2 ++ crate/src/lib.rs | 11 ++++--- 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/crate/Cargo.lock b/crate/Cargo.lock index 790404568..abe0091a5 100644 --- a/crate/Cargo.lock +++ b/crate/Cargo.lock @@ -54,6 +54,16 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "memoffset" version = "0.9.0" @@ -63,6 +73,62 @@ dependencies = [ "autocfg", ] +[[package]] +name = "ndarray" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "rawpointer", +] + +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "numpy" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef41cbb417ea83b30525259e30ccef6af39b31c240bda578889494c5392d331" +dependencies = [ + "libc", + "ndarray", + "num-complex", + "num-integer", + "num-traits", + "pyo3", + "rustc-hash", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -167,6 +233,8 @@ name = "qibolab" version = "0.1.0" dependencies = [ "anyhow", + "ndarray", + "numpy", "pyo3", ] @@ -179,6 +247,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "redox_syscall" version = "0.4.1" @@ -188,6 +262,12 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "scopeguard" version = "1.2.0" diff --git a/crate/Cargo.toml b/crate/Cargo.toml index bae9d89a7..f60ff4d45 100644 --- a/crate/Cargo.toml +++ b/crate/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +ndarray = "0.15.6" +numpy = "0.20.0" pyo3 = { version = "0.20.2", features = ["auto-initialize"] } [dev-dependencies] diff --git a/crate/src/lib.rs b/crate/src/lib.rs index 912bb3f87..3238e6acb 100644 --- a/crate/src/lib.rs +++ b/crate/src/lib.rs @@ -1,7 +1,9 @@ +use ndarray::Array2; +use numpy::PyArray2; use pyo3::prelude::*; use pyo3::types::PyDict; -pub fn execute_qasm(circuit: String, platform: String, nshots: u32) -> PyResult> { +pub fn execute_qasm(circuit: String, platform: String, nshots: u32) -> PyResult> { Python::with_gil(|py| { let kwargs = PyDict::new(py); kwargs.set_item("circuit", circuit)?; @@ -9,11 +11,12 @@ pub fn execute_qasm(circuit: String, platform: String, nshots: u32) -> PyResult< kwargs.set_item("nshots", nshots)?; let qibolab = PyModule::import(py, "qibolab")?; - qibolab + let pyarray: &PyArray2 = qibolab .getattr("execute_qasm")? .call((), Some(kwargs))? .call_method0("samples")? - .call_method0("ravel")? - .extract() + .extract()?; + + Ok(pyarray.to_owned_array()) }) } From 1999b67ad7149cbb7b22e16cc623eb407ba24edf Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 19:00:15 +0100 Subject: [PATCH 07/16] Add Rust workflow --- .github/workflows/rustapi.yml | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/rustapi.yml diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml new file mode 100644 index 000000000..a335c0cb6 --- /dev/null +++ b/.github/workflows/rustapi.yml @@ -0,0 +1,36 @@ +# Test Qibolab C API +name: C API + +on: + push: + workflow_dispatch: + +jobs: + tests: + strategy: + matrix: + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + - name: Prepare virtual environment + run: | + python -m venv env + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - name: Check and lint + working-directory: crate + run: | + cargo check + cargo clippy --all-targets + - name: Build & run example + working-directory: crate + run: | + cargo run --example example From c9778932f4049bd38df9185d1e45ad129d6c853d Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 19:02:56 +0100 Subject: [PATCH 08/16] Fix workflow name --- .github/workflows/rustapi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml index a335c0cb6..36920d5e7 100644 --- a/.github/workflows/rustapi.yml +++ b/.github/workflows/rustapi.yml @@ -1,5 +1,5 @@ -# Test Qibolab C API -name: C API +# Test Qibolab Rust API +name: Rust API on: push: From 085ad24cf511152b61bc5dbdb39889d61780988b Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 19:04:42 +0100 Subject: [PATCH 09/16] Patch python path roughly --- .github/workflows/rustapi.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml index 36920d5e7..9f205b572 100644 --- a/.github/workflows/rustapi.yml +++ b/.github/workflows/rustapi.yml @@ -33,4 +33,5 @@ jobs: - name: Build & run example working-directory: crate run: | + export PYTHONPATH=$(realpath ../src/):$(realpath ../env/lib/python3.10/site-packages/):$PYTHONPATH cargo run --example example From 3b31ca1af417e4af33fd4c9f5044b107c4c4c790 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 19:06:32 +0100 Subject: [PATCH 10/16] Install package in virtual environment Ops... --- .github/workflows/rustapi.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml index 9f205b572..b182ebaeb 100644 --- a/.github/workflows/rustapi.yml +++ b/.github/workflows/rustapi.yml @@ -21,6 +21,7 @@ jobs: - name: Prepare virtual environment run: | python -m venv env + pip install . - name: Install Rust uses: actions-rs/toolchain@v1 with: @@ -33,5 +34,6 @@ jobs: - name: Build & run example working-directory: crate run: | - export PYTHONPATH=$(realpath ../src/):$(realpath ../env/lib/python3.10/site-packages/):$PYTHONPATH + export PYTHONPATH=$(realpath ../env/lib/python3.10/site-packages/):$PYTHONPATH + export PYTHONPATH=$(realpath ../src/):$PYTHONPATH cargo run --example example From 5934fa2ea775dd2b8c25a76bf3d6bc9e8a2fe6ff Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 19:11:22 +0100 Subject: [PATCH 11/16] Avoid setting python path explicitly --- .github/workflows/rustapi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml index b182ebaeb..b93ce3e4e 100644 --- a/.github/workflows/rustapi.yml +++ b/.github/workflows/rustapi.yml @@ -34,6 +34,6 @@ jobs: - name: Build & run example working-directory: crate run: | - export PYTHONPATH=$(realpath ../env/lib/python3.10/site-packages/):$PYTHONPATH - export PYTHONPATH=$(realpath ../src/):$PYTHONPATH + #export PYTHONPATH=$(realpath ../env/lib/python3.10/site-packages/):$PYTHONPATH + #export PYTHONPATH=$(realpath ../src/):$PYTHONPATH cargo run --example example From daf02ef7d597f78528150d87a0cb5880d8c44bde Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 22 Jan 2024 19:20:54 +0100 Subject: [PATCH 12/16] Attempt to run also on MacOS --- .github/workflows/rustapi.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml index b93ce3e4e..db9808524 100644 --- a/.github/workflows/rustapi.yml +++ b/.github/workflows/rustapi.yml @@ -9,7 +9,7 @@ jobs: tests: strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: @@ -31,9 +31,13 @@ jobs: run: | cargo check cargo clippy --all-targets + - name: Set Python path + if: ${{ matrix.os == 'macos-latest' }} + run: | + PYTHONPATH=$(realpath ../env/lib/python3.10/site-packages/):$PYTHONPATH + PYTHONPATH=$(realpath ../src/):$PYTHONPATH + echo "PYTHONPATH=$PYTHONPATH" >> "$GITHUB_ENV" - name: Build & run example working-directory: crate run: | - #export PYTHONPATH=$(realpath ../env/lib/python3.10/site-packages/):$PYTHONPATH - #export PYTHONPATH=$(realpath ../src/):$PYTHONPATH cargo run --example example From 5d0f741d665b3e014011aa9b57d451aa42a275ae Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 23 Jan 2024 11:23:44 +0100 Subject: [PATCH 13/16] Fix MacOS python path setting The missing realpath command is replaced by a Python script Since the package is not installed in editable mode in the workflow, there is no need for the explicit src/ path --- .github/workflows/rustapi.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml index db9808524..29412bb4c 100644 --- a/.github/workflows/rustapi.yml +++ b/.github/workflows/rustapi.yml @@ -34,9 +34,11 @@ jobs: - name: Set Python path if: ${{ matrix.os == 'macos-latest' }} run: | - PYTHONPATH=$(realpath ../env/lib/python3.10/site-packages/):$PYTHONPATH - PYTHONPATH=$(realpath ../src/):$PYTHONPATH - echo "PYTHONPATH=$PYTHONPATH" >> "$GITHUB_ENV" + site=$(python3 -c ' + from pathlib import Path; + print(Path("../.venv/lib/python3.11/site-packages/").resolve()) + ') + echo "PYTHONPATH=$site:$PYTHONPATH" >> "$GITHUB_ENV" - name: Build & run example working-directory: crate run: | From 472dfefd3c7214330db0ed634264c150fdabd86f Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 23 Jan 2024 11:23:57 +0100 Subject: [PATCH 14/16] Add minimal README to Rust API --- crate/README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 crate/README.md diff --git a/crate/README.md b/crate/README.md new file mode 100644 index 000000000..65b15d3f9 --- /dev/null +++ b/crate/README.md @@ -0,0 +1,31 @@ +# Rust API + +## Install + +You just need to install Qibolab as usual (see [main README.md](../README.md)) and +specify the `qibolab` crate inside `Cargo.toml`. + +See the example below. + +## Example + +To run the example in the [`examples/`](./examples) folder just use Cargo: + +```sh +cargo run --example example +``` + +## Environment + +In order to properly locate `qibolab` in a virtual environment, on some platform (e.g. +MacOS) it is required to manually modify the `$PYTHONPATH`. + +```sh +PYTHONPATH=$(realpath ${VIRTUAL_ENV}/lib/python3.11/site-packages):$PYTHONPATH +``` + +In editable mode installation, you might also need to manually add the `src/` folder: + +```sh +PYTHONPATH=$(realpath qibolab/src/):$PYTHONPATH +``` From 138a9696b7dc7c67511495dcd11816f2992e9c24 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 23 Jan 2024 12:18:34 +0100 Subject: [PATCH 15/16] Drop pyhton path export, since not required --- .github/workflows/rustapi.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml index 29412bb4c..bc3b8345b 100644 --- a/.github/workflows/rustapi.yml +++ b/.github/workflows/rustapi.yml @@ -31,14 +31,6 @@ jobs: run: | cargo check cargo clippy --all-targets - - name: Set Python path - if: ${{ matrix.os == 'macos-latest' }} - run: | - site=$(python3 -c ' - from pathlib import Path; - print(Path("../.venv/lib/python3.11/site-packages/").resolve()) - ') - echo "PYTHONPATH=$site:$PYTHONPATH" >> "$GITHUB_ENV" - name: Build & run example working-directory: crate run: | From 0d4d03495cc150d71751e94d5c457601edcba1c1 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Tue, 23 Jan 2024 12:36:13 +0100 Subject: [PATCH 16/16] Drop unused venv creation in workflow --- .github/workflows/rustapi.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/rustapi.yml b/.github/workflows/rustapi.yml index bc3b8345b..ed69c5a83 100644 --- a/.github/workflows/rustapi.yml +++ b/.github/workflows/rustapi.yml @@ -20,7 +20,6 @@ jobs: python-version: "3.10" - name: Prepare virtual environment run: | - python -m venv env pip install . - name: Install Rust uses: actions-rs/toolchain@v1