Commit 3b69a4ff authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Added the pass to remove consecutive reset ops



2 resets -> just need to keep 1.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent ddf60396
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -32,6 +32,30 @@ cx q[0], q[1];
  EXPECT_TRUE(llvm.find("__quantum__qis") == std::string::npos);
}

TEST(qasm3PassManagerTester, checkResetSimplification) {
  const std::string src = R"#(OPENQASM 3;
include "qelib1.inc";
qubit q[2];

reset q[0];
x q[1];
reset q[0];
)#";
  auto llvm =
      qcor::mlir_compile(src, "test_kernel", qcor::OutputType::LLVMIR, false);
  std::cout << "LLVM:\n" << llvm << "\n";

  // Get the main kernel section only
  llvm = llvm.substr(llvm.find("@__internal_mlir_test_kernel"));
  const auto last = llvm.find_first_of("}");
  llvm = llvm.substr(0, last + 1);
  std::cout << "LLVM:\n" << llvm << "\n";
  // One reset and one X:
  EXPECT_EQ(countSubstring(llvm, "__quantum__qis"), 2);
  EXPECT_EQ(countSubstring(llvm, "__quantum__qis__x"), 1);
  EXPECT_EQ(countSubstring(llvm, "__quantum__qis__reset"), 1);
}

TEST(qasm3PassManagerTester, checkRotationMerge) {
  const std::string src = R"#(OPENQASM 3;
include "qelib1.inc";
+43 −0
Original line number Diff line number Diff line
@@ -130,4 +130,47 @@ void CNOTIdentityPairRemovalPass::runOnOperation() {
    op.erase();
  }
}

void DuplicateResetRemovalPass::getDependentDialects(
    DialectRegistry &registry) const {
  registry.insert<LLVM::LLVMDialect>();
}

void DuplicateResetRemovalPass::runOnOperation() {
  // Walk the operations within the function.
  std::vector<mlir::quantum::ValueSemanticsInstOp> deadOps;
  getOperation().walk([&](mlir::quantum::ValueSemanticsInstOp op) {
    if (std::find(deadOps.begin(), deadOps.end(), op) != deadOps.end()) {
      // Skip this op since it was deleted (forward search)
      return;
    }
    auto inst_name = op.name();
    
    if (inst_name != "reset") {
      return;
    }

    auto return_value = *op.result().begin();
    if (return_value.hasOneUse()) {
      // get that one user
      auto user = *return_value.user_begin();
      // cast to a inst op
      if (auto next_inst =
              dyn_cast_or_null<mlir::quantum::ValueSemanticsInstOp>(user)) {
        if (next_inst.name().str() == "reset") {
          // Two resets in a row:
          // Chain the input -> output and mark this second reset to delete:
          (*next_inst.result_begin())
              .replaceAllUsesWith(next_inst.getOperand(0));
          deadOps.emplace_back(next_inst);
        }
      }
    }
  });

  for (auto &op : deadOps) {
    op->dropAllUses();
    op.erase();
  }
}
} // namespace qcor
+9 −0
Original line number Diff line number Diff line
@@ -29,4 +29,13 @@ struct CNOTIdentityPairRemovalPass
  void runOnOperation() final;
  CNOTIdentityPairRemovalPass() {}
};

// Remove duplicate reset:
// 2 consecutive resets on a single qubit line => remove one.
struct DuplicateResetRemovalPass
    : public PassWrapper<DuplicateResetRemovalPass, OperationPass<ModuleOp>> {
  void getDependentDialects(DialectRegistry &registry) const override;
  void runOnOperation() final;
  DuplicateResetRemovalPass() {}
};
} // namespace qcor
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ void configureOptimizationPasses(mlir::PassManager &passManager) {
    // Simple Identity pair removals
    passManager.addPass(std::make_unique<SingleQubitIdentityPairRemovalPass>());
    passManager.addPass(std::make_unique<CNOTIdentityPairRemovalPass>());
    passManager.addPass(std::make_unique<DuplicateResetRemovalPass>());
    
    // Rotation merging
    passManager.addPass(std::make_unique<RotationMergingPass>());