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

MLIR gen support for qubit array aliasing



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 77977ed4
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -17,11 +17,26 @@ def QallocOp : QuantumOp<"qalloc", []> {
    let results = (outs ArrayType:$qubits);
}

// Create an array holding Qubit pointers for aliasing purposes,
// i.e. not allocating new qubits.
def QaliasArrayAllocOp : QuantumOp<"createQubitArray", []> {
    let arguments = (ins AnyI64Attr:$size, StrAttr:$name);
    let results = (outs ArrayType:$qubits);
}

def ExtractQubitOp : QuantumOp<"qextract", []> {
    let arguments = (ins ArrayType:$qreg, AnyInteger:$idx);
    let results = (outs QubitType:$qbit);
}

// Assign a qubit pointer (extracted w/ qextract) to an alias pointer. 
// Signature: void qassign(Qubit* destination, Qubit* source)
// where destination and source are retrieved by qextract.
def AssignQubitOp : QuantumOp<"qassign", []> {
    let arguments = (ins QubitType:$dest, QubitType:$src);
    let results = (outs);
}

def InstOp : QuantumOp<"inst", [AttrSizedOperandSegments]> {
    let arguments = (ins StrAttr:$name, Variadic<QubitType>:$qubits, Variadic<F64>:$params);
    let results = (outs Optional<ResultType>:$bit);
+5 −0
Original line number Diff line number Diff line
@@ -7,3 +7,8 @@ add_test(NAME qcor_qasm3_quantum_decl_tester COMMAND qasm3VisitorTester)
target_include_directories(qasm3VisitorTester PRIVATE . ../../ ${XACC_ROOT}/include/gtest)
target_link_libraries(qasm3VisitorTester qcor-mlir-api gtest gtest_main)

link_directories(${XACC_ROOT}/lib)
add_executable(qasm3VisitorAliasTester test_alias_handler.cpp)
add_test(NAME qcor_qasm3_quantum_alias_decl_tester COMMAND test_alias_handler)
target_include_directories(qasm3VisitorAliasTester PRIVATE . ../../ ${XACC_ROOT}/include/gtest)
target_link_libraries(qasm3VisitorAliasTester qcor-mlir-api gtest gtest_main)
 No newline at end of file
+22 −0
Original line number Diff line number Diff line
#include "gtest/gtest.h"
#include "qcor_mlir_api.hpp"

TEST(qasm3VisitorTester, checkAlias) {
  std::cout << "HOWDY\n";
  const std::string src = R"#(OPENQASM 3;
include "qelib1.inc";
qubit q[6];
// myreg[0] refers to the qubit q[1]
let myreg = q[1, 3, 5];
)#";
  auto mlir =
      qcor::mlir_compile("qasm3", src, "test", qcor::OutputType::MLIR, true);
  std::cout << "MLIR:\n" << mlir << "\n";
  qcor::execute("qasm3", src, "test");
}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  auto ret = RUN_ALL_TESTS();
  return ret;
}
+15 −10
Original line number Diff line number Diff line
@@ -19,9 +19,6 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
  //     | indexIdentifier '||' indexIdentifier
  //     ;

  printErrorMessage(
      "Alias not yet supported yet - Thien, remove this for development.");

  // The name of the new alias register, pointing to previously allocated
  // register
  auto alias = context->Identifier()->getText();
@@ -36,12 +33,12 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
    auto expressions =
        context->indexIdentifier()->expressionList()->expression();
    auto n_expressions = expressions.size();    

    // Allocate a new array of qubits of given size
    // Create a qubit array of given size
    // which keeps alias references to Qubits in the original input array. 
    auto str_attr = builder.getStringAttr(alias);
    auto integer_attr =
        mlir::IntegerAttr::get(builder.getI64Type(), n_expressions);
    mlir::Value allocation = builder.create<mlir::quantum::QallocOp>(
    mlir::Value alias_allocation = builder.create<mlir::quantum::QaliasArrayAllocOp>(
        location, array_type, integer_attr, str_attr);

    auto counter = 0;
@@ -51,13 +48,21 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
      auto idx =
          symbol_table.evaluate_constant_integer_expression(expr->getText());

      // get the extracted element from the original register
      auto extracted = builder.create<mlir::quantum::ExtractQubitOp>(
      // get the src_extracted element from the original register
      auto src_extracted = builder.create<mlir::quantum::ExtractQubitOp>(
          location, qubit_type, allocated_symbol,
          get_or_create_constant_integer_value(
              idx, location, builder.getI64Type(), symbol_table, builder));

      // get the dest_extracted element from the alias register
      auto dest_extracted = builder.create<mlir::quantum::ExtractQubitOp>(
          location, qubit_type, alias_allocation,
          get_or_create_constant_integer_value(
              counter, location, builder.getI64Type(), symbol_table, builder));
      ++counter;
      // use extracted with a new qassign dialect operation.
      // void qAssign(Qubit* dest, Qubit* src)
      builder.create<mlir::quantum::AssignQubitOp>(location, dest_extracted,
                                                   src_extracted);
    }

  } else if (auto range_def = context->indexIdentifier()->rangeDefinition()) {