18#ifndef __EXECUTION_COST_H_
19#define __EXECUTION_COST_H_
21#include "../Simulators/QcsimPauliPropagator.h"
22#include "../Simulators/Factory.h"
23#include "../Utils/LogFile.h"
72 const double opOrder = exp2(nrQubits);
75 for (
const auto& op : *circuit) {
76 const auto affectedQubits = op->AffectedQubits();
79 cost += opOrder * affectedQubits.size();
81 cost += 2. * opOrder * affectedQubits.size();
84 if (affectedQubits.size() == 1)
86 else if (affectedQubits.size() == 2)
88 else if (affectedQubits.size() == 3)
94 const double twoQubitOpOrder = pow(maxBondDim, 3);
95 const double oneQubitOpOrder = pow(maxBondDim, 2);
98 for (
const auto& op : *circuit) {
99 const auto affectedQubits = op->AffectedQubits();
114 cost += twoQubitOpOrder * affectedQubits.size() * nrQubits / 2.;
117 if (affectedQubits.size() == 1)
118 cost += oneQubitOpOrder;
119 else if (affectedQubits.size() == 2)
122 cost += twoQubitOpOrder * nrQubits / 3.;
123 else if (affectedQubits.size() == 3)
126 cost += twoQubitOpOrder * nrQubits * 2;
131 const double measOrder = pow(nrQubits, 2);
132 const double opOrder = nrQubits;
135 for (
const auto& op : *circuit) {
136 const auto affectedQubits = op->AffectedQubits();
140 cost += measOrder * affectedQubits.size();
143 cost += opOrder * affectedQubits.size();
150 return std::numeric_limits<double>::infinity();
155 size_t nrQubitsSampled,
size_t samples,
159 const bool hasMeasurementsInTheMiddle = circuit->HasOpsAfterMeasurements();
160 const std::vector<bool> executedOps =
161 circuit->ExecuteNonMeasurements(
nullptr, dummyState);
163 const size_t dif = circuit->size() - executedOps.size();
167 circuit, nrQubitsSampled, samples);
170 const double opOrder = exp2(nrQubits);
173 for (
size_t i = 0; i < circuit->size(); ++i) {
174 if (i >= dif && !executedOps[i - dif])
continue;
176 const auto& op = (*circuit)[i];
177 const auto affectedQubits = op->AffectedQubits();
180 cost += opOrder * affectedQubits.size();
182 cost += 2. * opOrder * affectedQubits.size();
185 if (affectedQubits.size() == 1)
187 else if (affectedQubits.size() == 2)
189 else if (affectedQubits.size() == 3)
190 cost += 16 * opOrder;
200 if (hasMeasurementsInTheMiddle) {
201 double samplingCost = 0;
202 for (
size_t i = dif; i < circuit->size(); ++i) {
203 if (executedOps[i - dif])
continue;
205 const auto& op = (*circuit)[i];
206 const auto affectedQubits = op->AffectedQubits();
209 samplingCost += opOrder * affectedQubits.size();
211 samplingCost += 2. * opOrder * affectedQubits.size();
214 if (affectedQubits.size() == 1)
215 samplingCost += opOrder;
216 else if (affectedQubits.size() == 2)
217 samplingCost += 4 * opOrder;
218 else if (affectedQubits.size() == 3)
219 samplingCost += 16 * opOrder;
223 samplingCost += opOrder * nrQubitsSampled;
225 return cost + samplingCost * samples;
229 return cost + 30 * opOrder + samples * nrQubits;
231 const double twoQubitOpOrder = pow(maxBondDim, 3);
232 const double oneQubitOpOrder = pow(maxBondDim, 2);
235 for (
size_t i = 0; i < circuit->size(); ++i) {
236 if (i >= dif && !executedOps[i - dif])
continue;
238 const auto& op = (*circuit)[i];
239 const auto affectedQubits = op->AffectedQubits();
254 cost += twoQubitOpOrder * affectedQubits.size() * nrQubits / 2.;
257 if (affectedQubits.size() == 1)
258 cost += oneQubitOpOrder;
259 else if (affectedQubits.size() == 2)
262 cost += twoQubitOpOrder * nrQubits / 3.;
263 else if (affectedQubits.size() == 3)
266 cost += twoQubitOpOrder * nrQubits * 2;
270 if (hasMeasurementsInTheMiddle) {
271 double samplingCost = 0;
272 for (
size_t i = dif; i < circuit->size(); ++i) {
273 if (executedOps[i - dif])
continue;
275 const auto& op = (*circuit)[i];
276 const auto affectedQubits = op->AffectedQubits();
282 twoQubitOpOrder * affectedQubits.size() * nrQubits / 2.;
285 if (affectedQubits.size() == 1)
286 samplingCost += oneQubitOpOrder;
287 else if (affectedQubits.size() == 2)
290 samplingCost += twoQubitOpOrder * nrQubits / 3.;
291 else if (affectedQubits.size() == 3)
295 twoQubitOpOrder * nrQubits * 2;
299 samplingCost += twoQubitOpOrder * nrQubits * nrQubits;
301 return cost + samplingCost * samples;
311 return cost + samples * twoQubitOpOrder * nrQubits * nrQubits;
313 const double measOrder = pow(nrQubits, 2);
314 const double opOrder = nrQubits;
317 for (
size_t i = 0; i < circuit->size(); ++i) {
318 if (i >= dif && !executedOps[i - dif])
continue;
320 const auto& op = (*circuit)[i];
321 const auto affectedQubits = op->AffectedQubits();
325 cost += measOrder * affectedQubits.size();
328 cost += opOrder * affectedQubits.size();
331 if (hasMeasurementsInTheMiddle) {
332 double samplingCost = 0;
333 for (
size_t i = dif; i < circuit->size(); ++i) {
334 if (executedOps[i - dif])
continue;
336 const auto& op = (*circuit)[i];
337 const auto affectedQubits = op->AffectedQubits();
342 samplingCost += measOrder * affectedQubits.size();
345 samplingCost += opOrder * affectedQubits.size();
348 samplingCost += measOrder * nrQubitsSampled;
350 return cost + samplingCost * samples;
356 return cost + samples * measOrder * nrQubitsSampled;
361 return std::numeric_limits<double>::infinity();
373 for (
char c : pauliString) {
374 if (c ==
'X' || c ==
'x' || c ==
'Y' || c ==
'y' || c ==
'Z' || c ==
'z')
380 const double opOrder = exp2(nrQubits);
384 cost += opOrder * (pauliCnt + 1);
388 const double twoQubitOpOrder = pow(maxBondDim, 3);
389 const double oneQubitOpOrder = pow(maxBondDim, 2);
393 cost += oneQubitOpOrder * pauliCnt + nrQubits * twoQubitOpOrder;
397 cost += nrQubits * nrQubits;
401 return std::numeric_limits<double>::infinity();
405 size_t nrQubits,
size_t depth,
double measureInsideProbability = 0.,
406 size_t nrMeasAtEnd = 0,
bool isClifford =
false,
407 size_t nrNonCliffordGatesLimit = 0) {
408 auto circuit = std::make_shared<Circuits::Circuit<>>();
409 std::random_device rdev;
410 std::mt19937 rng(rdev());
411 std::uniform_real_distribution<double> dist(0.0, 1.0);
412 std::uniform_real_distribution<double> paramDist(-2 * M_PI, 2 * M_PI);
413 std::uniform_int_distribution<Types::qubit_t> qubitDist(0, nrQubits - 1);
414 std::uniform_int_distribution<int> gateDist(
417 std::uniform_int_distribution<int> gateDistOneQubit(
420 std::vector<Types::qubit_t> qubits(nrQubits);
421 std::iota(qubits.begin(), qubits.end(), 0);
423 size_t nrNonCliffordGates = 0;
424 if (nrNonCliffordGatesLimit == 0 && !isClifford)
425 nrNonCliffordGatesLimit = depth;
427 for (
size_t i = 0; i < depth; ++i) {
428 if (dist(rng) < measureInsideProbability) {
430 std::vector<std::pair<Types::qubit_t, size_t>> qs = {{q, q}};
431 circuit->AddOperation(
436 std::shuffle(qubits.begin(), qubits.end(), rng);
437 const auto q1 = qubits[0];
438 const auto q2 = qubits[1];
439 const auto q3 = qubits[2];
442 nrNonCliffordGatesLimit < depth
443 ? gateDistOneQubit(rng)
446 auto param1 = paramDist(rng);
447 auto param2 = paramDist(rng);
448 auto param3 = paramDist(rng);
449 auto param4 = paramDist(rng);
452 gateType, q1, q2, q3, param1, param2, param3, param4);
454 while (!theGate->IsClifford()) {
457 gateType, q1, q2, q3, param1, param2, param3, param4);
461 if (!theGate->IsClifford()) ++nrNonCliffordGates;
463 if (nrNonCliffordGates > nrNonCliffordGatesLimit) {
468 gateType, q1, q2, q3, param1, param2, param3, param4);
469 while (!theGate->IsClifford()) {
473 gateType, q1, q2, q3, param1, param2, param3, param4);
475 --nrNonCliffordGates;
478 circuit->AddOperation(theGate);
481 if (nrMeasAtEnd > 0) {
482 if (nrMeasAtEnd > nrQubits) nrMeasAtEnd = nrQubits;
483 std::shuffle(qubits.begin(), qubits.end(), rng);
485 for (
size_t i = 0; i < nrMeasAtEnd; ++i) {
486 std::vector<std::pair<Types::qubit_t, size_t>> qs = {{qubits[i], i}};
487 circuit->AddOperation(
498 size_t nrReps,
size_t maxBondDim) {
499 auto sim =
GetSimulator(simType, method, nrQubits, maxBondDim);
502 auto start = std::chrono::high_resolution_clock::now();
503 for (
size_t i = 0; i < nrReps; ++i) circuit->Execute(sim, dummyState);
504 auto end = std::chrono::high_resolution_clock::now();
505 return std::chrono::duration<double>(end - start).count();
511 size_t nrQubitsSampled,
size_t nrSamples,
size_t nrReps,
513 auto sim =
GetSimulator(simType, method, nrQubits, maxBondDim);
516 if (nrQubitsSampled > nrQubits) nrQubitsSampled = nrQubits;
518 std::iota(qubitsSampled.begin(), qubitsSampled.end(), 0);
520 const bool hasMeasurementsInTheMiddle = circuit->HasOpsAfterMeasurements();
522 auto start = std::chrono::high_resolution_clock::now();
524 if (hasMeasurementsInTheMiddle) {
525 for (
size_t i = 0; i < nrReps; ++i) {
526 const auto executedOps = circuit->ExecuteNonMeasurements(
530 for (
size_t sample = 0; sample < nrSamples; ++sample) {
531 circuit->ExecuteMeasurements(
532 sim, dummyState, executedOps);
536 for (
size_t i = 0; i < nrReps; ++i) {
537 circuit->Execute(sim, dummyState);
538 sim->SampleCountsMany(qubitsSampled, nrSamples);
541 auto end = std::chrono::high_resolution_clock::now();
543 return std::chrono::duration<double>(end - start).count();
549 const std::string& pauliString,
size_t nrReps,
size_t maxBondDim) {
550 auto sim =
GetSimulator(simType, method, nrQubits, maxBondDim);
552 auto start = std::chrono::high_resolution_clock::now();
553 for (
size_t i = 0; i < nrReps; ++i) {
554 circuit->Execute(sim, dummyState);
555 sim->ExpectationValue(pauliString);
557 auto end = std::chrono::high_resolution_clock::now();
558 return std::chrono::duration<double>(end - start).count();
563 size_t nrQubits,
size_t maxBondDim) {
566 const auto strVal = std::to_string(maxBondDim);
567 sim->Configure(
"matrix_product_state_max_bond_dimension", strVal.c_str());
569 sim->AllocateQubits(nrQubits);
570 sim->SetMultithreading(
false);
579 info.
nrQubits = circuit->GetMaxQubitIndex() + 1;
581 const bool hasMeasurementsInTheMiddle = circuit->HasOpsAfterMeasurements();
582 const std::vector<bool> executedOps =
583 circuit->ExecuteNonMeasurements(
nullptr, dummyState);
585 const size_t dif = circuit->size() - executedOps.size();
588 for (
const auto& op : *circuit) {
589 const auto affectedQubits = op->AffectedQubits();
592 if (hasMeasurementsInTheMiddle)
598 if (affectedQubits.size() == 1) {
601 }
else if (affectedQubits.size() == 2) {
604 }
else if (affectedQubits.size() == 3) {
606 if (i < dif || executedOps[i - dif])
616 static std::vector<ExecutionInfo>
ReadLog(
const std::string& logFilePath) {
617 std::vector<ExecutionInfo> executionInfos;
619 std::ifstream logFile(logFilePath);
620 if (!logFile.is_open()) {
621 std::cerr <<
"Failed to open log file: " << logFilePath << std::endl;
622 return executionInfos;
627 while (std::getline(logFile, line)) {
628 std::stringstream ss(line);
631 std::getline(ss, value,
',');
633 std::getline(ss, value,
',');
635 std::getline(ss, value,
',');
637 std::getline(ss, value,
',');
639 std::getline(ss, value,
',');
641 std::getline(ss, value,
',');
643 std::getline(ss, value,
',');
645 std::getline(ss, value,
',');
647 std::getline(ss, value,
',');
650 std::getline(ss, value,
',');
652 std::getline(ss, value,
',');
654 std::getline(ss, value,
',');
656 std::getline(ss, value,
',');
659 std::getline(ss, value,
',');
661 std::getline(ss, value,
',');
666 executionInfos.push_back(std::move(info));
669 return executionInfos;
674 size_t nrReps,
size_t nrMinQubits,
size_t nrMaxQubits,
size_t stepQubits,
675 size_t depthMin,
size_t depthMax,
size_t stepDepth,
676 double measureInsideProbability,
size_t nrMeasAtEndMin,
677 size_t nrMeasAtEndMax,
size_t stepMeasAtEnd,
678 size_t nrRandomCircuitsPerConfig,
size_t maxBondDim,
679 const std::string& logFilePath) {
681 int nrNonCliffordGates = depthMax;
684 nrNonCliffordGates = 1;
686 nrNonCliffordGates = 0;
689 std::cout <<
"Benchmarking execution for simType: "
690 <<
static_cast<int>(simType)
691 <<
", method: " <<
static_cast<int>(method) << std::endl;
695 for (
size_t nrQubits = nrMinQubits; nrQubits <= nrMaxQubits;
696 nrQubits += stepQubits) {
697 std::cout <<
" Qubits: " << nrQubits << std::endl;
698 for (
size_t depth = depthMin; depth <= depthMax; depth += stepDepth) {
699 std::cout <<
" Depth: " << depth << std::endl;
700 for (
size_t nrMeasAtEnd = nrMeasAtEndMin;
701 nrMeasAtEnd <= std::min(nrMeasAtEndMax, nrQubits);
702 nrMeasAtEnd += stepMeasAtEnd) {
703 std::cout <<
" Measurements at end: " << nrMeasAtEnd
705 for (
size_t i = 0; i < nrRandomCircuitsPerConfig; ++i) {
706 std::cout <<
" Random circuit: " << i + 1 <<
"/"
707 << nrRandomCircuitsPerConfig << std::endl;
709 isClifford = !isClifford;
712 nrQubits, depth, measureInsideProbability, nrMeasAtEnd,
713 isClifford, nrNonCliffordGates);
724 pauli.resize(nrQubits);
725 std::random_device rd;
726 std::mt19937 g(rd());
727 std::uniform_int_distribution<int> dist(0, 3);
729 for (
size_t i = 0; i < nrQubits; ++i) {
730 const int v = dist(g);
752 size_t nrReps,
size_t nrMinQubits,
size_t nrMaxQubits,
size_t stepQubits,
753 size_t depthMin,
size_t depthMax,
size_t stepDepth,
754 size_t nrRandomCircuitsPerConfig,
size_t maxBondDim,
755 const std::string& logFilePath) {
757 int nrNonCliffordGates = depthMax;
760 nrNonCliffordGates = 1;
762 nrNonCliffordGates = 0;
766 std::cout <<
"Benchmarking Pauli expectation for simType: "
767 <<
static_cast<int>(simType)
768 <<
", method: " <<
static_cast<int>(method) << std::endl;
770 for (
size_t nrQubits = nrMinQubits; nrQubits <= nrMaxQubits;
771 nrQubits += stepQubits) {
772 std::cout <<
" Qubits: " << nrQubits << std::endl;
773 for (
size_t depth = depthMin; depth <= depthMax; depth += stepDepth) {
774 std::cout <<
" Depth: " << depth << std::endl;
775 for (
size_t i = 0; i < nrRandomCircuitsPerConfig; ++i) {
777 isClifford = !isClifford;
780 nrQubits, depth, 0., 0, isClifford, nrNonCliffordGates);
783 std::cout <<
" Random circuit: " << i + 1 <<
"/"
784 << nrRandomCircuitsPerConfig
785 <<
" Pauli string: " << pauliString << std::endl;
787 nrReps, maxBondDim, log);
795 size_t nrReps,
size_t nrMinQubits,
size_t nrMaxQubits,
size_t stepQubits,
796 size_t depthMin,
size_t depthMax,
size_t stepDepth,
size_t nrMeasAtEndMin,
797 size_t nrMeasAtEndMax,
size_t stepMeasAtEnd,
size_t nrSamplesMin,
798 size_t nrSamplesMax,
size_t multiplierSamples,
799 size_t nrRandomCircuitsPerConfig,
size_t maxBondDim,
800 const std::string& logFilePath) {
802 int nrNonCliffordGates = depthMax;
805 nrNonCliffordGates = 1;
807 nrNonCliffordGates = 0;
811 std::cout <<
"Benchmarking sampling for simType: "
812 <<
static_cast<int>(simType)
813 <<
", method: " <<
static_cast<int>(method) << std::endl;
815 for (
size_t nrQubits = nrMinQubits; nrQubits <= nrMaxQubits;
816 nrQubits += stepQubits) {
817 std::cout <<
" Qubits: " << nrQubits << std::endl;
818 for (
size_t depth = depthMin; depth <= depthMax; depth += stepDepth) {
819 std::cout <<
" Depth: " << depth << std::endl;
820 for (
size_t nrSamples = nrSamplesMin; nrSamples <= nrSamplesMax;
821 nrSamples *= multiplierSamples) {
822 std::cout <<
" Samples: " << nrSamples << std::endl;
823 for (
size_t i = 0; i < nrRandomCircuitsPerConfig; ++i) {
825 isClifford = !isClifford;
827 nrQubits, depth, 0., 0, isClifford, nrNonCliffordGates);
828 for (
size_t nrQubitsSampled = nrQubits; nrQubitsSampled >= 1;
829 nrQubitsSampled /= 2) {
830 std::cout <<
" Random circuit: " << i + 1 <<
"/"
831 << nrRandomCircuitsPerConfig
832 <<
" Qubits sampled: " << nrQubitsSampled << std::endl;
834 nrSamples, nrReps, maxBondDim, log);
847 const double estimatedCost =
849 const double executionTime =
854 std::stringstream ss;
856 ss << info.nrQubits <<
"," << info.nrOneQubitOps <<
","
857 << info.nrTwoQubitOps <<
"," << info.nrThreeQubitOps <<
","
858 << info.nrMiddleMeasurementOps <<
"," << info.nrEndMeasurementOps <<
","
859 << info.nrOneQubitOpsExecutedOnce <<
","
860 << info.nrTwoQubitOpsExecutedOnce <<
","
861 << info.nrThreeQubitOpsExecutedOnce <<
","
862 <<
"0,0," << maxBondDim <<
","
863 <<
"0," << estimatedCost <<
"," << executionTime;
871 size_t nrQubitsSampled,
size_t nrSamples,
size_t nrReps,
875 method, info.nrQubits, nrQubitsSampled, nrSamples, circuit, maxBondDim);
876 const double samplingTime =
878 nrQubitsSampled, nrSamples, nrReps, maxBondDim) /
880 std::stringstream ss;
881 ss << info.nrQubits <<
"," << info.nrOneQubitOps <<
","
882 << info.nrTwoQubitOps <<
"," << info.nrThreeQubitOps <<
","
883 << info.nrMiddleMeasurementOps <<
"," << info.nrEndMeasurementOps <<
","
884 << info.nrOneQubitOpsExecutedOnce <<
","
885 << info.nrTwoQubitOpsExecutedOnce <<
","
886 << info.nrThreeQubitOpsExecutedOnce <<
"," << nrSamples <<
","
887 << nrQubitsSampled <<
"," << maxBondDim <<
","
888 <<
"0," << estimatedCost <<
"," << samplingTime;
895 const std::string& pauliString,
size_t nrReps,
size_t maxBondDim,
898 info.nrQubits = std::max(info.nrQubits, pauliString.size());
900 pauliString, method, info.nrQubits, circuit, maxBondDim);
901 const double expectationTime =
903 pauliString, nrReps, maxBondDim) /
907 for (
char c : pauliString) {
908 if (c ==
'X' || c ==
'x' || c ==
'Y' || c ==
'y' || c ==
'Z' || c ==
'z')
912 std::stringstream ss;
913 ss << info.nrQubits <<
"," << info.nrOneQubitOps <<
","
914 << info.nrTwoQubitOps <<
"," << info.nrThreeQubitOps <<
","
915 << info.nrMiddleMeasurementOps <<
"," << info.nrEndMeasurementOps <<
","
916 << info.nrOneQubitOpsExecutedOnce <<
","
917 << info.nrTwoQubitOpsExecutedOnce <<
","
918 << info.nrThreeQubitOpsExecutedOnce <<
","
919 <<
"0,0," << maxBondDim <<
"," << cntPauli <<
"," << estimatedCost <<
","
static const std::shared_ptr< IQuantumGate< Time > > CreateGate(QuantumGateType type, size_t q1, size_t q2=0, size_t q3=0, double param1=0, double param2=0, double param3=0, double param4=0)
Construct a quantum gate.
Circuit class for holding the sequence of operations.
Measurement operation class.
The state class that stores the classical state of a quantum circuit execution.
static double MeasureSamplingTime(Simulators::SimulatorType simType, Simulators::SimulationType method, size_t nrQubits, const std::shared_ptr< Circuits::Circuit<> > &circuit, size_t nrQubitsSampled, size_t nrSamples, size_t nrReps, size_t maxBondDim)
static double MeasureExecutionTime(Simulators::SimulatorType simType, Simulators::SimulationType method, size_t nrQubits, const std::shared_ptr< Circuits::Circuit<> > &circuit, size_t nrReps, size_t maxBondDim)
static void BenchmarkAndLogPauliExpectation(Simulators::SimulatorType simType, Simulators::SimulationType method, const std::shared_ptr< Circuits::Circuit<> > &circuit, const std::string &pauliString, size_t nrReps, size_t maxBondDim, Utils::LogFile &log)
static double MeasurePauliExpectationTime(Simulators::SimulatorType simType, Simulators::SimulationType method, size_t nrQubits, const std::shared_ptr< Circuits::Circuit<> > &circuit, const std::string &pauliString, size_t nrReps, size_t maxBondDim)
static std::shared_ptr< Simulators::ISimulator > GetSimulator(Simulators::SimulatorType simType, Simulators::SimulationType method, size_t nrQubits, size_t maxBondDim)
static double EstimatePauliExpectationCost(const std::string &pauliString, Simulators::SimulationType method, size_t nrQubits, const std::shared_ptr< Circuits::Circuit<> > &circuit, size_t maxBondDim)
static void BenchmarkAndLogSampling(Simulators::SimulatorType simType, Simulators::SimulationType method, const std::shared_ptr< Circuits::Circuit<> > &circuit, size_t nrQubitsSampled, size_t nrSamples, size_t nrReps, size_t maxBondDim, Utils::LogFile &log)
static void BenchmarkAndLogPauliExpectation(Simulators::SimulatorType simType, Simulators::SimulationType method, size_t nrReps, size_t nrMinQubits, size_t nrMaxQubits, size_t stepQubits, size_t depthMin, size_t depthMax, size_t stepDepth, size_t nrRandomCircuitsPerConfig, size_t maxBondDim, const std::string &logFilePath)
static double EstimateSamplingCost(Simulators::SimulationType method, size_t nrQubits, size_t nrQubitsSampled, size_t samples, const std::shared_ptr< Circuits::Circuit<> > &circuit, size_t maxBondDim)
static std::string GeneratePauliString(size_t nrQubits)
static double EstimateExecutionCost(Simulators::SimulationType method, size_t nrQubits, const std::shared_ptr< Circuits::Circuit<> > &circuit, size_t maxBondDim)
static CircuitInfo GetCircuitInfo(const std::shared_ptr< Circuits::Circuit<> > &circuit)
static void BenchmarkAndLogExecution(Simulators::SimulatorType simType, Simulators::SimulationType method, size_t nrReps, size_t nrMinQubits, size_t nrMaxQubits, size_t stepQubits, size_t depthMin, size_t depthMax, size_t stepDepth, double measureInsideProbability, size_t nrMeasAtEndMin, size_t nrMeasAtEndMax, size_t stepMeasAtEnd, size_t nrRandomCircuitsPerConfig, size_t maxBondDim, const std::string &logFilePath)
static void BenchmarkAndLogExecution(Simulators::SimulatorType simType, Simulators::SimulationType method, const std::shared_ptr< Circuits::Circuit<> > &circuit, size_t nrReps, size_t maxBondDim, Utils::LogFile &log)
static void BenchmarkAndLogSampling(Simulators::SimulatorType simType, Simulators::SimulationType method, size_t nrReps, size_t nrMinQubits, size_t nrMaxQubits, size_t stepQubits, size_t depthMin, size_t depthMax, size_t stepDepth, size_t nrMeasAtEndMin, size_t nrMeasAtEndMax, size_t stepMeasAtEnd, size_t nrSamplesMin, size_t nrSamplesMax, size_t multiplierSamples, size_t nrRandomCircuitsPerConfig, size_t maxBondDim, const std::string &logFilePath)
static std::vector< ExecutionInfo > ReadLog(const std::string &logFilePath)
static std::shared_ptr< Circuits::Circuit<> > GenerateRandomCircuit(size_t nrQubits, size_t depth, double measureInsideProbability=0., size_t nrMeasAtEnd=0, bool isClifford=false, size_t nrNonCliffordGatesLimit=0)
static double GetSamplingCost(const std::shared_ptr< Circuits::Circuit<> > &circuit, size_t nrQubitsSampled, size_t samples)
static double GetCost(const std::shared_ptr< Circuits::Circuit<> > &circuit)
static std::shared_ptr< ISimulator > CreateSimulator(SimulatorType t=SimulatorType::kQCSim, SimulationType method=SimulationType::kMatrixProductState)
Create a quantum computing simulator.
void Log(const std::string &message)
QuantumGateType
The type of quantum gates.
@ kConditionalGate
conditional gate, similar with gate, but conditioned on something from 'OperationState'
@ kConditionalMeasurement
conditional measurement, similar with measurement, but conditioned on something from 'OperationState'
@ kMeasurement
measurement, result in 'OperationState'
@ kGate
the usual quantum gate, result stays in simulator's state
@ kReset
reset, no result in 'state', just apply measurement, then apply not on all qubits that were measured ...
SimulationType
The type of simulation.
@ kStatevector
statevector simulation type
@ kMatrixProductState
matrix product state simulation type
@ kStabilizer
Clifford gates simulation type.
@ kPauliPropagator
Pauli propagator simulation type.
SimulatorType
The type of simulator.
uint_fast64_t qubit_t
The type of a qubit.
std::vector< qubit_t > qubits_vector
The type of a vector of qubits.
size_t nrTwoQubitOpsExecutedOnce
size_t nrEndMeasurementOps
size_t nrOneQubitOpsExecutedOnce
size_t nrThreeQubitOpsExecutedOnce
size_t nrMiddleMeasurementOps