Skip to content

Commit 0e7be5d

Browse files
committed
♻️ refactor control type handling in bindings for improved simplicity and clarity
Signed-off-by: burgholzer <burgholzer@me.com>
1 parent 31c8445 commit 0e7be5d

File tree

1 file changed

+32
-44
lines changed

1 file changed

+32
-44
lines changed

bindings/dd/register_dd_package.cpp

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,10 @@
3333
#include <nanobind/stl/pair.h> // NOLINT(misc-include-cleaner)
3434
#include <nanobind/stl/set.h> // NOLINT(misc-include-cleaner)
3535
#include <nanobind/stl/string.h> // NOLINT(misc-include-cleaner)
36-
#include <nanobind/stl/variant.h> // NOLINT(misc-include-cleaner)
3736
#include <nanobind/stl/vector.h> // NOLINT(misc-include-cleaner)
3837
#include <random>
39-
#include <set>
4038
#include <stdexcept>
4139
#include <utility>
42-
#include <variant>
4340
#include <vector>
4441

4542
namespace mqt {
@@ -54,9 +51,6 @@ using SingleQubitMatrix =
5451
using TwoQubitMatrix =
5552
nb::ndarray<nb::numpy, std::complex<dd::fp>, nb::shape<4, 4>>;
5653

57-
using Control = std::variant<qc::Control, nb::int_>;
58-
using Controls = std::set<Control>;
59-
6054
namespace {
6155

6256
/// Recursive helper function to create a vector DD from a numpy array
@@ -103,33 +97,6 @@ dd::mCachedEdge makeDDFromMatrix(dd::Package& p, const Matrix& m,
10397
makeDDFromMatrix(p, m, rowHalf, rowEnd, colStart, colHalf, level - 1),
10498
makeDDFromMatrix(p, m, rowHalf, rowEnd, colHalf, colEnd, level - 1)});
10599
}
106-
107-
/// Helper function to convert Control variant to qc::Control
108-
qc::Control getControl(const Control& control) {
109-
if (std::holds_alternative<qc::Control>(control)) {
110-
return std::get<qc::Control>(control);
111-
}
112-
const auto controlInt =
113-
static_cast<std::int64_t>(std::get<nb::int_>(control));
114-
if (controlInt < 0) {
115-
throw nb::value_error("Control qubit index cannot be negative");
116-
}
117-
const auto controlUint = static_cast<std::uint64_t>(controlInt);
118-
if (controlUint > std::numeric_limits<qc::Qubit>::max()) {
119-
throw nb::value_error("Control qubit index exceeds maximum value");
120-
}
121-
return static_cast<qc::Qubit>(controlUint);
122-
}
123-
124-
/// Helper function to convert Controls variant to qc::Controls
125-
qc::Controls getControls(const Controls& controls) {
126-
qc::Controls result;
127-
for (const auto& control : controls) {
128-
result.insert(getControl(control));
129-
}
130-
return result;
131-
}
132-
133100
} // namespace
134101

135102
// NOLINTNEXTLINE(misc-use-internal-linkage)
@@ -493,14 +460,19 @@ Specifically, it
493460

494461
dd.def(
495462
"controlled_single_qubit_gate",
496-
[](dd::Package& p, const SingleQubitMatrix& mat, const Control& control,
497-
const dd::Qubit target) {
463+
[](dd::Package& p, const SingleQubitMatrix& mat,
464+
const qc::Control& control, const dd::Qubit target) {
498465
return p.makeGateDD({mat(0, 0), mat(0, 1), mat(1, 0), mat(1, 1)},
499-
getControl(control), target);
466+
control, target);
500467
},
501468
"matrix"_a, "control"_a, "target"_a,
502469
// keep the DD package alive while the returned matrix DD is alive.
503470
nb::keep_alive<0, 1>(),
471+
nb::sig(
472+
"def controlled_single_qubit_gate(self, "
473+
"matrix: Annotated[ANDArray[numpy.complex128], {\"shape\": (2, 2)}],"
474+
"control: mqt.core.ir.operations.Control | int,"
475+
"target: int) -> mqt.core.dd.MatrixDD"),
504476
R"pb(Create the DD for a controlled single-qubit gate.
505477
506478
Args:
@@ -513,14 +485,19 @@ Specifically, it
513485

514486
dd.def(
515487
"multi_controlled_single_qubit_gate",
516-
[](dd::Package& p, const SingleQubitMatrix& mat, const Controls& controls,
517-
const dd::Qubit target) {
488+
[](dd::Package& p, const SingleQubitMatrix& mat,
489+
const qc::Controls& controls, const dd::Qubit target) {
518490
return p.makeGateDD({mat(0, 0), mat(0, 1), mat(1, 0), mat(1, 1)},
519-
getControls(controls), target);
491+
controls, target);
520492
},
521493
"matrix"_a, "controls"_a, "target"_a,
522494
// keep the DD package alive while the returned matrix DD is alive.
523495
nb::keep_alive<0, 1>(),
496+
nb::sig(
497+
"def multi_controlled_single_qubit_gate(self, "
498+
"matrix: Annotated[ANDArray[numpy.complex128], {\"shape\": (2, 2)}],"
499+
"controls: collections.abc.Set[mqt.core.ir.operations.Control | int],"
500+
"target: int) -> mqt.core.dd.MatrixDD"),
524501
R"pb(Create the DD for a multi-controlled single-qubit gate.
525502
526503
Args:
@@ -556,18 +533,23 @@ Specifically, it
556533

557534
dd.def(
558535
"controlled_two_qubit_gate",
559-
[](dd::Package& p, const TwoQubitMatrix& mat, const Control& control,
536+
[](dd::Package& p, const TwoQubitMatrix& mat, const qc::Control& control,
560537
const dd::Qubit target0, const dd::Qubit target1) {
561538
return p.makeTwoQubitGateDD(
562539
{std::array{mat(0, 0), mat(0, 1), mat(0, 2), mat(0, 3)},
563540
{mat(1, 0), mat(1, 1), mat(1, 2), mat(1, 3)},
564541
{mat(2, 0), mat(2, 1), mat(2, 2), mat(2, 3)},
565542
{mat(3, 0), mat(3, 1), mat(3, 2), mat(3, 3)}},
566-
getControl(control), target0, target1);
543+
control, target0, target1);
567544
},
568545
"matrix"_a, "control"_a, "target0"_a, "target1"_a,
569546
// keep the DD package alive while the returned matrix DD is alive.
570547
nb::keep_alive<0, 1>(),
548+
nb::sig(
549+
"def controlled_two_qubit_gate(self, "
550+
"matrix: Annotated[ANDArray[numpy.complex128], {\"shape\": (4, 4)}],"
551+
"control: mqt.core.ir.operations.Control | int,"
552+
"target0: int, target1: int) -> mqt.core.dd.MatrixDD"),
571553
R"pb(Create the DD for a controlled two-qubit gate.
572554
573555
Args:
@@ -581,18 +563,24 @@ Specifically, it
581563

582564
dd.def(
583565
"multi_controlled_two_qubit_gate",
584-
[](dd::Package& p, const TwoQubitMatrix& mat, const Controls& controls,
585-
const dd::Qubit target0, const dd::Qubit target1) {
566+
[](dd::Package& p, const TwoQubitMatrix& mat,
567+
const qc::Controls& controls, const dd::Qubit target0,
568+
const dd::Qubit target1) {
586569
return p.makeTwoQubitGateDD(
587570
{std::array{mat(0, 0), mat(0, 1), mat(0, 2), mat(0, 3)},
588571
{mat(1, 0), mat(1, 1), mat(1, 2), mat(1, 3)},
589572
{mat(2, 0), mat(2, 1), mat(2, 2), mat(2, 3)},
590573
{mat(3, 0), mat(3, 1), mat(3, 2), mat(3, 3)}},
591-
getControls(controls), target0, target1);
574+
controls, target0, target1);
592575
},
593576
"matrix"_a, "controls"_a, "target0"_a, "target1"_a,
594577
// keep the DD package alive while the returned matrix DD is alive.
595578
nb::keep_alive<0, 1>(),
579+
nb::sig(
580+
"def multi_controlled_two_qubit_gate(self, "
581+
"matrix: Annotated[ANDArray[numpy.complex128], {\"shape\": (4, 4)}],"
582+
"controls: collections.abc.Set[mqt.core.ir.operations.Control | int],"
583+
"target0: int, target1: int) -> mqt.core.dd.MatrixDD"),
596584
R"pb(Create the DD for a multi-controlled two-qubit gate.
597585
598586
Args:

0 commit comments

Comments
 (0)