Skip to content

Commit

Permalink
Make qasm3.CustomGate accessible from Python space
Browse files Browse the repository at this point in the history
We previously exposed the data attribute `STDGATES_INC_GATES`, but its
contents are all `CustomGate`, which can't be inspected programmatically
from Python space.  This makes it so you can query _what_ the gates,
their number of parameters, and how to construct them.
  • Loading branch information
jakelishman committed Sep 19, 2024
1 parent 5121a0f commit 20f5c31
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 3 deletions.
13 changes: 12 additions & 1 deletion crates/qasm3/src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,23 @@ register_type!(PyClassicalRegister);

/// Information received from Python space about how to construct a Python-space object to
/// represent a given gate that might be declared.
#[pyclass(module = "qiskit._accelerate.qasm3", frozen, name = "CustomGate")]
#[pyclass(
module = "qiskit._accelerate.qasm3",
frozen,
name = "CustomGate",
get_all
)]
#[derive(Clone, Debug)]
pub struct PyGate {
/// A callable Python object that takes ``num_params`` angles as positional arguments, and
/// returns a :class:`~.circuit.Gate` object representing the gate.
constructor: Py<PyAny>,
/// The name of the gate as it appears in the OpenQASM 3 program. This is not necessarily
/// identical to the name that Qiskit gives the gate.
name: String,
/// The number of angle-like parameters the gate requires.
num_params: usize,
/// The number of qubits the gate acts on.
num_qubits: usize,
}

Expand Down
4 changes: 2 additions & 2 deletions crates/qasm3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use crate::error::QASM3ImporterError;
/// :class:`.QuantumCircuit`: the constructed circuit object.
///
/// Raises:
/// :class:`.QASM3ImporterError`: if an error occurred during parsing or semantic analysis.
/// :exc:`.QASM3ImporterError`: if an error occurred during parsing or semantic analysis.
/// In the case of a parsing error, most of the error messages are printed to the terminal
/// and formatted, for better legibility.
#[pyfunction]
Expand Down Expand Up @@ -120,7 +120,7 @@ pub fn loads(
/// :class:`.QuantumCircuit`: the constructed circuit object.
///
/// Raises:
/// :class:`.QASM3ImporterError`: if an error occurred during parsing or semantic analysis.
/// :exc:`.QASM3ImporterError`: if an error occurred during parsing or semantic analysis.
/// In the case of a parsing error, most of the error messages are printed to the terminal
/// and formatted, for better legibility.
#[pyfunction]
Expand Down
1 change: 1 addition & 0 deletions qiskit/qasm3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
using the :class:`CustomGate` object:
.. autoclass:: CustomGate
:members:
In ``custom_gates`` is not given, Qiskit will attempt to use its standard-library gate objects for
the gates defined in OpenQASM 3 standard library file ``stdgates.inc``. This sequence of gates is
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
features_qasm:
- |
The class :class:`.qasm3.CustomGate` is now inspectable programmatically. Its
:attr:`~.qasm3.CustomGate.constructor`, :attr:`~.qasm3.CustomGate.name`,
:attr:`~.qasm3.CustomGate.num_params` and :attr:`~.qasm3.CustomGate.num_qubits` can now be
viewed from Python after the object has been constructed. This allows you to inspect the
contents of provided data attributes like :data:`.STDGATES_INC_GATES`.
14 changes: 14 additions & 0 deletions test/python/qasm3/test_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,17 @@ def test_gate_broadcast(self):
expected.ccx(q0[1], q1, q2[0])
expected.ccx(q0[0], q1, q2[1])
self.assertEqual(parsed, expected)

def test_custom_gate_inspectable(self):
"""Test that the `CustomGate` object can be inspected programmatically after creation."""
custom = qasm3.CustomGate(lib.CXGate, "cx", 0, 2)
self.assertEqual(custom.name, "cx")
self.assertEqual(custom.num_params, 0)
self.assertEqual(custom.num_qubits, 2)

self.assertIsInstance(qasm3.STDGATES_INC_GATES[0], qasm3.CustomGate)
stdgates = {
gate.name: (gate.num_params, gate.num_qubits) for gate in qasm3.STDGATES_INC_GATES
}
self.assertEqual(stdgates["rx"], (1, 1))
self.assertEqual(stdgates["cphase"], (1, 2))

0 comments on commit 20f5c31

Please sign in to comment.