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

new 'gatecost' heuristic implemented #105

Merged
merged 30 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
db0e890
commits that include the new benchmark tests of the tcad version---si…
AlexPloier Jul 25, 2022
56d3e5d
added the profile with optimization level 2, and changed the path to …
AlexPloier Jul 25, 2022
c4eb70a
Merge branch 'main' into task_based_simulator
AlexPloier Jul 25, 2022
4aa6034
updated header-file
AlexPloier Jul 25, 2022
f3a0053
:bug: resolving some bugs
AlexPloier Jul 25, 2022
b3049c3
:bug: resolving some bugs with the tests
AlexPloier Jul 25, 2022
6edc2a8
:bug: resolving some bugs with the tests
AlexPloier Jul 25, 2022
38f52cc
:bug: resolving some bugs with c++ tests
AlexPloier Jul 25, 2022
99c59ca
:art: added tests for the gatecost heuristic in c++
AlexPloier Jul 26, 2022
b8d9d0f
:art: added tests for the gatecost heuristic in c++ to cover more lin…
AlexPloier Jul 26, 2022
68d4202
:art: codestyle
AlexPloier Jul 26, 2022
d6db701
:art: added python tests for code coverage
AlexPloier Jul 26, 2022
3cd8af9
:art: added c++ tests for code coverage
AlexPloier Jul 27, 2022
2ed6e02
:art: added c++ tests for code coverage
AlexPloier Jul 27, 2022
f22cbf6
:art: added c++ tests for code coverage
AlexPloier Jul 27, 2022
cedf23c
:art: changes according to PR
AlexPloier Aug 30, 2022
9d313b5
Fixed compilation error and tests
hillmich Jan 30, 2023
ba6db95
Merge branch 'main' into task_based_simulator
hillmich Jan 30, 2023
285040f
Format
hillmich Jan 30, 2023
d24dd22
small fix for python
hillmich Jan 30, 2023
a0efe09
Another small fix
hillmich Jan 30, 2023
53d4664
Fixed string and removed unused variable
hillmich Jan 31, 2023
782922b
Fixed python errors
hillmich Jan 31, 2023
2918391
Deduplicated code
hillmich Jan 31, 2023
48f849d
Simplified tests
hillmich Jan 31, 2023
4a21cc0
Refactored Bindings and tests a bit
hillmich Jan 31, 2023
09a661d
Removed unnecessary import
hillmich Jan 31, 2023
c2f90d7
Moved code out of loop
hillmich Jan 31, 2023
e27339c
Clang Format xD
hillmich Jan 31, 2023
7f83797
Merge branch 'main' into task_based_simulator
hillmich Feb 1, 2023
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
38 changes: 25 additions & 13 deletions include/PathSimulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,25 @@ class PathSimulator: public CircuitSimulator<Config> {
PairwiseRecursiveGrouping,
BracketGrouping,
Alternating,
Cotengra
Cotengra,
GateCost
};

// mode to use
Mode mode;

// settings for the bracket size
std::size_t bracketSize;
// settings for the alternating mode
std::size_t alternatingStart;

// settings for the alternating and gatecost mode, which need a starting point
std::size_t startingPoint;
// settings for the gate costs mode
std::list<std::size_t> gateCost;
burgholzer marked this conversation as resolved.
Show resolved Hide resolved
// random seed
std::size_t seed;

//Add new variables here
explicit Configuration(const Mode mode_ = Mode::Sequential, const std::size_t bracketSize_ = 2, const std::size_t alternatingStart_ = 0, const std::size_t seed_ = 0):
mode(mode_), bracketSize(bracketSize_), alternatingStart(alternatingStart_), seed(seed_){};
explicit Configuration(const Mode mode_ = Mode::Sequential, const std::size_t bracketSize_ = 2, const std::size_t startingPoint_ = 0, std::list<std::size_t> gateCost_ = {}, const std::size_t seed_ = 0):
mode(mode_), bracketSize(bracketSize_), startingPoint(startingPoint_), gateCost(std::move(gateCost_)), seed(seed_){};

static Mode modeFromString(const std::string& mode) {
if (mode == "sequential" || mode == "0") {
Expand All @@ -80,6 +82,8 @@ class PathSimulator: public CircuitSimulator<Config> {
return Mode::Alternating;
} else if (mode == "cotengra" || mode == "4") {
return Mode::Cotengra;
} else if (mode == "gate_cost" || mode == "5") {
return Mode::GateCost;
} else {
throw std::invalid_argument("Invalid simulation path mode: " + mode);
}
Expand All @@ -97,6 +101,8 @@ class PathSimulator: public CircuitSimulator<Config> {
return "alternating";
case Mode::Cotengra:
return "cotengra";
case Mode::GateCost:
return "gate_cost";
default:
throw std::invalid_argument("Invalid simulation path mode");
}
Expand All @@ -108,7 +114,10 @@ class PathSimulator: public CircuitSimulator<Config> {
if (mode == Mode::BracketGrouping) {
conf["bracket_size"] = bracketSize;
} else if (mode == Mode::Alternating) {
conf["alternating_start"] = alternatingStart;
conf["starting_point"] = startingPoint;
} else if (mode == Mode::GateCost) {
conf["starting_point"] = startingPoint;
conf["gate_cost"] = gateCost;
}
if (seed != 0) {
conf["seed"] = seed;
Expand All @@ -132,8 +141,8 @@ class PathSimulator: public CircuitSimulator<Config> {
qc::CircuitOptimizer::removeFinalMeasurements(*(CircuitSimulator<Config>::qc));

// case distinction for the starting point of the alternating strategy
if (configuration.alternatingStart == 0) {
configuration.alternatingStart = (CircuitSimulator<Config>::qc->getNops()) / 2;
if (configuration.startingPoint == 0) {
configuration.startingPoint = (CircuitSimulator<Config>::qc->getNops()) / 2;
}

// Add new strategies here
Expand All @@ -147,17 +156,19 @@ class PathSimulator: public CircuitSimulator<Config> {
case Configuration::Mode::Cotengra:
break;
case Configuration::Mode::Alternating:
generateAlternatingSimulationPath(configuration.alternatingStart);
generateAlternatingSimulationPath(configuration.startingPoint);
break;
case Configuration::Mode::GateCost:
generateGatecostSimulationPath(configuration.startingPoint, configuration.gateCost);
break;
case Configuration::Mode::Sequential:
default:
generateSequentialSimulationPath();
break;
}
}

PathSimulator(std::unique_ptr<qc::QuantumComputation>&& qc_, typename Configuration::Mode mode, std::size_t bracketSize, std::size_t alternatingStart, std::size_t seed_):
PathSimulator<Config>(std::move(qc_), Configuration{mode, bracketSize, alternatingStart, seed_}) {}
PathSimulator(std::unique_ptr<qc::QuantumComputation>&& qc_, typename Configuration::Mode mode_, std::size_t bracketSize_, std::size_t startingPoint_, std::list<std::size_t> gateCost_, std::size_t seed_):
PathSimulator(std::move(qc_), Configuration{mode_, bracketSize_, startingPoint_, std::move(gateCost_), seed_}) {}

std::map<std::string, std::size_t> Simulate(std::size_t shots) override;

Expand All @@ -176,6 +187,7 @@ class PathSimulator: public CircuitSimulator<Config> {
void generatePairwiseRecursiveGroupingSimulationPath();
void generateBracketSimulationPath(std::size_t bracketSize);
void generateAlternatingSimulationPath(std::size_t startingPoint);
void generateGatecostSimulationPath(std::size_t startingPoint, std::list<std::size_t>& gateCosts);

private:
std::unordered_map<std::size_t, tf::Task> tasks{};
Expand Down
5 changes: 3 additions & 2 deletions mqt/ddsim/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from mqt.ddsim.provider import DDSIMProvider
from mqt.ddsim.pyddsim import CircuitSimulator, HybridCircuitSimulator, PathCircuitSimulator, UnitarySimulator, HybridMode, \
PathSimulatorMode, PathSimulatorConfiguration, ConstructionMode, get_matrix, dump_tensor_network, __version__
from mqt.ddsim.pyddsim import CircuitSimulator, HybridCircuitSimulator, PathCircuitSimulator, UnitarySimulator, \
HybridMode, PathSimulatorMode, PathSimulatorConfiguration, ConstructionMode, get_matrix, dump_tensor_network, \
__version__
11 changes: 7 additions & 4 deletions mqt/ddsim/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ PYBIND11_MODULE(pyddsim, m) {
.value("cotengra", PathSimulator<>::Configuration::Mode::Cotengra)
.value("bracket", PathSimulator<>::Configuration::Mode::BracketGrouping)
.value("alternating", PathSimulator<>::Configuration::Mode::Alternating)
.value("gate_cost", PathSimulator<>::Configuration::Mode::GateCost)
.export_values()
.def(py::init([](const std::string& str) -> PathSimulator<>::Configuration::Mode { return PathSimulator<>::Configuration::modeFromString(str); }));

Expand All @@ -169,8 +170,10 @@ PYBIND11_MODULE(pyddsim, m) {
R"pbdoc(Setting the mode used for determining a simulation path)pbdoc")
.def_readwrite("bracket_size", &PathSimulator<>::Configuration::bracketSize,
R"pbdoc(Size of the brackets one wants to combine)pbdoc")
.def_readwrite("alternating_start", &PathSimulator<>::Configuration::alternatingStart,
R"pbdoc(Start of the alternating strategy)pbdoc")
.def_readwrite("starting_point", &PathSimulator<>::Configuration::startingPoint,
R"pbdoc(Start of the alternating or gate_cost strategy)pbdoc")
.def_readwrite("gate_cost", &PathSimulator<>::Configuration::gateCost,
R"pbdoc(A list that contains the number of gates which are considered in each step)pbdoc")
.def_readwrite("seed", &PathSimulator<>::Configuration::seed,
R"pbdoc(Seed for the simulator)pbdoc")
.def("json", &PathSimulator<>::Configuration::json)
Expand All @@ -179,8 +182,8 @@ PYBIND11_MODULE(pyddsim, m) {
py::class_<PathSimulator<>>(m, "PathCircuitSimulator")
.def(py::init<>(&create_simulator_without_seed<PathSimulator<>, PathSimulator<>::Configuration&>),
"circ"_a, "config"_a = PathSimulator<>::Configuration())
.def(py::init<>(&create_simulator_without_seed<PathSimulator<>, PathSimulator<>::Configuration::Mode&, const std::size_t&, const std::size_t&, const std::size_t&>),
"circ"_a, "mode"_a = PathSimulator<>::Configuration::Mode::Sequential, "bracket_size"_a = 2, "alternating_start"_a = 0, "seed"_a = 0)
.def(py::init<>(&create_simulator_without_seed<PathSimulator<>, PathSimulator<>::Configuration::Mode&, const std::size_t&, const std::size_t&, const std::list<std::size_t>&, const std::size_t&>),
"circ"_a, "mode"_a = PathSimulator<>::Configuration::Mode::Sequential, "bracket_size"_a = 2, "starting_point"_a = 0, "gate_cost"_a = std::list<std::size_t>{}, "seed"_a = 0)
.def("set_simulation_path", py::overload_cast<const PathSimulator<>::SimulationPath::Components&, bool>(&PathSimulator<>::setSimulationPath))
.def("get_number_of_qubits", &CircuitSimulator<>::getNumberOfQubits)
.def("get_name", &CircuitSimulator<>::getName)
Expand Down
5 changes: 5 additions & 0 deletions mqt/ddsim/pathqasmsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ def _default_options(cls) -> Options:
mode=None,
bracket_size=None,
alternating_start=None,
gate_cost=None,
seed=None,
cotengra_max_time=60,
cotengra_max_repeats=1024,
Expand Down Expand Up @@ -217,6 +218,10 @@ def run_experiment(self, qobj_experiment: QasmQobjExperiment, **options):
if alternating_start is not None:
pathsim_configuration.alternating_start = alternating_start

gate_cost = options.get('gate_cost')
if gate_cost is not None:
pathsim_configuration.gate_cost = gate_cost

seed = options.get('seed')
if seed is not None:
pathsim_configuration.seed = seed
Expand Down
1 change: 0 additions & 1 deletion src/CircuitSimulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ std::map<std::string, std::size_t> CircuitSimulator<Config>::Simulate(std::size_
}
m_counter[result_string]++;
}

burgholzer marked this conversation as resolved.
Show resolved Hide resolved
return m_counter;
}

Expand Down
60 changes: 60 additions & 0 deletions src/PathSimulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,66 @@ void PathSimulator<Config>::generateAlternatingSimulationPath(std::size_t starti
setSimulationPath(components, true);
}

template<class Config>
void PathSimulator<Config>::generateGatecostSimulationPath(std::size_t startingPoint, std::list<std::size_t>& gateCosts) {
typename SimulationPath::Components components{};
components.reserve(CircuitSimulator<Config>::qc->getNops());
std::size_t startElem = startingPoint;
components.emplace_back(startElem, startElem + 1);
std::size_t leftID = startElem - 1;
const std::size_t leftEnd = 0;
std::size_t rightID = startElem + 2;
const std::size_t rightEnd = CircuitSimulator<Config>::qc->getNops() + 1;
std::size_t nextID = rightEnd;
std::size_t runID = 0;
while (leftID != leftEnd && rightID != rightEnd) {
if (runID == 0) {
for (auto i = 0U; i < gateCosts.front() - 1; ++i) {
components.emplace_back(nextID, rightID);
++nextID;
++rightID;
}
gateCosts.pop_front();
++runID;
} else {
components.emplace_back(leftID, nextID);
++nextID;
--leftID;
for (auto i = 0U; i < gateCosts.front(); ++i) {
components.emplace_back(nextID, rightID);
++nextID;
++rightID;
if (rightID == rightEnd) {
break;
}
}
gateCosts.pop_front();
++runID;
if (rightID == rightEnd) {
break;
}
}
}

//Finish the left-hand side
while (leftID != leftEnd) {
components.emplace_back(leftID, nextID);
++nextID;
--leftID;
}

//Finish the right-hand side
while (rightID != rightEnd) {
components.emplace_back(nextID, rightID);
++nextID;
++rightID;
}

//Add the remaining matrix-vector multiplication
components.emplace_back(0, nextID);
setSimulationPath(components, true);
}

template<class Config>
void PathSimulator<Config>::constructTaskGraph() {
const auto& path = simulationPath.components;
Expand Down
Loading