-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fidelity-aware heuristic and search graph visualization (#384)
## Description Includes: - a new fidelity-aware heuristic (+some changes to the current heuristic mapping system making it compatible with the new approach) - a data logger (logging all search nodes and metadata in the heuristic mapper) - a Python visualization module for visualizing search graphs after mapping - the option to automatically split layers if the search takes too long - iterative bidirectional routing (similar to Qiskit's SabreLayout but using QMAP's routing pass) Currently, the fidelity-aware heuristic mapping is not yet compatible with dynamic initial layouting, lookahead or qubit teleportation. Therefore, I did not yet add an example for fidelity-aware mapping in Mapping.ipynb in the documentation. (I think advertising this feature outside the API reference only makes sense once it is more fleshed out) ## Checklist: <!--- This checklist serves as a reminder of a couple of things that ensure your pull request will be merged swiftly. --> - [x] The pull request only contains commits that are related to it. - [x] I have added appropriate tests and documentation. - [x] I have made sure that all CI jobs on GitHub pass. - [x] The pull request introduces no new warnings and follows the project's style guidelines. --------- Co-authored-by: Lukas Burgholzer <[email protected]>
- Loading branch information
1 parent
07642b8
commit b20ddfa
Showing
33 changed files
with
6,069 additions
and
448 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,4 @@ Library | |
Subarchitectures | ||
Synthesis | ||
SynthesisResults | ||
Visualization |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
Visualization | ||
============= | ||
|
||
.. currentmodule:: mqt.qmap | ||
|
||
All visualization functionality is bundled in the sub-module :mod:`mqt.qmap.visualization`. | ||
|
||
Search graph visualization | ||
########################## | ||
|
||
.. currentmodule:: mqt.qmap.visualization | ||
|
||
The recommended way to visualize search graphs of a mapping process is via a :class:`SearchVisualizer` object, which can be passed to the :func:`mqt.qmap.compile` function to enable data logging during mapping, after which this data can be visualized by calling the method :meth:`SearchVisualizer.visualize_search_graph`. | ||
|
||
.. note:: | ||
:meth:`SearchVisualizer.visualize_search_graph` returns an IPython display object and therefore requires to be executed in a jupyter notebook or jupyter lab environment. | ||
|
||
.. note:: | ||
Automatic layouting of architecture or search nodes requires `Graphviz <https://graphviz.org/>`_ to be installed (except for the layouting method :code:`walker`). If Graphviz is called without it being installed, it will ensue in an error such as: | ||
|
||
:code:`FileNotFoundError: [Errno 2] "sfdp" not found in path.` | ||
|
||
Consequently, the only way to use :meth:`SearchVisualizer.visualize_search_graph` without Graphviz is by passing explicit architecture node positions or hiding the architecture graph by passing :code:`show_layout=None`. | ||
|
||
.. autoclass:: SearchVisualizer | ||
:special-members: __init__ | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// | ||
// This file is part of the MQT QMAP library released under the MIT license. | ||
// See README.md or go to https://github.com/cda-tum/qmap for more information. | ||
// | ||
|
||
#pragma once | ||
|
||
#include "Architecture.hpp" | ||
#include "Mapper.hpp" | ||
#include "MappingResults.hpp" | ||
#include "QuantumComputation.hpp" | ||
|
||
#include <fstream> | ||
#include <string> | ||
|
||
class DataLogger { | ||
public: | ||
DataLogger(std::string path, Architecture& arch, qc::QuantumComputation qc) | ||
: dataLoggingPath(std::move(path)), architecture(&arch), | ||
nqubits(arch.getNqubits()), inputCircuit(std::move(qc)) { | ||
initLog(); | ||
logArchitecture(); | ||
logInputCircuit(inputCircuit); | ||
for (std::size_t i = 0; i < inputCircuit.getNqubits(); ++i) { | ||
qregs.emplace_back("q", "q[" + std::to_string(i) + "]"); | ||
} | ||
for (std::size_t i = 0; i < inputCircuit.getNcbits(); ++i) { | ||
cregs.emplace_back("c", "c[" + std::to_string(i) + "]"); | ||
} | ||
} | ||
|
||
void initLog(); | ||
void clearLog(); | ||
void logArchitecture(); | ||
void logSearchNode(std::size_t layer, std::size_t nodeId, | ||
std::size_t parentId, double costFixed, double costHeur, | ||
double lookaheadPenalty, | ||
const std::array<std::int16_t, MAX_DEVICE_QUBITS>& qubits, | ||
bool validMapping, | ||
const std::vector<std::vector<Exchange>>& swaps, | ||
std::size_t depth); | ||
void logFinalizeLayer( | ||
std::size_t layer, const qc::CompoundOperation& ops, | ||
const std::vector<std::uint16_t>& singleQubitMultiplicity, | ||
const std::map<std::pair<std::uint16_t, std::uint16_t>, | ||
std::pair<std::uint16_t, std::uint16_t>>& | ||
twoQubitMultiplicity, | ||
const std::array<std::int16_t, MAX_DEVICE_QUBITS>& initialLayout, | ||
std::size_t finalNodeId, double finalCostFixed, double finalCostHeur, | ||
double finalLookaheadPenalty, | ||
const std::array<std::int16_t, MAX_DEVICE_QUBITS>& finalLayout, | ||
const std::vector<std::vector<Exchange>>& finalSwaps, | ||
std::size_t finalSearchDepth); | ||
void splitLayer(); | ||
void logMappingResult(MappingResults& result); | ||
void logInputCircuit(qc::QuantumComputation& qc) { | ||
if (deactivated) { | ||
return; | ||
} | ||
qc.dump(dataLoggingPath + "/input.qasm", qc::Format::OpenQASM); | ||
}; | ||
void logOutputCircuit(qc::QuantumComputation& qc) { | ||
if (deactivated) { | ||
return; | ||
} | ||
qc.dump(dataLoggingPath + "/output.qasm", qc::Format::OpenQASM); | ||
} | ||
void close(); | ||
|
||
protected: | ||
std::string dataLoggingPath; | ||
Architecture* architecture; | ||
std::uint16_t nqubits; | ||
qc::QuantumComputation inputCircuit; | ||
qc::RegisterNames qregs{}; | ||
qc::RegisterNames cregs{}; | ||
std::vector<std::ofstream> searchNodesLogFiles; // 1 per layer | ||
bool deactivated = false; | ||
|
||
void openNewLayer(std::size_t layer); | ||
}; |
Oops, something went wrong.