37static PassPtr gate_translation_pass(
38 const T &transform,
OpTypeSet after_set,
bool respect_connectivity,
39 const std::string &name) {
45 std::type_index ti =
typeid(ConnectivityPredicate);
46 PredicatePtr out_gateset = std::make_shared<GateSetPredicate>(after_set);
47 PredicatePtr max2qb = std::make_shared<MaxTwoQubitGatesPredicate>();
52 if (!respect_connectivity)
59 PassPtr ptr = std::make_shared<StandardPass>(precons, transform, postcon, j);
64 static const PassPtr pp(gate_translation_pass(
70 static const PassPtr pp(gate_translation_pass(
76 static const PassPtr pp(gate_translation_pass(
83 static const PassPtr pp(gate_translation_pass(
96 j[
"name"] =
"RemoveRedundancies";
97 return std::make_shared<StandardPass>(precons, t, postcon, j);
109 j[
"name"] =
"CommuteThroughMultis";
110 return std::make_shared<StandardPass>(precons, t, postcon, j);
124 j[
"name"] =
"DecomposeArbitrarilyControlledGates";
125 return std::make_shared<StandardPass>(precons, t, postcon, j);
138 for (
const std::pair<const OpType, OpTypeInfo> &ott :
optypeinfo()) {
139 if (!ott.second.signature || *ott.second.signature == singleq ||
140 *ott.second.signature == noargs)
141 ots.insert(ott.first);
144 PredicatePtr outp_gates = std::make_shared<GateSetPredicate>(ots);
145 PredicatePtr twoqbpred = std::make_shared<MaxTwoQubitGatesPredicate>();
153 j[
"name"] =
"DecomposeMultiQubitsCX";
154 return std::make_shared<StandardPass>(precons, t, postcon, j);
166 for (
const std::pair<const OpType, OpTypeInfo> &ott :
optypeinfo()) {
167 if (!ott.second.signature || *ott.second.signature != singleq)
168 ots.insert(ott.first);
171 PredicatePtr outp_gates = std::make_shared<GateSetPredicate>(ots);
178 j[
"name"] =
"DecomposeSingleQubitsTK1";
179 return std::make_shared<StandardPass>(precons, t, postcon, j);
197 PredicatePtr noclas = std::make_shared<NoClassicalControlPredicate>();
201 PredicatePtr no_wire_swap = std::make_shared<NoWireSwapsPredicate>();
209 j[
"name"] =
"ComposePhasePolyBoxes";
210 j[
"min_size"] = min_size;
212 return std::make_shared<StandardPass>(precons, t, postcon, j);
216 const std::unordered_set<OpType> &excluded_types,
217 const std::unordered_set<std::string> &excluded_opgroups,
218 const std::optional<std::unordered_set<OpType>> &included_types,
219 const std::optional<std::unordered_set<std::string>> &included_opgroups) {
221 excluded_types, excluded_opgroups, included_types, included_opgroups);
240 j[
"name"] =
"DecomposeBoxes";
241 j[
"excluded_types"] = excluded_types;
242 j[
"excluded_opgroups"] = excluded_opgroups;
243 if (included_types) j[
"included_types"] = *included_types;
244 if (included_opgroups) j[
"included_opgroups"] = *included_opgroups;
245 return std::make_shared<StandardPass>(s_ps, t, postcon, j);
257 j[
"name"] =
"SquashTK1";
258 return std::make_shared<StandardPass>(s_ps, t, postcon, j);
272 j[
"name"] =
"DecomposeBridges";
273 return std::make_shared<StandardPass>(s_ps, t, postcon, j);
288 PredicatePtr simple = std::make_shared<DefaultRegisterPredicate>();
296 j[
"name"] =
"FlattenRegisters";
297 return std::make_shared<StandardPass>(s_ps, t, postcon, j);
306 BGL_FORALL_VERTICES(v, circ.
dag,
DAG) {
308 barriers.push_back(v);
313 return !barriers.empty();
316 const PredicatePtr no_barriers = std::make_shared<NoBarriersPredicate>();
322 j[
"name"] =
"RemoveBarriers";
323 return std::make_shared<StandardPass>(no_precons, t, postcons, j);
329 auto f = [](
bool allow_partial) {
335 if (!allow_partial) {
337 std::make_shared<CommutableMeasuresPredicate>();
340 PredicatePtr midmeaspred = std::make_shared<NoMidMeasurePredicate>();
347 j[
"name"] =
"DelayMeasures";
348 j[
"allow_partial"] = allow_partial;
349 return std::make_shared<StandardPass>(precon, t, postcon, j);
351 static const PassPtr delay(f(
false));
352 static const PassPtr try_delay(f(
true));
353 return allow_partial ? try_delay : delay;
362 j[
"name"] =
"RemoveDiscarded";
363 return std::make_shared<StandardPass>(no_precons, t, postcon, j);
380 j[
"name"] =
"SimplifyMeasured";
381 return std::make_shared<StandardPass>(no_precons, t, postcon, j);
395 PredicatePtr normalisedpred = std::make_shared<NormalisedTK2Predicate>();
400 j[
"name"] =
"NormaliseTK2";
401 return std::make_shared<StandardPass>(no_precons, t, postcon, j);
417 j[
"name"] =
"ZZPhaseToRz";
418 return std::make_shared<StandardPass>(precons, t, postcon, j);
431 j[
"name"] =
"SquashRzPhasedX";
432 return std::make_shared<StandardPass>(s_ps, t, postcon, j);
445 j[
"name"] =
"CnXPairwiseDecomposition";
446 return std::make_shared<StandardPass>(s_ps, t, postcon, j);
456 return has_implicit_wire_swaps;
459 PredicatePtr no_wire_swap = std::make_shared<NoWireSwapsPredicate>();
465 specific_postcons, generic_postcons, default_postcon};
470 j[
"name"] =
"RemoveImplicitQubitPermutation";
471 return std::make_shared<StandardPass>(precons, t, postcons, j);
477 auto create_pass_ptr = []<
bool allow_wire_swaps>() ->
PassPtr {
479 std::optional<std::string> name = circ.
get_name();
488 for (
unsigned i = 0; i < orig_qs.size(); ++i)
489 qmap.insert({c_qs.at(i), orig_qs.at(i)});
491 if constexpr (!allow_wire_swaps) {
495 if (name.has_value()) {
506 std::make_shared<GateSetPredicate>(in_optypes)),
508 std::make_shared<NoClassicalBitsPredicate>())};
516 specific_postcons, generic_postcons, default_postcon};
518 j[
"name"] =
"ZXGraphlikeOptimisation";
519 return std::make_shared<StandardPass>(precons, t, postcons, j);
522 static const PassPtr pp{create_pass_ptr.operator()<
true>()};
527 static const PassPtr pp_no_implicit_swaps{
528 create_pass_ptr.operator()<
false>()};
529 return pp_no_implicit_swaps;
536 BGL_FORALL_VERTICES(v, circ.
dag,
DAG) {
538 OpType optype = op->get_type();
541 optype = op->get_type();
549 return !phases.empty();
554 j[
"name"] =
"RemovePhaseOps";
555 return std::make_shared<StandardPass>(no_precons, t, postcons, j);
bool rename_units(const std::map< UnitA, UnitB > &qm)
Rename all the units according to the given mapping.
void set_name(const std::string _name)
Set the name of the circuit.
const Op_ptr get_Op_ptr_from_Vertex(const Vertex &vert) const
qubit_vector_t all_qubits() const
bool has_implicit_wireswaps() const
Whether the circuit contains implicit wireswaps.
unit_map_t flatten_registers()
Convert all quantum and classical bits to use default registers.
void remove_vertices(const VertexSet &surplus, GraphRewiring graph_rewiring, VertexDeletion vertex_deletion)
std::optional< std::string > get_name() const
Get the name of the circuit.
void replace_all_implicit_wire_swaps()
replaces all implicit wire swaps with SWAP gates
OpType get_OpType_from_Vertex(const Vertex &vert) const
static TypePredicatePair make_type_pair(const PredicatePtr &ptr)
Decorates another op, adding a QASM-style classical condition.
Asserts that all operations are in the specified set of types.
Asserts that any measurements occur at the end of the circuit.
Location holding a qubit.
static Rewrite reduce_graphlike_form()
Given a diagram in graphlike form, applies local complementations and pivoting to remove as many inte...
static Rewrite to_graphlike_form()
Given a diagram with ZX generators, yields a diagram with only ZSpiders, connected by at most one Had...
const RewriteFun apply
The actual rewrite to be applied.
static Rewrite to_MBQC_diag()
Given a diagram in graphlike form, will rebase to MBQC generators, ensure that output qubits are PX(0...
Defines tket::DeviceCharacterisation, used in NoiseAwarePlacement and in commute_SQ_gates_through_SWA...
const PassPtr & ZXGraphlikeOptimisation(bool allow_swaps)
Attempt to optimise the circuit by simplifying in ZX calculus and extracting a circuit back out.
OpType
Named operation types.
@ Measure
Measure a qubit, producing a classical output.
@ Output
Quantum output node of the circuit.
@ Collapse
Measure a qubit producing no output.
@ Input
Quantum input node of the circuit.
@ Barrier
No-op that must be preserved by compilation.
@ Reset
Reset a qubit to the zero state.
@ CX
Controlled OpType::X.
@ CZ
Controlled OpType::Z.
@ Conditional
See Conditional.
std::unordered_set< OpType > OpTypeSet
Set of operation types.
std::shared_ptr< BasePass > PassPtr
std::list< Vertex > VertexList
const PassPtr & SquashTK1()
Squash sequences of single-qubit gates to TK1 gates.
const PassPtr & RebaseTket()
std::pair< ZXDiagram, BoundaryVertMap > circuit_to_zx(const Circuit &circ)
Construct a zx diagram from a given circuit.
std::map< Qubit, Qubit > qubit_map_t
const PassPtr & RemoveImplicitQubitPermutation()
Remove any implicit qubit permutation by appending SWAP gates.
@ Quantum
A wire carrying quantum information, corresponding to some allocated Qubit.
PassPtr ComposePhasePolyBoxes(const unsigned min_size)
converts a circuit containing all possible gates to a circuit containing only phase poly boxes + H ga...
const OpTypeSet & all_projective_types()
Set of all measurement and reset gates.
const PassPtr & SynthesiseTK()
const PassPtr & RemoveRedundancies()
const PassPtr & NormaliseTK2()
Normalises all TK2 gates.
const PassPtr & RemovePhaseOps()
Remove all OpType::Phase (including conditionals) from the circuit.
std::shared_ptr< const Op > Op_ptr
const PassPtr & RemoveBarriers()
Remove all& OpType::Barrier from the circuit.
const PassPtr & SquashRzPhasedX()
Squash single qubit gates into PhasedX and Rz gates.
const PassPtr & CnXPairwiseDecomposition()
Decompose CnX gates to 2-qubit gates and single qubit gates.
const PassPtr & ZZPhaseToRz()
Converts ZZPhase with angle 1 or -1 to two Rz(1) gates.
PassPtr DecomposeBoxes(const std::unordered_set< OpType > &excluded_types, const std::unordered_set< std::string > &excluded_opgroups, const std::optional< std::unordered_set< OpType > > &included_types, const std::optional< std::unordered_set< std::string > > &included_opgroups)
Recursively replaces all boxes by their decomposition using Box::to_circuit.
const PassPtr & DecomposeMultiQubitsCX()
std::map< std::type_index, Guarantee > PredicateClassGuarantees
std::map< UnitID, UnitID > unit_map_t
const PassPtr & RemoveDiscarded()
Remove all operations that have no OpType::Output or OpType::ClOutput in their causal future.
const PassPtr & SimplifyMeasured()
Replace all measured classical maps that are followed by Measure operations whose quantum output is d...
const PassPtr & CommuteThroughMultis()
const PassPtr & SynthesiseTket()
const PassPtr & RebaseUFR()
std::vector< EdgeType > op_signature_t
std::map< std::type_index, PredicatePtr > PredicatePtrMap
const PassPtr & DecomposeBridges()
std::shared_ptr< Predicate > PredicatePtr
const PassPtr & DecomposeArbitrarilyControlledGates()
std::vector< Qubit > qubit_vector_t
const PassPtr & DelayMeasures(const bool allow_partial)
Commutes measurements to the end of the circuit.
boost::adjacency_list< boost::listS, boost::listS, boost::bidirectionalS, boost::property< boost::vertex_index_t, std::size_t, VertexProperties >, EdgeProperties > DAG
Graph representing a circuit, with operations as nodes.
const PassPtr & DecomposeSingleQubitsTK1()
Circuit zx_to_circuit(const ZXDiagram &d)
Takes a unitary ZX diagram in MBQC form with the promise that a gflow exists.
bool update_maps(std::shared_ptr< unit_bimaps_t > maps, const std::map< UnitA, UnitB > &um_initial, const std::map< UnitA, UnitB > &um_final)
Update a pair of "initial" and "final" correspondences.
const std::map< OpType, OpTypeInfo > & optypeinfo()
Information including name and shape of each operation type.
const PassPtr & FlattenRegisters()