Commit 5883259a authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

removing macosx qcor driver, updates to qcor.in to work for both linux/mac

parent b418d8fc
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
set(LIBRARY_NAME qcor-clang-wrapper)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")

message(STATUS "HOWDY: ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
configure_file(qcor_clang_wrapper.in.cpp
               ${CMAKE_BINARY_DIR}/tools/clang-wrapper/qcor_clang_wrapper.cpp)

+1 −6
Original line number Diff line number Diff line
@@ -3,15 +3,10 @@
set (CLANG_EXECUTABLE "${LLVM_INSTALL_PREFIX}/bin/clang++")
set(QCOR_APPEND_PLUGIN_PATH "")
if (NOT ${XACC_ROOT} MATCHES ${CMAKE_INSTALL_PREFIX}) 
  message(STATUS "WE ARE BUILDING WITH HOMEBREW")
  set (QCOR_APPEND_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/plugins")
endif()

if (APPLE) 
configure_file(qcor-macosx.in
               ${CMAKE_BINARY_DIR}/qcor)
else() 
configure_file(qcor.in
               ${CMAKE_BINARY_DIR}/qcor)
endif()

install(PROGRAMS ${CMAKE_BINARY_DIR}/qcor DESTINATION bin)

tools/driver/qcor-macosx.in

deleted100755 → 0
+0 −384
Original line number Diff line number Diff line
#!/usr/bin/env python3
import sys, os, subprocess, mimetypes, re

def main(argv=None):
    compiler = '@CLANG_EXECUTABLE@'
    verbose=False
    baseLibs = ['-rdynamic', '-Wl,-rpath,@XACC_ROOT@/lib', '-Wl,-rpath,@LLVM_INSTALL_PREFIX@/lib', '-Wl,-rpath,@CMAKE_INSTALL_PREFIX@/clang-plugins',
                            '-L', '@XACC_ROOT@/lib', '-lxacc', '-lCppMicroServices', '-lxacc-quantum-gate', '-lxacc-pauli', '-lxacc-fermion', 
                            '-L', '@CMAKE_INSTALL_PREFIX@/lib', '-lqcor', '-lqrt', '-lqcor-hybrid', '-lqcor-jit', '-lqcor-quasimo',
                            '-lpthread']
    baseIncludes = ['-I', '@XACC_ROOT@/include/xacc', '-I', '@CMAKE_INSTALL_PREFIX@/include/qcor', '-I', '@XACC_ROOT@/include/quantum/gate', '-I', '@XACC_ROOT@/include/eigen']
    extra_headers = '@QCOR_EXTRA_HEADERS@'.replace('"','')
    for path in extra_headers.split(';'):
        baseIncludes += ['-I', path]

    defaultFlags = ['-std=c++17', '-fplugin=@CMAKE_INSTALL_PREFIX@/clang-plugins/libqcor-syntax-handler@CMAKE_SHARED_LIBRARY_SUFFIX@', '-Wno-stdlibcxx-not-found']

    # This flag is primarily for our testers to point to the 
    # qcor syntax handler before make install is called
    if '-internal-syntax-handler-plugin-path' in sys.argv[1:]:
        idx = sys.argv.index('-internal-syntax-handler-plugin-path')
        pth = sys.argv[idx+1]
        sys.argv.remove(pth)
        sys.argv.remove('-internal-syntax-handler-plugin-path')
        defaultFlags = ['-std=c++17', '-fplugin='+pth+'/libqcor-syntax-handler@CMAKE_SHARED_LIBRARY_SUFFIX@']

    # Need to know if this is compile-only
    compileOnly = '-c' in sys.argv[1:]

    if '-h' in sys.argv[1:] or '--help' in sys.argv[1:]:
        import argparse
        parser = argparse.ArgumentParser(description="qcor: the quantum-classical C++ compiler",
                                     formatter_class=argparse.RawTextHelpFormatter,
                                     fromfile_prefix_chars='@')
        parser.add_argument('-v', metavar='',
                        help='turn on qcor verbose mode - prints actual clang calls plus extra info while compiling.')
        parser.add_argument('-qpu', metavar=('name[:backend]'), help='specify quantum backend name. this corresponds to the name of an xacc accelerator (plus optional backend name).\nExamples include qcs:Aspen-4-2Q-H, ibm:ibmq_valencia, tnqvm, etc.')
        parser.add_argument('-shots', metavar=('n_shots'), nargs=1,help='provide the number of shots to execute on shot-enabled backend.')
        parser.add_argument('-c', metavar=('file.cpp'), help='specify compile-only, no library linking.\n$ qcor -c src.cpp [outputs src.o for future linking]\n')
        parser.add_argument('-o', metavar=('object.o'), help='provide the name of the object file (if compile only) or executable (if compile and link or just link).\n$ qcor -o out.o -c src.cpp\n$ qcor -o out.exe src.cpp\n')
        parser.add_argument('file', help='you must specify the c++ source file name to compile.')
        parser.add_argument('-opt', nargs=1, help='specify optimization level for quantum circuit optimization.')
        parser.add_argument('-print-opt-stats', help='print circuit optimization pass statistics.')
        parser.add_argument('-I',action='append',nargs=1, metavar=('header_file.hpp'),help='specify additional headers to add to the include search path.')
        parser.add_argument('-L',action='append',nargs=1,metavar=('/path/to/libs'),help='specifiy additional linker search paths.')
        parser.add_argument('-l',action='append',nargs=1,metavar=('lib_name'),help='specifiy additional libraries to link.')
        parser.add_argument('-set-credentials', nargs=1, help='set api key and other credential information for remote qpu.\nMust provide at least -key KEY arguments. For IBM also specify -hub HUB -group GROUP -project PROJECT.')
        parser.add_argument('-print-credentials', nargs=1, help='print remote api credentials for given qpu name.')
        parser.add_argument('-update-credentials', nargs=1, help='set a specific credential for remote qpu access. Example\nqcor -update-credentials ibm -project MYOTHERPROJECT.')
        parser.add_argument('-xacc-install', nargs=1, help='returns the install directory for xacc.')
        parser.add_argument('-qcor-install', nargs=1, help='returns the install directory for qcor.')
        parser.add_argument('-clear-jit-cache', help='delete existing QJIT cache.')
        parser.add_argument('-xacc-version', nargs=1, help='returns the current build version for underlying xacc install.')
        parser.add_argument('-version', nargs=1, help='returns the current qcor build version.')
        parser.add_argument('-pythonpath', help='print the correct PYTHONPATH to leverage qcor and xacc python API.')
        args = parser.parse_args(sys.argv)
    
    if '-pythonpath' in sys.argv[1:]:
        if '@XACC_ROOT@' == '@CMAKE_INSTALL_PREFIX@':
            print('@XACC_ROOT@')
        else:
            print('@XACC_ROOT@:@CMAKE_INSTALL_PREFIX@')
        exit(0)
    
    if '-version' in sys.argv[1:]:
        version = open('@CMAKE_INSTALL_PREFIX@/include/qcor/qcor_version', 'r').read().rstrip()
        print('qcor build version = {}'.format(version))
        exit(0)

    if '-xacc-version' in sys.argv[1:]:
        version = open('@XACC_ROOT@/include/xacc/xacc_version', 'r').read().rstrip()
        print('xacc build version = {}'.format(version))
        exit(0)
    
    if '-xacc-install' in sys.argv[1:]:
        print('@XACC_ROOT@')
        exit(0)
    if '-qcor-install' in sys.argv[1:]:
        print('@CMAKE_INSTALL_PREFIX@')
        exit(0)

    if '-clear-jit-cache' in sys.argv[1:]:
        files = glob.glob(os.getenv('HOME') + '/.qjit/*.bc')
        for f in files:
            print("removing ", f)
            os.remove(f)
        if os.path.exists(os.getenv('HOME') + '/.qjit/qjit_cache.json'):
            os.remove(os.getenv('HOME') + '/.qjit/qjit_cache.json')
            print('removing {}/.qjit/qjit_cache.json'.format(os.getenv('HOME')))
        exit(0)

    if '--verbose' in sys.argv[1:]:
        verbose=True
        sys.argv.remove('--verbose')
    if '-v' in sys.argv[1:]:
        verbose=True
        sys.argv.remove('-v')

    if '-set-credentials' in sys.argv[1:]:
        idx = sys.argv.index('-set-credentials')
        accName = sys.argv[idx+1]
        if accName not in ['ibm', 'qcs', 'rigetti', 'dwave']:
            print('invalid remote qpu name: ', accName)
            exit(1)

        try:
            kidx = sys.argv.index('-key')
        except:
            print('-key not found in command line args. must provide key if -set-credentials is used.')
            exit(1)
        
        if accName == 'ibm':
            try:
                hidx = sys.argv.index('-hub')
                gidx = sys.argv.index('-group')
                pidx = sys.argv.index('-project')
            except:
                print('-hub, -project, or -group not found in command line args. must provide them if setting credentials for ibm.')
                exit(1)
            
            key = sys.argv[kidx+1]
            hub = sys.argv[hidx+1]
            group = sys.argv[gidx+1]
            project = sys.argv[pidx+1]
            s = 'key: {}\nhub: {}\ngroup: {}\nproject: {}\n'.format(key,hub,group,project)
            f = open(os.getenv('HOME')+'/.ibm_config', 'w')
            f.write(s)
            f.close()
            print('Writing to $HOME/.ibm_config \n\n')
            print(s)
            exit(0)

    if '-print-credentials' in sys.argv[1:]:
        idx = sys.argv.index('-print-credentials')
        try:
            accName = sys.argv[idx+1]
        except:
            print('must provide qpu name after -print-credentials.')
            exit(1)
        f = open(os.getenv('HOME')+'/.{}_config'.format(accName), 'r')
        print(f.read())
        f.close()
        exit(0)

    if '-update-credentials' in sys.argv[1:]:
        idx = sys.argv.index('-update-credentials')
        try:
            accName = sys.argv[idx+1]
        except:
            print('must provide qpu name after -update-credentials.')
            exit(1)

        f = open(os.getenv('HOME')+'/.{}_config'.format(accName), 'r')
        lines = f.readlines()
        f.close()

        if '-key' in sys.argv[1:]:
            kidx = sys.argv.index('-key')
            lines[0] = 'key: {}\n'.format(sys.argv[kidx+1])

        if '-hub' in sys.argv[1:]:
            kidx = sys.argv.index('-hub')
            lines[1] = 'hub: {}\n'.format(sys.argv[kidx+1])

        if '-group' in sys.argv[1:]:
            kidx = sys.argv.index('-group')
            lines[2] = 'group: {}\n'.format(sys.argv[kidx+1])

        if '-project' in sys.argv[1:]:
            kidx = sys.argv.index('-project')
            lines[3] = 'project: {}\n'.format(sys.argv[kidx+1])
        
        f = open(os.getenv('HOME')+'/.{}_config'.format(accName), 'w')
        f.writelines(lines)
        f.close()
        print('Credential after update:')
        print(''.join([l for l in lines]))
        exit(0)

    if '--verbose' in sys.argv[1:]:
        verbose=True
        sys.argv.remove('--verbose')
    if '-v' in sys.argv[1:]:
        verbose=True
        sys.argv.remove('-v')

    sHandlerArgs = []
    # Get the QPU Backend
    accName = ''
    if '-qpu' in sys.argv[1:]:
        accidx = sys.argv.index('-qpu')
        accName = sys.argv[accidx+1]
        sys.argv.remove(accName)
        sys.argv.remove('-qpu')
        sys.argv += ['-D__internal__qcor__compile__backend=\"'+accName+'\"']
        sHandlerArgs = ['-Xclang', '-plugin-arg-qcor-args', '-Xclang', '-qpu', '-Xclang', '-plugin-arg-qcor-args', '-Xclang', accName]
    else:
        accName = 'qpp'
        sys.argv += ['-D__internal__qcor__compile__backend=\"'+accName+'\"']
        sHandlerArgs = ['-Xclang', '-plugin-arg-qcor-args', '-Xclang', '-qpu', '-Xclang', '-plugin-arg-qcor-args', '-Xclang', accName]

    # Get the shots if necessary
    shots = 0
    if '-shots' in sys.argv[1:]:
        sidx = sys.argv.index('-shots')
        shots = sys.argv[sidx+1]
        sys.argv.remove(shots)
        sys.argv.remove('-shots')
        sys.argv += ['-D__internal__qcor__compile__shots=\"'+str(shots)+'\"']
        sHandlerArgs += ['-Xclang', '-plugin-arg-qcor-args', '-Xclang', '-shots', '-Xclang', '-plugin-arg-qcor-args', '-Xclang', shots]

    if verbose:
        sHandlerArgs += ['-Xclang', '-plugin-arg-qcor-args', '-Xclang', '-qcor-verbose']

    if '-print-qir' in sys.argv[1:]:
        sys.argv.remove('-print-qir')
        sHandlerArgs += ['-Xclang', '-load', '-Xclang', '@CMAKE_INSTALL_PREFIX@/qopt-plugins/libprint_llvm_qir.so']

    # Optimization level for flattened (runtime) kernel
    # Default: 0 (no optimization)
    qrtOptLevel = 0
    if '-opt' in sys.argv[1:]:
        sidx = sys.argv.index('-opt')
        qrtOptLevel = sys.argv[sidx+1]
        sys.argv.remove(qrtOptLevel)
        sys.argv.remove('-opt')
        sys.argv += ['-D__internal__qcor__compile__opt__level='+qrtOptLevel]

    # Enable runtime kernel optimization stats print-out:
    # i.e. passes that are executed and their info (walltime, gate count reduction, etc.)
    if '-print-opt-stats' in sys.argv[1:]:
        sys.argv.remove('-print-opt-stats')
        sys.argv += ['-D__internal__qcor__compile__opt__print__stats']

    # Specify optimization passes to run *in addition* to the default passes at an optimization level.
    # Syntax: -opt-pass pass1[,pass2] 
    # i.e. a comma-separated list of passes.
    # Rationale:
    # - This option can be used to run an independent pass by using level 0 (no optimization)
    # and then specify which pass to be executed.
    # - It can also be used to add passes to pre-defined list of passes for an optimization level.
    # e.g., those XACC passes that are contributed externally. 
    if '-opt-pass' in sys.argv[1:]:
        sidx = sys.argv.index('-opt-pass')
        qrtOptPasses = sys.argv[sidx+1]
        sys.argv.remove(qrtOptPasses)
        sys.argv.remove('-opt-pass')
        sys.argv += ['-D__internal__qcor__compile__opt__passes=\\"'+qrtOptPasses+'\\"']
    
    # Parse qubit mapping:
    if '-qubit-map' in sys.argv[1:]:
        sidx = sys.argv.index('-qubit-map')
        qubitMap = sys.argv[sidx+1]
        sys.argv.remove(qubitMap)
        sys.argv.remove('-qubit-map')
        sys.argv += ['-D__internal__qcor__compile__qubit__map=\\"'+qubitMap+'\\"']
    
    # Parse placement name
    if '-placement' in sys.argv[1:]:
        sidx = sys.argv.index('-placement')
        placementName = sys.argv[sidx+1]
        sys.argv.remove(placementName)
        sys.argv.remove('-placement')
        sys.argv += ['-D__internal__qcor__compile__placement__name=\"'+placementName+'\"']
    
    if '-em' in sys.argv[1:]:
        sidx = sys.argv.index('-em')
        decorator_name = sys.argv[sidx+1]
        sys.argv.remove(decorator_name)
        sys.argv.remove('-em')
        sys.argv += ['-D__internal__qcor__compile__decorator__list=\"'+decorator_name+'\"']
    
    # Define the QRT, e.g. "nisq" or "ftqc"
    if '-qrt' in sys.argv[1:]:
        sidx = sys.argv.index('-qrt')
        qrtName = sys.argv[sidx+1]
        sys.argv.remove(qrtName)
        sys.argv.remove('-qrt')
        sys.argv += ['-D__internal__qcor__compile__qrt__mode=\"'+qrtName+'\"']   
        if qrtName == 'ftqc': 
            sys.argv += ['-D_QCOR_FTQC_RUNTIME']
    
       # if not empty
    if '@QCOR_APPEND_PLUGIN_PATH@':
        sys.argv += ['-D__internal__qcor__compile__plugin__path=\"@QCOR_APPEND_PLUGIN_PATH@\"']
        
    filename = ''
    fileType = ''
    for arg in sys.argv[1:]:
        if os.path.isfile(arg) and mimetypes.guess_type(arg)[0] is not None:
            filename = arg
            fileType = mimetypes.guess_type(filename)[0]
            if fileType == 'text/x-c++src':
                break
        if os.path.isfile(arg) and os.path.splitext(arg)[1] == '.qasm':
            fileType = 'openqasm'
            filename = arg
        
    if fileType == 'openqasm':
        # 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 = []
        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)
        if '-no-entrypoint' in extra_args:
            exit(0)

        sys.argv.remove(filename)
        sys.argv.append(base_name+'.o')
        fileType = None
        filename = None                

    # If it is a C++ file
    if fileType == 'text/x-c':
        fileIdx = sys.argv[1:].index(filename)
        tmpFileName = os.path.basename(filename)

        # Move tmpFileName to end of list
        sys.argv.remove(filename)
        sys.argv.append(filename)

        sys.argv[0] = compiler
        commands = [compiler] + defaultFlags + sHandlerArgs + baseIncludes
        if compileOnly:
            commands += sys.argv[1:]
        else:
            commands += baseLibs + sys.argv[1:]


        if verbose:
            print('[qcor-exec]: ', ' '.join([c for c in commands]))

        try:
            result = subprocess.run(commands, check=True)
        except subprocess.CalledProcessError as e:
            print(e.output)
            print(e.returncode)
            return e.returncode
    elif fileType == '' and filename == '':
        if '-x' in sys.argv[1:] and 'c++' in sys.argv[1:]:
            sys.argv[0] = compiler
            commands = [compiler] + defaultFlags + sHandlerArgs + baseIncludes 
            if compileOnly:
                commands += sys.argv[1:]
            else:
                commands += baseLibs + sys.argv[1:]


            if verbose:
                print('[qcor-exec]: ', ' '.join([c for c in commands]))

            try:
                result = subprocess.run(commands, check=True)
            except subprocess.CalledProcessError as e:
                print(e.output)
                print(e.returncode)
                return e.returncode
        else:
            print('invalid command line arguments for qcor')
            exit(1)
    else:
        # This is a .o file, so execute the link phase
        commands = [compiler] + baseLibs + sys.argv[1:]
        if verbose:
            print('[qcor-exec]: ', ' '.join([c for c in commands]))
        try:
            result = subprocess.run(commands, check=True)
        except subprocess.CalledProcessError as e:
            print(e.output)
            print(e.returncode)
            return e.returncode

    return 0

if __name__ == "__main__":
    sys.exit(main())
+10 −11
Original line number Diff line number Diff line
@@ -4,14 +4,17 @@ import argparse, sys, os, glob, subprocess, mimetypes, re, pathlib
def main(argv=None):
    compiler = '@CLANG_EXECUTABLE@'
    verbose=False
    baseLibs = ['-rdynamic', '-Wl,-rpath,@XACC_ROOT@/lib:@CMAKE_INSTALL_PREFIX@/lib:@LLVM_INSTALL_PREFIX@/lib',
    baseLibs = ['-rdynamic', '-Wl,-rpath,@XACC_ROOT@/lib:@CMAKE_INSTALL_PREFIX@/lib:@LLVM_INSTALL_PREFIX@/lib:@CMAKE_INSTALL_PREFIX@/clang-plugins',
                            '-L', '@CMAKE_INSTALL_PREFIX@/lib','-lqcor', '-lqrt', '-lqcor-hybrid', '-lqcor-quasimo', '-lqcor-jit', '-lqir-qrt',
                             '-L', '@XACC_ROOT@/lib', '-lxacc', '-lCppMicroServices',
                            '-lxacc-quantum-gate',
                             '-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']
    defaultFlags = ['-std=c++17', '-fplugin=@CMAKE_INSTALL_PREFIX@/clang-plugins/libqcor-syntax-handler@CMAKE_SHARED_LIBRARY_SUFFIX@']

    extra_headers = '@QCOR_EXTRA_HEADERS@'.replace('"','')
    for path in extra_headers.split(';'):
        baseIncludes += ['-I', path]

    # This flag is primarily for our testers to point to the 
    # qcor syntax handler before make install is called
@@ -20,7 +23,7 @@ def main(argv=None):
        pth = sys.argv[idx+1]
        sys.argv.remove(pth)
        sys.argv.remove('-internal-syntax-handler-plugin-path')
        defaultFlags = ['-std=c++17', '-fplugin='+pth+'/libqcor-syntax-handler.so']
        defaultFlags = ['-std=c++17', '-fplugin='+pth+'/libqcor-syntax-handler@CMAKE_SHARED_LIBRARY_SUFFIX@']

    # Need to know if this is compile-only
    compileOnly = '-c' in sys.argv[1:]
@@ -40,7 +43,7 @@ def main(argv=None):
        parser.add_argument('-I',action='append',nargs=1, metavar=('header_file.hpp'),help='specify additional headers to add to the include search path.')
        parser.add_argument('-L',action='append',nargs=1,metavar=('/path/to/libs'),help='specifiy additional linker search paths.')
        parser.add_argument('-l',action='append',nargs=1,metavar=('lib_name'),help='specifiy additional libraries to link.')
        parser.add_argument('-opt', nargs=1, help='specify optimization level for quantum circuit optimization.')
        parser.add_argument('-opt', nargs=1, help='specify level of quantum circuit optimization (1 or 2).')
        parser.add_argument('-print-opt-stats', help='print circuit optimization pass statistics.')
        parser.add_argument('-set-credentials', nargs=1, help='set api key and other credential information for remote qpu.\nMust provide at least -key KEY arguments. For IBM also specify -hub HUB -group GROUP -project PROJECT.')
        parser.add_argument('-print-credentials', nargs=1, help='print remote api credentials for given qpu name.')
@@ -205,10 +208,6 @@ def main(argv=None):
    if verbose:
        sHandlerArgs += ['-Xclang', '-plugin-arg-qcor-args', '-Xclang', '-qcor-verbose']

    if '-print-qir' in sys.argv[1:]:
        sys.argv.remove('-print-qir')
        sHandlerArgs += ['-Xclang', '-load', '-Xclang', '@CMAKE_INSTALL_PREFIX@/qopt-plugins/libprint_llvm_qir.so']

    # Optimization level for flattened (runtime) kernel
    # Default: 0 (no optimization)
    qrtOptLevel = 0
@@ -313,7 +312,7 @@ def main(argv=None):
        filename = None

    # If it is a C++ file
    if fileType == 'text/x-c++src':
    if 'text/x-c' in fileType:
        fileIdx = sys.argv[1:].index(filename)
        tmpFileName = os.path.basename(filename)