Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
SimpleController.h
Go to the documentation of this file.
1
14
15#pragma once
16
17#ifndef _SIMPLE_CONTROLLER_H_
18#define _SIMPLE_CONTROLLER_H_
19
22#include "../graph/Optimiser.h"
23#include "Controller.h"
24
25namespace Network {
26
41template <typename Time = Types::time_type>
42class SimpleController : public IController<Time> {
43public:
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)
58 return nullptr; // maybe throw an exception?
59
60 // don't destroy the passed one, make a copy
61 std::shared_ptr<Circuits::Circuit<Time>> distCirc =
62 std::static_pointer_cast<Circuits::Circuit<Time>>(circuit->Clone());
63
64 // this is a different optimization than below, that one is for qubits
65 // layout in the network this one simpifies the circuit by merging gates
66 // could be done after the distribution, perhaps, I'll think about it...
67 // might change some things that would break up the netqasm conversion, so
68 // for now it's here
69
70 // also if it merges three cnots into a swap, for example, it shouldn't be
71 // done after 'ConvertForDistribution' because the swap is converted to 3
72 // cnots
73 if (optimize)
74 distCirc->Optimize(optimizeRotationGates);
75
76 // this converts the 3 qubit gates and swap to 2-qubit gates (the swap to 3
77 // cnots)
78 distCirc->ConvertForDistribution();
79
80 // virtual, by default does nothing, but in derived classes it can do
81 // something for example, for netqasm it arranges the measurements in the
82 // proper order for conversion
83 distCirc =
84 this->DoNetworkSpecificConversionsForDistribution(network, distCirc);
85
86 if (optimiser) {
87 // optimise the circuit
88 optimiser->SetNetworkAndCircuit(network, distCirc);
89 optimiser->Optimise();
90 const auto &qubitsMap = optimiser->GetQubitsMap();
91 distCirc = std::dynamic_pointer_cast<Circuits::Circuit<Time>>(
92 distCirc->Remap(qubitsMap, qubitsMap));
93 }
94
95 // now distribute
96
97 // the first thing to do is to adjust the qubits indexes in the circuit
98 // according to the network topology walk over the network hosts and add one
99 // qubit per host for the entangled one (as it's the case for the 'simple
100 // network') and one cbit per host for measuring the entangled qubit for now
101 // they will be added at the end of the registers, to be easier to convert
102 // the circuit for distribution
103
104 return remapper->Remap(network, distCirc);
105 }
106
123 std::shared_ptr<Circuits::Circuit<Time>> SplitCompositeOperations(
124 const std::shared_ptr<INetwork<Time>> &network,
125 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) override {
126 if (!remapper)
127 return nullptr; // maybe throw an exception?
128
129 return remapper->SplitCompositeOperations(network, circuit);
130 }
131
140 size_t GetId() const override { return std::numeric_limits<size_t>::max(); }
141
150 size_t GetNumQubits() const override { return 0; }
151
161 size_t GetNumNetworkEntangledQubits() const override { return 0; }
162
171 size_t GetNumClassicalBits() const override { return 0; }
172
181 bool IsQubitOnHost(size_t qubitId) const override { return false; }
182
191 bool IsClassicalBitOnHost(size_t qubitId) const override { return false; }
192
202 bool IsEntangledQubitOnHost(size_t qubitId) const override { return false; }
203
212 bool AreQubitsOnSameHost(size_t qubitId1, size_t qubitId2) const override {
213 return false;
214 }
215
224 bool AreCbitsOnSameHost(size_t qubitId1, size_t qubitId2) const override {
225 return false;
226 }
227
236 std::vector<size_t> GetQubitsIds() const override { return {}; }
237
248 std::vector<size_t> GetNetworkEntangledQubitsIds() const override {
249 return {};
250 }
251
260 std::vector<size_t> GetClassicalBitsIds() const override { return {}; }
261
272 std::vector<size_t> GetEntangledQubitMeasurementBitIds() const override {
273 return {};
274 }
275
287 const std::shared_ptr<Distribution::IRemapper<Time>> &r) override {
288 remapper = r;
289 }
290
300 std::shared_ptr<Distribution::IRemapper<Time>> GetRemapper() const override {
301 return remapper;
302 }
303
319 bool SendPacketToHost(size_t hostId,
320 const std::vector<uint8_t> &packet) override {
321 return false;
322 }
323
339 bool RecvPacketFromHost(size_t hostId,
340 const std::vector<uint8_t> &packet) override {
341 return false;
342 }
343
352 size_t GetStartQubitId() const override { return 0; }
353
362 size_t GetStartClassicalBitId() const override { return 0; }
363
371 std::shared_ptr<Graphs::IOptimiser<Time>> GetOptimiser() const override {
372 return optimiser;
373 }
374
383 throw std::runtime_error("SimpleController::CreateOptimiser: not "
384 "implemented for this type of network controller");
385 }
386
400 std::shared_ptr<Circuits::Circuit<Time>>
402 const std::shared_ptr<INetwork<Time>> &network,
403 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) override {
404 return circuit;
405 }
406
418 void
419 CreateScheduler(const std::shared_ptr<INetwork<Time>> &network,
420 SchedulerType schType =
422 throw std::runtime_error("SimpleController::CreateScheduler: not "
423 "implemented for this type of network controller");
424 }
425
434 std::shared_ptr<Schedulers::IScheduler<Time>> GetScheduler() const override {
435 return scheduler;
436 }
437
438 bool GetOptimizeRotationGates() const override {
439 return optimizeRotationGates;
440 }
441
442 void SetOptimizeRotationGates(bool val = true) override {
443 optimizeRotationGates = val;
444 }
445
454 void SetOptimizeCircuit(bool o = true) override { optimize = o; }
455
463 bool GetOptimizeCircuit() const override { return optimize; }
464
465protected:
466 std::shared_ptr<Distribution::IRemapper<Time>>
469
470 // the problem with setting a default optimiser here is that everywhere where
471 // amplitudes are checked in tests for some network distributions, the tests
472 // will fail
473 // because the qubits are scrambled by the optimiser, they are rearranged so
474 // the number of distributions is reduced so better set it explicitly only
475 // when tests for results are checked!
476 std::shared_ptr<Graphs::IOptimiser<Time>>
478 // Graphs::Factory<Time>::Create(Graphs::OptimiserType::kMonteCarlo);
479 // /**< The optimiser used to optimise the circuit. */
480
481 std::shared_ptr<Schedulers::IScheduler<Time>>
483
484private:
485 bool optimize = true;
486 bool optimizeRotationGates =
487 true;
489};
490} // namespace Network
491
492#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:100
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 optimiser used to optimise the circuit.
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.
OptimiserType
The type of optimiser.
Definition Optimiser.h:26
SchedulerType
The type of the network scheduler for scheduling execution of multiple circuits.
Definition Controller.h:81