Skip to content

Commit 6499ceb

Browse files
authored
C API: Burn ConsolidateBlocks (Qiskit#14751)
* Add: C FFI for `ConsolidateBlocks` - Add `qk_transpiler_pass_standalone_consolidate_blocks` to expose a version of the `ConsolidateBlocks` pass to C. The pass runs on an instance of `CircuitData` and an optional `Target`. * Chore: Add tests and fix formatting. * Fix: C test deallocates * Fix: Add missing void in function signature for c tests, * Fix: Free circuit instruction instance afterwards. * FIx: Add missing `qk_count_ops_free` to Ctests * Fix: Modify the Circuit in place. * Docs: Add release note * Chore: Add test with target * Fix: Incorrect formatting on c tests. * Fix: Address review comments. - Quit using malloc in favor of stack allocations. - Remove dependency on synthesis module from `cext`. - Add mention of `NaN` on docstring. * Fix: Pivot to freeing the allocated space. * Fix: Adapt to Qiskit#14930 * Fix: Redo stack approach correctly
1 parent a776456 commit 6499ceb

File tree

4 files changed

+395
-0
lines changed

4 files changed

+395
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// This code is part of Qiskit.
2+
//
3+
// (C) Copyright IBM 2025
4+
//
5+
// This code is licensed under the Apache License, Version 2.0. You may
6+
// obtain a copy of this license in the LICENSE.txt file in the root directory
7+
// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8+
//
9+
// Any modifications or derivative works of this code must retain this
10+
// copyright notice, and modified files need to carry a notice indicating
11+
// that they have been altered from the originals.
12+
13+
use qiskit_circuit::{
14+
circuit_data::CircuitData, converters::dag_to_circuit, dag_circuit::DAGCircuit,
15+
};
16+
use qiskit_transpiler::{passes::run_consolidate_blocks, target::Target};
17+
18+
use crate::pointers::{const_ptr_as_ref, mut_ptr_as_ref};
19+
20+
/// @ingroup QkTranspilerPasses
21+
/// Run the ConsolidateBlocks pass on a circuit.
22+
///
23+
/// ConsolidateBlocks is a transpiler pass that consolidates consecutive blocks of
24+
/// gates operating on the same qubits into a Unitary gate, to later on be
25+
/// resynthesized, which leads to a more optimal subcircuit.
26+
///
27+
/// @param circuit A pointer to the circuit to run ConsolidateBlocks on.
28+
/// @param target A pointer to the target to run ConsolidateBlocks on.
29+
/// @param approximation_degree A float between `[0.0, 1.0]` or a `NaN` which
30+
/// defaults to `1.0`. Lower approximates more.
31+
/// @param force_consolidate: Force block consolidation.
32+
///
33+
/// # Safety
34+
///
35+
/// Behavior is undefined if ``circuit`` is not a valid, non-null pointer to a ``QkCircuit`` and
36+
/// if ``target`` is not a valid pointer to a ``QkTarget``.
37+
#[no_mangle]
38+
#[cfg(feature = "cbinding")]
39+
pub unsafe extern "C" fn qk_transpiler_pass_standalone_consolidate_blocks(
40+
circuit: *mut CircuitData,
41+
target: *const Target,
42+
approximation_degree: f64,
43+
force_consolidate: bool,
44+
) {
45+
let circuit = unsafe { mut_ptr_as_ref(circuit) };
46+
let target = unsafe {
47+
if target.is_null() {
48+
None
49+
} else {
50+
Some(const_ptr_as_ref(target))
51+
}
52+
};
53+
let approximation_degree = if approximation_degree.is_nan() {
54+
1.0
55+
} else {
56+
approximation_degree
57+
};
58+
let mut circ_as_dag = DAGCircuit::from_circuit_data(circuit, true, None, None, None, None)
59+
.expect("Error while converting from CircuitData to DAGCircuit.");
60+
61+
// Call the pass
62+
run_consolidate_blocks(
63+
&mut circ_as_dag,
64+
force_consolidate,
65+
Some(approximation_degree),
66+
target,
67+
)
68+
.expect("Error running the consolidate blocks pass.");
69+
70+
let result_circuit = dag_to_circuit(&circ_as_dag, true)
71+
.expect("Error while converting from DAGCircuit to CircuitData.");
72+
*circuit = result_circuit;
73+
}

crates/cext/src/transpiler/passes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// that they have been altered from the originals.
1212

1313
pub mod commutative_cancellation;
14+
pub mod consolidate_blocks;
1415
pub mod elide_permutations;
1516
pub mod gate_direction;
1617
pub mod inverse_cancellation;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
features_c:
3+
- |
4+
Add support for the :class:`.ConsolidateBlocks` transpiler pass to the C
5+
API via the method :cpp:func:`qk_transpiler_pass_standalone_consolidate_blocks`.
6+
7+
Here's an example:
8+
9+
.. code-block:: C
10+
11+
#include <qiskit.h>
12+
13+
// Build circuit
14+
QkCircuit *circuit = qk_circuit_new(2, 0);
15+
uint32_t cx_qargs[2] = {1, 0};
16+
17+
qk_circuit_gate(circuit, QkGate_H, (uint32_t[1]){0}, NULL);
18+
qk_circuit_gate(circuit, QkGate_CX, cx_qargs, NULL);
19+
20+
// Run pass, without Target
21+
qk_transpiler_pass_standalone_consolidate_blocks(circuit, NULL, 1.0, true);
22+
23+
// Free the circuit once you're done
24+
qk_circuit_free(circuit);

0 commit comments

Comments
 (0)