-
Notifications
You must be signed in to change notification settings - Fork 90
Create Rust QIR Runtime Wrapper Library #878
Changes from all commits
8805dd3
f552c3a
98026b7
6e289b5
87363b7
f1b3dae
d486177
69312ac
2c15e3c
3bf0e47
533df83
d1ef7eb
0edd58f
d955aec
1b010bb
f4ee602
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| [workspace] | ||
|
|
||
| members = [ | ||
| "src/Simulation/qdk_sim_rs", | ||
| "src/Qir/microsoft-quantum-qir-runtime-sys", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| [package] | ||
| name = "microsoft-quantum-qir-runtime-sys" | ||
| version = "0.1.0" | ||
| edition = "2018" | ||
| build = "build.rs" | ||
|
|
||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
|
||
| [dependencies] | ||
| cty = "0.2.1" | ||
| libloading = "0.7.0" | ||
| log = "0.4.14" | ||
| tempfile = "3.2.0" | ||
| llvm-sys = { version = "110", optional = true } | ||
| inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master", default-features = false, features = ["llvm11-0", "target-x86"], optional = true } | ||
| lazy_static = "1.4.0" | ||
|
|
||
| [build-dependencies] | ||
| cmake = "0.1.46" | ||
| bindgen = "0.59.1" | ||
| cc = "1.0.71" | ||
| which = "4.2.2" | ||
|
|
||
| [lib] | ||
|
|
||
|
|
||
| [features] | ||
| runtime = [] | ||
| foundation = [] | ||
| llvm-libloading = ["llvm-sys", "inkwell"] | ||
| default = ["runtime", "foundation"] |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,79 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Copyright (c) Microsoft Corporation. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Licensed under the MIT License. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use cmake::Config; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use std::boxed::Box; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use std::env; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use std::error::Error; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn main() -> Result<(), Box<dyn Error>> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| println!("cargo:rerun-if-env-changed=TARGET"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| println!("cargo:rerun-if-changed=build.rs"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (key, value) in env::vars() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| println!("{}: {}", key, value); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if cfg!(target_os = "windows") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let path_to_runtime_src = "..\\Runtime"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| compile_runtime_libraries(path_to_runtime_src)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let path_to_runtime_src = "../Runtime"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| compile_runtime_libraries(path_to_runtime_src)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn compile_runtime_libraries(path_to_runtime_src: &str) -> Result<(), Box<dyn Error>> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut config = Config::new(path_to_runtime_src); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if cfg!(target_os = "windows") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.static_crt(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set_compiler(&mut config)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set_profile(&mut config)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.generator("Ninja"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let _ = config.build(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+41
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Nit. I don't know Rust. Talking in C/C++ terminology)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In Rust, expressions and functions always must return a value (by contrast with All that leads up to that As for why it seems like it always returns |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#how-do-i-use-a-different-compiler | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // We set this here as setting it in the cmakefile is discouraged | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn set_compiler(config: &mut Config) -> Result<(), Box<dyn Error>>{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if cfg!(target_os = "linux") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut c_cfg = cc::Build::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let clang_11 = which::which("clang-11")?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| c_cfg.compiler(clang_11); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.init_c_cfg(c_cfg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut cxx_cfg = cc::Build::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let clangpp_11 = which::which("clang++-11")?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cxx_cfg.compiler(clangpp_11); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.init_cxx_cfg(cxx_cfg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if cfg!(target_os = "windows") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut c_cfg = cc::Build::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let clang = which::which("clang.exe")?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| c_cfg.compiler(clang); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.init_c_cfg(c_cfg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let mut cxx_cfg = cc::Build::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let clangpp = which::which("clang++.exe")?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cxx_cfg.compiler(clangpp); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.init_cxx_cfg(cxx_cfg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if cfg!(target_os = "macos") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Use macos default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| panic!("Unsupported platform") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+46
to
+70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Nit. . . .)
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fn set_profile(config: &mut Config) -> Result<(), Box<dyn Error>> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.define("CMAKE_BUILD_TYPE", "RelWithDebInfo"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.define("CMAKE_C_COMPILER_WORKS", "1"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.define("CMAKE_CXX_COMPILER_WORKS", "1"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use lazy_static::lazy_static; | ||
|
|
||
| use libloading::Library; | ||
|
|
||
| #[cfg(target_os = "linux")] | ||
| const FOUNDATION_BYTES: &'static [u8] = include_bytes!(concat!( | ||
| env!("OUT_DIR"), | ||
| "/build/lib/QSharpFoundation/libMicrosoft.Quantum.Qir.QSharp.Foundation.so" | ||
| )); | ||
|
|
||
| #[cfg(target_os = "macos")] | ||
| const FOUNDATION_BYTES: &'static [u8] = include_bytes!(concat!( | ||
| env!("OUT_DIR"), | ||
| "/build/lib/QSharpFoundation/libMicrosoft.Quantum.Qir.QSharp.Foundation.dylib" | ||
| )); | ||
|
|
||
| #[cfg(target_os = "windows")] | ||
| const FOUNDATION_BYTES: &'static [u8] = include_bytes!(concat!( | ||
| env!("OUT_DIR"), | ||
| "/build/lib/QSharpFoundation/Microsoft.Quantum.Qir.QSharp.Foundation.dll" | ||
| )); | ||
|
Comment on lines
+8
to
+24
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just FYI (I'm not saying whether it is good or bad): If that is not applicable to Rust then is it possible to write like this? (deduplicated) const FOUNDATION_BYTES: &'static [u8] = include_bytes!(concat!(
env!("OUT_DIR"),
#[cfg(target_os = "linux")]
"/build/lib/QSharpFoundation/libMicrosoft.Quantum.Qir.QSharp.Foundation.so"
#[cfg(target_os = "macos")]
"/build/lib/QSharpFoundation/libMicrosoft.Quantum.Qir.QSharp.Foundation.dylib"
#[cfg(target_os = "windows")]
"/build/lib/QSharpFoundation/Microsoft.Quantum.Qir.QSharp.Foundation.dll"
));
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify, I did that due to requirements in our CI and packaging pipeline for .NET projects; I wouldn't recommend following my approach in this case. |
||
|
|
||
| lazy_static! { | ||
| pub(crate) static ref FOUNDATION_LIBRARY: Library = unsafe { | ||
| crate::qir_libloading::load_library_bytes( | ||
| "Microsoft.Quantum.Qir.QSharp.Foundation", | ||
| FOUNDATION_BYTES, | ||
| ) | ||
| .unwrap() | ||
| }; | ||
| } | ||
|
|
||
| pub struct QSharpFoundation {} | ||
|
|
||
| impl QSharpFoundation { | ||
| pub fn new() -> QSharpFoundation { | ||
| let _ = FOUNDATION_LIBRARY; | ||
| QSharpFoundation {} | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use crate::foundation::QSharpFoundation; | ||
|
|
||
| #[test] | ||
| fn library_loads_on_new() { | ||
| let _ = QSharpFoundation::new(); | ||
| } | ||
| #[test] | ||
| fn library_can_be_initialized_multiple_times() { | ||
| let _ = QSharpFoundation::new(); | ||
| let _ = QSharpFoundation::new(); | ||
| let _ = QSharpFoundation::new(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| #[cfg(feature = "foundation")] | ||
| pub mod foundation; | ||
|
|
||
| #[cfg(feature = "runtime")] | ||
| pub mod runtime; | ||
|
|
||
| mod qir_libloading; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use libloading::{library_filename, Library}; | ||
| use log; | ||
| use std::error::Error; | ||
| use std::path::Path; | ||
| use tempfile::tempdir; | ||
|
|
||
| pub(crate) fn write_library<P: AsRef<Path>>( | ||
| path: P, | ||
| lib: &'static [u8], | ||
| ) -> Result<(), Box<dyn Error>> { | ||
| log::debug!("Writing {}", path.as_ref().display()); | ||
| std::fs::write(path, lib)?; | ||
| Ok(()) | ||
| } | ||
|
|
||
| pub(crate) unsafe fn load_library_bytes( | ||
| base_name: &str, | ||
| lib: &'static [u8], | ||
| ) -> Result<Library, Box<dyn Error>> { | ||
| let name = library_filename(base_name) | ||
| .into_string() | ||
| .expect("Could not get library name as string"); | ||
| let path = tempdir().expect(""); | ||
| let filepath = path.as_ref().join(name); | ||
| write_library(&filepath, lib)?; | ||
| let library = load_library(&filepath)?; | ||
| Ok(library) | ||
| } | ||
|
|
||
| pub(crate) unsafe fn load_library<P: AsRef<Path>>(path: P) -> Result<Library, Box<dyn Error>> { | ||
| log::debug!("Loading {}", path.as_ref().display()); | ||
| let library = Library::new(path.as_ref().as_os_str())?; | ||
|
|
||
| #[cfg(feature = "llvm-libloading")] | ||
| load_library_with_llvm(path); | ||
|
|
||
| Ok(library) | ||
| } | ||
|
|
||
| #[cfg(feature = "llvm-libloading")] | ||
| fn load_library_with_llvm<P: AsRef<Path>>(path: P) { | ||
| let library_path = path | ||
| .as_ref() | ||
| .to_str() | ||
| .expect("Could not convert library path to &str"); | ||
| let was_loaded_by_llvm = inkwell::support::load_library_permanently(library_path); | ||
| if was_loaded_by_llvm { | ||
| log::error!("Failed to load {} into LLVM", library_path); | ||
| } else { | ||
| log::debug!("Loaded {} into LLVM", library_path); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| use lazy_static::lazy_static; | ||
|
|
||
| use std::ffi::CString; | ||
|
|
||
| use cty; | ||
| use libloading::Library; | ||
|
|
||
| #[cfg(target_os = "linux")] | ||
| const RUNTIME_BYTES: &'static [u8] = include_bytes!(concat!( | ||
| env!("OUT_DIR"), | ||
| "/build/lib/QIR/libMicrosoft.Quantum.Qir.Runtime.so" | ||
| )); | ||
|
|
||
| #[cfg(target_os = "macos")] | ||
| const RUNTIME_BYTES: &'static [u8] = include_bytes!(concat!( | ||
| env!("OUT_DIR"), | ||
| "/build/lib/QIR/libMicrosoft.Quantum.Qir.Runtime.dylib" | ||
| )); | ||
|
|
||
| #[cfg(target_os = "windows")] | ||
| const RUNTIME_BYTES: &'static [u8] = include_bytes!(concat!( | ||
| env!("OUT_DIR"), | ||
| "/build/lib/QIR/Microsoft.Quantum.Qir.Runtime.dll" | ||
| )); | ||
|
|
||
| lazy_static! { | ||
| pub(crate) static ref RUNTIME_LIBRARY: Library = unsafe { | ||
| crate::qir_libloading::load_library_bytes("Microsoft.Quantum.Qir.Runtime", RUNTIME_BYTES) | ||
| .unwrap() | ||
| }; | ||
| } | ||
|
|
||
| pub type QUBIT = u64; | ||
|
|
||
| #[repr(C)] | ||
| pub struct QirArray { | ||
| private: [u8; 0], | ||
| } | ||
|
|
||
| pub type IRuntimeDriver = cty::c_void; | ||
|
|
||
| pub struct BasicRuntimeDriver {} | ||
|
|
||
| impl BasicRuntimeDriver { | ||
| pub unsafe fn initialize_qir_context(track_allocated_objects: bool) { | ||
| // The libloading calls need to be used instead of the extern "C" calls | ||
| // to prevent linkage. Python can't init the lib if we take a hard | ||
| // dependency on the library | ||
| let driver = QirRuntime::create_basic_runtime_driver(); | ||
| QirRuntime::initialize_qir_context(driver, track_allocated_objects); | ||
| } | ||
| } | ||
|
|
||
| pub struct QirRuntime {} | ||
|
|
||
| impl QirRuntime { | ||
| pub fn new() -> QirRuntime { | ||
| let _ = RUNTIME_LIBRARY; | ||
| QirRuntime {} | ||
| } | ||
|
|
||
| pub unsafe fn create_basic_runtime_driver() -> *mut cty::c_void { | ||
| let library = &RUNTIME_LIBRARY; | ||
| let create = library | ||
| .get::<fn() -> *mut IRuntimeDriver>( | ||
| CString::new("CreateBasicRuntimeDriver") | ||
| .unwrap() | ||
| .as_bytes_with_nul(), | ||
| ) | ||
| .unwrap(); | ||
| create() | ||
| } | ||
|
|
||
| pub unsafe fn initialize_qir_context(driver: *mut cty::c_void, track_allocated_objects: bool) { | ||
| let library = &RUNTIME_LIBRARY; | ||
| let init = library | ||
| .get::<fn(*mut cty::c_void, bool)>( | ||
| CString::new("InitializeQirContext") | ||
| .unwrap() | ||
| .as_bytes_with_nul(), | ||
| ) | ||
| .unwrap(); | ||
| init(driver, track_allocated_objects) | ||
| } | ||
|
|
||
| pub unsafe fn quantum_rt_array_get_element_ptr_1d( | ||
| array: *mut QirArray, | ||
| index: i64, | ||
| ) -> *mut cty::c_char { | ||
| let library = &RUNTIME_LIBRARY; | ||
| let get_element_ptr = library | ||
| .get::<fn(*mut QirArray, arg2: i64) -> *mut cty::c_char>( | ||
| CString::new("__quantum__rt__array_get_element_ptr_1d") | ||
| .unwrap() | ||
| .as_bytes_with_nul(), | ||
| ) | ||
| .unwrap(); | ||
| get_element_ptr(array, index) | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use crate::runtime::QirRuntime; | ||
| #[test] | ||
| fn library_loads_on_new() { | ||
| let _ = QirRuntime::new(); | ||
| } | ||
| #[test] | ||
| fn library_can_be_initialized_multiple_times() { | ||
| let _ = QirRuntime::new(); | ||
| let _ = QirRuntime::new(); | ||
| let _ = QirRuntime::new(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Nit)
Consider deduplicating as much as possible, such that only the differing part is placed in
if .. else ... Something like this (pseudocode):