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: Initialize Instructions from a Quil string. Python Instructions support the pickle module. #382

Merged
merged 6 commits into from
Jul 26, 2024
Merged
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: 3 additions & 1 deletion quil-py/src/instruction/calibration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rigetti_pyo3::{

use crate::{
expression::PyExpression,
impl_copy_for_instruction, impl_eq, impl_to_quil,
impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction, impl_to_quil,
instruction::{PyGateModifier, PyInstruction, PyQubit},
validation::identifier::RustIdentifierValidationError,
};
Expand All @@ -31,6 +31,7 @@ impl_repr!(PyCalibration);
impl_to_quil!(PyCalibration);
impl_copy_for_instruction!(PyCalibration);
impl_eq!(PyCalibration);
impl_pickle_for_instruction!(PyCalibration);

#[pymethods]
impl PyCalibration {
Expand Down Expand Up @@ -70,6 +71,7 @@ impl_repr!(PyMeasureCalibrationDefinition);
impl_to_quil!(PyMeasureCalibrationDefinition);
impl_copy_for_instruction!(PyMeasureCalibrationDefinition);
impl_eq!(PyMeasureCalibrationDefinition);
impl_pickle_for_instruction!(PyMeasureCalibrationDefinition);

#[pymethods]
impl PyMeasureCalibrationDefinition {
Expand Down
3 changes: 2 additions & 1 deletion quil-py/src/instruction/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rigetti_pyo3::{
};

use super::PyInstruction;
use crate::{impl_copy_for_instruction, impl_eq, impl_to_quil};
use crate::{impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction, impl_to_quil};

py_wrap_data_struct! {
#[derive(Debug, PartialEq)]
Expand All @@ -23,6 +23,7 @@ impl_repr!(PyCircuitDefinition);
impl_to_quil!(PyCircuitDefinition);
impl_copy_for_instruction!(PyCircuitDefinition);
impl_eq!(PyCircuitDefinition);
impl_pickle_for_instruction!(PyCircuitDefinition);

#[pymethods]
impl PyCircuitDefinition {
Expand Down
9 changes: 8 additions & 1 deletion quil-py/src/instruction/classical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rigetti_pyo3::{
};

use super::PyMemoryReference;
use crate::{impl_copy_for_instruction, impl_eq, impl_to_quil};
use crate::{impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction, impl_to_quil};

py_wrap_data_struct! {
#[derive(Debug, PartialEq)]
Expand All @@ -31,6 +31,7 @@ impl_to_quil!(PyArithmetic);
impl_copy_for_instruction!(PyArithmetic);
impl_hash!(PyArithmetic);
impl_eq!(PyArithmetic);
impl_pickle_for_instruction!(PyArithmetic);

#[pymethods]
impl PyArithmetic {
Expand Down Expand Up @@ -115,6 +116,7 @@ impl_repr!(PyBinaryLogic);
impl_to_quil!(PyBinaryLogic);
impl_copy_for_instruction!(PyBinaryLogic);
impl_eq!(PyBinaryLogic);
impl_pickle_for_instruction!(PyBinaryLogic);

#[pymethods]
impl PyBinaryLogic {
Expand Down Expand Up @@ -146,6 +148,7 @@ impl_to_quil!(PyConvert);
impl_copy_for_instruction!(PyConvert);
impl_hash!(PyConvert);
impl_eq!(PyConvert);
impl_pickle_for_instruction!(PyConvert);

#[pymethods]
impl PyConvert {
Expand Down Expand Up @@ -175,6 +178,7 @@ impl_to_quil!(PyMove);
impl_copy_for_instruction!(PyMove);
impl_hash!(PyMove);
impl_eq!(PyMove);
impl_pickle_for_instruction!(PyMove);

#[pymethods]
impl PyMove {
Expand Down Expand Up @@ -204,6 +208,7 @@ impl_to_quil!(PyExchange);
impl_copy_for_instruction!(PyExchange);
impl_hash!(PyExchange);
impl_eq!(PyExchange);
impl_pickle_for_instruction!(PyExchange);

#[pymethods]
impl PyExchange {
Expand Down Expand Up @@ -259,6 +264,7 @@ impl_to_quil!(PyComparison);
impl_copy_for_instruction!(PyComparison);
impl_hash!(PyComparison);
impl_eq!(PyComparison);
impl_pickle_for_instruction!(PyComparison);

#[pymethods]
impl PyComparison {
Expand Down Expand Up @@ -303,6 +309,7 @@ impl_to_quil!(PyUnaryLogic);
impl_copy_for_instruction!(PyUnaryLogic);
impl_hash!(PyUnaryLogic);
impl_eq!(PyUnaryLogic);
impl_pickle_for_instruction!(PyUnaryLogic);

#[pymethods]
impl PyUnaryLogic {
Expand Down
6 changes: 5 additions & 1 deletion quil-py/src/instruction/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rigetti_pyo3::{
PyWrapper,
};

use crate::{impl_eq, impl_to_quil, instruction::PyMemoryReference};
use crate::{impl_eq, impl_pickle_for_instruction, impl_to_quil, instruction::PyMemoryReference};

/// Implements __copy__ and __deepcopy__ for instructions containing a [`Target`].
///
Expand Down Expand Up @@ -51,6 +51,7 @@ impl_hash!(PyLabel);
impl_to_quil!(PyLabel);
impl_copy_for_target_containing_instructions!(PyLabel);
impl_eq!(PyLabel);
impl_pickle_for_instruction!(PyLabel);

#[pymethods]
impl PyLabel {
Expand Down Expand Up @@ -105,6 +106,7 @@ impl_repr!(PyJump);
impl_to_quil!(PyJump);
impl_copy_for_target_containing_instructions!(PyJump);
impl_eq!(PyJump);
impl_pickle_for_instruction!(PyJump);

#[pymethods]
impl PyJump {
Expand All @@ -126,6 +128,7 @@ impl_repr!(PyJumpWhen);
impl_to_quil!(PyJumpWhen);
impl_copy_for_target_containing_instructions!(PyJumpWhen);
impl_eq!(PyJumpWhen);
impl_pickle_for_instruction!(PyJumpWhen);

#[pymethods]
impl PyJumpWhen {
Expand All @@ -147,6 +150,7 @@ impl_repr!(PyJumpUnless);
impl_to_quil!(PyJumpUnless);
impl_copy_for_target_containing_instructions!(PyJumpUnless);
impl_eq!(PyJumpUnless);
impl_pickle_for_instruction!(PyJumpUnless);

#[pymethods]
impl PyJumpUnless {
Expand Down
5 changes: 4 additions & 1 deletion quil-py/src/instruction/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use quil_rs::instruction::{
};

use super::PyArithmeticOperand;
use crate::{impl_copy_for_instruction, impl_eq, impl_to_quil};
use crate::{impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction, impl_to_quil};

use rigetti_pyo3::{
impl_from_str, impl_hash, impl_parse, impl_repr, py_wrap_data_struct, py_wrap_error,
Expand Down Expand Up @@ -123,6 +123,7 @@ impl_to_quil!(PyDeclaration);
impl_copy_for_instruction!(PyDeclaration);
impl_hash!(PyDeclaration);
impl_eq!(PyDeclaration);
impl_pickle_for_instruction!(PyDeclaration);

#[pymethods]
impl PyDeclaration {
Expand Down Expand Up @@ -178,6 +179,7 @@ impl_to_quil!(PyLoad);
impl_copy_for_instruction!(PyLoad);
impl_hash!(PyLoad);
impl_eq!(PyLoad);
impl_pickle_for_instruction!(PyLoad);

#[pymethods]
impl PyLoad {
Expand Down Expand Up @@ -210,6 +212,7 @@ impl_to_quil!(PyStore);
impl_copy_for_instruction!(PyStore);
impl_hash!(PyStore);
impl_eq!(PyStore);
impl_pickle_for_instruction!(PyStore);

#[pymethods]
impl PyStore {
Expand Down
17 changes: 14 additions & 3 deletions quil-py/src/instruction/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ use rigetti_pyo3::{
use super::PyQubit;
use crate::{
expression::PyExpression,
impl_copy_for_instruction, impl_eq, impl_to_quil,
impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction, impl_to_quil,
instruction::{PyMemoryReference, PyWaveformInvocation},
};

py_wrap_union_enum! {
#[derive(Debug, PartialEq, Eq)]
#[pyo3(module = "quil.instructions")]
PyAttributeValue(AttributeValue) as "AttributeValue" {
string: String => Py<PyString>,
expression: Expression => PyExpression
Expand All @@ -43,7 +44,7 @@ pub type PyFrameAttributes = IndexMap<String, PyAttributeValue>;

py_wrap_data_struct! {
#[derive(Debug, PartialEq, Eq)]
#[pyo3(subclass)]
#[pyo3(subclass, module = "quil.instructions")]
PyFrameDefinition(FrameDefinition) as "FrameDefinition" {
identifier: FrameIdentifier => PyFrameIdentifier,
attributes: FrameAttributes => PyFrameAttributes
Expand All @@ -53,6 +54,7 @@ impl_repr!(PyFrameDefinition);
impl_to_quil!(PyFrameDefinition);
impl_copy_for_instruction!(PyFrameDefinition);
impl_eq!(PyFrameDefinition);
impl_pickle_for_instruction!(PyFrameDefinition);

#[pymethods]
impl PyFrameDefinition {
Expand All @@ -71,7 +73,7 @@ impl PyFrameDefinition {

py_wrap_data_struct! {
#[derive(Debug, PartialEq, Eq, Hash)]
#[pyo3(subclass)]
#[pyo3(subclass, module = "quil.instructions")]
PyFrameIdentifier(FrameIdentifier) as "FrameIdentifier" {
name: String => Py<PyString>,
qubits: Vec<Qubit> => Vec<PyQubit>
Expand Down Expand Up @@ -107,6 +109,7 @@ impl_repr!(PyCapture);
impl_to_quil!(PyCapture);
impl_copy_for_instruction!(PyCapture);
impl_eq!(PyCapture);
impl_pickle_for_instruction!(PyCapture);

#[pymethods]
impl PyCapture {
Expand Down Expand Up @@ -140,6 +143,7 @@ impl_repr!(PyPulse);
impl_to_quil!(PyPulse);
impl_copy_for_instruction!(PyPulse);
impl_eq!(PyPulse);
impl_pickle_for_instruction!(PyPulse);

#[pymethods]
impl PyPulse {
Expand Down Expand Up @@ -174,6 +178,7 @@ impl_to_quil!(PyRawCapture);
impl_copy_for_instruction!(PyRawCapture);
impl_hash!(PyRawCapture);
impl_eq!(PyRawCapture);
impl_pickle_for_instruction!(PyRawCapture);

#[pymethods]
impl PyRawCapture {
Expand Down Expand Up @@ -207,6 +212,7 @@ impl_to_quil!(PySetFrequency);
impl_copy_for_instruction!(PySetFrequency);
impl_hash!(PySetFrequency);
impl_eq!(PySetFrequency);
impl_pickle_for_instruction!(PySetFrequency);

#[pymethods]
impl PySetFrequency {
Expand Down Expand Up @@ -236,6 +242,7 @@ impl_to_quil!(PySetPhase);
impl_copy_for_instruction!(PySetPhase);
impl_hash!(PySetPhase);
impl_eq!(PySetPhase);
impl_pickle_for_instruction!(PySetPhase);

#[pymethods]
impl PySetPhase {
Expand All @@ -261,6 +268,7 @@ impl_to_quil!(PySetScale);
impl_copy_for_instruction!(PySetScale);
impl_hash!(PySetScale);
impl_eq!(PySetScale);
impl_pickle_for_instruction!(PySetScale);

#[pymethods]
impl PySetScale {
Expand All @@ -286,6 +294,7 @@ impl_to_quil!(PyShiftFrequency);
impl_copy_for_instruction!(PyShiftFrequency);
impl_hash!(PyShiftFrequency);
impl_eq!(PyShiftFrequency);
impl_pickle_for_instruction!(PyShiftFrequency);

#[pymethods]
impl PyShiftFrequency {
Expand Down Expand Up @@ -315,6 +324,7 @@ impl_to_quil!(PyShiftPhase);
impl_copy_for_instruction!(PyShiftPhase);
impl_hash!(PyShiftPhase);
impl_eq!(PyShiftPhase);
impl_pickle_for_instruction!(PyShiftPhase);

#[pymethods]
impl PyShiftPhase {
Expand All @@ -340,6 +350,7 @@ impl_to_quil!(PySwapPhases);
impl_copy_for_instruction!(PySwapPhases);
impl_hash!(PySwapPhases);
impl_eq!(PySwapPhases);
impl_pickle_for_instruction!(PySwapPhases);

#[pymethods]
impl PySwapPhases {
Expand Down
6 changes: 4 additions & 2 deletions quil-py/src/instruction/gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use rigetti_pyo3::{
use strum;

use crate::{
expression::PyExpression, impl_copy_for_instruction, impl_eq, impl_to_quil,
instruction::PyQubit,
expression::PyExpression, impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction,
impl_to_quil, instruction::PyQubit,
};

wrap_error!(RustGateError(quil_rs::instruction::GateError));
Expand All @@ -45,6 +45,7 @@ impl_copy_for_instruction!(PyGate);
impl_to_quil!(PyGate);
impl_hash!(PyGate);
impl_eq!(PyGate);
impl_pickle_for_instruction!(PyGate);

#[pymethods]
impl PyGate {
Expand Down Expand Up @@ -271,6 +272,7 @@ impl_to_quil!(PyGateDefinition);
impl_copy_for_instruction!(PyGateDefinition);
impl_hash!(PyGateDefinition);
impl_eq!(PyGateDefinition);
impl_pickle_for_instruction!(PyGateDefinition);

#[pymethods]
impl PyGateDefinition {
Expand Down
3 changes: 2 additions & 1 deletion quil-py/src/instruction/measurement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rigetti_pyo3::{
};

use crate::{
impl_copy_for_instruction, impl_eq, impl_to_quil,
impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction, impl_to_quil,
instruction::{PyMemoryReference, PyQubit},
};

Expand All @@ -23,6 +23,7 @@ impl_copy_for_instruction!(PyMeasurement);
impl_hash!(PyMeasurement);
impl_repr!(PyMeasurement);
impl_eq!(PyMeasurement);
impl_pickle_for_instruction!(PyMeasurement);

#[pymethods]
impl PyMeasurement {
Expand Down
11 changes: 11 additions & 0 deletions quil-py/src/instruction/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use std::str::FromStr;

use pyo3::exceptions::PyValueError;
use quil_rs::instruction::Instruction;
use rigetti_pyo3::{
create_init_submodule, impl_repr, py_wrap_union_enum,
Expand Down Expand Up @@ -105,6 +108,14 @@ impl PyInstruction {
self.as_inner().is_quil_t()
}

#[staticmethod]
pub fn parse(string: &str) -> PyResult<Self> {
match Instruction::from_str(string) {
Ok(instruction) => Ok(Self(instruction)),
Err(err) => Err(PyValueError::new_err(err.to_string())),
}
}

// Implement the __copy__ and __deepcopy__ dunder methods, which are used by Python's
// `copy` module.
//
Expand Down
4 changes: 3 additions & 1 deletion quil-py/src/instruction/pragma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rigetti_pyo3::{
PyTryFrom,
};

use crate::{impl_copy_for_instruction, impl_eq, impl_to_quil};
use crate::{impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction, impl_to_quil};

py_wrap_data_struct! {
#[derive(Debug, PartialEq, Eq)]
Expand All @@ -26,6 +26,7 @@ impl_to_quil!(PyPragma);
impl_copy_for_instruction!(PyPragma);
impl_hash!(PyPragma);
impl_eq!(PyPragma);
impl_pickle_for_instruction!(PyPragma);

#[pymethods]
impl PyPragma {
Expand Down Expand Up @@ -68,6 +69,7 @@ impl_to_quil!(PyInclude);
impl_copy_for_instruction!(PyInclude);
impl_hash!(PyInclude);
impl_eq!(PyInclude);
impl_pickle_for_instruction!(PyInclude);

#[pymethods]
impl PyInclude {
Expand Down
Loading
Loading