Commit 33fffd06 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding first pass at quantum kernel just in time compilation

parent da8f7138
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line

#include "qcor.hpp"
#include "qcor_jit.hpp"
int main() {

  QJIT qjit;
  qjit.jit_compile(R"#(__qpu__ void bell(qreg q) {
        printf("hello world\n");
        using qcor::openqasm;
        h q[0];
        cx q[0], q[1];
        creg c[2];
        measure q -> c;
    })#");

  auto q = qalloc(2);
  qjit.invoke("bell", q);

  q.print();
}
 No newline at end of file
+247 −247
Original line number Diff line number Diff line
#include "qcor_syntax_handler.hpp"
#include "token_collector_util.hpp"
#include <iostream>
#include <regex>
@@ -7,47 +8,21 @@
#include "clang/AST/Type.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Parse/Parser.h"

using namespace clang;

namespace {
namespace qcor {

bool qrt = false;
std::string qpu_name = "qpp";
int shots = 0;

class QCORSyntaxHandler : public SyntaxHandler {
public:
  QCORSyntaxHandler() : SyntaxHandler("qcor") {}

  void GetReplacement(Preprocessor &PP, Declarator &D, CachedTokens &Toks,
                      llvm::raw_string_ostream &OS) override {

    // Get the Diagnostics engine and create a few custom
    // error messgaes
    auto &diagnostics = PP.getDiagnostics();
    auto invalid_no_args = diagnostics.getCustomDiagID(
        clang::DiagnosticsEngine::Error,
        "Invalid quantum kernel - must provide at least a qreg argument.");
    auto invalid_arg_type =
        diagnostics.getCustomDiagID(clang::DiagnosticsEngine::Error,
                                    "Invalid quantum kernel - args can only be "
                                    "qreg, double, or std::vector<double>.");
    auto invalid_qreg_name = diagnostics.getCustomDiagID(
        clang::DiagnosticsEngine::Error,
        "Invalid quantum kernel - could not discover qreg variable name.");
    // Get the function prototype as a string
    SourceManager &sm = PP.getSourceManager();
    auto lo = PP.getLangOpts();

    // Get the Function Type Info from the Declarator,
    // If the function has no arguments, then we throw an error
void QCORSyntaxHandler::GetReplacement(Preprocessor &PP, Declarator &D,
                                       CachedTokens &Toks,
                                       llvm::raw_string_ostream &OS) {
  const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
    std::string kernel_name = D.getName().Identifier->getName().str();
  auto kernel_name = D.getName().Identifier->getName().str();

    // Loop over the function arguments and get the
    // buffer name and any program parameter doubles.
  std::vector<std::string> program_parameters, program_arg_types;
  std::vector<std::string> bufferNames;
  for (unsigned int ii = 0; ii < FTI.NumParams; ii++) {
@@ -75,9 +50,38 @@ public:
    program_parameters.push_back(var);
  }

  GetReplacement(PP, kernel_name, program_arg_types, program_parameters,
                 bufferNames, Toks, OS);
}

void QCORSyntaxHandler::GetReplacement(
    Preprocessor &PP, std::string &kernel_name,
    std::vector<std::string> program_arg_types,
    std::vector<std::string> program_parameters,
    std::vector<std::string> bufferNames, CachedTokens &Toks,
    llvm::raw_string_ostream &OS) {

  // Get the Diagnostics engine and create a few custom
  // error messgaes
  auto &diagnostics = PP.getDiagnostics();
  auto invalid_no_args = diagnostics.getCustomDiagID(
      clang::DiagnosticsEngine::Error,
      "Invalid quantum kernel - must provide at least a qreg argument.");
  auto invalid_arg_type =
      diagnostics.getCustomDiagID(clang::DiagnosticsEngine::Error,
                                  "Invalid quantum kernel - args can only be "
                                  "qreg, double, or std::vector<double>.");
  auto invalid_qreg_name = diagnostics.getCustomDiagID(
      clang::DiagnosticsEngine::Error,
      "Invalid quantum kernel - could not discover qreg variable name.");
  // Get the function prototype as a string
  SourceManager &sm = PP.getSourceManager();
  auto lo = PP.getLangOpts();

  // Get Tokens as a string, rewrite code
  // with XACC api calls
  qcor::append_kernel(kernel_name);

  auto new_src = qcor::run_token_collector(PP, Toks, bufferNames);

  auto random_string = [](size_t length) {
@@ -176,8 +180,7 @@ public:

  // Second constructor, takes parent CompositeInstruction
  // KERNEL_NAME(CompositeInstruction, Args...)
    OS << kernel_name
       << "(std::shared_ptr<qcor::CompositeInstruction> _parent, "
  OS << kernel_name << "(std::shared_ptr<qcor::CompositeInstruction> _parent, "
     << program_arg_types[0] << " " << program_parameters[0];
  for (int i = 1; i < program_arg_types.size(); i++) {
    OS << ", " << program_arg_types[i] << " " << program_parameters[i];
@@ -214,8 +217,7 @@ public:

  OS << "if (is_callable) {\n";
  if (bufferNames.size() > 1) {
      OS << "xacc::AcceleratorBuffer * buffers[" << bufferNames.size()
         << "] = {";
    OS << "xacc::AcceleratorBuffer * buffers[" << bufferNames.size() << "] = {";
    OS << bufferNames[0] << ".results()";
    for (unsigned int k = 1; k < bufferNames.size(); k++) {
      OS << ", " << bufferNames[k] << ".results()";
@@ -264,16 +266,14 @@ public:
  OS << "}\n";

  auto s = OS.str();
    qcor::info("[qcor syntax-handler] Rewriting " + kernel_name + " to\n\n" +
               s);
  qcor::info("[qcor syntax-handler] Rewriting " + kernel_name + " to\n\n" + s);
}

  void AddToPredefines(llvm::raw_string_ostream &OS) override {
void QCORSyntaxHandler::AddToPredefines(llvm::raw_string_ostream &OS) {
  OS << "#include \"qcor.hpp\"\n";
  OS << "using namespace qcor;\n";
  OS << "using namespace xacc::internal_compiler;\n";
}
};

class DoNothingConsumer : public ASTConsumer {
public:
@@ -323,9 +323,9 @@ public:
  }
};

} // namespace
} // namespace qcor

static SyntaxHandlerRegistry::Add<QCORSyntaxHandler>
static SyntaxHandlerRegistry::Add<qcor::QCORSyntaxHandler>
    X("qcor", "qcor quantum kernel syntax handler");

static FrontendPluginRegistry::Add<QCORArgs> XX("qcor-args", "");
static FrontendPluginRegistry::Add<qcor::QCORArgs> XX("qcor-args", "");
+23 −0
Original line number Diff line number Diff line
#pragma once

#include "clang/Parse/Parser.h"

using namespace clang;

namespace qcor {
class QCORSyntaxHandler : public SyntaxHandler {
public:
  QCORSyntaxHandler() : SyntaxHandler("qcor") {}
  void GetReplacement(Preprocessor &PP, Declarator &D, CachedTokens &Toks,
                      llvm::raw_string_ostream &OS) override;
  
  // For use with qcor jit
  void GetReplacement(Preprocessor &PP, std::string &kernel_name,
                      std::vector<std::string> program_arg_types,
                      std::vector<std::string> program_parameters,
                      std::vector<std::string> bufferNames, CachedTokens &Toks,
                      llvm::raw_string_ostream &OS);

  void AddToPredefines(llvm::raw_string_ostream &OS) override;
};
} // namespace qcor
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -38,3 +38,4 @@ endif()

add_subdirectory(objectives)
add_subdirectory(qrt)
add_subdirectory(jit)
 No newline at end of file
+28 −0
Original line number Diff line number Diff line

set(LIBRARY_NAME qcor-jit)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
add_library(${LIBRARY_NAME}
            SHARED
            qcor_jit.cpp)

target_include_directories(${LIBRARY_NAME}
                           PUBLIC . ${XACC_ROOT}/include/xacc ${CMAKE_SOURCE_DIR}/handlers
                                  ${CLANG_INCLUDE_DIRS}
                                  ${LLVM_INCLUDE_DIRS})

target_link_libraries(${LIBRARY_NAME}
                      PRIVATE qcor-syntax-handler ${CLANG_LIBS} ${LLVM_LIBS} qcor-clang-wrapper)
if(APPLE)
  set_target_properties(${LIBRARY_NAME}
                        PROPERTIES INSTALL_RPATH "@loader_path/../lib;${LLVM_INSTALL_PREFIX}/lib")
  set_target_properties(${LIBRARY_NAME}
                        PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
else()
  set_target_properties(${LIBRARY_NAME}
                        PROPERTIES INSTALL_RPATH "$ORIGIN/../lib:${LLVM_INSTALL_PREFIX}/lib:${XACC_ROOT}/clang-plugins")
  set_target_properties(${LIBRARY_NAME} PROPERTIES LINK_FLAGS "-shared")
endif()

install(FILES qcor_jit.hpp DESTINATION include/qcor)

install(TARGETS ${LIBRARY_NAME} DESTINATION lib)
Loading