|
17 | 17 | #include <array> |
18 | 18 | #include <cmath> |
19 | 19 | #include <cstddef> |
20 | | -#include <format> |
21 | 20 | #include <llvm/ADT/STLExtras.h> |
22 | 21 | #include <mlir/IR/MLIRContext.h> |
23 | 22 | #include <mlir/IR/Operation.h> |
|
26 | 25 | #include <mlir/Support/LLVM.h> |
27 | 26 | #include <mlir/Support/LogicalResult.h> |
28 | 27 | #include <numbers> |
| 28 | +#include <random> |
29 | 29 | #include <string> |
30 | 30 | #include <unsupported/Eigen/MatrixFunctions> |
31 | 31 | #include <utility> |
@@ -149,11 +149,6 @@ struct GateDecompositionPattern final |
149 | 149 | matchAndRewrite(UnitaryInterface op, |
150 | 150 | mlir::PatternRewriter& rewriter) const override { |
151 | 151 | auto series = TwoQubitSeries::getTwoQubitSeries(op); |
152 | | - llvm::errs() << "SERIES SIZE: " << series.gates.size() << '\n'; |
153 | | - for (auto&& gate : series.gates) { |
154 | | - std::cerr << gate.op->getName().stripDialect().str() << ", "; |
155 | | - } |
156 | | - std::cerr << '\n'; |
157 | 152 |
|
158 | 153 | if (series.gates.size() < 3) { |
159 | 154 | // too short |
@@ -182,16 +177,11 @@ struct GateDecompositionPattern final |
182 | 177 | } |
183 | 178 | } |
184 | 179 | if (!bestSequence) { |
185 | | - llvm::errs() << "NO SEQUENCE GENERATED!\n"; |
186 | 180 | return mlir::failure(); |
187 | 181 | } |
188 | 182 | // only accept new sequence if it shortens existing series by more than two |
189 | 183 | // gates; this prevents an oscillation with phase gates |
190 | 184 | if (bestSequence->complexity() + 2 >= series.complexity) { |
191 | | - llvm::errs() << "SEQUENCE LONGER THAN INPUT (" |
192 | | - << bestSequence->gates.size() << "; " |
193 | | - << bestSequence->complexity() << " vs " << series.complexity |
194 | | - << ")\n"; |
195 | 185 | return mlir::failure(); |
196 | 186 | } |
197 | 187 |
|
@@ -483,57 +473,13 @@ struct GateDecompositionPattern final |
483 | 473 | {}); |
484 | 474 | } |
485 | 475 |
|
486 | | - std::cerr << "SERIES: "; |
487 | | - for (auto&& gate : series.gates) { |
488 | | - auto name = gate.op->getName().stripDialect().str(); |
489 | | - if (name == "x" && gate.qubitIds.size() == 2) { |
490 | | - // controls come first |
491 | | - std::cerr << std::format("cx() q[{}], q[{}];", gate.qubitIds[1], |
492 | | - gate.qubitIds[0]); |
493 | | - } else if (name == "i") { |
494 | | - } else if (gate.op.getParams().empty()) { |
495 | | - std::cerr << std::format( |
496 | | - "{}() q[{}] {};", name, gate.qubitIds[0], |
497 | | - (gate.qubitIds.size() > 1 |
498 | | - ? (", q[" + std::to_string(gate.qubitIds[1]) + "]") |
499 | | - : std::string{})); |
500 | | - } else { |
501 | | - auto parameter = helpers::getParameters(gate.op)[0]; |
502 | | - std::cerr << std::format( |
503 | | - "{}({}*pi) q[{}] {};", name, parameter / qc::PI, gate.qubitIds[0], |
504 | | - (gate.qubitIds.size() > 1 |
505 | | - ? (", q[" + std::to_string(gate.qubitIds[1]) + "]") |
506 | | - : std::string{})); |
507 | | - } |
508 | | - } |
509 | | - std::cerr << '\n'; |
510 | | - std::cerr << "GATE SEQUENCE!: gphase(" << sequence.globalPhase / qc::PI |
511 | | - << "*pi); \n"; |
512 | 476 | matrix4x4 unitaryMatrix = |
513 | 477 | helpers::kroneckerProduct(IDENTITY_GATE, IDENTITY_GATE); |
514 | 478 | for (auto&& gate : sequence.gates) { |
515 | 479 | auto gateMatrix = getTwoQubitMatrix(gate); |
516 | 480 | unitaryMatrix = gateMatrix * unitaryMatrix; |
517 | 481 |
|
518 | | - if (gate.type == qc::X && gate.qubitId.size() == 2) { |
519 | | - // controls come first |
520 | | - std::cerr << std::format("cx() q[{}], q[{}];", gate.qubitId[1], |
521 | | - gate.qubitId[0]); |
522 | | - } else if (gate.parameter.empty()) { |
523 | | - std::cerr << std::format( |
524 | | - "{}() q[{}] {};", qc::toString(gate.type), gate.qubitId[0], |
525 | | - (gate.qubitId.size() > 1 |
526 | | - ? (", q[" + std::to_string(gate.qubitId[1]) + "]") |
527 | | - : std::string{})); |
528 | | - } else { |
529 | | - std::cerr << std::format( |
530 | | - "{}({}*pi) q[{}] {};", qc::toString(gate.type), |
531 | | - gate.parameter[0] / qc::PI, gate.qubitId[0], |
532 | | - (gate.qubitId.size() > 1 |
533 | | - ? (", q[" + std::to_string(gate.qubitId[1]) + "]") |
534 | | - : std::string{})); |
535 | | - } |
536 | | - std::cerr << '\n'; |
| 482 | + // TODO: need to add each basis gate we want to use |
537 | 483 | if (gate.type == qc::X) { |
538 | 484 | mlir::SmallVector<mlir::Value, 1> inCtrlQubits; |
539 | 485 | if (gate.qubitId.size() > 1) { |
@@ -572,7 +518,6 @@ struct GateDecompositionPattern final |
572 | 518 | throw std::runtime_error{"Unknown gate type!"}; |
573 | 519 | } |
574 | 520 | } |
575 | | - std::cerr << '\n'; |
576 | 521 | assert((unitaryMatrix * std::exp(IM * sequence.globalPhase)) |
577 | 522 | .isApprox(series.getUnitaryMatrix(), SANITY_CHECK_PRECISION)); |
578 | 523 |
|
@@ -1769,8 +1714,10 @@ struct GateDecompositionPattern final |
1769 | 1714 | decomp, target1qEulerBases, 0, {}, true, std::nullopt); |
1770 | 1715 | eulerDecompositions.push_back(eulerDecomp); |
1771 | 1716 | } |
1772 | | - TwoQubitGateSequence gates{.globalPhase = |
1773 | | - targetDecomposition.globalPhase}; |
| 1717 | + TwoQubitGateSequence gates{ |
| 1718 | + .gates = {}, |
| 1719 | + .globalPhase = targetDecomposition.globalPhase, |
| 1720 | + }; |
1774 | 1721 | // Worst case length is 5x 1q gates for each 1q decomposition + 1x 2q |
1775 | 1722 | // gate We might overallocate a bit if the euler basis is different but |
1776 | 1723 | // the worst case is just 16 extra elements with just a String and 2 |
|
0 commit comments