Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
SimpleController.h
Go to the documentation of this file.
1
15#pragma once
16
17#ifndef _SIMPLE_CONTROLLER_H_
18#define _SIMPLE_CONTROLLER_H_
19
20#include "../Distribution/Remapper.h"
21#include "../Scheduler/Scheduler.h"
22#include "../graph/Optimiser.h"
23#include "Controller.h"
24
25namespace Network {
26
41template <typename Time = Types::time_type>
42class SimpleController : public IController<Time> {
43 public:
54 std::shared_ptr<Circuits::Circuit<Time>> DistributeCircuit(
55 const std::shared_ptr<INetwork<Time>> &network,
56 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) override {
57 if (!remapper) return nullptr; // maybe throw an exception?
58
59 // don't destroy the passed one, make a copy
60 std::shared_ptr<Circuits::Circuit<Time>> distCirc =
61 std::static_pointer_cast<Circuits::Circuit<Time>>(circuit->Clone());
62
63 // this is a different optimization than below, that one is for qubits
64 // layout in the network this one simpifies the circuit by merging gates
65 // could be done after the distribution, perhaps, I'll think about it...
66 // might change some things that would break up the netqasm conversion, so
67 // for now it's here
68
69 // also if it merges three cnots into a swap, for example, it shouldn't be
70 // done after 'ConvertForDistribution' because the swap is converted to 3
71 // cnots
72 if (optimize) distCirc->Optimize(optimizeRotationGates);
73
74 // this converts the 3 qubit gates and swap to 2-qubit gates (the swap to 3
75 // cnots)
76 distCirc->ConvertForDistribution();
77
78 // virtual, by default does nothing, but in derived classes it can do
79 // something for example, for netqasm it arranges the measurements in the
80 // proper order for conversion
81 distCirc =
82 this->DoNetworkSpecificConversionsForDistribution(network, distCirc);
83
84 if (optimiser) {
85 // optimise the circuit
86 optimiser->SetNetworkAndCircuit(network, distCirc);
87 optimiser->Optimise();
88 const auto &qubitsMap = optimiser->GetQubitsMap();
89 distCirc = std::dynamic_pointer_cast<Circuits::Circuit<Time>>(
90 distCirc->Remap(qubitsMap, qubitsMap));
91 }
92
93 // now distribute
94
95 // the first thing to do is to adjust the qubits indexes in the circuit
96 // according to the network topology walk over the network hosts and add one
97 // qubit per host for the entangled one (as it's the case for the 'simple
98 // network') and one cbit per host for measuring the entangled qubit for now
99 // they will be added at the end of the registers, to be easier to convert
100 // the circuit for distribution
101
102 return remapper->Remap(network, distCirc);
103 }
104
121 std::shared_ptr<Circuits::Circuit<Time>> SplitCompositeOperations(
122 const std::shared_ptr<INetwork<Time>> &network,
123 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) override {
124 if (!remapper) return nullptr; // maybe throw an exception?
125
126 return remapper->SplitCompositeOperations(network, circuit);
127 }
128
137 size_t GetId() const override { return std::numeric_limits<size_t>::max(); }
138
147 size_t GetNumQubits() const override { return 0; }
148
158 size_t GetNumNetworkEntangledQubits() const override { return 0; }
159
168 size_t GetNumClassicalBits() const override { return 0; }
169
178 bool IsQubitOnHost(size_t qubitId) const override { return false; }
179
188 bool IsClassicalBitOnHost(size_t qubitId) const override { return false; }
189
199 bool IsEntangledQubitOnHost(size_t qubitId) const override { return false; }
200
209 bool AreQubitsOnSameHost(size_t qubitId1, size_t qubitId2) const override {
210 return false;
211 }
212
221 bool AreCbitsOnSameHost(size_t qubitId1, size_t qubitId2) const override {
222 return false;
223 }
224
233 std::vector<size_t> GetQubitsIds() const override { return {}; }
234
245 std::vector<size_t> GetNetworkEntangledQubitsIds() const override {
246 return {};
247 }
248
257 std::vector<size_t> GetClassicalBitsIds() const override { return {}; }
258
269 std::vector<size_t> GetEntangledQubitMeasurementBitIds() const override {
270 return {};
271 }
272
284 const std::shared_ptr<Distribution::IRemapper<Time>> &r) override {
285 remapper = r;
286 }
287
297 std::shared_ptr<Distribution::IRemapper<Time>> GetRemapper() const override {
298 return remapper;
299 }
300
316 bool SendPacketToHost(size_t hostId,
317 const std::vector<uint8_t> &packet) override {
318 return false;
319 }
320
336 bool RecvPacketFromHost(size_t hostId,
337 const std::vector<uint8_t> &packet) override {
338 return false;
339 }
340
349 size_t GetStartQubitId() const override { return 0; }
350
359 size_t GetStartClassicalBitId() const override { return 0; }
360
368 std::shared_ptr<Graphs::IOptimiser<Time>> GetOptimiser() const override {
369 return optimiser;
370 }
371
379 void CreateOptimiser(Graphs::OptimiserType type) override {
380 throw std::runtime_error(
381 "SimpleController::CreateOptimiser: not "
382 "implemented for this type of network controller");
383 }
384
398 std::shared_ptr<Circuits::Circuit<Time>>
400 const std::shared_ptr<INetwork<Time>> &network,
401 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) override {
402 return circuit;
403 }
404
417 const std::shared_ptr<INetwork<Time>> &network,
418 SchedulerType schType =
420 throw std::runtime_error(
421 "SimpleController::CreateScheduler: not "
422 "implemented for this type of network controller");
423 }
424
433 std::shared_ptr<Schedulers::IScheduler<Time>> GetScheduler() const override {
434 return scheduler;
435 }
436
437 bool GetOptimizeRotationGates() const override {
438 return optimizeRotationGates;
439 }
440
441 void SetOptimizeRotationGates(bool val = true) override {
442 optimizeRotationGates = val;
443 }
444
453 void SetOptimizeCircuit(bool o = true) override { optimize = o; }
454
462 bool GetOptimizeCircuit() const override { return optimize; }
463
464 protected:
465 std::shared_ptr<Distribution::IRemapper<Time>>
469 // the problem with setting a default optimiser here is that everywhere where
470 // amplitudes are checked in tests for some network distributions, the tests
471 // will fail
472 // because the qubits are scrambled by the optimiser, they are rearranged so
473 // the number of distributions is reduced so better set it explicitly only
474 // when tests for results are checked!
475 std::shared_ptr<Graphs::IOptimiser<Time>>
477 // Graphs::Factory<Time>::Create(Graphs::OptimiserType::kMonteCarlo);
478 // /**< The optimiser used to optimise the circuit. */
479
480 std::shared_ptr<Schedulers::IScheduler<Time>>
483 private:
484 bool optimize = true;
485 bool optimizeRotationGates =
486 true;
488};
489} // namespace Network
490
491#endif // !_SIMPLE_CONTROLLER_H_
Circuit class for holding the sequence of operations.
Definition Circuit.h:45
Remapper abstract class.
Definition Remapper.h:47
The controller host interface.
Definition Controller.h:105
The network interface.
Definition Network.h:56
The simple controller host implementation.
bool IsQubitOnHost(size_t qubitId) const override
Check if a qubit is in the host.
std::vector< size_t > GetEntangledQubitMeasurementBitIds() const override
Get the ids of the classical bits used for measurement of the qubits used for entanglement between ho...
std::shared_ptr< Circuits::Circuit< Time > > SplitCompositeOperations(const std::shared_ptr< INetwork< Time > > &network, const std::shared_ptr< Circuits::Circuit< Time > > &circuit) override
Splits the composite operations from the circuit.
void CreateOptimiser(Graphs::OptimiserType type) override
Creates an optimiser.
size_t GetNumClassicalBits() const override
Get the number of classical bits.
std::shared_ptr< Circuits::Circuit< Time > > DistributeCircuit(const std::shared_ptr< INetwork< Time > > &network, const std::shared_ptr< Circuits::Circuit< Time > > &circuit) override
Distributes the circuit on the hosts.
bool RecvPacketFromHost(size_t hostId, const std::vector< uint8_t > &packet) override
Receive a packet from a host.
void SetRemapper(const std::shared_ptr< Distribution::IRemapper< Time > > &r) override
Changes the remapper that is used for remapping a circuit to a distributed one.
void SetOptimizeRotationGates(bool val=true) override
size_t GetStartQubitId() const override
Get the id of the first qubit assigned to the host.
void SetOptimizeCircuit(bool o=true) override
Set circuit optimization.
std::shared_ptr< Schedulers::IScheduler< Time > > GetScheduler() const override
Get the scheduler for the network.
std::shared_ptr< Graphs::IOptimiser< Time > > optimiser
std::shared_ptr< Graphs::IOptimiser< Time > > GetOptimiser() const override
Returns the optimiser used.
std::shared_ptr< Distribution::IRemapper< Time > > remapper
The remapper used to remap a circuit to a distributed one.
bool IsEntangledQubitOnHost(size_t qubitId) const override
Check if a qubit used for entanglement between hosts is in the host.
bool GetOptimizeCircuit() const override
Get circuit optimization.
std::shared_ptr< Distribution::IRemapper< Time > > GetRemapper() const override
Gets the remapper that is used for remapping a circuit to a distributed one.
std::vector< size_t > GetQubitsIds() const override
Get the ids of the qubits in the host.
bool IsClassicalBitOnHost(size_t qubitId) const override
Check if a classical bit is in the host.
std::vector< size_t > GetNetworkEntangledQubitsIds() const override
Get the ids of the qubits used for entanglement between hosts in the host.
bool AreCbitsOnSameHost(size_t qubitId1, size_t qubitId2) const override
Check if two classical bits are in the same host.
std::shared_ptr< Circuits::Circuit< Time > > DoNetworkSpecificConversionsForDistribution(const std::shared_ptr< INetwork< Time > > &network, const std::shared_ptr< Circuits::Circuit< Time > > &circuit) override
Convert the circuit for distribution for specific networks.
size_t GetNumQubits() const override
Get the number of qubits.
bool AreQubitsOnSameHost(size_t qubitId1, size_t qubitId2) const override
Check if two qubits are in the same host.
size_t GetId() const override
Get the host id.
size_t GetNumNetworkEntangledQubits() const override
Get the number of network entangled qubits.
std::shared_ptr< Schedulers::IScheduler< Time > > scheduler
The scheduler used to schedule the circuits.
bool GetOptimizeRotationGates() const override
std::vector< size_t > GetClassicalBitsIds() const override
Get the ids of the classical bits in the host.
void CreateScheduler(const std::shared_ptr< INetwork< Time > > &network, SchedulerType schType=SchedulerType::kNoEntanglementQubitsParallel) override
Create the scheduler for the network.
size_t GetStartClassicalBitId() const override
Get the id of the first classical bit assigned to the host.
bool SendPacketToHost(size_t hostId, const std::vector< uint8_t > &packet) override
Send a packet to a host.
SchedulerType
The type of the network scheduler for scheduling execution of multiple circuits.
Definition Controller.h:85