Commit 9f220cb8 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

updates to handle openqasm from staq.

parent 125fe1e6
Loading
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
#include <qalloc>

__qpu__ void add_3_5(qreg a, qreg b, qreg c) {
  using qcor::openqasm;

  oracle adder a0,a1,a2,a3,b0,b1,b2,b3,c0,c1,c2,c3 { "add_3_5.v" }

  creg result[4];
  // a = 3
  x a[0];
  x a[1];

  // b = 5
  x b[0];
  x b[2];

  adder a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],c[0],c[1],c[2],c[3];

  // measure
  measure c -> result;
}

int main(int argc, char** argv) {

    auto a = qalloc(4);
    auto b = qalloc(4);
    auto c = qalloc(4);

    // Execute on the quantum accelerator
    add_3_5(a, b, c);

    // Get the results and display
    auto counts = c.counts();
    for (const auto & kv: counts) {
        printf("%s: %i\n", kv.first.c_str(), kv.second);
    }
}

examples/qrt/add_3_5.v

0 → 100644
+31 −0
Original line number Diff line number Diff line
module top (\a[0],\a[1],\a[2],\a[3],\b[0],\b[1],\b[2],\b[3],\c[0],\c[1],\c[2],\c[3]);
  input \a[0],\a[1],\a[2],\a[3],\b[0],\b[1],\b[2],\b[3];
  output \c[0],\c[1],\c[2],\c[3];
  wire n386,n387,n388,n389,n390,n391,n392,n393,n394,n395,n396,n397,n398,n399,n400,n401,n402,n403,n404,n405,n406,n407,n408,n409,n410 ;
  assign n386 = \a[0]  & ~\b[0] ;
  assign n387 = ~\a[0]  & \b[0] ;
  assign \c[0]  = n386 | n387;
  assign n389 = \a[0]  & \b[0] ;
  assign n390 = ~\a[1]  & ~\b[1] ;
  assign n391 = \a[1]  & \b[1] ;
  assign n392 = ~n390 & ~n391;
  assign n393 = n389 & ~n392;
  assign n394 = ~n389 & n392;
  assign \c[1]  = n393 | n394;
  assign n396 = n389 & ~n390;
  assign n397 = ~n391 & ~n396;
  assign n398 = ~\a[2]  & ~\b[2] ;
  assign n399 = \a[2]  & \b[2] ;
  assign n400 = ~n398 & ~n399;
  assign n401 = n397 & ~n400;
  assign n402 = ~n397 & n400;
  assign \c[2]  = ~n401 & ~n402;
  assign n404 = ~n397 & ~n398;
  assign n405 = ~n399 & ~n404;
  assign n406 = ~\a[3]  & ~\b[3] ;
  assign n407 = \a[3]  & \b[3] ;
  assign n408 = ~n406 & ~n407;
  assign n409 = n405 & ~n408;
  assign n410 = ~n405 & n408;
  assign \c[3]  = ~n409 & ~n410;
endmodule
+150 −18
Original line number Diff line number Diff line
@@ -155,26 +155,30 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,
      current_token = Toks[i];
      current_token_str = PP.getSpelling(current_token);
    }
    if (ss.str().find("oracle") == std::string::npos) {
      ss << terminating_char;
    }

    // std::cout << "COMPILING\n"
    //           << function_prototype + "{" + ss.str() + "}"
    //           << function_prototype + "{\n" + ss.str() + "\n}"
    //           << "\n";

    // FIXME, check canParse, and if not, then just write ss.str() to qrt_code
    // somehow

    // FIXME, may return multiple instructions
    return compiler
        ->compile("__qpu__ " + function_prototype + "{" + ss.str() + "}")
        ->getComposites()[0]
        ->getInstruction(0);
        ->compile("__qpu__ " + function_prototype + "{\n" + ss.str() + "\n}")
        ->getComposites()[0];
  };

  auto compiler = xacc::getCompiler("xasm");
  auto terminating_char = compiler->get_statement_terminator();

  std::stringstream qrt_code;
  std::string extra_preamble = "";
  std::string extra_preamble = "", language = "xasm";
  std::map<std::string, std::string> oracle_name_to_extra_preamble;
  std::map<std::string, int> creg_name_to_size;

  for (int i = 0; i < Toks.size(); i++) {
    auto current_token = Toks[i];
@@ -183,7 +187,7 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,
    if (current_token.is(clang::tok::kw_using)) {
      // Found using
      // i+3 bc we skip using, qcor and ::;
      auto language = PP.getSpelling(Toks[i + 3]);
      language = PP.getSpelling(Toks[i + 3]);
      if (language == "openqasm") {
        // use staq
        language = xacc::hasCompiler("staq") ? "staq" : "openqasm";
@@ -207,6 +211,103 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,
      continue;
    }

    if (current_token_str == "oracle") {
      if (language != "staq") {
        xacc::error("Error - must specify 'using qcor::openqasm;' before using "
                    "staq openqasm code.");
      }
      std::stringstream slurp_oracle;
      i++;
      current_token = Toks[i];
      std::string oracle_name = PP.getSpelling(current_token);
      slurp_oracle << "oracle " << oracle_name << " ";

      while (true) {

        i++;
        current_token = Toks[i];
        slurp_oracle << PP.getSpelling(current_token);

        if (current_token.is(clang::tok::r_brace)) {
          break;
        }
      }

      auto preamble = slurp_oracle.str() + "\n";

      oracle_name_to_extra_preamble.insert({oracle_name, preamble});
      continue;
    }

    if (oracle_name_to_extra_preamble.count(current_token_str)) {
      // add the appropriate preamble here
      extra_preamble += oracle_name_to_extra_preamble[current_token_str];
      auto comp_inst = process_inst_stmt(i, compiler, current_token,
                                         terminating_char, extra_preamble);
      {
        auto visitor = std::make_shared<qrt_mapper>();
        xacc::InstructionIterator iter(comp_inst);
        while (iter.hasNext()) {
          auto next = iter.next();
          if (!next->isComposite()) {
            next->accept(visitor);
          }
        }
        qrt_code << visitor->get_new_src();
      }
      continue;
    }

    if (current_token_str == "measure") {
      // we have an ibm style measure,
      // so make sure that we map to individual measures
      // since we don't know the size of the qreg

      // next token is qreg name
      i++;
      current_token = Toks[i];
      current_token_str = PP.getSpelling(current_token);
      auto qreg_name = current_token_str;

      // next token could be [ or could be ->
      i++;
      current_token = Toks[i];
      if (current_token.is(clang::tok::l_square)) {
        i--;
        i--;
        current_token = Toks[i];
        // This we can parse, so just eat it up and get the Measure IR node out
        auto comp_inst = process_inst_stmt(i, compiler, current_token,
                                           terminating_char, extra_preamble);
        {
          auto visitor = std::make_shared<qrt_mapper>();
          xacc::InstructionIterator iter(comp_inst);
          while (iter.hasNext()) {
            auto next = iter.next();
            if (!next->isComposite()) {
              next->accept(visitor);
            }
          }
          // inst->accept(visitor);
          qrt_code << visitor->get_new_src();
        }
        continue;
      } else {
        // the token is ->

        // the next one is the creg name
        i++;
        current_token = Toks[i];
        current_token_str = PP.getSpelling(current_token);
        auto creg_name = current_token_str;
        auto size = creg_name_to_size[creg_name];
        for (int k = 0; k < size; k++) {
          qrt_code << "quantum::mz(" << qreg_name << "["<<k<<"]); // hello\n";
        }
        continue;
      }
    }

    // FIXME may want this later
    // if (current_token_str == "qreg") {

@@ -241,6 +342,12 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,

    if (current_token_str == "creg") {

      auto creg_name = PP.getSpelling(Toks[i + 1]);
      auto creg_size = PP.getSpelling(Toks[i + 3]);

      std::cout << "CREG: " << creg_name << ", " << creg_size << "\n";
      creg_name_to_size.insert({creg_name, std::stoi(creg_size)});

      std::stringstream sss;
      while (current_token.isNot(clang::tok::semi)) {
        sss << current_token_str << " ";
@@ -293,11 +400,18 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,
        while (l_brace_count != 0) {
          // In here we have statements separated by compiler terminator
          // (default ';')
          auto inst = process_inst_stmt(i, compiler, current_token,
          auto comp_inst = process_inst_stmt(i, compiler, current_token,
                                             terminating_char, extra_preamble);
          {
            auto visitor = std::make_shared<qrt_mapper>();
            inst->accept(visitor);
            xacc::InstructionIterator iter(comp_inst);
            while (iter.hasNext()) {
              auto next = iter.next();
              if (!next->isComposite()) {
                next->accept(visitor);
              }
            }
            // inst->accept(visitor);
            qrt_code << visitor->get_new_src();
          }
          // missing ';', eat it up too
@@ -325,11 +439,17 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,

        qrt_code << "\n   ";

        auto inst = process_inst_stmt(i, compiler, current_token,
        auto comp_inst = process_inst_stmt(i, compiler, current_token,
                                           terminating_char, extra_preamble);
        {
          auto visitor = std::make_shared<qrt_mapper>();
          inst->accept(visitor);
          xacc::InstructionIterator iter(comp_inst);
          while (iter.hasNext()) {
            auto next = iter.next();
            if (!next->isComposite()) {
              next->accept(visitor);
            }
          }
          qrt_code << visitor->get_new_src();
        }

@@ -344,11 +464,17 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,

    // this is a quantum statement + terminating char
    // slurp up to the terminating char
    auto inst = process_inst_stmt(i, compiler, current_token, terminating_char,
                                  extra_preamble);
    auto comp_inst = process_inst_stmt(i, compiler, current_token,
                                       terminating_char, extra_preamble);
    {
      auto visitor = std::make_shared<qrt_mapper>();
      inst->accept(visitor);
      xacc::InstructionIterator iter(comp_inst);
      while (iter.hasNext()) {
        auto next = iter.next();
        if (!next->isComposite()) {
          next->accept(visitor);
        }
      }
      qrt_code << visitor->get_new_src();
    }
  }
@@ -360,6 +486,12 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,
  for (auto &buf : bufferNames) {
    OS << buf << ".setNameAndStore(\"" + buf + "\");\n";
  }

  if (!oracle_name_to_extra_preamble.empty()) {
    // we had an oracle synthesis, just add an
    // anc registry preemptively
    OS << "auto anc = qalloc(" << std::numeric_limits<int>::max() << ");\n";
  }
  if (shots > 0) {
    OS << "quantum::set_shots(" << shots << ");\n";
  }
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ void one_qubit_inst(const std::string &name, const qubit &qidx,

void h(const qubit &qidx) { one_qubit_inst("H", qidx); }
void x(const qubit &qidx) { one_qubit_inst("X", qidx); }
void t(const qubit &qidx) { one_qubit_inst("T", qidx); }
void tdg(const qubit &qidx) { one_qubit_inst("Tdg", qidx); }

void rx(const qubit &qidx, const double theta) {
  one_qubit_inst("Rx", qidx, {theta});
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ void one_qubit_inst(const std::string &name, const qubit &qidx,

void h(const qubit &qidx);
void x(const qubit &qidx);
void t(const qubit & qidx);
void tdg(const qubit& qidx);

void rx(const qubit &qidx, const double theta);
void ry(const qubit &qidx, const double theta);