Commit 2288ba69 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Got inliner to work: inline QASM3 subroutines



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 94519a75
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -18,17 +18,25 @@ struct QuantumInlinerInterface : public DialectInlinerInterface {
  /// This hook checks to see if the given callable operation is legal to inline
  /// into the given call.
  /// Operations in Quantum dialect are always legal to inline.
  bool isLegalToInline(Operation *, Operation *, bool) const final {
  bool isLegalToInline(Operation *call, Operation *callable,
                       bool wouldBeCloned) const final {
    return true;
  }

  /// This hook checks to see if the given operation is legal to inline into the
  /// given region.
  /// Always legal to inline.
  bool isLegalToInline(Operation *, Region *, bool,
  /// Only inline VSOp for now:
  // FIXME: there is a weird error when qalloc is inlined at MLIR level
  // hence, just allow VSOp to be inlined for the timebeing.
  // i.e. all quantum subroutines that only contain VSOp's can be inlined.
  bool isLegalToInline(Operation *op, Region *regione, bool,
                       BlockAndValueMapping &) const final {
    if (dyn_cast_or_null<mlir::quantum::ValueSemanticsInstOp>(op)) {
      return true;
    }

    return false;
  }
};
} // namespace
//===----------------------------------------------------------------------===//
+28 −0
Original line number Diff line number Diff line
@@ -96,6 +96,34 @@ cx q[0], q[1];
  EXPECT_EQ(countSubstring(llvm, "__quantum__rt__qubit_release_array"), 0);
}

TEST(qasm3PassManagerTester, checkInliner) {
  // Inline a call ==> gate cancellation
  const std::string src = R"#(OPENQASM 3;
include "qelib1.inc";
gate oracle b {
  x b;
}

qubit q[2];
x q[0];
oracle q[0];
)#";
  auto llvm =
      qcor::mlir_compile("qasm3", src, "test_kernel", qcor::OutputType::LLVMIR, false);
  std::cout << "LLVM:\n" << llvm << "\n";
  
  // Get the main kernel section only (there is the oracle LLVM section as well)
  llvm = llvm.substr(llvm.find("@test_kernel"));
  const auto last = llvm.find_first_of("}");
  llvm = llvm.substr(0, last + 1);
  std::cout << "LLVM:\n" << llvm << "\n";
  // No gates, extract, or alloc/dealloc:
  EXPECT_EQ(countSubstring(llvm, "__quantum__qis"), 0);
  EXPECT_EQ(countSubstring(llvm, "__quantum__rt__array_get_element_ptr_1d"), 0);
  EXPECT_EQ(countSubstring(llvm, "__quantum__rt__qubit_allocate_array"), 0);
  EXPECT_EQ(countSubstring(llvm, "__quantum__rt__qubit_release_array"), 0);
}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  auto ret = RUN_ALL_TESTS();