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 &&
98 std::shared_ptr<Circuits::MeasurementOperation<Time>> measurementsOp;
102 if (optimiseMultipleShots && hasMeasurementsOnlyAtEnd) {
103 bool isQiskitAer =
false;
109 measurementsOp =
dcirc->GetLastMeasurements(executed, isQiskitAer);
110 const auto &qbits = measurementsOp->GetQubits();
124 if (optimiseMultipleShots &&
125 (specialOptimizationForStatevector || hasMeasurementsOnlyAtEnd)) {
126 const auto &qbits = measurementsOp->GetQubits();
128 const auto sampleres =
optSim->SampleCountsMany(qbits,
curCnt);
130 for (
const auto &[mstate, cnt] : sampleres) {
131 measurementsOp->SetStateFromSample(mstate, state);
136 localRes[bits] += cnt;
142 for (
const auto &r : localRes)
res[r.first] += r.second;
148 for (
size_t i = 0; i <
curCnt; ++i) {
149 if (optimiseMultipleShots) {
152 optSim->SetGatesCounter(0);
154 dcirc->ExecuteMeasurements(
optSim, state, executed);
159 optSim->SetGatesCounter(0);
172 for (
const auto &r : localRes)
res[r.first] += r.second;
181 const bool hasMeasurementsOnlyAtEnd = !
dcirc->HasOpsAfterMeasurements();
183 const bool specialOptimizationForStatevector =
184 optimiseMultipleShots &&
186 hasMeasurementsOnlyAtEnd;
187 const bool specialOptimizationForMPS =
188 optimiseMultipleShots &&
190 hasMeasurementsOnlyAtEnd;
194 optSim->SetMultithreading(
true);
200 optSim->Configure(
"matrix_product_state_max_bond_dimension",
203 optSim->Configure(
"matrix_product_state_truncation_threshold",
213 if (optimiseMultipleShots) {
216 if (!specialOptimizationForStatevector &&
217 !specialOptimizationForMPS &&
curCnt > 1)
221 network->GetMPSOptimizeSwaps())
227 bool needToExecuteGates =
true;
230 needToExecuteGates =
false;
234 if (needToExecuteGates && optimiseMultipleShots) {
236 if (!specialOptimizationForStatevector &&
237 !specialOptimizationForMPS &&
curCnt > 1)
241 network->GetMPSOptimizeSwaps())
246 network->GetMPSOptimizeSwaps())
252 network->GetMPSOptimizeSwaps())
259 optSim->SetMultithreading(
true);
262 optSim->Configure(
"matrix_product_state_max_bond_dimension",
265 optSim->Configure(
"matrix_product_state_truncation_threshold",
275 if (optimiseMultipleShots) {
278 if (!specialOptimizationForStatevector && !specialOptimizationForMPS &&
288 std::shared_ptr<Circuits::MeasurementOperation<Time>> measurementsOp;
292 if (optimiseMultipleShots && hasMeasurementsOnlyAtEnd) {
293 bool isQiskitAer =
false;
299 measurementsOp =
dcirc->GetLastMeasurements(executed, isQiskitAer);
300 const auto &qbits = measurementsOp->GetQubits();
311 if (optimiseMultipleShots &&
312 (specialOptimizationForStatevector || hasMeasurementsOnlyAtEnd)) {
313 const auto &qbits = measurementsOp->GetQubits();
315 const auto sampleres =
optSim->SampleCountsMany(qbits,
curCnt);
317 for (
const auto &[mstate, cnt] : sampleres) {
318 measurementsOp->SetStateFromSample(mstate, state);
332 for (
size_t i = 0; i <
curCnt; ++i) {
333 if (optimiseMultipleShots) {
336 optSim->SetGatesCounter(0);
338 dcirc->ExecuteMeasurements(
optSim, state, executed);
343 optSim->SetGatesCounter(0);
364 void OptimizeMPSInitialQubitsMap(
365 std::shared_ptr<Simulators::ISimulator> &sim,
367 if (sim->GetSimulationType() ==
369 (
network->GetInitialQubitsMapOptimization() ||
370 network->GetMPSOptimizeSwaps()) &&
371 sim->SupportsMPSSwapOptimization()) {
373 const auto bondDimThreshold =
374 network->GetMPSOptimizationBondDimensionThreshold();
375 const auto maxBondDimValue =
378 if (
maxBondDim.empty() ||
static_cast<int>(bondDimThreshold) <= maxBondDimValue) {
380 dcirc->ConvertForCutting();
381 auto layers =
dcirc->ToMultipleQubitsLayersNoClone();
384 dummySim.setGrowthFactorGate(
network->getGrowthFactorGate());
385 dummySim.setGrowthFactorSwap(
network->getGrowthFactorSwap());
387 dummySim.SetMaxBondDimension(maxBondDimValue);
389 if (
network->GetInitialQubitsMapOptimization()) {
390 const auto optimalMap = dummySim.ComputeOptimalQubitsMap(layers);
391 sim->SetInitialQubitsMap(optimalMap);
396 if (
network->GetMPSOptimizeSwaps()) {
398 int lookaheadDepthLocal =
network->GetLookaheadDepth();
400 if (lookaheadDepthLocal == std::numeric_limits<int>::max()) {
401 double avgTwoQubitGatesPerLayer = 0.0;
402 for (
const auto &layer : layers) {
403 int twoQubitGates = 0;
404 for (
const auto &op : layer->GetOperations()) {
405 if (op->AffectedQubits().size() >= 2) {
409 avgTwoQubitGatesPerLayer += twoQubitGates;
411 avgTwoQubitGatesPerLayer /= layers.size();
414 static_cast<int>(4. * avgTwoQubitGatesPerLayer);
415 if (lookaheadVal > 15) lookaheadVal = 15;
417 lookaheadDepthLocal = layers.size() < 10 ||
nrQubits <= 10 ? 0
419 ?
static_cast<int>(lookaheadVal)
420 : layers.size() < 35 ? 1.5 * lookaheadVal
424 int lookaheadHeuristicDepthLocal =
425 network->GetLookaheadDepthWithHeuristic();
427 if (lookaheadHeuristicDepthLocal == std::numeric_limits<int>::max())
428 lookaheadHeuristicDepthLocal =
429 layers.size() < 10 ||
nrQubits <= 10 ? 0
431 ? lookaheadDepthLocal - 1
432 : lookaheadDepthLocal - 2;
434 sim->SetUseOptimalMeetingPosition(
true);
435 sim->SetLookaheadDepth(lookaheadDepthLocal);
436 sim->SetLookaheadDepthWithHeuristic(lookaheadHeuristicDepthLocal);
437 sim->setGrowthFactorGate(
network->getGrowthFactorGate());
438 sim->setGrowthFactorSwap(
network->getGrowthFactorSwap());
439 sim->SetUpcomingGates(
dcirc->GetOperations());
447 std::shared_ptr<Circuits::Circuit<Time>>
dcirc;
459 std::shared_ptr<Simulators::ISimulator>
optSim;
467 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)