Commit 5f64ace4 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

enable include statements within qasm3 files via the clang++ preprocessor

parent b04998ab
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -105,14 +105,16 @@ MlirGenerationResult mlir_gen(const std::string &qasm_src,
}

MlirGenerationResult mlir_gen(const std::string &inputFilename,
                              bool add_entry_point) {
                              bool add_entry_point, std::string function_name = "") {
  llvm::StringRef ref(inputFilename);
  std::ifstream t(ref.str());
  std::string qasm_src((std::istreambuf_iterator<char>(t)),
                       std::istreambuf_iterator<char>());
  auto function_name = llvm::sys::path::filename(inputFilename)
  if (function_name.empty()) {
    function_name = llvm::sys::path::filename(inputFilename)
                           .split(StringRef("."))
                           .first.str();
  }
  return mlir_gen(qasm_src, function_name, add_entry_point);
}
} // namespace util
+10 −2
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
#include <fstream>

#include "Quantum/QuantumDialect.h"
#include "llvm/Support/TargetSelect.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/SCF/SCF.h"
@@ -17,7 +18,6 @@
#include "qcor-mlir-helper.hpp"
#include "quantum_to_llvm.hpp"
#include "tools/ast_printer.hpp"
#include "llvm/Support/TargetSelect.h"

using namespace mlir;
using namespace staq;
@@ -36,6 +36,9 @@ cl::opt<bool> mlir_quantum_opt(
    "q-optimize",
    cl::desc("Turn on MLIR-level quantum instruction optimizations."));

cl::opt<std::string> mlir_specified_func_name(
    "internal-func-name", cl::desc("qcor provided function name"));

namespace {
enum Action { None, DumpMLIR, DumpMLIRLLVM, DumpLLVMIR };
}
@@ -61,7 +64,12 @@ int main(int argc, char **argv) {
  llvm::cl::ParseCommandLineOptions(argc, argv,
                                    "qcor quantum assembly compiler\n");
  bool qoptimizations = mlir_quantum_opt;
  auto mlir_gen_result = qcor::util::mlir_gen(inputFilename, !noEntryPoint);
  std::string input_func_name = "";
  if (!mlir_specified_func_name.empty()) {
    input_func_name = mlir_specified_func_name;
  }
  auto mlir_gen_result =
      qcor::util::mlir_gen(inputFilename, !noEntryPoint, input_func_name);
  mlir::OwningModuleRef &module = *(mlir_gen_result.module_ref);
  mlir::MLIRContext &context = *(mlir_gen_result.mlir_context);
  std::vector<std::string> &unique_function_names =
+47 −6
Original line number Diff line number Diff line
@@ -413,12 +413,27 @@ def main(argv=None):
    # To support mixing multiple file types in one compilation.
    # Util to compile QASM2/3 (MLIR)
    def compile_qasm(filename):
        llvm_bin_path = str(pathlib.Path(compiler).parent)
        # Run preprocessor to handle any includes
        result = subprocess.check_output(
            [compiler, '-x', 'c++', '-E', '-P', filename]).decode('ascii')
        # process to single file
        text = 'OPENQASM 3;\n' + \
            '\n'.join([line for line in result.split('\n')
                       if 'OPENQASM' not in line and len(line) > 0])

        base_name = os.path.splitext(filename)[0].split(os.path.sep)[-1]

        # Write to a temporary file
        temp_file_name = '__tmp__'+base_name+'.qasm'
        with open(temp_file_name, 'w') as f:
            f.write(text)
        
        # Convert to MLIR and then to LLVM QIR
        base_name = os.path.splitext(filename)[0]
        ll_file_name = base_name + '.ll'
        bc_file_name = base_name + '.bc'
        object_file_name = base_name+'.o'
        extra_args = []
        extra_args = ['-internal-func-name', base_name]
        if '-no-entrypoint' in sys.argv[1:]:
            sys.argv.remove('-no-entrypoint')
            extra_args.append('-no-entrypoint')
@@ -426,11 +441,35 @@ def main(argv=None):
        if '--q-optimize' in sys.argv[1:]:
            sys.argv.remove('--q-optimize')
            extra_args.append('--q-optimize')
        result = subprocess.run(['@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool', filename] + extra_args, check=True)
        llvm_bin_path = str(pathlib.Path(compiler).parent)

        if '--emit-mlir' in sys.argv[1:]:
            result = subprocess.run(['@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool',
                                     '-emit=mlir', temp_file_name] + extra_args, check=True)
            os.remove(temp_file_name)
            exit(0)

        if '--emit-llvm' in sys.argv[1:]:
            result = subprocess.run(['@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool',
                                     '-emit=llvm', temp_file_name] + extra_args, check=True)
            os.remove(temp_file_name)
            exit(0)

        if '--emit-mlir-llvm' in sys.argv[1:]:
            result = subprocess.run(['@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool',
                                     '-emit=mlir-llvm', temp_file_name] + extra_args, check=True)
            os.remove(temp_file_name)
            exit(0)

        # Operate on the temporary file
        result = subprocess.run(
            ['@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool', temp_file_name] + extra_args, check=True)
        # Rename the output
        os.rename('__tmp__'+ll_file_name, ll_file_name)
        if verbose:
            print('[qcor-exec]: ', '@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool {}'.format(filename) )
            print('[qcor-exec]: ', '{}'.format(' '.join([llvm_bin_path+'/llvm-as', ll_file_name, '-o', bc_file_name ])) )
            print(
                '[qcor-exec]: ', '@CMAKE_INSTALL_PREFIX@/bin/qcor-mlir-tool {}'.format(filename))
            print('[qcor-exec]: ', '{}'.format(' '.join([llvm_bin_path +
                                                         '/llvm-as', ll_file_name, '-o', bc_file_name])))
            print('[qcor-exec]: ', '{}'.format(' '.join([llvm_bin_path+'/llc', '-filetype=obj', bc_file_name ])) )
        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)
@@ -439,6 +478,7 @@ def main(argv=None):

        sys.argv.remove(filename)
        sys.argv.append(base_name+'.o')
        os.remove(temp_file_name)
        fileType = None
        filename = None
        if not keep_bit_code_files:
@@ -446,6 +486,7 @@ def main(argv=None):
            os.remove(ll_file_name)
            os.remove(bc_file_name)

    
    # Util to compile Q#
    def compile_qsharp(filename):
        base_name = os.path.splitext(filename)[0]