52 const bool hasMeasurementsOnlyAtEnd = !
dcirc->HasOpsAfterMeasurements();
54 const bool specialOptimizationForStatevector =
55 optimiseMultipleShots &&
57 hasMeasurementsOnlyAtEnd;
58 const bool specialOptimizationForMPS =
59 optimiseMultipleShots &&
61 hasMeasurementsOnlyAtEnd;
70 optSim->Configure(
"matrix_product_state_max_bond_dimension",
73 optSim->Configure(
"matrix_product_state_truncation_threshold",
83 if (optimiseMultipleShots) {
86 if (!specialOptimizationForStatevector && !specialOptimizationForMPS &&
92 network->GetMPSOptimizeSwaps()) {
100 std::static_pointer_cast<Circuits::Circuit<Time>>(
dcirc->Clone());
101 circ->ConvertForCutting();
102 optSim->SetUpcomingGates(circ->GetOperations());
105 std::shared_ptr<Circuits::MeasurementOperation<Time>> measurementsOp;
109 if (optimiseMultipleShots && hasMeasurementsOnlyAtEnd) {
110 bool isQiskitAer =
false;
116 measurementsOp =
dcirc->GetLastMeasurements(executed, isQiskitAer);
117 const auto &qbits = measurementsOp->GetQubits();
131 if (optimiseMultipleShots &&
132 (specialOptimizationForStatevector || hasMeasurementsOnlyAtEnd)) {
133 const auto &qbits = measurementsOp->GetQubits();
135 const auto sampleres =
optSim->SampleCountsMany(qbits,
curCnt);
137 for (
const auto &[mstate, cnt] : sampleres) {
138 measurementsOp->SetStateFromSample(mstate, state);
143 localRes[bits] += cnt;
149 for (
const auto &r : localRes)
res[r.first] += r.second;
155 for (
size_t i = 0; i <
curCnt; ++i) {
156 if (optimiseMultipleShots) {
159 optSim->SetGatesCounter(0);
161 dcirc->ExecuteMeasurements(
optSim, state, executed);
166 optSim->SetGatesCounter(0);
179 for (
const auto &r : localRes)
res[r.first] += r.second;
188 const bool hasMeasurementsOnlyAtEnd = !
dcirc->HasOpsAfterMeasurements();
190 const bool specialOptimizationForStatevector =
191 optimiseMultipleShots &&
193 hasMeasurementsOnlyAtEnd;
194 const bool specialOptimizationForMPS =
195 optimiseMultipleShots &&
197 hasMeasurementsOnlyAtEnd;
201 optSim->SetMultithreading(
true);
207 optSim->Configure(
"matrix_product_state_max_bond_dimension",
210 optSim->Configure(
"matrix_product_state_truncation_threshold",
220 if (optimiseMultipleShots) {
223 if (!specialOptimizationForStatevector &&
224 !specialOptimizationForMPS &&
curCnt > 1)
228 network->GetMPSOptimizeSwaps()) {
237 bool needToExecuteGates =
true;
240 needToExecuteGates =
false;
244 if (needToExecuteGates && optimiseMultipleShots) {
246 if (!specialOptimizationForStatevector &&
247 !specialOptimizationForMPS &&
curCnt > 1)
251 network->GetMPSOptimizeSwaps()) {
259 network->GetMPSOptimizeSwaps()) {
268 network->GetMPSOptimizeSwaps()) {
270 std::static_pointer_cast<Circuits::Circuit<Time>>(
dcirc->Clone());
271 circ->ConvertForCutting();
272 optSim->SetUpcomingGates(circ->GetOperations());
279 optSim->SetMultithreading(
true);
282 optSim->Configure(
"matrix_product_state_max_bond_dimension",
285 optSim->Configure(
"matrix_product_state_truncation_threshold",
295 if (optimiseMultipleShots) {
298 if (!specialOptimizationForStatevector && !specialOptimizationForMPS &&
311 std::shared_ptr<Circuits::MeasurementOperation<Time>> measurementsOp;
315 if (optimiseMultipleShots && hasMeasurementsOnlyAtEnd) {
316 bool isQiskitAer =
false;
322 measurementsOp =
dcirc->GetLastMeasurements(executed, isQiskitAer);
323 const auto &qbits = measurementsOp->GetQubits();
334 if (optimiseMultipleShots &&
335 (specialOptimizationForStatevector || hasMeasurementsOnlyAtEnd)) {
336 const auto &qbits = measurementsOp->GetQubits();
338 const auto sampleres =
optSim->SampleCountsMany(qbits,
curCnt);
340 for (
const auto &[mstate, cnt] : sampleres) {
341 measurementsOp->SetStateFromSample(mstate, state);
355 for (
size_t i = 0; i <
curCnt; ++i) {
356 if (optimiseMultipleShots) {
359 optSim->SetGatesCounter(0);
361 dcirc->ExecuteMeasurements(
optSim, state, executed);
366 optSim->SetGatesCounter(0);
387 void OptimizeMPSInitialQubitsMap(
388 std::shared_ptr<Simulators::ISimulator> &sim,
390 if (sim->GetSimulationType() ==
392 (
network->GetInitialQubitsMapOptimization() ||
393 network->GetMPSOptimizeSwaps()) &&
394 sim->SupportsMPSSwapOptimization()) {
396 const auto bondDimThreshold =
397 network->GetMPSOptimizationBondDimensionThreshold();
398 const auto maxBondDimValue =
401 if (
maxBondDim.empty() ||
static_cast<int>(bondDimThreshold) <= maxBondDimValue) {
403 dcirc->ConvertForCutting();
404 auto layers =
dcirc->ToMultipleQubitsLayersNoClone();
407 dummySim.setGrowthFactorGate(
network->getGrowthFactorGate());
408 dummySim.setGrowthFactorSwap(
network->getGrowthFactorSwap());
410 dummySim.SetMaxBondDimension(maxBondDimValue);
412 if (
network->GetInitialQubitsMapOptimization()) {
413 const auto optimalMap = dummySim.ComputeOptimalQubitsMap(layers);
414 sim->SetInitialQubitsMap(optimalMap);
419 if (
network->GetMPSOptimizeSwaps()) {
421 int lookaheadDepthLocal =
network->GetLookaheadDepth();
423 if (lookaheadDepthLocal == std::numeric_limits<int>::max()) {
424 double avgTwoQubitGatesPerLayer = 0.0;
425 for (
const auto &layer : layers) {
426 int twoQubitGates = 0;
427 for (
const auto &op : layer->GetOperations()) {
428 if (op->AffectedQubits().size() >= 2) {
432 avgTwoQubitGatesPerLayer += twoQubitGates;
434 avgTwoQubitGatesPerLayer /= layers.size();
437 static_cast<int>(4. * avgTwoQubitGatesPerLayer);
438 if (lookaheadVal > 15) lookaheadVal = 15;
440 lookaheadDepthLocal =
441 layers.size() < 8 ||
nrQubits <= 10 ? 0
442 : layers.size() < 15 ?
static_cast<int>(lookaheadVal)
443 : layers.size() < 25 ? static_cast<int>(1.5 * lookaheadVal)
447 int lookaheadHeuristicDepthLocal =
448 network->GetLookaheadDepthWithHeuristic();
450 if (lookaheadHeuristicDepthLocal == std::numeric_limits<int>::max())
451 lookaheadHeuristicDepthLocal =
452 layers.size() < 10 ||
nrQubits <= 10 ? 0
454 ? lookaheadDepthLocal - 1
455 : lookaheadDepthLocal - 2;
457 if (lookaheadHeuristicDepthLocal < 0)
458 lookaheadHeuristicDepthLocal = 0;
460 sim->SetUseOptimalMeetingPosition(
true);
461 sim->SetLookaheadDepth(lookaheadDepthLocal);
462 sim->SetLookaheadDepthWithHeuristic(lookaheadHeuristicDepthLocal);
463 sim->setGrowthFactorGate(
network->getGrowthFactorGate());
464 sim->setGrowthFactorSwap(
network->getGrowthFactorSwap());
465 sim->SetUpcomingGates(
dcirc->GetOperations());
473 std::shared_ptr<Circuits::Circuit<Time>>
dcirc;
485 std::shared_ptr<Simulators::ISimulator>
optSim;
493 std::shared_ptr<Network::INetwork<Time>>
network;
ExecuteJob(const std::shared_ptr< Circuits::Circuit< Time > > &c, ExecuteResults &r, size_t cnt, size_t nq, size_t nc, size_t ncr, Simulators::SimulatorType t, Simulators::SimulationType m, std::mutex &mut)