Commit ef1ce545 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

added ability to call openqasm function from qcor c++

parent 42f81c84
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ void OpenQasmMLIRGenerator::visit(Program &prog) {
    builder.create<mlir::quantum::SetQregOp>(builder.getUnknownLoc(),
                                             tmp->getArguments()[0]);
    builder.create<mlir::CallOp>(builder.getUnknownLoc(), function2);
    builder.create<mlir::quantum::QRTFinalizeOp>(builder.getUnknownLoc());
    builder.create<mlir::ReturnOp>(builder.getUnknownLoc(), llvm::None);
    builder.setInsertionPointToStart(save_main_entry_block);

+36 −25
Original line number Diff line number Diff line
@@ -2,9 +2,10 @@

#include <alloca.h>

#include "qcor.hpp"
// #include "qcor.hpp"
#include "qrt.hpp"
#include "xacc.hpp"
#include "xacc_internal_compiler.hpp"
#include "xacc_service.hpp"

Result ResultZero = 0;
@@ -18,6 +19,7 @@ QRT_MODE mode;
std::vector<std::unique_ptr<Array>> allocated_arrays;
int shots = 1024;
bool verbose = false;
bool external_qreg_provided = false;

bool initialized = false;
void __quantum__rt__initialize(int argc, int8_t** argv) {
@@ -25,7 +27,8 @@ void __quantum__rt__initialize(int argc, int8_t** argv) {
  std::vector<std::string> args(casted, casted + argc);

  mode = QRT_MODE::FTQC;
  for (auto [i, arg] : qcor::enumerate(args)) {
  for (int i = 0; i < args.size(); i++) {
    auto arg = args[i];
    if (arg == "-qpu") {
      qpu_name = args[i + 1];
    } else if (arg == "-qrt") {
@@ -50,7 +53,8 @@ void initialize() {
    // qcor::set_verbose(true);
    xacc::internal_compiler::__qrt_env = "ftqc";
    xacc::Initialize();
    if (verbose) std::cout << "[qir-qrt] Running on " << qpu_name << " backend.\n";
    if (verbose)
      std::cout << "[qir-qrt] Running on " << qpu_name << " backend.\n";
    std::shared_ptr<xacc::Accelerator> qpu;

    if (mode == QRT_MODE::NISQ) {
@@ -69,7 +73,8 @@ void initialize() {
}

void __quantum__rt__set_external_qreg(qreg* q) {

  qbits = xacc::as_shared_ptr(q->results());
  external_qreg_provided = true;
}

void __quantum__qis__cnot(Qubit* src, Qubit* tgt) {
@@ -142,7 +147,8 @@ void __quantum__qis__rz(double x, Qubit* q) {
}

Result* __quantum__qis__mz(Qubit* q) {
  if(verbose) printf("[qir-qrt] Measuring qubit %lu\n", reinterpret_cast<std::size_t>(q));
  if (verbose)
    printf("[qir-qrt] Measuring qubit %lu\n", reinterpret_cast<std::size_t>(q));
  std::size_t qcopy = reinterpret_cast<std::size_t>(q);

  if (!qbits) {
@@ -151,7 +157,8 @@ Result* __quantum__qis__mz(Qubit* q) {

  ::quantum::set_current_buffer(qbits.get());
  auto bit = ::quantum::mz({"q", qcopy});
  if (mode == QRT_MODE::FTQC) if(verbose) printf("[qir-qrt] Result was %d.\n", bit);
  if (mode == QRT_MODE::FTQC)
    if (verbose) printf("[qir-qrt] Result was %d.\n", bit);
  return bit ? &ResultOne : &ResultZero;
}

@@ -181,7 +188,8 @@ int8_t* __quantum__rt__array_get_element_ptr_1d(Array* q, uint64_t idx) {
  int8_t* ptr = arr[idx];
  Qubit* qq = reinterpret_cast<Qubit*>(ptr);

  if(verbose) printf("[qir-qrt] Returning qubit array element %lu, idx=%lu.\n", *qq, idx);
  if (verbose)
    printf("[qir-qrt] Returning qubit array element %lu, idx=%lu.\n", *qq, idx);
  return ptr;
}

@@ -190,7 +198,8 @@ void __quantum__rt__qubit_release_array(Array* q) {
    if (allocated_arrays[i].get() == q) {
      auto& array_ptr = allocated_arrays[i];
      auto array_size = array_ptr->size();
      if(verbose) printf("[qir-qrt] deallocating the qubit array of size %lu\n",
      if (verbose)
        printf("[qir-qrt] deallocating the qubit array of size %lu\n",
               array_size);
      for (int k = 0; k < array_size; k++) {
        delete (*array_ptr)[k];
@@ -207,7 +216,9 @@ void __quantum__rt__finalize() {
    auto counts = qbits->getMeasurementCounts();
    std::cout << "Observed Counts:\n";
    for (auto [bits, count] : counts) {
      qcor::print(bits, ":", count);
      std::cout << bits << " : " << count << "\n";
    }
  } else if (external_qreg_provided) {
    ::quantum::submit(qbits.get());
  }
}
 No newline at end of file
+4 −1
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@

extern "C" {

// FIXME - Qubit should be a struct that keeps track of idx
// qreg name, array it comes from, and associated accelerator buffer

using Qubit = uint64_t;
using Result = uint64_t;
using Array = std::vector<int8_t*>;
+2 −0
Original line number Diff line number Diff line
@@ -63,3 +63,5 @@ internal_startup startup;
} // namespace __internal__

} // namespace qcor

#define qcor_include_qasm(NAME) extern "C" void NAME(qreg);
+12 −4
Original line number Diff line number Diff line
@@ -5,10 +5,12 @@ def main(argv=None):
    compiler = '@CLANG_EXECUTABLE@'
    verbose=False
    baseLibs = ['-rdynamic', '-Wl,-rpath,@XACC_ROOT@/lib:@CMAKE_INSTALL_PREFIX@/lib:@LLVM_INSTALL_PREFIX@/lib',
                            '@CMAKE_INSTALL_PREFIX@/lib/objects/qir-qrt/qir-qrt.cpp.o',
                            '-L', '@CMAKE_INSTALL_PREFIX@/lib','-lqcor', '-lqrt', '-lqcor-hybrid', '-lqcor-qsim', '-lqcor-jit', 
                             '-L', '@XACC_ROOT@/lib', '-lxacc', '-lCppMicroServices',
                            '-lxacc-quantum-gate',
                            '-lxacc-pauli', '-lxacc-fermion', '-lpthread']

    baseIncludes = ['-I', '@XACC_ROOT@/include/xacc', '-I', '@CMAKE_INSTALL_PREFIX@/include/qcor', '-I', '@XACC_ROOT@/include/quantum/gate', '-I', '@XACC_ROOT@/include/eigen']
    defaultFlags = ['-std=c++17', '-fplugin=@CMAKE_INSTALL_PREFIX@/clang-plugins/libqcor-syntax-handler.so']

@@ -295,11 +297,17 @@ def main(argv=None):
        ll_file_name = base_name + '.ll'
        bc_file_name = base_name + '.bc'
        object_file_name = base_name+'.o'
        result = subprocess.run(['@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool', filename], check=True)
        extra_args = []
        if '-no-entrypoint' in sys.argv[1:]:
            sys.argv.remove('-no-entrypoint')
            extra_args.append('-no-entrypoint')
        result = subprocess.run(['@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool', filename] + extra_args, check=True)
        llvm_bin_path = str(pathlib.Path(compiler).parent)
        result = subprocess.run([llvm_bin_path+'/llvm-as', ll_file_name, '-o', bc_file_name ], check=True)
        result = subprocess.run([llvm_bin_path+'/llc', '-filetype=obj', bc_file_name ], check=True)
        baseLibs = ['@CMAKE_INSTALL_PREFIX@/lib/objects/qir-qrt/qir-qrt.cpp.o'] + baseLibs
        if '-no-entrypoint' in extra_args:
            exit(0)

        sys.argv.remove(filename)
        sys.argv.append(base_name+'.o')
        fileType = None
@@ -358,7 +366,7 @@ def main(argv=None):
    else:
        # This is a .o file, so execute the link phase
        commands = [compiler] + baseLibs + sys.argv[1:]
        if verbose:
        # if verbose:
        print('[qcor-exec]: ', ' '.join([c for c in commands]))
        try:
            result = subprocess.run(commands, check=True)