Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Shot count is now represented as an unsigned 32-bit, up from 16-bit, allowing for higher shot counts #509

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/lib/src/compiler/libquil.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions crates/lib/src/compiler/quilc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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()
Expand Down
20 changes: 10 additions & 10 deletions crates/lib/src/executable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -87,7 +87,7 @@ use quil_rs::program::ProgramError;
#[allow(missing_debug_implementations)]
pub struct Executable<'executable, 'execution> {
quil: Arc<str>,
shots: NonZeroU16,
shots: NonZeroU32,
readout_memory_region_names: Option<Vec<Cow<'executable, str>>>,
params: Parameters,
qcs_client: Option<Arc<Qcs>>,
Expand Down Expand Up @@ -119,7 +119,7 @@ impl<'executable> Executable<'executable, '_> {
pub fn from_quil<Quil: Into<Arc<str>>>(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(),
Expand Down Expand Up @@ -318,7 +318,7 @@ pub type ExecutionResult = Result<execution_data::ExecutionData, Error>;
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
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand All @@ -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);
Expand All @@ -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();

Expand Down
12 changes: 6 additions & 6 deletions crates/lib/src/qpu/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<Qcs>,
}

Expand Down Expand Up @@ -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<str>,
shots: NonZeroU16,
shots: NonZeroU32,
quantum_processor_id: Cow<'a, str>,
client: Arc<Qcs>,
quilc_client: Option<Arc<dyn quilc::Client + Send + Sync>>,
Expand Down Expand Up @@ -164,15 +164,15 @@ impl<'a> Execution<'a> {
&mut self,
options: Option<TranslationOptions>,
) -> Result<EncryptedTranslationResult, Error> {
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.
Expand Down
10 changes: 5 additions & 5 deletions crates/lib/src/qvm/execution.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::str::FromStr;
use std::{collections::HashMap, num::NonZeroU16};
use std::{collections::HashMap, num::NonZeroU32};

use quil_rs::Program;

Expand Down Expand Up @@ -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<C: Client + ?Sized>(
&self,
shots: NonZeroU16,
shots: NonZeroU32,
addresses: HashMap<String, AddressRequest>,
params: &Parameters,
client: &C,
Expand All @@ -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};
Expand All @@ -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(),
&params,
&qvm_client(),
Expand All @@ -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(),
&params,
&qvm_client(),
Expand Down
16 changes: 8 additions & 8 deletions crates/lib/src/qvm/http.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -62,7 +62,7 @@ pub struct MultishotRequest {
/// The memory regions to include in the response.
pub addresses: HashMap<String, AddressRequest>,
/// 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)>,
Expand Down Expand Up @@ -109,7 +109,7 @@ impl MultishotRequest {
#[must_use]
pub fn new(
compiled_quil: String,
trials: NonZeroU16,
trials: NonZeroU32,
addresses: HashMap<String, AddressRequest>,
measurement_noise: Option<(f64, f64, f64)>,
gate_noise: Option<(f64, f64, f64)>,
Expand Down Expand Up @@ -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<u64>,
/// Simulated measurement noise for the X, Y, and Z axes.
Expand All @@ -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)>,
Expand Down Expand Up @@ -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;

Expand All @@ -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,
Expand All @@ -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()
Expand Down
6 changes: 3 additions & 3 deletions crates/lib/src/qvm/mod.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand Down Expand Up @@ -129,7 +129,7 @@ impl QvmResultData {
#[allow(clippy::too_many_arguments)]
pub async fn run<C: Client + Send + Sync + ?Sized>(
quil: &str,
shots: NonZeroU16,
shots: NonZeroU32,
addresses: HashMap<String, AddressRequest>,
params: &Parameters,
measurement_noise: Option<(f64, f64, f64)>,
Expand Down Expand Up @@ -160,7 +160,7 @@ pub async fn run<C: Client + Send + Sync + ?Sized>(
#[allow(clippy::too_many_arguments)]
pub async fn run_program<C: Client + ?Sized>(
program: &Program,
shots: NonZeroU16,
shots: NonZeroU32,
addresses: HashMap<String, AddressRequest>,
params: &Parameters,
measurement_noise: Option<(f64, f64, f64)>,
Expand Down
4 changes: 2 additions & 2 deletions crates/lib/tests/basic_qvm.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion crates/lib/tests/mocked_qpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
6 changes: 3 additions & 3 deletions crates/lib/tests/qvm_api.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -49,7 +49,7 @@ async fn test_get_version_info<C: qvm::Client>(client: C) {
async fn test_run<C: qvm::Client>(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)),
Expand All @@ -74,7 +74,7 @@ async fn test_run<C: qvm::Client>(client: C) {
async fn test_run_and_measure<C: qvm::Client>(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)),
Expand Down
4 changes: 2 additions & 2 deletions crates/python/src/executable.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{num::NonZeroU16, sync::Arc};
use std::{num::NonZeroU32, sync::Arc};

use opentelemetry::trace::FutureExt;
use pyo3::{pyclass, FromPyObject};
Expand Down Expand Up @@ -108,7 +108,7 @@
quil: String,
registers: Vec<String>,
parameters: Vec<PyParameter>,
#[pyo3(from_py_with = "crate::from_py::optional_non_zero_u16")] shots: Option<NonZeroU16>,
#[pyo3(from_py_with = "crate::from_py::optional_non_zero_u16")] shots: Option<NonZeroU32>,

Check failure on line 111 in crates/python/src/executable.rs

View workflow job for this annotation

GitHub Actions / publish-docs

cannot find value `optional_non_zero_u16` in module `crate::from_py`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linting failure on crate::from_py::optional_non_zero_u16. Should probably be this?

Suggested change
#[pyo3(from_py_with = "crate::from_py::optional_non_zero_u16")] shots: Option<NonZeroU32>,
#[pyo3(from_py_with = "crate::from_py::optional_non_zero_u32")] shots: Option<NonZeroU32>,

quilc_client: Option<PyQuilcClient>,
compiler_options: Option<PyCompilerOpts>,
) -> Self {
Expand Down
Loading
Loading