Skip to content

Commit

Permalink
Upgrade mapper/router to new IR
Browse files Browse the repository at this point in the history
- New IR in place of old IR
- New DDG is used in place of old scheduler
- Various code improvements (e.g. return result instead of modify
  reference parameter)
- Remove BASE_RC and MINEXTEND_RC mapper options
- Really order available gates by decreasing "criticality" which was the
original intent but was gonne from the code.
  • Loading branch information
pablolh committed May 30, 2023
1 parent 83e64cc commit ca5c0aa
Show file tree
Hide file tree
Showing 69 changed files with 2,657 additions and 5,691 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- support for resource constrained scheduler
- creates .map file reporting measurement statements present in input, to allow retrieving measurements downstream
- support for Python up to 3.11
- OperandsHelper class in ir/ops.h for easily grabbing qubit operand indices in new IR

### Changed
- pass dec.Instructions: duration=0 in new-style decomposition rules now disables checking whether expansion fits, allowing automatic calculation of duration (and requiring scheduling after decomposition of such rules)
Expand All @@ -45,14 +46,27 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- classification of gates as *real-time* measurement now based on signal definition ("signal/type" equals "measure" and "signal/value" empty)
- absence of key "cc" now implies empty "signal", so `"cc": { "signal": [] }` is no longer necessary
- passes and architectures self-register statically to their respective factories
<<<<<<< HEAD
- initial placer uses new IR and new MIP solver called HiGHS
=======
- Mapper/Router:
- uses new IR in place of old IR and com::ddg in place of Scheduler
- no longer assigns cycle numbers to output circuit
- no longer decomposes instructions into primitives in the output circuit (it still does internally for accurate scheduling)
>>>>>>> a3e93559 (Upgrade mapper/router to new IR)
### Removed
- CC backend:
- support for JSON key "pragma/break" for instruction definitions
- macro expansion for JSON key instruction/signal/value (unused anyway)
- support for sweep points in API and the WriteSweepPointsPass
<<<<<<< HEAD
- support for Python up to and including 3.6
=======
- Mapper/Router:
- Deprecated maxfidelity route heuristic
- 1qfirst lookahead mode
>>>>>>> a3e93559 (Upgrade mapper/router to new IR)
### Fixed
- pass dec.Instructions
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ add_library(ql
"${CMAKE_CURRENT_SOURCE_DIR}/src/ql/com/sch/scheduler.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/ql/com/map/expression_mapper.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/ql/com/map/qubit_mapping.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/ql/com/map/reference_updater.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/ql/com/dec/unitary.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/ql/com/dec/rules.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/ql/com/dec/structure.cc"
Expand Down
11 changes: 3 additions & 8 deletions docs/old/passes/mapping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -522,10 +522,6 @@ What needs to be done when multiple alternatives compare equal, is specified lat
and just subtracting the depths before and after doing that;
the various options controlling this scheduling-in, will be specified later below.

- ``minextendrc``:
map the circuit:
as in ``minextend``, but taking resource constraints into account when scheduling-in the ``swap``\ s and ``move``\ s.

.. _mapping_look_back:

Look-Back, Maximize Instruction-Level Parallelism By Scheduling
Expand All @@ -534,8 +530,7 @@ Look-Back, Maximize Instruction-Level Parallelism By Scheduling
To know the circuit's latency extension of an alternative,
the mapped gates are represented as a scheduled circuit, i.e. with gates with a defined ``cycle`` attribute,
and the gates ordered in the circuit with non-decreasing ``cycle`` value.
In case the ``mapper`` option has the ``minextendrc`` value, also the state of all resources is maintained.
When a ``swap`` or ``move`` gate is added, it is ASAP scheduled (optionally taking the resource constraints into account)
When a ``swap`` or ``move`` gate is added, it is ASAP scheduled
into the circuit and the corresponding cycle value is assigned to the ``cycle`` attribute of the added gate.
Note that when ``swap`` or ``move`` is defined by a composite gate, the decomposed sequence is scheduled-in instead.

Expand Down Expand Up @@ -644,7 +639,7 @@ Looking farther ahead beyond the mapping of the current two-qubit gate,
the router recurses considering the effects of its mapping on subsequent two-qubit gates.

After having evaluated the metric for each alternative, multiple alternatives may remain, all with the best value.
For the ``minextend`` and ``minextendrc`` strategies, there are options to select from these by looking ahead farther,
For the ``minextend`` strategy, there are options to select from these by looking ahead farther,
i.e. beyond the metric evaluation of this alternative for mapping one two-qubit gate.
This *recursion* assumes that the current alternative is selected, its ``swap``\ s
and ``move``\ s are added to the circuit
Expand Down Expand Up @@ -725,7 +720,7 @@ The following options control this recursion:
Deciding For The Best, Committing To The Best
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

With or without recursion, for the ``base`` strategy as well as for the ``minextend`` and ``minextendrc`` strategies,
With or without recursion, for the ``base`` strategy as well as for the ``minextend`` strategy,
when at the end multiple alternatives still compare equally well, a decision has to be taken which two-qubit gate
to route and map.
This selection is made based on the value of the following option:
Expand Down
8 changes: 4 additions & 4 deletions include/ql/com/ddg/build.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class EventGatherer {
private:

/**
* Reference to the root of the IR.
* Reference to the platform.
*/
ir::Ref ir;
ir::PlatformRef platform;

/**
* The actual event list.
Expand Down Expand Up @@ -49,7 +49,7 @@ class EventGatherer {
/**
* Constructs an object reference gatherer.
*/
explicit EventGatherer(const ir::Ref &ir);
explicit EventGatherer(const ir::PlatformRef &p);

/**
* Returns the contained list of object accesses.
Expand Down Expand Up @@ -116,7 +116,7 @@ class EventGatherer {
* node in the final schedule, and such that the sign indicates the direction
*/
void build(
const ir::Ref &ir,
const ir::PlatformRef &platform,
const ir::BlockBaseRef &block,
utils::Bool commute_multi_qubit = true,
utils::Bool commute_single_qubit = true
Expand Down
7 changes: 7 additions & 0 deletions include/ql/com/ddg/ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ void clear(const ir::BlockBaseRef &block);
*/
void reverse(const ir::BlockBaseRef &block);

/**
* Add the Remaining annotation to nodes in the graph.
* Remaining gives the remaining length of the critical path.
* Can be used to e.g. compare which gate is most critical.
*/
void add_remaining(const ir::BlockBaseRef &block);

} // namespace ddg
} // namespace com
} // namespace ql
6 changes: 6 additions & 0 deletions include/ql/com/ddg/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,12 @@ struct Graph {

};

struct Remaining {
utils::UInt remaining = 0;

Remaining(utils::UInt r) : remaining(r) {};
};

} // namespace ddg
} // namespace com
} // namespace ql
1 change: 0 additions & 1 deletion include/ql/com/dec/rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ using RulePredicate = std::function<utils::Bool(const ir::DecompositionRef&)>;
* reordered.
*/
utils::UInt apply_decomposition_rules(
const ir::Ref &ir,
const ir::BlockBaseRef &block,
utils::Bool ignore_schedule = true,
const RulePredicate &predicate = [](const ir::DecompositionRef&){ return true; }
Expand Down
43 changes: 43 additions & 0 deletions include/ql/com/map/reference_updater.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "ql/ir/ir.h"

namespace ql {
namespace com {
namespace map {

/*
This class is a visitor for changing virtual qubit indices to real qubit indices, given a mapping.
*/

class ReferenceUpdater : public ir::RecursiveVisitor {
public:
using Callback = std::function<void(utils::UInt)>;

/*
m: a vector represening the virtual->real qubit mapping.
m[i] is the real qubit index corresponding to virtual qubit i.
c: a callback to be called for every mapped virtual qubit index.
*/
ReferenceUpdater(ir::PlatformRef p, const utils::Vec<utils::UInt> &m,
Callback c = {}) : platform(p), mapping(m), callback(c) {}

void visit_node(ir::Node &node) override {};

void visit_reference(ir::Reference &ref) override;

// Gate operands may be virtual qubits, but in the instruction type it's always real qubit indices.
void visit_instruction_type(ir::InstructionType &t) override {};

private:
ir::PlatformRef platform;
const utils::Vec<utils::UInt> &mapping;
Callback callback{};
};

void mapInstruction(const ir::PlatformRef &platform, const utils::Vec<utils::UInt> &mapping, const ir::CustomInstructionRef &instr, ReferenceUpdater::Callback callback = {});

void mapProgram(const ir::PlatformRef &platform, const utils::Vec<utils::UInt> &mapping, const ir::ProgramRef &program);

}
}
}
20 changes: 2 additions & 18 deletions include/ql/ir/compat/gate.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ql/utils/json.h"
#include "ql/utils/misc.h"
#include "ql/utils/tree.h"
#include "ql/ir/swap_parameters.h"

namespace ql {
namespace ir {
Expand Down Expand Up @@ -70,23 +71,6 @@ std::ostream &operator<<(std::ostream &os, ConditionType condition_type);

const utils::UInt MAX_CYCLE = utils::MAX;

struct SwapParamaters {
utils::Bool part_of_swap = false;
// at the end of the swap r0 stores v0 and r1 stores v1
utils::Int r0 = -1;
utils::Int r1 = -1;
utils::Int v0 = -1;
utils::Int v1 = -1;

// default constructor
SwapParamaters() {}

// initializer list
SwapParamaters(utils::Bool _part_of_swap, utils::Int _r0, utils::Int _r1, utils::Int _v0, utils::Int _v1)
: part_of_swap(_part_of_swap), r0(_r0), r1(_r1), v0(_v0), v1(_v1)
{}
};

/**
* gate interface
*/
Expand All @@ -98,7 +82,7 @@ class Gate : public utils::Node {
utils::Vec<utils::UInt> breg_operands; // bit operands e.g. assigned to by measure; cond_operands are separate
utils::Vec<utils::UInt> cond_operands; // 0, 1 or 2 bit operands of condition
ConditionType condition = ConditionType::ALWAYS; // defines condition and by that number of bit operands of condition
SwapParamaters swap_params; // if the gate is part of a swap/move, this will contain the real and virtual qubits involved
SwapParameters swap_params; // if the gate is part of a swap/move, this will contain the real and virtual qubits involved
utils::Int int_operand = 0; // FIXME: move to class 'classical'
utils::UInt duration = 0;
utils::Real angle = 0.0; // for arbitrary rotations
Expand Down
5 changes: 5 additions & 0 deletions include/ql/ir/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ using StatementRef = utils::One<Statement>;
*/
using InstructionRef = utils::One<Instruction>;

/**
* Reference to a custom instruction.
*/
using CustomInstructionRef = utils::One<CustomInstruction>;

/**
* Link to a (custom) instruction type.
*/
Expand Down
Loading

0 comments on commit ca5c0aa

Please sign in to comment.