Skip to content

Commit

Permalink
Compiling.
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinhartman committed Nov 18, 2024
1 parent d90fb30 commit 7f260db
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 259 deletions.
34 changes: 26 additions & 8 deletions crates/circuit/src/circuit_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ use pyo3::{intern, IntoPy, PyObject, PyResult};

use smallvec::SmallVec;

use crate::imports::{CONTROLLED_GATE, CONTROL_FLOW_OP, GATE, INSTRUCTION, OPERATION, WARNINGS_WARN, get_std_instruction_types};
use crate::imports::{
CONTROLLED_GATE, CONTROL_FLOW_OP, GATE, INSTRUCTION, OPERATION, WARNINGS_WARN,
};
use crate::operations::{
Operation, OperationRef, Param, PyGate, PyInstruction, PyOperation, StandardGate,
StandardInstruction,
};
use crate::packed_instruction::PackedOperation;

Expand Down Expand Up @@ -330,6 +333,9 @@ impl CircuitInstruction {
OperationRef::Standard(standard) => standard
.create_py_op(py, Some(&self.params), &self.extra_attrs)?
.into_any(),
OperationRef::StandardInstruction(instruction) => {
instruction.create_py_op(py, &self.extra_attrs)?.into_any()
}
OperationRef::Gate(gate) => gate.gate.clone_ref(py),
OperationRef::Instruction(instruction) => instruction.instruction.clone_ref(py),
OperationRef::Operation(operation) => operation.operation.clone_ref(py),
Expand Down Expand Up @@ -659,6 +665,8 @@ impl<'py> FromPyObject<'py> for OperationFromPython {
};

'standard: {
// Our standard gates have a `_standard_gate` field at the class level so we can quickly
// identify them here without an `isinstance` check.
let Some(standard) = ob_type
.getattr(intern!(py, "_standard_gate"))
.and_then(|standard| standard.extract::<StandardGate>())
Expand Down Expand Up @@ -693,6 +701,23 @@ impl<'py> FromPyObject<'py> for OperationFromPython {
extra_attrs: extract_extra()?,
});
}
'standard_instr: {
// We check the *instance* for a `_standard_instruction` field since standard
// instructions (unlike standard gates) can have a payload and are thus stateful.
let Some(standard) = ob
.getattr(intern!(py, "_standard_instruction"))
.and_then(|standard| standard.extract::<StandardInstruction>())
.ok()
else {
break 'standard_instr;
};
return Ok(OperationFromPython {
operation: PackedOperation::from_standard_instruction(standard),
params: extract_params()?,
extra_attrs: extract_extra()?,
});
}

if ob_type.is_subclass(GATE.get_bound(py))? {
let params = extract_params()?;
let gate = Box::new(PyGate {
Expand All @@ -708,13 +733,6 @@ impl<'py> FromPyObject<'py> for OperationFromPython {
extra_attrs: extract_extra()?,
});
}
if ob_type.is_subclass(get_std_instruction_types(py))? {
return Ok(OperationFromPython {
operation: PackedOperation::from_standard_instruction(standard),
params: extract_params()?,
extra_attrs: extract_extra()?,
});
}
if ob_type.is_subclass(INSTRUCTION.get_bound(py))? {
let params = extract_params()?;
let instruction = Box::new(PyInstruction {
Expand Down
5 changes: 3 additions & 2 deletions crates/circuit/src/dag_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3396,7 +3396,8 @@ def _format(operand):
OperationRef::Operation(py_op) => {
py_op.operation.setattr(py, "condition", new_condition)?;
}
OperationRef::Standard(_) => {}
OperationRef::Standard(_)
| OperationRef::StandardInstruction(_) => {}
}
}
}
Expand Down Expand Up @@ -6502,7 +6503,7 @@ impl DAGCircuit {
};
#[cfg(feature = "cache_pygates")]
let py_op = match new_op.operation.view() {
OperationRef::Standard(_) => OnceCell::new(),
OperationRef::Standard(_) | OperationRef::StandardInstruction(_) => OnceCell::new(),
OperationRef::Gate(gate) => OnceCell::from(gate.gate.clone_ref(py)),
OperationRef::Instruction(instruction) => {
OnceCell::from(instruction.instruction.clone_ref(py))
Expand Down
23 changes: 3 additions & 20 deletions crates/circuit/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ use pyo3::prelude::*;
use pyo3::sync::GILOnceCell;
use pyo3::types::PyTuple;

use crate::operations::{
StandardGate, StandardInstruction, STANDARD_GATE_SIZE, STANDARD_INSTRUCTION_SIZE,
};
use crate::operations::{StandardGate, STANDARD_GATE_SIZE};

/// Helper wrapper around `GILOnceCell` instances that are just intended to store a Python object
/// that is lazily imported.
Expand Down Expand Up @@ -360,23 +358,8 @@ pub fn get_std_instruction_types(py: Python) -> &Bound<PyTuple> {
MEASURE.get_bound(py),
RESET.get_bound(py),
],
).unbind()
)
.unbind()
})
.bind(py)
}

#[inline]
pub fn get_std_instruction_class(py: Python, rs_instr: StandardInstruction) -> PyResult<PyObject> {
Ok(match rs_instr {
StandardInstruction::Barrier(_) => {
// TODO: bake in num gates by returning a custom callable?
BARRIER.get_bound(py).unbind()
}
StandardInstruction::Delay(_, _) => {
// TODO: bake in parameters like duration by returning a custom callable?
DELAY.get_bound(py).unbind()
}
StandardInstruction::Measure => MEASURE.get_bound(py).unbind(),
StandardInstruction::Reset => RESET.get_bound(py).unbind(),
})
}
Loading

0 comments on commit 7f260db

Please sign in to comment.