54 const bool hasMeasurementsOnlyAtEnd = !
dcirc->HasOpsAfterMeasurements();
56 const bool specialOptimizationForStatevector =
57 optimiseMultipleShots &&
59 hasMeasurementsOnlyAtEnd;
60 const bool specialOptimizationForMPS =
61 optimiseMultipleShots &&
63 hasMeasurementsOnlyAtEnd;
67 size_t curMaxBondDimLocal = 0;
79 if (optimiseMultipleShots) {
82 if (!specialOptimizationForStatevector && !specialOptimizationForMPS &&
88 network->GetMPSOptimizeSwaps()) {
96 std::static_pointer_cast<Circuits::Circuit<Time>>(
dcirc->Clone());
97 circ->ConvertForCutting();
98 optSim->SetUpcomingGates(circ->GetOperations());
101 std::shared_ptr<Circuits::MeasurementOperation<Time>> measurementsOp;
105 if (optimiseMultipleShots && hasMeasurementsOnlyAtEnd) {
106 bool isQiskitAer =
false;
112 measurementsOp =
dcirc->GetLastMeasurements(executed, isQiskitAer);
113 const auto &qbits = measurementsOp->GetQubits();
130 if (optimiseMultipleShots &&
131 (specialOptimizationForStatevector || hasMeasurementsOnlyAtEnd)) {
132 const auto &qbits = measurementsOp->GetQubits();
134 const auto sampleres =
optSim->SampleCountsMany(qbits,
curCnt);
136 for (
const auto &[mstate, cnt] : sampleres) {
137 measurementsOp->SetStateFromSample(mstate, state);
142 localRes[bits] += cnt;
148 for (
const auto &r : localRes)
res[r.first] += r.second;
157 for (
size_t i = 0; i <
curCnt; ++i) {
158 if (optimiseMultipleShots) {
161 optSim->SetGatesCounter(0);
163 dcirc->ExecuteMeasurements(
optSim, state, executed, &curMaxBondDimLocal);
165 dcirc->ExecuteBD(
optSim, state, &curMaxBondDimLocal);
168 optSim->SetGatesCounter(0);
181 for (
const auto &r : localRes)
res[r.first] += r.second;
193 const bool hasMeasurementsOnlyAtEnd = !
dcirc->HasOpsAfterMeasurements();
195 const bool specialOptimizationForStatevector =
196 optimiseMultipleShots &&
198 hasMeasurementsOnlyAtEnd;
199 const bool specialOptimizationForMPS =
200 optimiseMultipleShots &&
202 hasMeasurementsOnlyAtEnd;
206 optSim->SetMultithreading(
true);
217 if (optimiseMultipleShots) {
220 if (!specialOptimizationForStatevector &&
221 !specialOptimizationForMPS &&
curCnt > 1)
225 network->GetMPSOptimizeSwaps()) {
234 bool needToExecuteGates =
true;
237 needToExecuteGates =
false;
241 if (needToExecuteGates && optimiseMultipleShots) {
243 if (!specialOptimizationForStatevector &&
244 !specialOptimizationForMPS &&
curCnt > 1)
248 network->GetMPSOptimizeSwaps()) {
256 network->GetMPSOptimizeSwaps()) {
265 network->GetMPSOptimizeSwaps()) {
267 std::static_pointer_cast<Circuits::Circuit<Time>>(
dcirc->Clone());
268 circ->ConvertForCutting();
269 optSim->SetUpcomingGates(circ->GetOperations());
276 optSim->SetMultithreading(
true);
284 if (optimiseMultipleShots) {
287 if (!specialOptimizationForStatevector && !specialOptimizationForMPS &&
300 std::shared_ptr<Circuits::MeasurementOperation<Time>> measurementsOp;
304 if (optimiseMultipleShots && hasMeasurementsOnlyAtEnd) {
305 bool isQiskitAer =
false;
311 measurementsOp =
dcirc->GetLastMeasurements(executed, isQiskitAer);
312 const auto &qbits = measurementsOp->GetQubits();
323 if (optimiseMultipleShots &&
324 (specialOptimizationForStatevector || hasMeasurementsOnlyAtEnd)) {
325 const auto &qbits = measurementsOp->GetQubits();
327 const auto sampleres =
optSim->SampleCountsMany(qbits,
curCnt);
329 for (
const auto &[mstate, cnt] : sampleres) {
330 measurementsOp->SetStateFromSample(mstate, state);
344 for (
size_t i = 0; i <
curCnt; ++i) {
345 if (optimiseMultipleShots) {
348 optSim->SetGatesCounter(0);
355 optSim->SetGatesCounter(0);
376 void OptimizeMPSInitialQubitsMap(
377 std::shared_ptr<Simulators::ISimulator> &sim,
379 if (sim->GetSimulationType() ==
381 (
network->GetInitialQubitsMapOptimization() ||
382 network->GetMPSOptimizeSwaps()) &&
383 sim->SupportsMPSSwapOptimization()) {
385 const auto bondDimThreshold =
386 network->GetMPSOptimizationBondDimensionThreshold();
387 const auto maxBondDimValue =
388 config.GetConfigurationAsInt(
"matrix_product_state_max_bond_dimension");
390 if (maxBondDimValue == 0 ||
391 static_cast<int>(bondDimThreshold) <= maxBondDimValue) {
393 dcirc->ConvertForCutting();
394 auto layers =
dcirc->ToMultipleQubitsLayersNoClone();
397 dummySim.setGrowthFactorGate(
network->getGrowthFactorGate());
398 dummySim.setGrowthFactorSwap(
network->getGrowthFactorSwap());
399 if (maxBondDimValue != 0)
400 dummySim.SetMaxBondDimension(maxBondDimValue);
402 if (
network->GetInitialQubitsMapOptimization()) {
403 const auto optimalMap = dummySim.ComputeOptimalQubitsMap(layers);
404 sim->SetInitialQubitsMap(optimalMap);
409 if (
network->GetMPSOptimizeSwaps()) {
411 int lookaheadDepthLocal =
network->GetLookaheadDepth();
413 if (lookaheadDepthLocal == std::numeric_limits<int>::max()) {
414 double avgTwoQubitGatesPerLayer = 0.0;
415 for (
const auto &layer : layers) {
416 int twoQubitGates = 0;
417 for (
const auto &op : layer->GetOperations()) {
418 if (op->AffectedQubits().size() >= 2) {
422 avgTwoQubitGatesPerLayer += twoQubitGates;
424 avgTwoQubitGatesPerLayer /= layers.size();
427 static_cast<int>(4. * avgTwoQubitGatesPerLayer);
428 if (lookaheadVal > 15) lookaheadVal = 15;
430 lookaheadDepthLocal =
431 layers.size() < 8 ||
nrQubits <= 10 ? 0
432 : layers.size() < 15 ?
static_cast<int>(lookaheadVal)
433 : layers.size() < 25 ? static_cast<int>(1.5 * lookaheadVal)
437 int lookaheadHeuristicDepthLocal =
438 network->GetLookaheadDepthWithHeuristic();
440 if (lookaheadHeuristicDepthLocal == std::numeric_limits<int>::max())
441 lookaheadHeuristicDepthLocal =
442 layers.size() < 10 ||
nrQubits <= 10 ? 0
444 ? lookaheadDepthLocal - 1
445 : lookaheadDepthLocal - 2;
447 if (lookaheadHeuristicDepthLocal < 0)
448 lookaheadHeuristicDepthLocal = 0;
450 sim->SetUseOptimalMeetingPosition(
true);
451 sim->SetLookaheadDepth(lookaheadDepthLocal);
452 sim->SetLookaheadDepthWithHeuristic(lookaheadHeuristicDepthLocal);
453 sim->setGrowthFactorGate(
network->getGrowthFactorGate());
454 sim->setGrowthFactorSwap(
network->getGrowthFactorSwap());
455 sim->SetUpcomingGates(
dcirc->GetOperations());
463 std::shared_ptr<Circuits::Circuit<Time>>
dcirc;
475 std::shared_ptr<Simulators::ISimulator>
optSim;
482 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)