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

Merge branch 'master' into tnguyen/vqe-benchmark



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parents 04812ca0 46b17eda
Loading
Loading
Loading
Loading
+138 −1
Original line number Diff line number Diff line
@@ -17,6 +17,98 @@ static std::vector<std::string> search_for_inliner{
    "u3", "u2",  "u1", "cx",  "id", "u0", "x",  "y",  "z",  "h",
    "s",  "sdg", "t",  "tdg", "rx", "ry", "rz", "cz", "cy", "swap"};

static std::map<std::string, std::string> missing_builtins{
    {"u", R"#(
gate u(theta,phi,lambda) q { U(theta,phi,lambda) q; })#"},
    {"p", R"#(gate p(theta) a
{
  rz(theta) a;
})#"},
    {"sx", R"#(gate sx a { sdg a; h a; sdg a; })#"},
    {"sxdg", R"#(gate sxdg a { s a; h a; s a; })#"},
    {"cswap", R"#(gate cswap a,b,c
{
  cx c,b;
  ccx a,b,c;
  cx c,b;
})#"},
    {"crx", R"#(gate crx(lambda) a,b
{
  u1(pi/2) b;
  cx a,b;
  u3(-lambda/2,0,0) b;
  cx a,b;
  u3(lambda/2,-pi/2,0) b;
})#"},
    {"cry", R"#(gate cry(lambda) a,b
{
  u3(lambda/2,0,0) b;
  cx a,b;
  u3(-lambda/2,0,0) b;
  cx a,b;
  ry(lambda) a;
})#"},
    {"cp", R"#(gate cp(lambda) a,b
{
  p(lambda/2) a;
  cx a,b;
  p(-lambda/2) b;
  cx a,b;
  p(lambda/2) b;
})#"},
    {"csx", R"#(gate csx a,b { h b; cu1(pi/2) a,b; h b; })#"},
    {"cu", R"#(gate cu(theta,phi,lambda,gamma) c, t
{ p(gamma) c;
  p((lambda+phi)/2) c;
  p((lambda-phi)/2) t;
  cx c,t;
  u(-theta/2,0,-(phi+lambda)/2) t;
  cx c,t;
  u(theta/2,phi,0) t;
})#"},
    {"rxx", R"#(gate rxx(theta) a,b
{
  u3(pi/2, theta, 0) a;
  h b;
  cx a,b;
  u1(-theta) b;
  cx a,b;
  h b;
  u2(-pi, pi-theta) a;
})#"},
    {"rzz", R"#(gate rzz(theta) a,b
{
  cx a,b;
  u1(theta) b;
  cx a,b;
})#"},
    {"rccx", R"#(gate rccx a,b,c
{
  u2(0,pi) c;
  u1(pi/4) c;
  cx b, c;
  u1(-pi/4) c;
  cx a, c;
  u1(pi/4) c;
  cx b, c;
  u1(-pi/4) c;
  u2(0,pi) c;
})#"}};

template <class Op>
void split(const std::string &s, char delim, Op op) {
  std::stringstream ss(s);
  for (std::string item; std::getline(ss, item, delim);) {
    *op++ = item;
  }
}

inline std::vector<std::string> split(const std::string &s, char delim) {
  std::vector<std::string> elems;
  split(s, delim, std::back_inserter(elems));
  return elems;
}

void CountGateDecls::visit(GateDecl &g) {
  auto name = g.id();
  if (std::find(builtins.begin(), builtins.end(), name) == builtins.end()) {
@@ -222,9 +314,54 @@ void OpenQasmMLIRGenerator::initialize_mlirgen(bool _add_entry_point,

void OpenQasmMLIRGenerator::mlirgen(const std::string &src) {
  using namespace staq;

  std::string src_copy = src;

  // Make sure we have the preamble text
  std::string preamble = "OPENQASM 2.0;";
  auto preamble_start = src.find(preamble);
  if (preamble_start == std::string::npos) {
    std::cout << "[OpenQASM MLIR Gen] Error, no OPENQASM 2.0 preamble text.\n";
    exit(1);
  }

  preamble = "include \"qelib1.inc\";";
  preamble_start = src.find(preamble);
  if (preamble_start == std::string::npos) {
    std::cout << "[OpenQASM MLIR Gen] Error, no include \"qelib1.inc\" "
                 "preamble text.\n";
    exit(1);
  }

  // Add any required missing pre-defines that we 
  // know the impl for.
  std::vector<std::string> added;
  std::string extra_insts = "\n";
  bool hasMeasures = false;
  auto lines = split(src, '\n');
  for (auto line : lines) {
    if (line.find("OPENQASM") == std::string::npos &&
        line.find("include") == std::string::npos &&
        line.find("measure") == std::string::npos &&
        line.find("qreg") == std::string::npos &&
        line.find("creg") == std::string::npos) {
      auto inst_name = split(line, ' ')[0];
      if (inst_name.find("(") != std::string::npos) {
        inst_name = inst_name.substr(0, inst_name.find("("));
      }
      if (std::find(builtins.begin(), builtins.end(), inst_name) ==
              builtins.end() &&
          std::find(added.begin(), added.end(), inst_name) == added.end()) {
        extra_insts += missing_builtins[inst_name] + "\n";
        added.push_back(inst_name);
      }
    }
  }
  src_copy.insert(preamble_start+preamble.length(), extra_insts);

  ast::ptr<ast::Program> prog;
  try {
    prog = parser::parse_string(src);
    prog = parser::parse_string(src_copy);
    // transformations::inline_ast(*prog);
    transformations::desugar(*prog);
  } catch (std::exception &e) {
+29 −4
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include "xacc_service.hpp"
#include "qcor_config.hpp"
#include "xacc_config.hpp"
#include "config_file_parser.hpp"

Result ResultZero = 0;
Result ResultOne = 1;
@@ -16,10 +17,11 @@ unsigned long allocated_qbits = 0;
std::shared_ptr<xacc::AcceleratorBuffer> qbits;
std::shared_ptr<xacc::Accelerator> qpu;
std::string qpu_name = "qpp";
std::string qpu_config = "";
enum QRT_MODE { FTQC, NISQ };
QRT_MODE mode;
std::vector<std::unique_ptr<Array>> allocated_arrays;
int shots = 1024;
int shots = 0;
bool verbose = false;
bool external_qreg_provided = false;

@@ -29,11 +31,13 @@ void print_help() {
  std::cout << "QCOR QIR Runtime Help Menu\n\n";
  std::cout << "optional arguments:\n";
  std::cout << "  -qpu QPUNAME[:BACKEND] | example -qpu ibm:ibmq_vigo, -qpu aer:ibmq_vigo\n";
  std::cout << "  -qpu-config config_file.ini | example: -qpu ibm:ibmq_vigo -qpu-config ibm_config.ini\n";
  std::cout << "  -qrt QRT_MODE (can be nisq or ftqc) | example -qrt nisq\n";
  std::cout << "  -shots NUMSHOTS (number of shots to use in nisq run)\n";
  std::cout << "  -opt LEVEL | example -opt 1\n";
  std::cout << "  -print-opt-stats (turn on printout of optimization statistics) \n";
  std::cout << "  -v,-verbose,--verbose (run with printouts)\n\n";
  std::cout << "  -v,-verbose,--verbose (run with printouts)\n";
  std::cout << "  -xacc-verbose (turn on extra xacc verbose print-out)\n\n";
  exit(0);
}

@@ -46,10 +50,15 @@ void __quantum__rt__initialize(int argc, int8_t** argv) {
    auto arg = args[i];
    if (arg == "-qpu") {
      qpu_name = args[i + 1];
    } else if (arg == "-qpu-config") {
      qpu_config = args[i+1];
    } else if (arg == "-qrt") {
      mode = args[i + 1] == "nisq" ? QRT_MODE::NISQ : QRT_MODE::FTQC;
    } else if (arg == "-shots") {
      shots = std::stoi(args[i + 1]);
    } else if (arg == "-xacc-verbose") {
      verbose = true;
      xacc::set_verbose(true);
    } else if (arg == "-v") {
      verbose = true;
    } else if (arg == "-verbose") {
@@ -99,9 +108,20 @@ void initialize() {
      std::cout << "[qir-qrt] Running on " << qpu_name << " backend.\n";
    std::shared_ptr<xacc::Accelerator> qpu;

    xacc::HeterogeneousMap qpu_config_map;
    if (!qpu_config.empty()) {
        auto parser = xacc::getService<xacc::ConfigFileParsingUtil>("ini");
        qpu_config_map = parser->parse(qpu_config);
    }

    if (!qpu_config_map.keyExists<int>("shots") && shots > 0 && mode == QRT_MODE::NISQ) {
      if (verbose) printf("Automatically setting shots for nisq mode execution to %d\n", shots);
      qpu_config_map.insert("shots", shots);
    }
    
    if (mode == QRT_MODE::NISQ) {
      xacc::internal_compiler::__qrt_env = "nisq";
      qpu = xacc::getAccelerator(qpu_name, {{"shots", shots}});
      qpu = xacc::getAccelerator(qpu_name, qpu_config_map);
    } else {
      qpu = xacc::getAccelerator(qpu_name);
    }
@@ -187,6 +207,11 @@ void __quantum__qis__rz(double x, Qubit* q) {
  if (verbose) printf("[qir-qrt] Applying Rz(%f) %lu\n", x, qcopy);
  ::quantum::rz({"q", qcopy}, x);
}
void __quantum__qis__u3(double theta, double phi, double lambda, Qubit* q) {
    std::size_t qcopy = reinterpret_cast<std::size_t>(q);
  if (verbose) printf("[qir-qrt] Applying U3(%f, %f, %f) %lu\n", theta, phi, lambda, qcopy);
  ::quantum::u3({"q", qcopy}, theta, phi, lambda);
}

Result* __quantum__qis__mz(Qubit* q) {
  if (verbose)
@@ -240,7 +265,7 @@ 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)
      if (verbose && mode == QRT_MODE::FTQC)
        printf("[qir-qrt] deallocating the qubit array of size %lu\n",
               array_size);
      for (int k = 0; k < array_size; k++) {
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ void __quantum__qis__z(Qubit* q);
void __quantum__qis__rx(double x, Qubit* q);
void __quantum__qis__ry(double x, Qubit* q);
void __quantum__qis__rz(double x, Qubit* q);
void __quantum__qis__u3(double theta, double phi, double lambda, Qubit* q);

Result* __quantum__qis__mz(Qubit* q);

+1 −0
Original line number Diff line number Diff line
@@ -696,6 +696,7 @@ class KernelBuilder(object):
            setattr(KernelBuilder, instruction[0].lower(), result[instruction[0].lower()])

    def measure_all(self):
        self.qjit_str += '\n'
        self.qjit_str += self.TAB + 'for i in range({}.size()):\n'.format(self.qreg_name)
        self.qjit_str += self.TAB+self.TAB+'Measure({}[i])\n'.format(self.qreg_name)

+8 −5
Original line number Diff line number Diff line
@@ -191,6 +191,9 @@ def main(argv=None):
        if '-qpu-config' in sys.argv[1:]:
            idx = sys.argv.index('-qpu-config')
            config_file = sys.argv[idx+1]
            if not os.path.exists(config_file):
                print('Invalid qpu config file path:', config_file)
                exit(1)

        accidx = sys.argv.index('-qpu')
        accName = sys.argv[accidx+1]
@@ -198,11 +201,9 @@ def main(argv=None):
        sys.argv.remove('-qpu')

        if config_file:
            # FIXME use absolute path name
            if ']' in accName:
                idx = accName.index(']')
                accName = accName[:idx] + ',qcor_qpu_config:'+config_file+accName[idx:]
                print(accName)
                accName = accName[:idx] + ',qcor_qpu_config:'+os.path.abspath(config_file)+accName[idx:]
            else:
                accName += '[qcor_qpu_config:'+config_file+']'
            sys.argv.remove(config_file)
@@ -377,7 +378,9 @@ def main(argv=None):
                print(e.returncode)
                return e.returncode
        else:
            print('invalid command line arguments for qcor')
            print('invalid command line arguments for qcor:')
            print('source file name and type:', (None if filename == '' else filename), ',', (None if fileType == '' else fileType))
            if verbose: print('current args: ', sys.argv)
            exit(1)
    else:
        # This is a .o file, so execute the link phase