Skip to content

Commit a5d8c10

Browse files
Passing Bound<HighLevelSynthesisData> to functions
This avoids cloning data when calling Python
1 parent 03a646c commit a5d8c10

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

crates/accelerate/src/high_level_synthesis.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl QubitTracker {
204204
}
205205

206206
/// Internal class that encapsulates immutable data required by the HighLevelSynthesis transpiler pass.
207-
#[pyclass(module="qiskit._accelerate.high_level_synthesis")]
207+
#[pyclass(module = "qiskit._accelerate.high_level_synthesis")]
208208
#[derive(Clone, Debug)]
209209
pub struct HighLevelSynthesisData {
210210
// The high-level-synthesis config that specifies the synthesis methods
@@ -344,15 +344,15 @@ impl HighLevelSynthesisData {
344344
/// Check whether an operation is natively supported.
345345
pub fn instruction_supported(
346346
py: Python,
347-
data: &HighLevelSynthesisData,
347+
data: &Bound<HighLevelSynthesisData>,
348348
name: &str,
349349
qubits: &[Qubit],
350350
) -> bool {
351-
match &data.target {
351+
match &data.borrow().target {
352352
Some(target) => {
353353
let target = target.borrow(py);
354354
if target.num_qubits.is_some() {
355-
if data.use_qubit_indices {
355+
if data.borrow().use_qubit_indices {
356356
let physical_qubits = qubits
357357
.iter()
358358
.map(|q| PhysicalQubit(q.index() as u32))
@@ -362,21 +362,21 @@ pub fn instruction_supported(
362362
target.instruction_supported(name, None)
363363
}
364364
} else {
365-
data.device_insts.contains(name)
365+
data.borrow().device_insts.contains(name)
366366
}
367367
}
368-
None => data.device_insts.contains(name),
368+
None => data.borrow().device_insts.contains(name),
369369
}
370370
}
371371

372372
/// Check whether an operation does not need to be synthesized.
373373
pub fn definitely_skip_op(
374374
py: Python,
375-
data: &HighLevelSynthesisData,
375+
data: &Bound<HighLevelSynthesisData>,
376376
op: &PackedOperation,
377377
qubits: &[Qubit],
378378
) -> bool {
379-
if qubits.len() < data.min_qubits {
379+
if qubits.len() < data.borrow().min_qubits {
380380
return true;
381381
}
382382

@@ -395,11 +395,11 @@ pub fn definitely_skip_op(
395395

396396
// If there are avilable plugins for this operation, we should try them
397397
// before checking the equivalence library.
398-
if data.hls_op_names.iter().any(|s| s == op.name()) {
398+
if data.borrow().hls_op_names.iter().any(|s| s == op.name()) {
399399
return false;
400400
}
401401

402-
if let Some(equiv_lib) = &data.equivalence_library {
402+
if let Some(equiv_lib) = &data.borrow().equivalence_library {
403403
if equiv_lib.borrow(py).has_entry(op) {
404404
return true;
405405
}
@@ -424,7 +424,7 @@ fn run_on_circuitdata(
424424
py: Python,
425425
input_circuit: &CircuitData,
426426
input_qubits: &[usize],
427-
data: &HighLevelSynthesisData,
427+
data: &Bound<HighLevelSynthesisData>,
428428
tracker: &mut QubitTracker,
429429
) -> PyResult<(CircuitData, Vec<usize>)> {
430430
if input_circuit.num_qubits() != input_qubits.len() {
@@ -651,7 +651,7 @@ fn run_on_circuitdata(
651651
/// each global qubit (whether it's clean, dirty, or cannot be used).
652652
fn synthesize_operation(
653653
py: Python,
654-
data: &HighLevelSynthesisData,
654+
data: &Bound<HighLevelSynthesisData>,
655655
tracker: &mut QubitTracker,
656656
input_qubits: &[usize],
657657
op: &PackedOperation,
@@ -678,7 +678,7 @@ fn synthesize_operation(
678678
// change, we return None.
679679

680680
// Try to synthesize using plugins.
681-
if data.hls_op_names.iter().any(|s| s == op.name()) {
681+
if data.borrow().hls_op_names.iter().any(|s| s == op.name()) {
682682
output_circuit_and_qubits = synthesize_op_using_plugins(
683683
py,
684684
data,
@@ -692,15 +692,15 @@ fn synthesize_operation(
692692

693693
// Check if present in the equivalent library.
694694
if output_circuit_and_qubits.is_none() {
695-
if let Some(equiv_lib) = &data.equivalence_library {
695+
if let Some(equiv_lib) = &data.borrow().equivalence_library {
696696
if equiv_lib.borrow(py).has_entry(op) {
697697
return Ok(None);
698698
}
699699
}
700700
}
701701

702702
// Extract definition.
703-
if output_circuit_and_qubits.is_none() && data.unroll_definitions {
703+
if output_circuit_and_qubits.is_none() && data.borrow().unroll_definitions {
704704
let definition_circuit = op.definition(params);
705705
match definition_circuit {
706706
Some(definition_circuit) => {
@@ -753,7 +753,7 @@ fn synthesize_operation(
753753
/// Currently, this function does not update the qubit tracker, which is handled upstream.
754754
fn synthesize_op_using_plugins(
755755
py: Python,
756-
data: &HighLevelSynthesisData,
756+
data: &Bound<HighLevelSynthesisData>,
757757
tracker: &QubitTracker,
758758
input_qubits: &[usize],
759759
op: &OperationRef,
@@ -778,7 +778,7 @@ fn synthesize_op_using_plugins(
778778
// ToDo: how can we avoid cloning data and tracker?
779779
let res = HLS_SYNTHESIZE_OP_USING_PLUGINS
780780
.get_bound(py)
781-
.call1((op_py, input_qubits, data.clone(), tracker.clone()))?
781+
.call1((op_py, input_qubits, data, tracker.clone()))?
782782
.extract::<Option<(QuantumCircuitData, Vec<usize>)>>()?;
783783

784784
if let Some((quantum_circuit_data, qubits)) = res {
@@ -798,7 +798,7 @@ pub fn py_synthesize_operation(
798798
py: Python,
799799
py_op: Bound<PyAny>,
800800
input_qubits: Vec<usize>,
801-
data: &HighLevelSynthesisData,
801+
data: &Bound<HighLevelSynthesisData>,
802802
tracker: &mut QubitTracker,
803803
) -> PyResult<Option<(CircuitData, Vec<usize>)>> {
804804
let op: OperationFromPython = py_op.extract()?;
@@ -823,7 +823,7 @@ pub fn py_synthesize_operation(
823823
pub fn py_run_on_dag(
824824
py: Python,
825825
dag: &DAGCircuit,
826-
data: &HighLevelSynthesisData,
826+
data: &Bound<HighLevelSynthesisData>,
827827
qubits_initially_zero: bool,
828828
) -> PyResult<Option<DAGCircuit>> {
829829
// Fast-path: check if HighLevelSynthesis can be skipped altogether. This is only

0 commit comments

Comments
 (0)