-
Notifications
You must be signed in to change notification settings - Fork 9
fix!: Fix rotation -> float param type conversion #1061
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
Changes from 4 commits
3075903
27b9805
9477447
620cea6
d569ab7
c2079df
102f2d9
f9b86da
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 |
---|---|---|
|
@@ -6,10 +6,11 @@ use hugr::extension::simple_op::MakeExtensionOp; | |
use hugr::extension::ExtensionId; | ||
use hugr::ops::ExtensionOp; | ||
use hugr::HugrView; | ||
use itertools::Itertools as _; | ||
use tket::serialize::pytket::decoder::{ | ||
DecodeStatus, LoadedParameter, PytketDecoderContext, TrackedBit, TrackedQubit, | ||
DecodeStatus, LoadedParameter, ParameterType, PytketDecoderContext, TrackedBit, TrackedQubit, | ||
}; | ||
use tket::serialize::pytket::encoder::EncodeStatus; | ||
use tket::serialize::pytket::encoder::{make_tk1_operation, EncodeStatus}; | ||
use tket::serialize::pytket::extension::PytketDecoder; | ||
use tket::serialize::pytket::{ | ||
PytketDecodeError, PytketEmitter, PytketEncodeError, PytketEncoderContext, | ||
|
@@ -83,8 +84,23 @@ impl QSystemEmitter { | |
} | ||
}; | ||
|
||
// We have to convert the parameters expressions (in half-turns) to radians. | ||
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. comment is wrong way round? |
||
|
||
// Most operations map directly to a pytket one. | ||
encoder.emit_node(serial_op, node, circ)?; | ||
encoder.emit_node_command( | ||
node, | ||
circ, | ||
|_| Vec::new(), | ||
move |mut inputs| { | ||
for param in inputs.params.to_mut() { | ||
*param = match param.strip_suffix(") * (pi)") { | ||
Some(s) if s.starts_with("(") => s[1..].to_string(), | ||
_ => format!("{param} / (pi)"), | ||
}; | ||
} | ||
make_tk1_operation(serial_op, inputs) | ||
}, | ||
)?; | ||
|
||
Ok(EncodeStatus::Success) | ||
} | ||
|
@@ -126,15 +142,23 @@ impl PytketDecoder for QSystemEmitter { | |
PytketOptype::ZZPhase => QSystemOp::ZZPhase, | ||
PytketOptype::ZZMax => { | ||
// This is a ZZPhase with a 1/2 angle. | ||
let param = decoder.load_parameter("pi/2"); | ||
let param = | ||
Arc::new(decoder.load_parameter_with_type("pi/2", ParameterType::FloatRadians)); | ||
decoder.add_node_with_wires(QSystemOp::ZZPhase, qubits, bits, &[param])?; | ||
return Ok(DecodeStatus::Success); | ||
} | ||
_ => { | ||
return Ok(DecodeStatus::Unsupported); | ||
} | ||
}; | ||
decoder.add_node_with_wires(op, qubits, bits, params)?; | ||
|
||
// We expect all parameters to be floats in radians. | ||
let params = params | ||
.iter() | ||
.map(|p| Arc::new(p.as_float_radians(&mut decoder.builder))) | ||
.collect_vec(); | ||
|
||
decoder.add_node_with_wires(op, qubits, bits, ¶ms)?; | ||
|
||
Ok(DecodeStatus::Success) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ mod param; | |
mod tracked_elem; | ||
mod wires; | ||
|
||
pub use param::{LoadedParameter, LoadedParameterType}; | ||
pub use param::{LoadedParameter, ParameterType}; | ||
pub use tracked_elem::{TrackedBit, TrackedQubit}; | ||
pub use wires::TrackedWires; | ||
|
||
|
@@ -420,8 +420,14 @@ impl<'h> PytketDecoderContext<'h> { | |
/// the first registers in `wires` for the bit inputs and the remaining | ||
/// registers for the outputs. | ||
/// | ||
/// The input wire types must match the operation's input signature, | ||
/// no type conversion is performed. | ||
/// The input wire types must match the operation's input signature, no type | ||
/// conversion is performed. | ||
/// | ||
/// The caller must take care of converting the parameter wires to the | ||
/// required types and units expected by the operation. An error will be | ||
/// returned if the parameter does not match the expected wire type, but the | ||
/// [`ParameterUnit`] (radians or half-turns) cannot be checked | ||
/// automatically. | ||
/// | ||
/// # Arguments | ||
/// | ||
|
@@ -435,6 +441,8 @@ impl<'h> PytketDecoderContext<'h> { | |
/// input ports. | ||
/// - Returns an error if the node's output ports cannot be assigned to | ||
/// arguments from the input wire set. | ||
/// - Returns an error if the parameter wires do not match the expected | ||
/// types. | ||
pub fn add_node_with_wires( | ||
&mut self, | ||
op: impl Into<OpType>, | ||
|
@@ -593,7 +601,19 @@ impl<'h> PytketDecoderContext<'h> { | |
/// - If the parameter is a variable, adds a new `rotation` input to the region. | ||
/// - If the parameter is a sympy expressions, adds it as a [`SympyOpDef`][crate::extension::sympy::SympyOpDef] black box. | ||
pub fn load_parameter(&mut self, param: &str) -> Arc<LoadedParameter> { | ||
self.wire_tracker.load_parameter(&mut self.builder, param) | ||
Arc::new( | ||
self.wire_tracker | ||
.load_parameter(&mut self.builder, param, None), | ||
) | ||
} | ||
|
||
/// Loads the given parameter expression as a [`LoadedParameter`] in the hugr, and converts it to the requested type and unit. | ||
/// | ||
/// See [`PytketDecoderContext::load_parameter`] for more details. | ||
pub fn load_parameter_with_type(&mut self, param: &str, typ: ParameterType) -> LoadedParameter { | ||
self.wire_tracker | ||
.load_parameter(&mut self.builder, param, Some(typ)) | ||
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. seems strange to pass the 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. As mentioned in the I guess it'd be less confusing if we change the hint for an assurance and do the |
||
.with_type(typ, &mut self.builder) | ||
} | ||
} | ||
|
||
|
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.
Dummy change so this gets a line in the tket-py changelog