Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update remove blank wires to keep classical bits #1435

Merged
merged 20 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pytket/binders/circuit/Circuit/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,9 @@ void def_circuit(py::class_<Circuit, std::shared_ptr<Circuit>> &pyCircuit) {
"from the circuit. This may occur when optimisations "
"recognise that the operations on a qubit reduce to the "
"identity, or when routing adds wires to \"fill out\" the "
"architecture.")
"architecture.\n\n:param keep_blank_classical_wires: select if "
"empty classical wires should not be removed",
py::arg("keep_blank_classical_wires") = false)
.def(
"add_blank_wires", &Circuit::add_blank_wires,
"Adds a number of new qubits to the circuit. These will be "
Expand Down
2 changes: 1 addition & 1 deletion pytket/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def package(self):
cmake.install()

def requirements(self):
self.requires("tket/1.3.3@tket/stable")
self.requires("tket/1.3.4@tket/stable")
self.requires("tklog/0.3.3@tket/stable")
self.requires("tkrng/0.3.3@tket/stable")
self.requires("tkassert/0.3.4@tket/stable")
Expand Down
3 changes: 2 additions & 1 deletion pytket/docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ Features:
* Add ``OpType.CnRx`` and ``OpType.CnRz``.
* Add ``AutoRebase`` and ``AutoSquash`` passes.
Deprecate ``auto_rebase_pass`` and ``auto_squash_pass``.
* Add new parameter to `remove_blank_wires` to allow to keep empty classical bits

Fixes:

* Allow barriers when dagger or transpose a circuit.
* Keep blank classical wires when running `FlattenRelabelRegistersPass`
* Handle Clifford-angle ``NPhasedX`` gates in Clifford resynthesis.


1.28.0 (May 2024)
-----------------

Expand Down
4 changes: 3 additions & 1 deletion pytket/pytket/_tket/circuit.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2263,9 +2263,11 @@ class Circuit:
"""
Query whether a qubit has its final state discarded
"""
def remove_blank_wires(self) -> None:
def remove_blank_wires(self, keep_blank_classical_wires: bool = False) -> None:
"""
Removes any Input-Output pairs in the DAG with no intervening operations, i.e. removes untouched qubits/bits from the circuit. This may occur when optimisations recognise that the operations on a qubit reduce to the identity, or when routing adds wires to "fill out" the architecture.

:param keep_blank_classical_wires: select if empty classical wires should not be removed
"""
def rename_units(self, map: dict[pytket._tket.unit_id.UnitID | pytket._tket.unit_id.Qubit | pytket._tket.unit_id.Bit, pytket._tket.unit_id.UnitID | pytket._tket.unit_id.Qubit | pytket._tket.unit_id.Bit]) -> bool:
"""
Expand Down
2 changes: 1 addition & 1 deletion tket/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

class TketConan(ConanFile):
name = "tket"
version = "1.3.3"
version = "1.3.4"
package_type = "library"
license = "Apache 2"
homepage = "https://github.com/CQCL/tket"
Expand Down
9 changes: 7 additions & 2 deletions tket/include/tket/Circuit/Circuit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,8 +762,13 @@ class Circuit {
// Basic Circuit Manipulation//
//////////////////////////////

// O(V), `V` the number of vertices
void remove_blank_wires();
/**
* O(V), `V` the number of vertices
* removes all blank wires
* @param keep_blank_classical_wires option to choose if empty classical wire
* should be removed as well
*/
void remove_blank_wires(bool keep_blank_classical_wires = false);

/**
* Remove all gates in the circuits that are identities
Expand Down
22 changes: 12 additions & 10 deletions tket/src/Circuit/basic_circ_manip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,22 @@ namespace tket {
// if there are any blank wires in the circuit,
// this method removes them and removes the vertices
// from boundaries
void Circuit::remove_blank_wires() {
void Circuit::remove_blank_wires(bool keep_blank_classical_wires) {
VertexList bin;
unit_vector_t unused_units;
const Op_ptr noop = get_op_ptr(OpType::noop);
for (const BoundaryElement& el : boundary.get<TagID>()) {
Vertex in = el.in_;
Vertex out = el.out_;
VertexVec succs = get_successors(in);
if (succs.size() == 1 && succs.front() == out) {
dag[in].op = noop;
bin.push_back(in);
dag[out].op = noop;
bin.push_back(out);
unused_units.push_back(el.id_);
if (!keep_blank_classical_wires || el.type() == UnitType::Qubit) {
Vertex in = el.in_;
Vertex out = el.out_;
VertexVec succs = get_successors(in);
if (succs.size() == 1 && succs.front() == out) {
dag[in].op = noop;
bin.push_back(in);
dag[out].op = noop;
bin.push_back(out);
unused_units.push_back(el.id_);
}
}
}
for (const UnitID& u : unused_units) {
Expand Down
2 changes: 1 addition & 1 deletion tket/src/Predicates/PassGenerators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ PassPtr gen_flatten_relabel_registers_pass(const std::string& label) {
Transform t =
Transform([=](Circuit& circuit, std::shared_ptr<unit_bimaps_t> maps) {
unsigned n_qubits = circuit.n_qubits();
circuit.remove_blank_wires();
circuit.remove_blank_wires(false);
bool changed = circuit.n_qubits() < n_qubits;
std::map<Qubit, Qubit> relabelling_map;
std::vector<Qubit> all_qubits = circuit.all_qubits();
Expand Down
31 changes: 27 additions & 4 deletions tket/test/src/Circuit/test_Circ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,11 +1012,34 @@ SCENARIO(
}

test.add_blank_wires(8);
int n = test.n_vertices();
REQUIRE(test.n_bits() == 0);
REQUIRE(test.n_qubits() == 10);
test.remove_blank_wires();
int m = test.n_vertices();
REQUIRE(n == 22);
REQUIRE(m == 6);
REQUIRE(test.n_bits() == 0);
REQUIRE(test.n_qubits() == 2);
test.assert_valid();
}

SCENARIO(
"Test a circuit with blank wires can have the blank wires removed keeping "
"classical",
"[blank_wires]") {
Circuit test(4, 2);
test.add_op<unsigned>(OpType::CX, {0, 1});
test.add_op<unsigned>(OpType::Z, {0});

WHEN("Check Commands work correctly") {
std::vector<Command> coms = test.get_commands();
REQUIRE(*coms[0].get_op_ptr() == *get_op_ptr(OpType::CX));
REQUIRE(*coms[1].get_op_ptr() == *get_op_ptr(OpType::Z));
}

test.add_blank_wires(8);
REQUIRE(test.n_bits() == 2);
REQUIRE(test.n_qubits() == 12);
test.remove_blank_wires(true);
REQUIRE(test.n_bits() == 2);
REQUIRE(test.n_qubits() == 2);
test.assert_valid();
}

Expand Down
Loading