Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 5 additions & 5 deletions quil-rs/python/quil/expression.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ class Expression:
Note that when comparing Quil expressions, any embedded NaNs are treated as *equal* to other
NaNs, not unequal, in contravention of the IEEE 754 spec.
"""
def to_real(self) -> builtins.float:
r"""
If this is a number with imaginary part "equal to" zero (of _small_ absolute value), return
that number. Otherwise, error with an evaluation error of a descriptive type.
"""
def into_simplified(self) -> Expression:
r"""
Return an expression derived from this one, simplified as much as possible.
Expand Down Expand Up @@ -68,6 +63,11 @@ class Expression:
"""
def __getnewargs__(self) -> tuple[MemoryReference | FunctionCallExpression | InfixExpression | complex | PrefixExpression | str]: ...
def __repr__(self) -> builtins.str: ...
def to_real(self) -> builtins.float:
r"""
If this is a number with imaginary part "equal to" zero (of _small_ absolute value), return
that number. Otherwise, error with an evaluation error of a descriptive type.
"""
class Address(Expression):
__match_args__ = ("_0",)
@property
Expand Down
167 changes: 90 additions & 77 deletions quil-rs/python/quil/instructions.pyi

Large diffs are not rendered by default.

25 changes: 13 additions & 12 deletions quil-rs/python/quil/program.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ class CalibrationSet:
so see the documentation there for more information.
"""
@property
def calibrations(self) -> builtins.list[Calibration]:
def calibrations(self) -> builtins.list[CalibrationDefinition]:
r"""
Return a list of all [`Calibration`]s in the set.
Return a list of all [`CalibrationDefinition`]s in the set.
"""
@property
def measure_calibrations(self) -> builtins.list[MeasureCalibrationDefinition]:
Expand All @@ -170,19 +170,19 @@ class CalibrationSet:
r"""
Return true if this contains no data.
"""
def insert_calibration(self, calibration:Calibration) -> typing.Optional[Calibration]:
def insert_calibration(self, calibration:CalibrationDefinition) -> typing.Optional[CalibrationDefinition]:
r"""
Insert a [`Calibration`] into the set.
Insert a [`CalibrationDefinition`] into the set.

If a calibration with the same [`CalibrationSignature`] already exists in the set, it will
be replaced, and the old calibration is returned.
If a calibration with the same [signature][crate::instruction::CalibrationSignature] already
exists in the set, it will be replaced and the old calibration will be returned.
"""
def insert_measurement_calibration(self, calibration:MeasureCalibrationDefinition) -> typing.Optional[MeasureCalibrationDefinition]:
r"""
Insert a [`MeasureCalibration`] into the set.
Insert a [`MeasureCalibrationDefinition`] into the set.

If a calibration with the same [`CalibrationSignature`] already exists in the set, it will
be replaced, and the old calibration is returned.
If a calibration with the same [signature][crate::instruction::CalibrationSignature] already
exists in the set, it will be replaced and the old calibration will be returned.
"""
def extend(self, other:CalibrationSet) -> None:
r"""
Expand All @@ -195,7 +195,7 @@ class CalibrationSet:
r"""
Return the Quil instructions which describe the contained calibrations.
"""
def __new__(cls, calibrations:typing.Sequence[Calibration], measure_calibrations:typing.Sequence[MeasureCalibrationDefinition]) -> CalibrationSet: ...
def __new__(cls, calibrations:typing.Sequence[CalibrationDefinition], measure_calibrations:typing.Sequence[MeasureCalibrationDefinition]) -> CalibrationSet: ...
def expand(self, instruction:Instruction, previous_calibrations:typing.Sequence[Instruction]) -> typing.Optional[builtins.list[Instruction]]:
r"""
Given an instruction, return the instructions to which it is expanded if there is a match.
Expand All @@ -218,7 +218,7 @@ class CalibrationSet:

In the case of multiple calibrations with equal precedence, the last one wins.
"""
def get_match_for_gate(self, gate:Gate) -> typing.Optional[Calibration]:
def get_match_for_gate(self, gate:Gate) -> typing.Optional[CalibrationDefinition]:
r"""
Return the final calibration which matches the gate per the QuilT specification:

Expand All @@ -234,7 +234,8 @@ class CalibrationSet:

class CalibrationSource:
r"""
A source of a calibration, either a [`Calibration`] or a [`MeasureCalibrationDefinition`]
The source of a calibration, either a [`CalibrationIdentifier`] or a
[`MeasureCalibrationIdentifier`].
"""
def __getnewargs__(self) -> tuple[CalibrationIdentifier | MeasureCalibrationIdentifier]: ...
def __repr__(self) -> builtins.str: ...
Expand Down
106 changes: 73 additions & 33 deletions quil-rs/src/instruction/calibration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@ pub trait CalibrationSignature {
fn has_signature(&self, signature: &Self::Signature<'_>) -> bool;
}

#[derive(Clone, Debug, Default, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
#[cfg_attr(
feature = "python",
pyo3::pyclass(module = "quil.instructions", eq, get_all, set_all, subclass)
)]
#[cfg_attr(not(feature = "python"), strip_pyo3)]
pub struct Calibration {
pub struct CalibrationDefinition {
#[pyo3(name = "identifier")]
pub identifier: CalibrationIdentifier,
pub instructions: Vec<Instruction>,
}

pickleable_new! {
impl Calibration {
impl CalibrationDefinition {
/// Builds a new calibration definition.
pub fn new(
identifier: CalibrationIdentifier,
Expand All @@ -47,8 +47,8 @@ pickleable_new! {
}
}

impl CalibrationSignature for Calibration {
type Signature<'a> = (&'a str, &'a [Expression], &'a [Qubit]);
impl CalibrationSignature for CalibrationDefinition {
type Signature<'a> = <CalibrationIdentifier as CalibrationSignature>::Signature<'a>;

fn signature(&self) -> Self::Signature<'_> {
self.identifier.signature()
Expand All @@ -59,7 +59,7 @@ impl CalibrationSignature for Calibration {
}
}

impl Quil for Calibration {
impl Quil for CalibrationDefinition {
fn write(
&self,
f: &mut impl std::fmt::Write,
Expand All @@ -76,7 +76,7 @@ impl Quil for Calibration {
}

/// Unique identifier for a calibration definition within a program
#[derive(Clone, Debug, Default, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
#[cfg_attr(
feature = "python",
Expand Down Expand Up @@ -175,19 +175,25 @@ impl CalibrationIdentifier {
}

impl CalibrationSignature for CalibrationIdentifier {
type Signature<'a> = (&'a str, &'a [Expression], &'a [Qubit]);
type Signature<'a> = (&'a [GateModifier], &'a str, &'a [Expression], &'a [Qubit]);

fn signature(&self) -> Self::Signature<'_> {
let Self {
modifiers,
name,
parameters,
qubits,
} = self;
(
self.name.as_str(),
self.parameters.as_slice(),
self.qubits.as_slice(),
modifiers.as_slice(),
name.as_str(),
parameters.as_slice(),
qubits.as_slice(),
)
}

fn has_signature(&self, signature: &Self::Signature<'_>) -> bool {
let (name, parameters, qubits) = signature;
self.name == *name && self.parameters == *parameters && self.qubits == *qubits
&self.signature() == signature
}
}

Expand Down Expand Up @@ -222,7 +228,7 @@ pickleable_new! {
}

impl CalibrationSignature for MeasureCalibrationDefinition {
type Signature<'a> = (Option<&'a Qubit>, &'a str);
type Signature<'a> = <MeasureCalibrationIdentifier as CalibrationSignature>::Signature<'a>;

fn signature(&self) -> Self::Signature<'_> {
self.identifier.signature()
Expand All @@ -249,36 +255,39 @@ impl Quil for MeasureCalibrationDefinition {
}

/// A unique identifier for a measurement calibration definition within a program
#[derive(Clone, Debug, Default, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
#[cfg_attr(
feature = "python",
pyo3::pyclass(module = "quil.instructions", eq, get_all, set_all, subclass)
)]
pub struct MeasureCalibrationIdentifier {
/// The qubit which is the target of measurement, if any
pub qubit: Option<Qubit>,
/// The qubit which is being measured.
pub qubit: Qubit,

/// The memory region name to which the measurement result is written
pub parameter: String,
/// The name the definition uses for the variable it will write the measurement result to, if
/// this is a measurement for record.
///
/// If this is missing, this is a calibration for a measurement for effect.
pub target: Option<String>,
}

pickleable_new! {
impl MeasureCalibrationIdentifier {
pub fn new(qubit: Option<Qubit>, parameter: String);
pub fn new(qubit: Qubit, target: Option<String>);
}
}

impl CalibrationSignature for MeasureCalibrationIdentifier {
type Signature<'a> = (Option<&'a Qubit>, &'a str);
type Signature<'a> = (&'a Qubit, Option<&'a str>);

fn signature(&self) -> Self::Signature<'_> {
(self.qubit.as_ref(), self.parameter.as_str())
let Self { qubit, target } = self;
(qubit, target.as_deref())
}

fn has_signature(&self, signature: &Self::Signature<'_>) -> bool {
let (qubit, parameter) = signature;
self.qubit.as_ref() == *qubit && self.parameter == *parameter
&self.signature() == signature
}
}

Expand All @@ -288,12 +297,14 @@ impl Quil for MeasureCalibrationIdentifier {
f: &mut impl std::fmt::Write,
fall_back_to_debug: bool,
) -> crate::quil::ToQuilResult<()> {
write!(f, "DEFCAL MEASURE")?;
if let Some(qubit) = &self.qubit {
write!(f, " ")?;
qubit.write(f, fall_back_to_debug)?;
let Self { qubit, target } = self;

write!(f, "DEFCAL MEASURE ")?;
qubit.write(f, fall_back_to_debug)?;
if let Some(target) = target {
write!(f, " {target}")?;
}
write!(f, " {}", self.parameter,)?;

Ok(())
}
}
Expand All @@ -313,8 +324,8 @@ mod test_measure_calibration_definition {
"With Fixed Qubit",
MeasureCalibrationDefinition {
identifier: MeasureCalibrationIdentifier {
qubit: Some(Qubit::Fixed(0)),
parameter: "theta".to_string(),
qubit: Qubit::Fixed(0),
target: Some("theta".to_string()),
},
instructions: vec![Instruction::Gate(Gate {
name: "X".to_string(),
Expand All @@ -324,12 +335,27 @@ mod test_measure_calibration_definition {

})]},
)]
#[case(
"Effect With Fixed Qubit",
MeasureCalibrationDefinition {
identifier: MeasureCalibrationIdentifier {
qubit: Qubit::Fixed(0),
target: None,
},
instructions: vec![Instruction::Gate(Gate {
name: "X".to_string(),
parameters: vec![Expression::PiConstant()],
qubits: vec![Qubit::Fixed(0)],
modifiers: vec![],

})]},
)]
#[case(
"With Variable Qubit",
MeasureCalibrationDefinition {
identifier: MeasureCalibrationIdentifier {
qubit: Some(Qubit::Variable("q".to_string())),
parameter: "theta".to_string(),
qubit: Qubit::Variable("q".to_string()),
target: Some("theta".to_string()),
},
instructions: vec![Instruction::Gate(Gate {
name: "X".to_string(),
Expand All @@ -338,6 +364,20 @@ mod test_measure_calibration_definition {
modifiers: vec![],
})]},
)]
#[case(
"Effect Variable Qubit",
MeasureCalibrationDefinition {
identifier: MeasureCalibrationIdentifier {
qubit: Qubit::Variable("q".to_string()),
target: None,
},
instructions: vec![Instruction::Gate(Gate {
name: "X".to_string(),
parameters: vec![Expression::PiConstant()],
qubits: vec![Qubit::Variable("q".to_string())],
modifiers: vec![],
})]},
)]
fn test_display(
#[case] description: &str,
#[case] measure_cal_def: MeasureCalibrationDefinition,
Expand Down
Loading
Loading