Maestro 0.3.11
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{
27
42template <typename Time = Types::time_type> class SimpleController : public IController<Time>
43{
44 public:
55 std::shared_ptr<Circuits::Circuit<Time>> DistributeCircuit(const std::shared_ptr<INetwork<Time>> &network,
56 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) override
57 {
58 if (!remapper)
59 return nullptr; // maybe throw an exception?
60
61 // don't destroy the passed one, make a copy
62 std::shared_ptr<Circuits::Circuit<Time>> distCirc = 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 = this->DoNetworkSpecificConversionsForDistribution(network, distCirc);
84
85 if (optimiser)
86 {
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>>(distCirc->Remap(qubitsMap, qubitsMap));
92 }
93
94 // now distribute
95
96 // the first thing to do is to adjust the qubits indexes in the circuit
97 // according to the network topology walk over the network hosts and add one
98 // qubit per host for the entangled one (as it's the case for the 'simple
99 // network') and one cbit per host for measuring the entangled qubit for now
100 // they will be added at the end of the registers, to be easier to convert
101 // the circuit for distribution
102
103 return remapper->Remap(network, distCirc);
104 }
105
122 std::shared_ptr<Circuits::Circuit<Time>> SplitCompositeOperations(const std::shared_ptr<INetwork<Time>> &network,
123 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) override
124 {
125 if (!remapper)
126 return nullptr; // maybe throw an exception?
127
128 return remapper->SplitCompositeOperations(network, circuit);
129 }
130
139 size_t GetId() const override
140 {
141 return std::numeric_limits<size_t>::max();
142 }
143
152 size_t GetNumQubits() const override
153 {
154 return 0;
155 }
156
166 size_t GetNumNetworkEntangledQubits() const override
167 {
168 return 0;
169 }
170
179 size_t GetNumClassicalBits() const override
180 {
181 return 0;
182 }
183
192 bool IsQubitOnHost(size_t qubitId) const override
193 {
194 return false;
195 }
196
205 bool IsClassicalBitOnHost(size_t qubitId) const override
206 {
207 return false;
208 }
209
219 bool IsEntangledQubitOnHost(size_t qubitId) const override
220 {
221 return false;
222 }
223
232 bool AreQubitsOnSameHost(size_t qubitId1, size_t qubitId2) const override
233 {
234 return false;
235 }
236
245 bool AreCbitsOnSameHost(size_t qubitId1, size_t qubitId2) const override
246 {
247 return false;
248 }
249
258 std::vector<size_t> GetQubitsIds() const override
259 {
260 return {};
261 }
262
273 std::vector<size_t> GetNetworkEntangledQubitsIds() const override
274 {
275 return {};
276 }
277
286 std::vector<size_t> GetClassicalBitsIds() const override
287 {
288 return {};
289 }
290
301 std::vector<size_t> GetEntangledQubitMeasurementBitIds() const override
302 {
303 return {};
304 }
305
316 void SetRemapper(const std::shared_ptr<Distribution::IRemapper<Time>> &r) override
317 {
318 remapper = r;
319 }
320
330 std::shared_ptr<Distribution::IRemapper<Time>> GetRemapper() const override
331 {
332 return remapper;
333 }
334
350 bool SendPacketToHost(size_t hostId, const std::vector<uint8_t> &packet) override
351 {
352 return false;
353 }
354
370 bool RecvPacketFromHost(size_t hostId, const std::vector<uint8_t> &packet) override
371 {
372 return false;
373 }
374
383 size_t GetStartQubitId() const override
384 {
385 return 0;
386 }
387
396 size_t GetStartClassicalBitId() const override
397 {
398 return 0;
399 }
400
408 std::shared_ptr<Graphs::IOptimiser<Time>> GetOptimiser() const override
409 {
410 return optimiser;
411 }
412
420 void CreateOptimiser(Graphs::OptimiserType type) override
421 {
422 throw std::runtime_error("SimpleController::CreateOptimiser: not "
423 "implemented for this type of network controller");
424 }
425
439 std::shared_ptr<Circuits::Circuit<Time>> DoNetworkSpecificConversionsForDistribution(const std::shared_ptr<INetwork<Time>> &network,
440 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) override
441 {
442 return circuit;
443 }
444
456 void CreateScheduler(const std::shared_ptr<INetwork<Time>> &network, SchedulerType schType = SchedulerType::kNoEntanglementQubitsParallel) override
457 {
458 throw std::runtime_error("SimpleController::CreateScheduler: not "
459 "implemented for this type of network controller");
460 }
461
470 std::shared_ptr<Schedulers::IScheduler<Time>> GetScheduler() const override
471 {
472 return scheduler;
473 }
474
475 bool GetOptimizeRotationGates() const override
476 {
477 return optimizeRotationGates;
478 }
479
480 void SetOptimizeRotationGates(bool val = true) override
481 {
482 optimizeRotationGates = val;
483 }
484
493 void SetOptimizeCircuit(bool o = true) override
494 {
495 optimize = o;
496 }
497
505 bool GetOptimizeCircuit() const override
506 {
507 return optimize;
508 }
509
510 protected:
511 std::shared_ptr<Distribution::IRemapper<Time>> remapper;
513
514 // the problem with setting a default optimiser here is that everywhere where
515 // amplitudes are checked in tests for some network distributions, the tests
516 // will fail
517 // because the qubits are scrambled by the optimiser, they are rearranged so
518 // the number of distributions is reduced so better set it explicitly only
519 // when tests for results are checked!
520 std::shared_ptr<Graphs::IOptimiser<Time>> optimiser; // =
521 // Graphs::Factory<Time>::Create(Graphs::OptimiserType::kMonteCarlo);
522 // /**< The optimiser used to optimise the circuit. */
523
524 std::shared_ptr<Schedulers::IScheduler<Time>> scheduler;
525
526 private:
527 bool optimize = true;
528 bool optimizeRotationGates = true;
530};
531} // namespace Network
532
533#endif // !_SIMPLE_CONTROLLER_H_
Circuit class for holding the sequence of operations.
Definition Circuit.h:51
Remapper abstract class.
Definition Remapper.h:49
The controller host interface.
Definition Controller.h:108
The network interface.
Definition Network.h:60
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.
SchedulerType
The type of the network scheduler for scheduling execution of multiple circuits.
Definition Controller.h:89