Commit 34f82ade authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

fixing bug in qcor syntax handler for function prototype args, adding exp qrt function

parent a499bed0
Loading
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
#include "token_collector_util.hpp"
#include <iostream>
#include <regex>
#include <sstream>

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Type.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Parse/Parser.h"
@@ -66,14 +68,17 @@ public:

      auto parm_var_decl = cast<ParmVarDecl>(decl);
      if (parm_var_decl) {
        auto type = parm_var_decl->getType().getCanonicalType().getAsString();
        auto type = QualType::getAsString(parm_var_decl->getType().split(),
                                           PrintingPolicy{{}});
                    // parm_var_decl->getType().getCanonicalType().getAsString();
        program_arg_types.push_back(type);
        program_parameters.push_back(ident->getName().str());
        if (type == "class xacc::internal_compiler::qreg") {
          bufferNames.push_back(ident->getName().str());
          function_prototype += "qreg " + ident->getName().str() + ", ";
        } else {
          function_prototype += type + " " + ident->getName().str() + ", ";
          function_prototype +=
              type + " " + ident->getName().str() + ", ";
        }
      }
    }
+12 −4
Original line number Diff line number Diff line
@@ -5,8 +5,10 @@
#include <qalloc>

#include "AllGateVisitor.hpp"

#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/Token.h"

namespace qcor {

void set_verbose(bool verbose) { xacc::set_verbose(verbose); }
@@ -53,7 +55,7 @@ run_token_collector(clang::Preprocessor &PP, clang::CachedTokens &Toks,

using namespace xacc::quantum;

class qrt_mapper : public AllGateVisitor {
class qrt_mapper : public AllGateVisitor, public xacc::InstructionVisitor<Circuit> {
protected:
  std::stringstream ss;

@@ -104,6 +106,11 @@ public:
  void visit(Measure &measure) override { addOneQubitGate("mz", measure); }
  void visit(Identity &i) override { addOneQubitGate("i", i); }
  void visit(U &u) override { addOneQubitGate("u", u); }
  void visit(Circuit& circ) override {
    if (circ.name() == "exp_i_theta") {
        ss << "quantum::exp(q"  << ", " << circ.getArguments()[0]->name << ", " << circ.getArguments()[1]->name << ");\n";
    }
  }
  void visit(IfStmt &ifStmt) override {}
};

@@ -146,9 +153,9 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,
    }
    ss << terminating_char;

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

    // FIXME, check canParse, and if not, then just write ss.str() to qrt_code
    // somehow
@@ -334,6 +341,7 @@ void run_token_collector_llvm_rt(clang::Preprocessor &PP,
                                  extra_preamble);
    {
      auto visitor = std::make_shared<qrt_mapper>();
      std::cout << "HELLO WORLD ACCEPTING: " << inst->name() << "\n";
      inst->accept(visitor);
      qrt_code << visitor->get_new_src();
    }
+3 −0
Original line number Diff line number Diff line
@@ -197,12 +197,15 @@ auto observe(QuantumKernel &kernel, std::shared_ptr<Observable> obs,
             Args... args) {
  auto program = __internal__::kernel_as_composite_instruction(kernel, args...);
  return [program, obs](Args... args) {
      
    // Get the first argument, which should be a qreg
    auto q = std::get<0>(std::forward_as_tuple(args...));
    // std::cout << "\n" << program->toString() << "\n";

    // Set the arguments on the IR
#ifndef QCOR_USE_QRT
    program->updateRuntimeArguments(args...);
#endif
    // std::cout << "\n" << program->toString() << "\n";

    // Observe the program
+2 −2
Original line number Diff line number Diff line
@@ -4,9 +4,9 @@ file(GLOB SRC *.cpp)

add_library(${LIBRARY_NAME} SHARED ${SRC})

target_include_directories(${LIBRARY_NAME} PUBLIC .)
target_include_directories(${LIBRARY_NAME} PUBLIC . ${XACC_ROOT}/include/eigen)

target_link_libraries(${LIBRARY_NAME} PUBLIC xacc::xacc)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc::xacc xacc::quantum_gate xacc::pauli)

xacc_configure_library_rpath(${LIBRARY_NAME})

+107 −0
Original line number Diff line number Diff line
#include "qrt.hpp"
#include "Instruction.hpp"
#include "PauliOperator.hpp"
#include "xacc.hpp"
#include "xacc_internal_compiler.hpp"
#include <Eigen/Dense>
#include <Utils.hpp>

namespace quantum {
std::shared_ptr<xacc::CompositeInstruction> program = nullptr;
@@ -48,6 +52,109 @@ void cnot(const qubit &src_idx, const qubit &tgt_idx) {
  program->addInstruction(cx);
}

void exp(qreg q, const double theta, xacc::Observable *H) {
  exp(q, theta, xacc::as_shared_ptr(H));
}

void exp(qreg q, const double theta, std::shared_ptr<xacc::Observable> H) {

  std::unordered_map<std::string, xacc::quantum::Term> terms;

  terms = dynamic_cast<xacc::quantum::PauliOperator *>(H.get())->getTerms();

  double pi = xacc::constants::pi;
  auto gateRegistry = xacc::getIRProvider("quantum");
  std::string xasm_src = "";

  for (auto inst : terms) {

    auto spinInst = inst.second;

    // Get the individual pauli terms
    auto termsMap = std::get<2>(spinInst);

    std::vector<std::pair<int, std::string>> terms;
    for (auto &kv : termsMap) {
      if (kv.second != "I" && !kv.second.empty()) {
        terms.push_back({kv.first, kv.second});
      }
    }
    // The largest qubit index is on the last term
    int largestQbitIdx = terms[terms.size() - 1].first;

    std::vector<std::size_t> qidxs;
    std::stringstream basis_front, basis_back;

    for (auto &term : terms) {

      auto qid = term.first;
      auto pop = term.second;

      qidxs.push_back(qid);

      if (pop == "X") {

        basis_front << "H(q[" << qid << "]);\n";
        basis_back << "H(q[" << qid << "]);\n";

      } else if (pop == "Y") {
        basis_front << "Rx(q[" << qid << "], " << 1.57079362679 << ");\n";
        basis_back << "Rx(q[" << qid << "], " << -1.57079362679 << ");\n";
      }
    }

    // std::cout << "QIDS:  " << qidxs << "\n";

    Eigen::MatrixXi cnot_pairs(2, qidxs.size() - 1);
    for (int i = 0; i < qidxs.size() - 1; i++) {
      cnot_pairs(0, i) = qidxs[i];
    }
    for (int i = 0; i < qidxs.size() - 1; i++) {
      cnot_pairs(1, i) = qidxs[i + 1];
    }

    // std::cout << "HOWDY: \n" << cnot_pairs << "\n";
    std::stringstream cnot_front, cnot_back;
    for (int i = 0; i < qidxs.size() - 1; i++) {
      Eigen::VectorXi pairs = cnot_pairs.col(i);
      auto c = pairs(0);
      auto t = pairs(1);
      cnot_front << "CNOT(q[" << c << "], q[" << t << "]);\n";
    }

    for (int i = qidxs.size() - 2; i >= 0; i--) {
      Eigen::VectorXi pairs = cnot_pairs.col(i);
      auto c = pairs(0);
      auto t = pairs(1);
      cnot_back << "CNOT(q[" << c << "], q[" << t << "]);\n";
    }

    xasm_src = xasm_src + "\n" + basis_front.str() + cnot_front.str();

    xasm_src = xasm_src + "Rz(q[" + std::to_string(qidxs[qidxs.size() - 1]) +
               "], " + std::to_string(std::real(spinInst.coeff()) * theta) +
               ");\n";

    xasm_src = xasm_src + cnot_back.str() + basis_back.str();
  }

  int name_counter = 1;
  std::string name = "exp_tmp";
  while (xacc::hasCompiled(name)) {
    name += std::to_string(name_counter);
  }

  xasm_src = "__qpu__ void " + name + "(qbit q) {\n" + xasm_src + "}";

  // std::cout << xasm_src << "\n";
  auto xasm = xacc::getCompiler("xasm");
  auto tmp = xasm->compile(xasm_src)->getComposites()[0];

  for (auto inst : tmp->getInstructions()) {
    program->addInstruction(inst);
  }
}

void submit(xacc::AcceleratorBuffer *buffer) {
  xacc::internal_compiler::execute(buffer, program.get());
}
Loading