15#ifndef _SIMPLE_NETWORK_H_
16#define _SIMPLE_NETWORK_H_
18#include "QubitRegister.h"
41 class Controller = SimpleController<Time>>
58 const std::vector<size_t> &cbits = {}) {
73 const std::vector<size_t> &cbits) {
74 size_t qubitsOffset = 0;
75 size_t cbitsOffset = 0;
77 for (
size_t i = 0; i < qubits.size(); ++i) {
78 const size_t numQubits = qubits[i];
79 const size_t numBits = (i < cbits.size() ? cbits[i] : 0);
81 i, qubitsOffset, numQubits, cbitsOffset, numBits));
82 qubitsOffset += numQubits;
83 cbitsOffset += numBits;
86 for (
size_t i = 0; i <
hosts.size(); ++i) {
87 std::static_pointer_cast<SimpleHost<Time>>(
hosts[i])->SetEntangledQubitId(
89 std::static_pointer_cast<SimpleHost<Time>>(
hosts[i])
90 ->SetEntangledQubitMeasurementBit(cbitsOffset);
110 const auto recreate = recreateIfNeeded;
114 size_t numQubits = 2;
118 numQubits =
simulator->GetNumberOfQubits();
121 recreateIfNeeded =
false;
125 recreateIfNeeded = recreate;
129 const auto &first = *res.begin();
136 method !=
simulator->GetSimulationType() ||
137 simulator->GetNumberOfQubits() != numQubits))))
154 size_t hostId)
override {
155 const auto recreate = recreateIfNeeded;
159 size_t numQubits = 2;
163 numQubits =
simulator->GetNumberOfQubits();
166 recreateIfNeeded =
false;
170 recreateIfNeeded = recreate;
174 const auto &first = *res.begin();
181 method !=
simulator->GetSimulationType() ||
182 simulator->GetNumberOfQubits() != numQubits))))
203 const std::vector<std::string> &paulis)
override {
204 const auto recreate = recreateIfNeeded;
208 size_t numQubits = 2;
212 numQubits =
simulator->GetNumberOfQubits();
215 recreateIfNeeded =
false;
217 pauliStrings = &paulis;
219 pauliStrings =
nullptr;
221 recreateIfNeeded = recreate;
225 const auto &first = *res.begin();
229 std::vector<double> expectations(paulis.size());
232 const size_t numOps =
simulator->GetNumberOfQubits();
237 const auto &qubitsMap = optimiser->GetQubitsMap();
239 for (
size_t i = 0; i < paulis.size(); ++i) {
240 std::string translated(numOps,
'I');
242 for (
size_t j = 0; j < paulis[i].size(); ++j) {
243 const auto pos = qubitsMap.find(j);
244 if (pos != qubitsMap.end())
245 translated[pos->second] = paulis[i][j];
247 translated[j] = paulis[i][j];
250 expectations[i] =
simulator->ExpectationValue(translated);
253 for (
size_t i = 0; i < paulis.size(); ++i)
254 expectations[i] =
simulator->ExpectationValue(paulis[i]);
259 method !=
simulator->GetSimulationType() ||
260 simulator->GetNumberOfQubits() != numQubits))
283 const std::vector<std::string> &paulis) {
284 const auto recreate = recreateIfNeeded;
288 size_t numQubits = 2;
292 numQubits =
simulator->GetNumberOfQubits();
295 recreateIfNeeded =
false;
296 pauliStrings = &paulis;
298 pauliStrings =
nullptr;
300 recreateIfNeeded = recreate;
304 const auto &first = *res.begin();
312 const size_t offsetBase = qubitsMapOnHost.size();
314 std::vector<double> expectations(paulis.size(), 1.);
317 const size_t numOps =
simulator->GetNumberOfQubits();
320 for (
size_t i = 0; i < paulis.size(); ++i) {
321 std::string translated(std::max(numOps, paulis[i].size()),
'I');
323 size_t offset = offsetBase;
325 for (
size_t j = 0; j < paulis[i].size(); ++j) {
326 auto pos = qubitsMapOnHost.find(j);
327 if (pos != qubitsMapOnHost.end())
328 translated[pos->second] = paulis[i][j];
330 translated[offset] = paulis[i][j];
337 expectations[i] =
simulator->ExpectationValue(translated);
342 method !=
simulator->GetSimulationType() ||
343 simulator->GetNumberOfQubits() != numQubits))
364 size_t shots = 1000)
override {
371 for (
auto q :
distCirc->AffectedQubits()) {
374 <<
"This is a distributed circuit, using entanglement or cutting"
385 if (
distCirc->HasOpsAfterMeasurements() &&
391 distCirc->MoveMeasurementsAndResets();
393 auto method =
simulator->GetSimulationType();
395 const auto saveSimType = simType;
396 const auto saveMethod = method;
402 && simType != Simulators::SimulatorType::kGpuSim
420 simulator->GetConfiguration(
"matrix_product_state_max_bond_dimension");
422 "matrix_product_state_truncation_threshold");
432 std::vector<bool> executed;
435 simType, method, executed);
443 if (simType == Simulators::SimulatorType::kGpuSim)
447 !
distCirc->HasOpsAfterMeasurements())
450 nrThreads = std::min(nrThreads, std::max<size_t>(shots, 1ULL));
452 std::mutex resultsMutex;
469 const size_t cntPerThread = std::max<size_t>(shots / nrThreads, 1ULL);
471 threadsPool.Resize(nrThreads);
472 threadsPool.SetFinishLimit(shots);
475 const size_t curCnt = std::min(cntPerThread, shots);
479 auto job = std::make_shared<ExecuteJob<Time>>(
480 dcirc, res, curCnt, nrQubits, nrQubits, nrCbitsResults, simType,
481 method, resultsMutex);
489 job->optSim = optSim->Clone();
490 job->executedGates = executed;
493 threadsPool.AddRunJob(std::move(job));
496 threadsPool.WaitForFinish();
499 const size_t curCnt = shots;
501 auto job = std::make_shared<ExecuteJob<Time>>(
502 dcirc, res, curCnt, nrQubits, nrQubits, nrCbitsResults, simType,
503 method, resultsMutex);
511 optSim->SetMultithreading(
true);
512 job->optSim = optSim;
513 job->executedGates = executed;
515 if (
simulator && method == saveMethod && simType == saveSimType) {
517 job->optSim = optSim;
523 if (!recreateIfNeeded)
527 if (recreateIfNeeded)
552 size_t hostId,
size_t shots = 1000)
override {
559 std::shared_ptr<Circuits::Circuit<Time>> optCircuit;
562 std::static_pointer_cast<Circuits::Circuit<Time>>(circuit->Clone());
563 optCircuit->Optimize();
566 GetController()->GetOptimizeCircuit() ? optCircuit : circuit, hostId,
567 nrQubits, nrCbits,
true);
577 simulator->GetConfiguration(
"matrix_product_state_max_bond_dimension");
579 "matrix_product_state_truncation_threshold");
582 if (
distCirc->HasOpsAfterMeasurements() &&
588 distCirc->MoveMeasurementsAndResets();
590 auto method =
simulator->GetSimulationType();
591 const auto saveSimType = simType;
592 const auto saveMethod = method;
598 && simType != Simulators::SimulatorType::kGpuSim
619 std::vector<bool> executed;
621 nrCbits, simType, method, executed);
629 if (simType == Simulators::SimulatorType::kGpuSim)
634 !
distCirc->HasOpsAfterMeasurements())
637 nrThreads = std::min(nrThreads, std::max<size_t>(shots, 1ULL));
642 std::mutex resultsMutex;
650 const size_t cntPerThread = std::max<size_t>(shots / nrThreads, 1ULL);
652 threadsPool.Resize(nrThreads);
653 threadsPool.SetFinishLimit(shots);
656 const size_t curCnt = std::min(cntPerThread, shots);
659 auto job = std::make_shared<ExecuteJob<Time>>(
660 dcirc, res, curCnt, nrQubits, nrCbits, nrCbits, simType, method,
669 job->optSim = optSim->Clone();
670 job->executedGates = executed;
673 threadsPool.AddRunJob(std::move(job));
676 threadsPool.WaitForFinish();
679 const size_t curCnt = shots;
681 auto job = std::make_shared<ExecuteJob<Time>>(
682 dcirc, res, curCnt, nrQubits, nrCbits, nrCbits, simType, method,
691 optSim->SetMultithreading(
true);
692 job->optSim = optSim;
693 job->executedGates = executed;
697 if (!recreateIfNeeded)
701 if (recreateIfNeeded)
704 if (!reverseQubitsMap.empty())
723 size_t distgates = 0;
725 for (
const auto &op : circuit->GetOperations())
784 size_t nrQubits = 0)
override {
794 simulator->Configure(
"matrix_product_state_max_bond_dimension",
797 simulator->Configure(
"matrix_product_state_truncation_threshold",
818 void Configure(
const char *key,
const char *value)
override {
822 if (std::string(
"matrix_product_state_max_bond_dimension") == key)
824 else if (std::string(
"matrix_product_state_truncation_threshold") == key)
826 else if (std::string(
"mps_sample_measure_algorithm") == key)
828 else if (std::string(
"max_simulators") == key)
843 std::shared_ptr<Simulators::ISimulator>
GetSimulator()
const override {
885 std::shared_ptr<Schedulers::IScheduler<Time>>
GetScheduler()
const override {
901 const std::shared_ptr<IHost<Time>>
GetHost(
size_t hostId)
const override {
902 if (hostId >=
hosts.size())
905 return hosts[hostId];
940 for (
const auto &host :
hosts)
941 res += host->GetNumQubits();
956 if (hostId >=
hosts.size())
959 return hosts[hostId]->GetNumQubits();
973 for (
const auto &host :
hosts)
974 res += host->GetNumNetworkEntangledQubits();
992 if (hostId >=
hosts.size())
995 return hosts[hostId]->GetNumNetworkEntangledQubits();
1009 for (
const auto &host :
hosts)
1010 res += host->GetNumClassicalBits();
1027 if (hostId >=
hosts.size())
1030 return hosts[hostId]->GetNumClassicalBits();
1069 const std::vector<uint8_t> &packet)
override {
1096 const auto qubits = op->AffectedQubits();
1101 size_t firstQubit = qubits[0];
1103 for (
size_t q = 1; q < qubits.size(); ++q)
1124 const auto qubits = op->AffectedQubits();
1131 size_t firstQubit = qubits[0];
1134 firstQubit = qubits[q];
1138 for (; q < qubits.size(); ++q)
1159 const auto qubits = op->AffectedQubits();
1164 for (
size_t q = 0; q < qubits.size(); ++q)
1184 const auto qubits = op->AffectedQubits();
1185 if (qubits.size() != 2)
1204 if (!op->IsConditional())
1207 const auto qubits = op->AffectedQubits();
1209 const std::shared_ptr<Circuits::IConditionalOperation<Time>> condOp =
1210 std::static_pointer_cast<Circuits::IConditionalOperation<Time>>(op);
1211 const auto &classicalBits = condOp->GetCondition()->GetBitsIndices();
1213 if (qubits.empty() && classicalBits.empty())
1214 throw std::runtime_error(
1215 "No classical bits specified!");
1223 for (
const auto bit : classicalBits)
1242 if (!op->IsConditional())
1243 throw std::runtime_error(
"Operation is not conditional!");
1245 std::shared_ptr<Circuits::IConditionalOperation<Time>> condOp =
1246 std::static_pointer_cast<Circuits::IConditionalOperation<Time>>(op);
1247 const auto classicalBits = condOp->AffectedBits();
1249 if (classicalBits.empty())
1250 throw std::runtime_error(
"No classical bits specified!");
1264 for (
const auto &host :
hosts) {
1265 const bool present1 = host->IsQubitOnHost(qubitId1);
1266 const bool present2 = host->IsQubitOnHost(qubitId2);
1268 if (present1 && present2)
1270 else if (present1 || present2)
1287 for (
const auto &host :
hosts) {
1288 const bool present1 = host->IsClassicalBitOnHost(bitId1);
1289 const bool present2 = host->IsClassicalBitOnHost(bitId2);
1291 if (present1 && present2)
1293 else if (present1 || present2)
1311 size_t bitId)
const override {
1312 for (
const auto &host :
hosts) {
1313 const bool present1 = host->IsQubitOnHost(qubitId);
1314 const bool present2 = host->IsClassicalBitOnHost(bitId);
1316 if (present1 && present2)
1318 else if (present1 || present2)
1335 for (
const auto &host :
hosts)
1336 if (host->IsQubitOnHost(qubitId))
1337 return host->GetId();
1339 return std::numeric_limits<size_t>::max();
1355 for (
const auto &host :
hosts)
1356 if (host->IsEntangledQubitOnHost(qubitId))
1357 return host->GetId();
1359 return std::numeric_limits<size_t>::max();
1388 for (
const auto &host :
hosts)
1389 if (host->IsClassicalBitOnHost(classicalBitId))
1390 return host->GetId();
1392 return std::numeric_limits<size_t>::max();
1404 if (hostId >=
hosts.size())
1405 return std::vector<size_t>();
1407 return hosts[hostId]->GetQubitsIds();
1422 if (hostId >=
hosts.size())
1423 return std::vector<size_t>();
1425 return hosts[hostId]->GetNetworkEntangledQubitsIds();
1438 if (hostId >=
hosts.size())
1439 return std::vector<size_t>();
1441 return hosts[hostId]->GetClassicalBitsIds();
1456 if (hostId >=
hosts.size())
1457 return std::vector<size_t>();
1459 return hosts[hostId]->GetEntangledQubitMeasurementBitIds();
1507 size_t qubitId2)
const override {
1524 throw std::runtime_error(
1525 "Entanglement between hosts is not supported in the simple network");
1540 throw std::runtime_error(
1541 "Entanglement between hosts is not supported in the simple network");
1554 throw std::runtime_error(
1555 "Entanglement between hosts is not supported in the simple network");
1567 std::shared_ptr<Circuits::Circuit<Time>>
1620 else if (val > (
size_t)QC::QubitRegisterCalculator<>::GetNumberOfThreads())
1621 val = (size_t)QC::QubitRegisterCalculator<>::GetNumberOfThreads();
1730 std::shared_ptr<INetwork<Time>>
Clone()
const override {
1733 std::vector<Types::qubit_t> qubits(numHosts);
1734 std::vector<size_t> cbits(numHosts);
1736 for (
size_t h = 0; h < numHosts; ++h) {
1742 std::make_shared<SimpleDisconnectedNetwork<Time, Controller>>(qubits,
1759 std::shared_ptr<Simulators::ISimulator>
1761 size_t &counts,
size_t nrQubits,
size_t nrCbits,
1764 std::vector<bool> &executed,
bool multithreading =
false,
1765 bool dontRunCircuitStart =
false)
const override {
1776 std::pair<Simulators::SimulatorType, Simulators::SimulationType>>
1779 const bool checkTensorNetwork =
1795#ifndef NO_QISKIT_AER
1815 if (checkTensorNetwork &&
1825 simulatorTypes.emplace_back(
1829#ifndef NO_QISKIT_AER
1842 simulatorTypes.emplace_back(
1850 simulatorTypes.emplace_back(
1859 simulatorTypes.emplace_back(Simulators::SimulatorType::kGpuSim,
1862 Simulators::SimulatorType::kGpuSim,
1864 simulatorTypes.emplace_back(
1865 Simulators::SimulatorType::kGpuSim,
1870 if (simulatorTypes.empty())
1872 else if (simulatorTypes.size() == 1) {
1873 simType = simulatorTypes[0].first;
1874 method = simulatorTypes[0].second;
1876 std::shared_ptr<Simulators::ISimulator> sim =
1881 sim->Configure(
"matrix_product_state_max_bond_dimension",
1884 sim->Configure(
"matrix_product_state_truncation_threshold",
1887 sim->Configure(
"mps_sample_measure_algorithm",
mpsSample.c_str());
1889 sim->SetMultithreading(
true);
1890 if (!dontRunCircuitStart)
1892 Time>::ExecuteUpToMeasurements(dcirc, nrQubits, nrCbits,
1893 nrResultCbits, sim, executed,
1901 simulatorTypes, dcirc, counts, nrQubits, nrCbits, nrResultCbits,
1904 dontRunCircuitStart);
1920 const auto &qubitsMap = optimiser->GetReverseQubitsMap();
1938 const std::unordered_map<Types::qubit_t, Types::qubit_t> &qubitsMap) {
1942 theClassicalState.
Remap(qubitsMap);
1959 const auto &qubitsMap = optimiser->GetReverseQubitsMap();
1979 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap)
const {
1982 size_t numClassicalBits = 0;
1983 for (
const auto &[q, b] : bitsMap)
1984 if (b >= numClassicalBits)
1985 numClassicalBits = b + 1;
1989 for (
const auto &r : res) {
1992 translatedState.
Remap(bitsMap,
false, numClassicalBits);
1993 translatedRes[translatedState.
GetAllBits()] = r.second;
1996 res.swap(translatedRes);
2010 std::unordered_map<Types::qubit_t, Types::qubit_t>
2012 size_t hostId,
size_t &nrQubits,
size_t &nrCbits,
2013 bool useSeparateSimForHosts =
false) {
2014 qubitsMapOnHost.clear();
2021 std::static_pointer_cast<SimpleHost<Time>>(
GetHost(hostId));
2022 const size_t hostNrQubits = host->GetNumQubits();
2024 std::unordered_map<Types::qubit_t, Types::qubit_t> reverseQubitsMap;
2026 if (!useSeparateSimForHosts) {
2028 size_t mnq = std::numeric_limits<size_t>::max();
2030 size_t mnb = std::numeric_limits<size_t>::max();
2032 for (
const auto &op : circuit->GetOperations()) {
2033 const auto qbits = op->AffectedQubits();
2034 for (
auto q : qbits) {
2040 const auto cbits = op->AffectedBits();
2041 for (
auto b : cbits) {
2054 nrQubits = mxq - mnq + 1;
2055 nrCbits = mxb - mnb + 1;
2056 if (nrCbits < nrQubits)
2059 const size_t startQubit = host->GetStartQubitId();
2061 if (mnq < startQubit || mxq >= startQubit + hostNrQubits) {
2066 throw std::runtime_error(
"Circuit does not fit on the host!");
2068 for (
size_t i = 0; i < nrCbits; ++i) {
2069 const size_t mapFrom = mnq + i;
2070 const size_t mapTo = startQubit + i;
2072 qubitsMapOnHost[mapFrom] = mapTo;
2073 reverseQubitsMap[mapTo] = mapFrom;
2076 distCirc = std::static_pointer_cast<Circuits::Circuit<Time>>(
2077 circuit->Remap(qubitsMapOnHost, qubitsMapOnHost));
2080 return reverseQubitsMap;
2083 distCirc = circuit->RemapToContinuous(qubitsMapOnHost, reverseQubitsMap,
2086 assert(nrQubits == qubitsMapOnHost.size());
2095 throw std::runtime_error(
"Circuit does not fit on the host!");
2097 return reverseQubitsMap;
2114 GetNumberOfThreads();
2119 std::shared_ptr<Simulators::ISimulator>
2122 std::shared_ptr<Circuits::Circuit<Time>>
2125 std::shared_ptr<IController<Time>>
2130 std::vector<std::shared_ptr<IHost<Time>>>
2133 std::unique_ptr<Estimators::SimulatorsEstimatorInterface<Time>>
2139 bool recreateIfNeeded =
2141 std::unordered_map<Types::qubit_t, Types::qubit_t>
2145 const std::vector<std::string> *pauliStrings =
int GetSimulationType(void *sim)
Circuit class for holding the sequence of operations.
The state class that stores the classical state of a quantum circuit execution.
const std::vector< bool > & GetAllBits() const
Get the classical bits.
void Clear()
Clear the classical state.
void SetResultsInOrder(const std::vector< bool > &results)
Set the classical bits.
void Remap(const std::unordered_map< Types::qubit_t, Types::qubit_t > &mapping, bool ignoreNotMapped=false, size_t newSize=0)
Convert the state using the provided mapping.
An interface for runtime estimators.
The controller host interface.
std::shared_ptr< INetwork< Time > > getptr()
std::unordered_set< SimulatorPair, boost::hash< SimulatorPair > > SimulatorsSet
typename Circuits::Circuit< Time >::ExecuteResults ExecuteResults
Simulators::SimulatorType GetLastSimulatorType() const override
Get the last used simulator type.
void SetController(const std::shared_ptr< IController< Time > > &cntrl)
Set the network controller host.
std::vector< double > ExecuteExpectations(const std::shared_ptr< Circuits::Circuit< Time > > &circuit, const std::vector< std::string > &paulis) override
Execute the circuit on the network and return the expectation values for the specified Pauli strings.
Simulators::SimulatorType lastSimulatorType
The last simulator type used.
size_t GetHostIdForEntangledQubit(size_t qubitId) const override
Get the host id for the specified qubit used for entanglement between hosts.
std::shared_ptr< Simulators::ISimulator > simulator
The quantum computing simulator for the network.
std::string singularValueThreshold
bool ExpectsClassicalBitFromOtherHost(const std::shared_ptr< Circuits::IOperation< Time > > &op) const override
Checks if a gate expects a classical bit from another host.
void ExecuteOnHost(const std::shared_ptr< Circuits::Circuit< Time > > &circuit, size_t hostId) override
Execute the circuit on the specified host.
size_t GetHostIdForClassicalControl(const std::shared_ptr< Circuits::IOperation< Time > > &op) const override
Get the host id where the classical control bit resides for a conditioned gate.
void MarkEntangledQubitFree(size_t qubitId) override
Mark the specified qubit used for entanglement between hosts as free.
bool OptimizationSimulatorExists(Simulators::SimulatorType type, Simulators::SimulationType kind) const override
Checks if a simulator exists in the optimization set.
size_t GetNumNetworkEntangledQubits() const override
Get the number of qubits used for entanglement between hosts.
std::unordered_map< Types::qubit_t, Types::qubit_t > MapCircuitOnHost(const std::shared_ptr< Circuits::Circuit< Time > > &circuit, size_t hostId, size_t &nrQubits, size_t &nrCbits, bool useSeparateSimForHosts=false)
Map the circuit on the host.
size_t GetNumQubitsForHost(size_t hostId) const override
Get the number of qubits in the network for the specified host.
Circuits::OperationState & GetState() override
Get the classical state of the network.
void AddOptimizationSimulator(Simulators::SimulatorType type, Simulators::SimulationType kind) override
Adds a simulator to the simulators optimization set.
ExecuteResults RepeatedExecuteOnHost(const std::shared_ptr< Circuits::Circuit< Time > > &circuit, size_t hostId, size_t shots=1000) override
Execute the circuit on the specified host, repeatedly.
Simulators::SimulationType lastMethod
The last simulation method used.
ExecuteResults RepeatedExecute(const std::shared_ptr< Circuits::Circuit< Time > > &circuit, size_t shots=1000) override
Execute the circuit on the network, repeatedly.
bool optimizeSimulator
The flag to optimize the simulator.
std::vector< size_t > GetQubitsIds(size_t hostId) const override
Get the qubit ids for the specified host.
std::shared_ptr< Circuits::Circuit< Time > > GetDistributedCircuit() const override
Get the distributed circuit.
size_t GetNumQubits() const override
Get the number of qubits in the network.
bool GetOptimizeSimulator() const override
Returns the 'optimize' flag.
size_t GetNumberOfGatesDistributedOrCut(const std::shared_ptr< Circuits::Circuit< Time > > &circuit) const override
Get the number of gates that span more than one host.
size_t GetHostIdForClassicalBit(size_t classicalBitId) const override
Get the host id for the specified classical bit.
bool IsLocalOperation(const std::shared_ptr< Circuits::IOperation< Time > > &op) const override
Check if the circuit operation is local.
void Configure(const char *key, const char *value) override
Configures the network.
void CreateSimulator(Simulators::SimulatorType simType=Simulators::SimulatorType::kQCSim, Simulators::SimulationType simExecType=Simulators::SimulationType::kMatrixProductState, size_t nrQubits=0) override
Create the simulator for the network.
std::unique_ptr< Estimators::SimulatorsEstimatorInterface< Time > > simulatorsEstimator
The simulators estimator.
const std::shared_ptr< IHost< Time > > GetHost(size_t hostId) const override
Get the host with the specified id.
size_t GetNumHosts() const override
Get the number of hosts in the network.
typename BaseClass::ExecuteResults ExecuteResults
The execute results type.
size_t GetHostIdForQubit(size_t qubitId) const override
Get the host id for the specified qubit.
bool IsNetworkEntangledQubit(size_t qubitId) const override
Check if the specified qubit id is for a qubit used for entanglement between hosts.
void RemoveOptimizationSimulator(Simulators::SimulatorType type, Simulators::SimulationType kind) override
Removes a simulator from the simulators optimization set.
std::shared_ptr< INetwork< Time > > Clone() const override
Clone the network.
Simulators::SimulationType GetLastSimulationType() const override
Get the last used simulation type.
void SetMaxSimulators(size_t val) override
Set the maximum number of simulators that can be used in the network.
bool AreQubitAndClassicalBitOnSameHost(size_t qubitId, size_t bitId) const override
Check if the specified qubit and classical bit are on the same host.
void SetOptimizeSimulator(bool optimize=true) override
Allows using an optimized simulator.
size_t GetNumClassicalBitsForHost(size_t hostId) const override
Get the number of classical bits in the network for the specified host.
bool IsEntanglingGate(const std::shared_ptr< Circuits::IOperation< Time > > &op) const override
Checks if a gate is an entangling gate.
void Execute(const std::shared_ptr< Circuits::Circuit< Time > > &circuit) override
Execute the circuit on the network.
std::vector< std::shared_ptr< IHost< Time > > > hosts
The hosts in the network.
BaseClass::SimulatorsSet simulatorsForOptimizations
bool AreQubitsOnSameHost(size_t qubitId1, size_t qubitId2) const override
Check if the specified qubits are on the same host.
std::vector< ExecuteResults > ExecuteScheduled(const std::vector< Schedulers::ExecuteCircuit< Time > > &circuits) override
Schedule and execute circuits on the network.
size_t GetHostIdForAnyQubit(size_t qubitId) const override
Get the host id for the specified qubit.
size_t GetNumNetworkEntangledQubitsForHost(size_t hostId) const override
Get the number of qubits used for entanglement between hosts for the specified host.
Circuits::OperationState classicalState
The classical state of the network.
void ConvertBackResults(ExecuteResults &res, const std::unordered_map< Types::qubit_t, Types::qubit_t > &bitsMap) const
Converts back the results using the passed qubits map.
void ConvertBackState()
Converts back the state from the optimized network distribution mapping.
std::vector< double > ExecuteOnHostExpectations(const std::shared_ptr< Circuits::Circuit< Time > > &circuit, size_t hostId, const std::vector< std::string > &paulis)
Execute the circuit on the specified host and return the expectation values for the specified Pauli s...
std::shared_ptr< Simulators::ISimulator > ChooseBestSimulator(const std::shared_ptr< Circuits::Circuit< Time > > &dcirc, size_t &counts, size_t nrQubits, size_t nrCbits, size_t nrResultCbits, Simulators::SimulatorType &simType, Simulators::SimulationType &method, std::vector< bool > &executed, bool multithreading=false, bool dontRunCircuitStart=false) const override
std::shared_ptr< Circuits::Circuit< Time > > distCirc
The distributed circuit.
std::shared_ptr< Schedulers::IScheduler< Time > > GetScheduler() const override
Get the scheduler for the network.
size_t GetNumClassicalBits() const override
Get the number of classical bits in the network.
const std::shared_ptr< IController< Time > > GetController() const override
Get the controller for the network.
bool IsDistributedOperation(const std::shared_ptr< Circuits::IOperation< Time > > &op) const override
Check if the circuit operation is distributed.
std::vector< std::shared_ptr< IHost< Time > > > & GetHosts()
Get the hosts in the network.
bool SendPacket(size_t fromHostId, size_t toHostId, const std::vector< uint8_t > &packet) override
Sends a packet between two hosts.
const BaseClass::SimulatorsSet & GetSimulatorsSet() const override
Get the optimizations simulators set.
std::shared_ptr< Simulators::ISimulator > GetSimulator() const override
Get the simulator for the network.
bool OperatesWithNetworkEntangledQubit(const std::shared_ptr< Circuits::IOperation< Time > > &op) const override
Check if the circuit operation operates on the entanglement qubits between hosts.
size_t GetMaxSimulators() const override
Get the maximum number of simulators that can be used in the network.
void MarkEntangledQubitsBusy(size_t qubitId1, size_t qubitId2) override
Mark the pair of the specified qubits used for entanglement between hosts as busy.
void CreateScheduler(SchedulerType schType=SchedulerType::kNoEntanglementQubitsParallel) override
Create the scheduler for the network.
std::vector< size_t > GetClassicalBitsIds(size_t hostId) const override
Get the classical bit ids for the specified host.
std::vector< size_t > GetEntangledQubitMeasurementBitIds(size_t hostId) const override
Get the classical bit ids used for measurement of entanglement qubits between the hosts for the speci...
bool AreEntanglementQubitsBusy(size_t qubitId1, size_t qubitId2) const override
Check if any of the two specified qubits used for entanglement between hosts are busy.
INetwork< Time > BaseClass
The base class type.
size_t maxSimulators
The maximum number of simulators that can be used in the network.
std::shared_ptr< IController< Time > > controller
The controller for the network.
void ClearEntanglements() override
Clear all entanglements between hosts in the network.
void ConvertBackResults(ExecuteResults &res)
Converts back the results from the optimized network distribution mapping.
bool IsEntanglementQubitBusy(size_t qubitId) const override
Check if the specified qubit used for entanglement between hosts is busy.
void RemoveAllOptimizationSimulatorsAndAdd(Simulators::SimulatorType type, Simulators::SimulationType kind) override
Removes all simulators from the simulators optimization set and adds the one specified.
void CreateNetwork(const std::vector< Types::qubit_t > &qubits, const std::vector< size_t > &cbits)
Creates the network hosts and controller.
SimpleDisconnectedNetwork(const std::vector< Types::qubit_t > &qubits={}, const std::vector< size_t > &cbits={})
The constructor.
std::vector< size_t > GetNetworkEntangledQubitsIds(size_t hostId) const override
Get the qubit ids used for entanglement between hosts for the specified host.
void ConvertBackState(const std::unordered_map< Types::qubit_t, Types::qubit_t > &qubitsMap)
Converts back the state using the passed qubits map.
NetworkType GetType() const override
Get the type of the network.
bool AreClassicalBitsOnSameHost(size_t bitId1, size_t bitId2) const override
Check if the specified classical bits are on the same host.
The simple host implementation.
static bool IsGpuLibraryAvailable()
static std::shared_ptr< ISimulator > CreateSimulator(SimulatorType t=SimulatorType::kQCSim, SimulationType method=SimulationType::kMatrixProductState)
Create a quantum computing simulator.
ThreadsPool class for holding and controlling a pool of threads.
@ kGate
the usual quantum gate, result stays in simulator's state
NetworkType
The type of the network.
@ kSimpleDisconnectedNetwork
Simple network, no communication among hosts, sequential simulation.
SchedulerType
The type of the network scheduler for scheduling execution of multiple circuits.
@ kNoEntanglementQubitsParallel
SimulationType
The type of simulation.
@ kStatevector
statevector simulation type
@ kMatrixProductState
matrix product state simulation type
@ kStabilizer
Clifford gates simulation type.
@ kTensorNetwork
Tensor network simulation type.
SimulatorType
The type of simulator.
@ kCompositeQCSim
composite qcsim simulator type
@ kQCSim
qcsim simulator type
@ kQiskitAer
qiskit aer simulator type
@ kCompositeQiskitAer
composite qiskit aer simulator type
double time_type
The type of time.
A way to pack together a circuit and the number of shots for its execution.