From 926f6202949781c61c251a0dfe94d8e6edca39ff Mon Sep 17 00:00:00 2001 From: Marquess Valdez Date: Wed, 23 Oct 2024 16:12:57 -0700 Subject: [PATCH 1/5] feat: Shot count is now represented as an unsigned 32-bit, up from 16-bit --- crates/lib/src/compiler/libquil.rs | 4 ++-- crates/lib/src/compiler/quilc.rs | 4 ++-- crates/lib/src/executable.rs | 20 ++++++++++---------- crates/lib/src/qpu/execution.rs | 6 +++--- crates/lib/src/qvm/execution.rs | 10 +++++----- crates/lib/src/qvm/http.rs | 16 ++++++++-------- crates/lib/src/qvm/mod.rs | 6 +++--- crates/lib/tests/basic_qvm.rs | 4 ++-- crates/lib/tests/mocked_qpu.rs | 2 +- crates/lib/tests/qvm_api.rs | 6 +++--- crates/python/src/executable.rs | 4 ++-- crates/python/src/from_py.rs | 18 +++++++++--------- crates/python/src/qvm/api.rs | 14 +++++++------- crates/python/src/qvm/mod.rs | 6 +++--- 14 files changed, 60 insertions(+), 60 deletions(-) diff --git a/crates/lib/src/compiler/libquil.rs b/crates/lib/src/compiler/libquil.rs index 391cbcb8c..1c436589e 100644 --- a/crates/lib/src/compiler/libquil.rs +++ b/crates/lib/src/compiler/libquil.rs @@ -174,7 +174,7 @@ mod test { use qcs_api_client_openapi::models::InstructionSetArchitecture; use quil_rs::quil::Quil; use regex::Regex; - use std::{collections::HashMap, fs::File, num::NonZeroU16}; + use std::{collections::HashMap, fs::File, num::NonZeroU32}; const EXPECTED_H0_OUTPUT: &str = "MEASURE 0\n"; @@ -231,7 +231,7 @@ MEASURE 1 ro[1] let mut results = qvm::Execution::new(&output.program.to_quil_or_debug()) .unwrap() .run( - NonZeroU16::new(10).expect("value is non-zero"), + NonZeroU32::new(10).expect("value is non-zero"), [("ro".to_string(), AddressRequest::IncludeAll)] .iter() .cloned() diff --git a/crates/lib/src/compiler/quilc.rs b/crates/lib/src/compiler/quilc.rs index de6a20fcd..c3e634532 100644 --- a/crates/lib/src/compiler/quilc.rs +++ b/crates/lib/src/compiler/quilc.rs @@ -345,7 +345,7 @@ mod tests { use qcs_api_client_openapi::models::InstructionSetArchitecture; use quil_rs::quil::Quil; use regex::Regex; - use std::{fs::File, num::NonZeroU16}; + use std::{fs::File, num::NonZeroU32}; const EXPECTED_H0_OUTPUT: &str = "MEASURE 0\n"; @@ -399,7 +399,7 @@ MEASURE 1 ro[1] let mut results = qvm::Execution::new(&output.program.to_quil_or_debug()) .unwrap() .run( - NonZeroU16::new(10).expect("value is non-zero"), + NonZeroU32::new(10).expect("value is non-zero"), [("ro".to_string(), AddressRequest::IncludeAll)] .iter() .cloned() diff --git a/crates/lib/src/executable.rs b/crates/lib/src/executable.rs index ba9c5ff24..a0d3a059b 100644 --- a/crates/lib/src/executable.rs +++ b/crates/lib/src/executable.rs @@ -3,7 +3,7 @@ use std::borrow::Cow; use std::collections::HashMap; -use std::num::NonZeroU16; +use std::num::NonZeroU32; use std::sync::Arc; use std::time::Duration; @@ -42,10 +42,10 @@ use quil_rs::program::ProgramError; /// /// #[tokio::main] /// async fn main() { -/// use std::num::NonZeroU16; +/// use std::num::NonZeroU32; /// use qcs::qvm; /// let qvm_client = qvm::http::HttpClient::from(&Qcs::load()); -/// let mut result = Executable::from_quil(PROGRAM).with_qcs_client(Qcs::default()).with_shots(NonZeroU16::new(4).unwrap()).execute_on_qvm(&qvm_client).await.unwrap(); +/// let mut result = Executable::from_quil(PROGRAM).with_qcs_client(Qcs::default()).with_shots(NonZeroU32::new(4).unwrap()).execute_on_qvm(&qvm_client).await.unwrap(); /// // "ro" is the only source read from by default if you don't specify a .read_from() /// /// // We first convert the readout data to a [`RegisterMap`] to get a mapping of registers @@ -87,7 +87,7 @@ use quil_rs::program::ProgramError; #[allow(missing_debug_implementations)] pub struct Executable<'executable, 'execution> { quil: Arc, - shots: NonZeroU16, + shots: NonZeroU32, readout_memory_region_names: Option>>, params: Parameters, qcs_client: Option>, @@ -119,7 +119,7 @@ impl<'executable> Executable<'executable, '_> { pub fn from_quil>>(quil: Quil) -> Self { Self { quil: quil.into(), - shots: NonZeroU16::new(1).expect("value is non-zero"), + shots: NonZeroU32::new(1).expect("value is non-zero"), readout_memory_region_names: None, params: Parameters::new(), compiler_options: CompilerOpts::default(), @@ -318,7 +318,7 @@ pub type ExecutionResult = Result; impl Executable<'_, '_> { /// Specify a number of times to run the program for each execution. Defaults to 1 run or "shot". #[must_use] - pub fn with_shots(mut self, shots: NonZeroU16) -> Self { + pub fn with_shots(mut self, shots: NonZeroU32) -> Self { self.shots = shots; self } @@ -827,7 +827,7 @@ mod describe_get_config { #[cfg(feature = "manual-tests")] mod describe_qpu_for_id { use assert2::let_assert; - use std::num::NonZeroU16; + use std::num::NonZeroU32; use crate::compiler::quilc::CompilerOpts; use crate::compiler::rpcq; @@ -857,7 +857,7 @@ mod describe_qpu_for_id { #[tokio::test] async fn it_loads_cached_version() { let mut exe = Executable::from_quil("").with_quilc_client(Some(quilc_client())); - let shots = NonZeroU16::new(17).expect("value is non-zero"); + let shots = NonZeroU32::new(17).expect("value is non-zero"); exe.shots = shots; exe.qpu = Some( qpu::Execution::new( @@ -879,7 +879,7 @@ mod describe_qpu_for_id { #[tokio::test] async fn it_creates_new_after_shot_change() { - let original_shots = NonZeroU16::new(23).expect("value is non-zero"); + let original_shots = NonZeroU32::new(23).expect("value is non-zero"); let mut exe = Executable::from_quil("") .with_quilc_client(Some(quilc_client())) .with_shots(original_shots); @@ -889,7 +889,7 @@ mod describe_qpu_for_id { // Cache so we can verify cache is not used. exe.qpu = Some(qpu); - let new_shots = NonZeroU16::new(32).expect("value is non-zero"); + let new_shots = NonZeroU32::new(32).expect("value is non-zero"); exe = exe.with_shots(new_shots); let qpu = exe.qpu_for_id("Aspen-9").await.unwrap(); diff --git a/crates/lib/src/qpu/execution.rs b/crates/lib/src/qpu/execution.rs index 1cd8bbabf..eb1f0ba94 100644 --- a/crates/lib/src/qpu/execution.rs +++ b/crates/lib/src/qpu/execution.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::convert::TryFrom; -use std::num::NonZeroU16; +use std::num::NonZeroU32; use std::sync::Arc; use std::time::Duration; @@ -35,7 +35,7 @@ use crate::compiler::quilc::{self, CompilerOpts, TargetDevice}; pub(crate) struct Execution<'a> { program: Program, pub(crate) quantum_processor_id: Cow<'a, str>, - pub(crate) shots: NonZeroU16, + pub(crate) shots: NonZeroU32, client: Arc, } @@ -119,7 +119,7 @@ impl<'a> Execution<'a> { /// for the QPU or that there is a bug in this library. pub(crate) async fn new( quil: Arc, - shots: NonZeroU16, + shots: NonZeroU32, quantum_processor_id: Cow<'a, str>, client: Arc, quilc_client: Option>, diff --git a/crates/lib/src/qvm/execution.rs b/crates/lib/src/qvm/execution.rs index 798cda969..6ded1ef0d 100644 --- a/crates/lib/src/qvm/execution.rs +++ b/crates/lib/src/qvm/execution.rs @@ -1,5 +1,5 @@ use std::str::FromStr; -use std::{collections::HashMap, num::NonZeroU16}; +use std::{collections::HashMap, num::NonZeroU32}; use quil_rs::Program; @@ -54,7 +54,7 @@ impl Execution { /// Missing parameters, extra parameters, or parameters of the wrong type will all cause errors. pub(crate) async fn run( &self, - shots: NonZeroU16, + shots: NonZeroU32, addresses: HashMap, params: &Parameters, client: &C, @@ -76,7 +76,7 @@ impl Execution { #[cfg(test)] mod describe_execution { - use std::{collections::HashMap, num::NonZeroU16}; + use std::{collections::HashMap, num::NonZeroU32}; use super::{Execution, Parameters}; use crate::{client::Qcs, qvm}; @@ -95,7 +95,7 @@ mod describe_execution { let result = exe .run( - NonZeroU16::new(1).expect("value is non-zero"), + NonZeroU32::new(1).expect("value is non-zero"), HashMap::new(), ¶ms, &qvm_client(), @@ -117,7 +117,7 @@ mod describe_execution { let result = exe .run( - NonZeroU16::new(1).expect("value is non-zero"), + NonZeroU32::new(1).expect("value is non-zero"), HashMap::new(), ¶ms, &qvm_client(), diff --git a/crates/lib/src/qvm/http.rs b/crates/lib/src/qvm/http.rs index 3c8e123bb..917655a6f 100644 --- a/crates/lib/src/qvm/http.rs +++ b/crates/lib/src/qvm/http.rs @@ -1,7 +1,7 @@ //! This module provides types and functions for making HTTP-based API calls to the QVM. //! Consider [`super::run_program`] for higher level access to the QVM that allows //! for running parameterized programs. -use std::{collections::HashMap, num::NonZeroU16}; +use std::{collections::HashMap, num::NonZeroU32}; use reqwest::Response; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -62,7 +62,7 @@ pub struct MultishotRequest { /// The memory regions to include in the response. pub addresses: HashMap, /// The number of trials ("shots") to run. - pub trials: NonZeroU16, + pub trials: NonZeroU32, /// Simulated measurement noise for the X, Y, and Z axes. #[serde(skip_serializing_if = "Option::is_none")] pub measurement_noise: Option<(f64, f64, f64)>, @@ -109,7 +109,7 @@ impl MultishotRequest { #[must_use] pub fn new( compiled_quil: String, - trials: NonZeroU16, + trials: NonZeroU32, addresses: HashMap, measurement_noise: Option<(f64, f64, f64)>, gate_noise: Option<(f64, f64, f64)>, @@ -142,7 +142,7 @@ pub struct MultishotMeasureRequest { /// The Quil program to run. pub compiled_quil: String, /// The number of trials ("shots") to run the program. - pub trials: NonZeroU16, + pub trials: NonZeroU32, /// Qubits to measure pub qubits: Vec, /// Simulated measurement noise for the X, Y, and Z axes. @@ -163,7 +163,7 @@ impl MultishotMeasureRequest { #[must_use] pub fn new( compiled_quil: String, - trials: NonZeroU16, + trials: NonZeroU32, qubits: &[u64], measurement_noise: Option<(f64, f64, f64)>, gate_noise: Option<(f64, f64, f64)>, @@ -389,7 +389,7 @@ where #[cfg(test)] mod describe_request { - use std::{collections::HashMap, num::NonZeroU16}; + use std::{collections::HashMap, num::NonZeroU32}; use crate::qvm::http::AddressRequest; @@ -400,7 +400,7 @@ mod describe_request { let program = "H 0"; let request = MultishotRequest::new( program.to_string(), - NonZeroU16::new(1).expect("value is non-zero"), + NonZeroU32::new(1).expect("value is non-zero"), HashMap::new(), None, None, @@ -413,7 +413,7 @@ mod describe_request { fn it_uses_kebab_case_for_json() { let request = MultishotRequest::new( "H 0".to_string(), - NonZeroU16::new(10).expect("value is non-zero"), + NonZeroU32::new(10).expect("value is non-zero"), [("ro".to_string(), AddressRequest::IncludeAll)] .iter() .cloned() diff --git a/crates/lib/src/qvm/mod.rs b/crates/lib/src/qvm/mod.rs index c01a2ca0c..e71d84728 100644 --- a/crates/lib/src/qvm/mod.rs +++ b/crates/lib/src/qvm/mod.rs @@ -1,7 +1,7 @@ //! This module contains all the functionality for running Quil programs on a QVM. Specifically, //! the [`Execution`] struct in this module. -use std::{collections::HashMap, num::NonZeroU16, str::FromStr, sync::Arc, time::Duration}; +use std::{collections::HashMap, num::NonZeroU32, str::FromStr, sync::Arc, time::Duration}; use quil_rs::{ instruction::{ArithmeticOperand, Instruction, MemoryReference, Move}, @@ -129,7 +129,7 @@ impl QvmResultData { #[allow(clippy::too_many_arguments)] pub async fn run( quil: &str, - shots: NonZeroU16, + shots: NonZeroU32, addresses: HashMap, params: &Parameters, measurement_noise: Option<(f64, f64, f64)>, @@ -160,7 +160,7 @@ pub async fn run( #[allow(clippy::too_many_arguments)] pub async fn run_program( program: &Program, - shots: NonZeroU16, + shots: NonZeroU32, addresses: HashMap, params: &Parameters, measurement_noise: Option<(f64, f64, f64)>, diff --git a/crates/lib/tests/basic_qvm.rs b/crates/lib/tests/basic_qvm.rs index ff013b1d8..7b8256a62 100644 --- a/crates/lib/tests/basic_qvm.rs +++ b/crates/lib/tests/basic_qvm.rs @@ -1,7 +1,7 @@ //! These are the integration tests for [`qcs::Executable::execute_on_qvm`]. //! In order to run them, QVM's web server must be running at localhost:5000. -use std::num::NonZeroU16; +use std::num::NonZeroU32; use qcs::{client::Qcs, compiler::rpcq, qvm, Executable}; @@ -29,7 +29,7 @@ async fn qvm_client() -> qvm::http::HttpClient { #[tokio::test] async fn test_bell_state() { - let shots: NonZeroU16 = NonZeroU16::new(10).expect("value is non-zero"); + let shots: NonZeroU32 = NonZeroU32::new(10).expect("value is non-zero"); let data = Executable::from_quil(PROGRAM) .with_quilc_client(Some(quilc_client().await)) diff --git a/crates/lib/tests/mocked_qpu.rs b/crates/lib/tests/mocked_qpu.rs index ac1597eaf..31ad4e271 100644 --- a/crates/lib/tests/mocked_qpu.rs +++ b/crates/lib/tests/mocked_qpu.rs @@ -76,7 +76,7 @@ async fn run_bell_state(connection_strategy: ConnectionStrategy) { .expect("should be valid execution options"); let result = Executable::from_quil(BELL_STATE) .with_quilc_client(Some(quilc_client().await)) - .with_shots(std::num::NonZeroU16::new(2).expect("value is non-zero")) + .with_shots(std::num::NonZeroU32::new(2).expect("value is non-zero")) .execute_on_qpu(QPU_ID, None, &execution_options_direct_access) .await .expect("Failed to run program that should be successful"); diff --git a/crates/lib/tests/qvm_api.rs b/crates/lib/tests/qvm_api.rs index 9040aca4e..a1fac5715 100644 --- a/crates/lib/tests/qvm_api.rs +++ b/crates/lib/tests/qvm_api.rs @@ -1,7 +1,7 @@ //! Integration tests for the [`qcs::qvm::http`] module. Requires the QVM //! web server to be running. -use std::{collections::HashMap, num::NonZeroU16}; +use std::{collections::HashMap, num::NonZeroU32}; use qcs::{ client::Qcs, @@ -49,7 +49,7 @@ async fn test_get_version_info(client: C) { async fn test_run(client: C) { let request = http::MultishotRequest::new( PROGRAM.to_string(), - NonZeroU16::new(2).expect("value is non-zero"), + NonZeroU32::new(2).expect("value is non-zero"), HashMap::from([("ro".to_string(), http::AddressRequest::IncludeAll)]), Some((0.1, 0.5, 0.4)), Some((0.1, 0.5, 0.4)), @@ -74,7 +74,7 @@ async fn test_run(client: C) { async fn test_run_and_measure(client: C) { let request = http::MultishotMeasureRequest::new( PROGRAM.to_string(), - NonZeroU16::new(5).expect("value is non-zero"), + NonZeroU32::new(5).expect("value is non-zero"), &[0, 1], Some((0.1, 0.5, 0.4)), Some((0.1, 0.5, 0.4)), diff --git a/crates/python/src/executable.rs b/crates/python/src/executable.rs index 0eaf82e64..c7dbe9ad6 100644 --- a/crates/python/src/executable.rs +++ b/crates/python/src/executable.rs @@ -1,4 +1,4 @@ -use std::{num::NonZeroU16, sync::Arc}; +use std::{num::NonZeroU32, sync::Arc}; use opentelemetry::trace::FutureExt; use pyo3::{pyclass, FromPyObject}; @@ -108,7 +108,7 @@ impl PyExecutable { quil: String, registers: Vec, parameters: Vec, - #[pyo3(from_py_with = "crate::from_py::optional_non_zero_u16")] shots: Option, + #[pyo3(from_py_with = "crate::from_py::optional_non_zero_u16")] shots: Option, quilc_client: Option, compiler_options: Option, ) -> Self { diff --git a/crates/python/src/from_py.rs b/crates/python/src/from_py.rs index a0078fa77..c639236e4 100644 --- a/crates/python/src/from_py.rs +++ b/crates/python/src/from_py.rs @@ -1,19 +1,19 @@ -use std::num::NonZeroU16; +use std::num::NonZeroU32; use pyo3::{exceptions::PyValueError, PyAny, PyResult}; -pub(crate) fn try_from_u16_to_non_zero_u16(int: u16) -> PyResult { - NonZeroU16::new(int).ok_or(PyValueError::new_err("value must be non-zero")) +pub(crate) fn try_from_u32_to_non_zero_u32(int: u32) -> PyResult { + NonZeroU32::new(int).ok_or(PyValueError::new_err("value must be non-zero")) } -pub(crate) fn non_zero_u16(obj: &PyAny) -> PyResult { - let value: u16 = obj.extract()?; - try_from_u16_to_non_zero_u16(value) +pub(crate) fn non_zero_u32(obj: &PyAny) -> PyResult { + let value: u32 = obj.extract()?; + try_from_u32_to_non_zero_u32(value) } -pub(crate) fn optional_non_zero_u16(obj: &PyAny) -> PyResult> { - let value: Option = obj.extract()?; +pub(crate) fn optional_non_zero_u32(obj: &PyAny) -> PyResult> { + let value: Option = obj.extract()?; match value { None => Ok(None), - Some(int) => Ok(Some(try_from_u16_to_non_zero_u16(int)?)), + Some(int) => Ok(Some(try_from_u32_to_non_zero_u32(int)?)), } } diff --git a/crates/python/src/qvm/api.rs b/crates/python/src/qvm/api.rs index f90900c62..e1e987044 100644 --- a/crates/python/src/qvm/api.rs +++ b/crates/python/src/qvm/api.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, num::NonZeroU16}; +use std::{collections::HashMap, num::NonZeroU32}; use crate::register_data::PyRegisterData; @@ -100,7 +100,7 @@ impl PyMultishotRequest { pub fn new( py: Python<'_>, program: String, - #[pyo3(from_py_with = "crate::from_py::non_zero_u16")] shots: NonZeroU16, + #[pyo3(from_py_with = "crate::from_py::non_zero_u32")] shots: NonZeroU32, addresses: HashMap, measurement_noise: Option<(f64, f64, f64)>, gate_noise: Option<(f64, f64, f64)>, @@ -123,7 +123,7 @@ impl PyMultishotRequest { #[setter] pub fn set_trials(&mut self, trials: u16) -> PyResult<()> { - // `NonZeroU16` doesn't implement `PyClass`, so `pyo3` doesn't allow it to be used + // `NonZeroU32` doesn't implement `PyClass`, so `pyo3` doesn't allow it to be used // as a method argument, even when combined with a `from_py_with` attribute. self.as_inner_mut().trials = crate::from_py::try_from_u16_to_non_zero_u16(trials)?; Ok(()) @@ -172,7 +172,7 @@ impl PyMultishotMeasureRequest { #[new] pub fn new( program: String, - #[pyo3(from_py_with = "crate::from_py::non_zero_u16")] shots: NonZeroU16, + #[pyo3(from_py_with = "crate::from_py::non_zero_u32")] shots: NonZeroU32, qubits: Vec, measurement_noise: Option<(f64, f64, f64)>, gate_noise: Option<(f64, f64, f64)>, @@ -194,10 +194,10 @@ impl PyMultishotMeasureRequest { } #[setter] - pub fn set_trials(&mut self, trials: u16) -> PyResult<()> { - // `NonZeroU16` doesn't implement `PyClass`, so `pyo3` doesn't allow it to be used + pub fn set_trials(&mut self, trials: u32) -> PyResult<()> { + // `NonZeroU32` doesn't implement `PyClass`, so `pyo3` doesn't allow it to be used // as a method argument, even when combined with a `from_py_with` attribute. - self.as_inner_mut().trials = crate::from_py::try_from_u16_to_non_zero_u16(trials)?; + self.as_inner_mut().trials = crate::from_py::try_from_u32_to_non_zero_u32(trials)?; Ok(()) } } diff --git a/crates/python/src/qvm/mod.rs b/crates/python/src/qvm/mod.rs index 5231b084b..484dd6194 100644 --- a/crates/python/src/qvm/mod.rs +++ b/crates/python/src/qvm/mod.rs @@ -9,7 +9,7 @@ use rigetti_pyo3::{ pyo3::{exceptions::PyRuntimeError, prelude::*, Python}, wrap_error, PyTryFrom, PyWrapper, PyWrapperMut, ToPython, ToPythonError, }; -use std::num::NonZeroU16; +use std::num::NonZeroU32; use std::{collections::HashMap, time::Duration}; use crate::register_data::PyRegisterData; @@ -249,8 +249,8 @@ py_function_sync_async! { #[tracing::instrument(skip_all)] async fn run( quil: String, - #[pyo3(from_py_with = "crate::from_py::non_zero_u16")] - shots: NonZeroU16, + #[pyo3(from_py_with = "crate::from_py::non_zero_u32")] + shots: NonZeroU32, addresses: HashMap, params: HashMap>, client: PyQvmClient, From 690a8ca06381c4e1310e9ea4e73be8b70d91b496 Mon Sep 17 00:00:00 2001 From: Marquess Valdez Date: Wed, 23 Oct 2024 16:28:03 -0700 Subject: [PATCH 2/5] fix clippy and a typo --- crates/lib/src/qpu/execution.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/lib/src/qpu/execution.rs b/crates/lib/src/qpu/execution.rs index eb1f0ba94..11024000f 100644 --- a/crates/lib/src/qpu/execution.rs +++ b/crates/lib/src/qpu/execution.rs @@ -164,15 +164,15 @@ impl<'a> Execution<'a> { &mut self, options: Option, ) -> Result { - let encrpyted_translation_result = translate( + let encrypted_translation_result = translate( self.quantum_processor_id.as_ref(), &self.program.to_quil()?, - self.shots.get().into(), + self.shots.get(), self.client.as_ref(), options, ) .await?; - Ok(encrpyted_translation_result) + Ok(encrypted_translation_result) } /// Run on a real QPU and wait for the results. From ff13550eee51dfc5292b1d0d17fe2dfbbf130119 Mon Sep 17 00:00:00 2001 From: Marquess Valdez Date: Wed, 23 Oct 2024 16:48:56 -0700 Subject: [PATCH 3/5] replace more u16s --- crates/python/src/executable.rs | 2 +- crates/python/src/qvm/api.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/python/src/executable.rs b/crates/python/src/executable.rs index c7dbe9ad6..ac3ee1454 100644 --- a/crates/python/src/executable.rs +++ b/crates/python/src/executable.rs @@ -108,7 +108,7 @@ impl PyExecutable { quil: String, registers: Vec, parameters: Vec, - #[pyo3(from_py_with = "crate::from_py::optional_non_zero_u16")] shots: Option, + #[pyo3(from_py_with = "crate::from_py::optional_non_zero_u32")] shots: Option, quilc_client: Option, compiler_options: Option, ) -> Self { diff --git a/crates/python/src/qvm/api.rs b/crates/python/src/qvm/api.rs index e1e987044..bb9b0a5d6 100644 --- a/crates/python/src/qvm/api.rs +++ b/crates/python/src/qvm/api.rs @@ -117,15 +117,15 @@ impl PyMultishotRequest { } #[getter] - pub fn trials(&self) -> u16 { + pub fn trials(&self) -> u32 { self.as_inner().trials.get() } #[setter] - pub fn set_trials(&mut self, trials: u16) -> PyResult<()> { + pub fn set_trials(&mut self, trials: u32) -> PyResult<()> { // `NonZeroU32` doesn't implement `PyClass`, so `pyo3` doesn't allow it to be used // as a method argument, even when combined with a `from_py_with` attribute. - self.as_inner_mut().trials = crate::from_py::try_from_u16_to_non_zero_u16(trials)?; + self.as_inner_mut().trials = crate::from_py::try_from_u32_to_non_zero_u32(trials)?; Ok(()) } } @@ -189,7 +189,7 @@ impl PyMultishotMeasureRequest { } #[getter] - pub fn trials(&self) -> u16 { + pub fn trials(&self) -> u32 { self.as_inner().trials.get() } From 6e2e7ac1ee24f4e023fb70b9f5dc33955b54cb85 Mon Sep 17 00:00:00 2001 From: Marquess Valdez Date: Wed, 23 Oct 2024 17:04:42 -0700 Subject: [PATCH 4/5] use u32 in libquil too --- crates/lib/src/qvm/libquil.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/lib/src/qvm/libquil.rs b/crates/lib/src/qvm/libquil.rs index 86e95fa23..1bb640118 100644 --- a/crates/lib/src/qvm/libquil.rs +++ b/crates/lib/src/qvm/libquil.rs @@ -80,7 +80,7 @@ impl crate::qvm::Client for Client { let result = libquil_sys::qvm::multishot( &program, addresses, - i32::from(request.trials.get()), + request.trials.get(), request.gate_noise, request.measurement_noise, request.rng_seed, @@ -147,7 +147,7 @@ impl crate::qvm::Client for Client { let result = libquil_sys::qvm::multishot_measure( &program, qubits.as_slice(), - i32::from(request.trials.get()), + request.trials.get(), request.rng_seed, ) .map_err(Error::LibquilSysQvm)?; From 29d7199b3f367c23e7a354df1855a0e5045b2e33 Mon Sep 17 00:00:00 2001 From: Marquess Valdez Date: Thu, 24 Oct 2024 10:53:24 -0700 Subject: [PATCH 5/5] libquil requires i32 --- crates/lib/src/executable.rs | 1 + crates/lib/src/qvm/libquil.rs | 4 ++-- crates/lib/src/qvm/mod.rs | 10 +++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/lib/src/executable.rs b/crates/lib/src/executable.rs index a0d3a059b..38ea5934b 100644 --- a/crates/lib/src/executable.rs +++ b/crates/lib/src/executable.rs @@ -732,6 +732,7 @@ impl From for Error { qvm::Error::ToQuil(q) => Self::ToQuil(q), qvm::Error::Parsing(_) | qvm::Error::ShotsMustBePositive + | qvm::Error::ShotCountOverflow(_) | qvm::Error::RegionSizeMismatch { .. } | qvm::Error::RegionNotFound { .. } | qvm::Error::Qvm { .. } => Self::Compilation(format!("{err}")), diff --git a/crates/lib/src/qvm/libquil.rs b/crates/lib/src/qvm/libquil.rs index 1bb640118..3c583a547 100644 --- a/crates/lib/src/qvm/libquil.rs +++ b/crates/lib/src/qvm/libquil.rs @@ -80,7 +80,7 @@ impl crate::qvm::Client for Client { let result = libquil_sys::qvm::multishot( &program, addresses, - request.trials.get(), + i32::try_from(request.trials.get())?, request.gate_noise, request.measurement_noise, request.rng_seed, @@ -147,7 +147,7 @@ impl crate::qvm::Client for Client { let result = libquil_sys::qvm::multishot_measure( &program, qubits.as_slice(), - request.trials.get(), + i32::try_from(request.trials.get())?, request.rng_seed, ) .map_err(Error::LibquilSysQvm)?; diff --git a/crates/lib/src/qvm/mod.rs b/crates/lib/src/qvm/mod.rs index e71d84728..e7fae1c6d 100644 --- a/crates/lib/src/qvm/mod.rs +++ b/crates/lib/src/qvm/mod.rs @@ -1,7 +1,13 @@ //! This module contains all the functionality for running Quil programs on a QVM. Specifically, //! the [`Execution`] struct in this module. -use std::{collections::HashMap, num::NonZeroU32, str::FromStr, sync::Arc, time::Duration}; +use std::{ + collections::HashMap, + num::{NonZeroU32, TryFromIntError}, + str::FromStr, + sync::Arc, + time::Duration, +}; use quil_rs::{ instruction::{ArithmeticOperand, Instruction, MemoryReference, Move}, @@ -275,6 +281,8 @@ pub enum Error { ToQuil(#[from] ToQuilError), #[error("Shots must be a positive integer.")] ShotsMustBePositive, + #[error("Requested shot count exceeds QVM limit.")] + ShotCountOverflow(#[from] TryFromIntError), #[error("Declared region {name} has size {declared} but parameters have size {parameters}.")] RegionSizeMismatch { name: String,