def run(test_dir, **settings): init_dir = os.getcwd() base_dir = os.path.dirname(os.path.realpath(__file__)) path_dir = os.path.join(base_dir, os.path.join('scripts', test_dir)) files = sorted(os.listdir(path_dir)) files = [f for f in files if (f.endswith(".py"))] os.chdir(path_dir) for f in files: print('> testing {0}'.format(str(f))) execute_pyccel(f, **settings) os.chdir(init_dir) print('\n')
from pyccel.codegen.utilities import execute_pyccel code = execute_pyccel('scripts/mxm_omp.py', convert_only=True) print(code)
from pyccel.codegen.utilities import execute_pyccel code = execute_pyccel('scripts/helloworld.py', convert_only=True) print(code)
def pyccel(files=None, openmp=None, openacc=None, output_dir=None, compiler='gfortran'): """ pyccel console command. """ parser = MyParser(description='pyccel command line') parser.add_argument('files', metavar='N', type=str, nargs='+', help='a Pyccel file') # ... compiler syntax, semantic and codegen group = parser.add_argument_group('Pyccel compiling stages') group.add_argument('-x', '--syntax-only', action='store_true', help='Using pyccel for Syntax Checking') group.add_argument('-e', '--semantic-only', action='store_true', help='Using pyccel for Semantic Checking') group.add_argument('-t', '--convert-only', action='store_true', help='Converts pyccel files only without build') # ... # ... backend compiler options group = parser.add_argument_group('Backend compiler options') group.add_argument('--compiler', type=str, \ help='Used compiler') group.add_argument('--fflags', type=str, \ help='Fortran compiler flags.') group.add_argument('--debug', action='store_true', \ help='compiles the code in a debug mode.') group.add_argument('--include', type=str, \ help='path to include directory.') group.add_argument('--libdir', type=str, \ help='path to lib directory.') group.add_argument('--libs', type=str, \ help='list of libraries to link with.') group.add_argument('--output', type=str, default = '',\ help='folder in which the output is stored.') group.add_argument('--prefix', type=str, default = '',\ help='add prefix to the generated file.') group.add_argument('--prefix-module', type=str, default = '',\ help='add prefix module name.') group.add_argument('--language', type=str, help='target language') # ... # ... Accelerators group = parser.add_argument_group('Accelerators options') group.add_argument('--openmp', action='store_true', \ help='uses openmp') group.add_argument('--openacc', action='store_true', \ help='uses openacc') # ... # ... Other options group = parser.add_argument_group('Other options') group.add_argument('--verbose', action='store_true', \ help='enables verbose mode.') group.add_argument('--developer-mode', action='store_true', \ help='shows internal messages') # ... # TODO move to another cmd line parser.add_argument('--analysis', action='store_true', \ help='enables code analysis mode.') # ... # ... args = parser.parse_args() # ... # ... if not files: files = args.files if args.compiler: compiler = args.compiler if not openmp: openmp = args.openmp if not openacc: openacc = args.openacc if args.convert_only or args.syntax_only or args.semantic_only: compiler = None # ... # ... if not files: raise ValueError("a python filename must be provided.") if len(files) > 1: raise ValueError('Expecting one single file for the moment.') # ... filename = files[0] # ... report error if os.path.isfile(filename): # we don't use is_valid_filename_py since it uses absolute path # file extension ext = filename.split('.')[-1] if not(ext in ['py', 'pyh']): errors = Errors() errors.report(INVALID_FILE_EXTENSION, symbol=ext, severity='fatal') errors.check() raise SystemExit(0) else: # we use Pyccel error manager, although we can do it in other ways errors = Errors() errors.report(INVALID_FILE_DIRECTORY, symbol=filename, severity='fatal') errors.check() raise SystemExit(0) # ... if compiler: if _which(compiler) is None: raise ValueError('Could not find {0}'.format(compiler)) accelerator = None if openmp: accelerator = "openmp" if openacc: accelerator = "openacc" debug = args.debug verbose = args.verbose include = args.include fflags = args.fflags libdir = args.libdir libs = args.libs output_folder = args.output prefix = args.prefix prefix_module = args.prefix_module language = args.language if (len(output_folder)>0 and output_folder[-1]!='/'): output_folder+='/' if not include: include = [] if not libdir: libdir = [] if not libs: libs = [] # ... # ... if args.developer_mode: # this will initialize the singelton ErrorsMode # making this settings available everywhere err_mode = ErrorsMode() err_mode.set_mode('developer') # ... # ... from pyccel.parser import Parser from pyccel.codegen import Codegen if args.syntax_only: pyccel = Parser(filename) ast = pyccel.parse() elif args.semantic_only: pyccel = Parser(filename) ast = pyccel.parse() settings = {} ast = pyccel.annotate(**settings) elif args.convert_only: pyccel = Parser(filename) ast = pyccel.parse() settings = {} if args.language: settings['language'] = args.language ast = pyccel.annotate(**settings) name = os.path.basename(filename) name = os.path.splitext(name)[0] codegen = Codegen(ast, name) settings['prefix_module'] = prefix_module code = codegen.doprint(**settings) if prefix: name = '{prefix}{name}'.format(prefix=prefix, name=name) codegen.export(output_folder+name) for son in pyccel.sons: if 'print' in son.metavars.keys(): name = son.filename.split('/')[-1].strip('.py') name = 'mod_'+name codegen = Codegen(son.ast, name) code = codegen.doprint() codegen.export() elif args.analysis: # TODO move to another cmd line from pyccel.complexity.arithmetic import OpComplexity complexity = OpComplexity(filename) print(" arithmetic cost ~ " + str(complexity.cost())) else: # TODO shall we add them in the cmd line? modules = [] binary = None execute_pyccel(filename, compiler=compiler, fflags=fflags, debug=False, verbose=verbose, accelerator=accelerator, include=include, libdir=libdir, modules=modules, libs=libs, binary=binary, output=output_folder)
from pyccel.codegen.utilities import execute_pyccel code = execute_pyccel('scripts/matrix_mul.py', convert_only=True) print(code)
from pyccel.codegen.utilities import execute_pyccel code = execute_pyccel('scripts/functions.py', convert_only=True) print(code)
from pyccel.codegen.utilities import execute_pyccel code = execute_pyccel('/scripts/oop.py', convert_only=True) print(code)
def epyccel_module(module, namespace=globals(), compiler=None, fflags=None, accelerator=None, verbose=False, debug=False, include=[], libdir=[], modules=[], libs=[], extra_args='', mpi=False, folder=None): # ... get the module source code if not isinstance(module, ModuleType): raise TypeError('> Expecting a module') lines = inspect.getsourcelines(module)[0] code = ''.join(lines) # ... # ... tag = random_string(6) # ... # ... module_name = module.__name__.split('.')[-1] fname = module.__file__ binary = '{}.o'.format(module_name) libname = tag # ... # ... if folder is None: basedir = os.getcwd() folder = '__pycache__' folder = os.path.join(basedir, folder) folder = os.path.abspath(folder) mkdir_p(folder) # ... # ... basedir = os.getcwd() os.chdir(folder) curdir = os.getcwd() # ... # ... we need to store the python file in the folder, so that execute_pyccel # can run copyfile(fname, os.path.basename(fname)) fname = os.path.basename(fname) # ... # ... if compiler is None: compiler = 'gfortran' # ... # ... if fflags is None: fflags = construct_flags_pyccel(compiler, fflags=None, debug=debug, accelerator=accelerator, include=[], libdir=[]) # ... # add -fPIC fflags = ' {} -fPIC '.format(fflags) # ... convert python to fortran using pyccel # we ask for the ast so that we can get the FunctionDef node output, cmd, ast = execute_pyccel(fname, compiler=compiler, fflags=fflags, debug=debug, verbose=verbose, accelerator=accelerator, include=include, libdir=libdir, modules=modules, libs=libs, binary=None, output='', return_ast=True) # ... # ... add -c to not warn if the library had to be created cmd = 'ar -rc lib{libname}.a {binary} '.format(binary=binary, libname=libname) output = subprocess.check_output(cmd, shell=True) if verbose: print(cmd) # ... # ... construct a f2py interface for the assembly # be careful: because of f2py we must use lower case funcs = ast.routines + ast.interfaces namespace = ast.parser.namespace.sons_scopes funcs, others = get_external_function_from_ast(funcs) static_funcs = [] imports = [] parents = OrderedDict() for f in funcs: if f.is_external: static_func = as_static_function(f) namespace['f2py_' + str(f.name).lower()] = namespace[str(f.name)] # S.H we set the new scope name elif f.is_external_call: static_func = as_static_function_call(f) namespace[str(static_func.name).lower()] = namespace[str(f.name)] imports += [Import(f.name, module_name.lower())] static_funcs.append(static_func) parents[static_func.name] = f.name for f in others: imports += [Import(f.name, module_name.lower())] f2py_module_name = 'f2py_{}'.format(module_name) f2py_module_name = f2py_module_name.lower() f2py_module = Module(f2py_module_name, variables=[], funcs=static_funcs, interfaces=[], classes=[], imports=imports) code = fcode(f2py_module, ast.parser) filename = '{}.f90'.format(f2py_module_name) write_code(filename, code, folder=folder) output, cmd = compile_f2py(filename, extra_args=extra_args, libs=[libname], libdirs=[curdir], compiler=compiler, accelerator=accelerator, mpi=mpi) if verbose: print(cmd) # ... # ... # update module name for dependencies # needed for interface when importing assembly # name.name is needed for f2py code = pycode(F2PY_ModuleInterface(f2py_module, parents)) _module_name = '__epyccel__{}'.format(module_name) filename = '{}.py'.format(_module_name) fname = write_code(filename, code, folder=folder) sys.path.append(folder) package = importlib.import_module(_module_name) sys.path.remove(folder) os.chdir(basedir) if verbose: print('> epyccel interface has been stored in {}'.format(fname)) # ... return package
def epyccel_function(func, namespace=globals(), compiler=None, fflags=None, accelerator=None, verbose=False, debug=False, include=[], libdir=[], modules=[], libs=[], extra_args='', folder=None, mpi=False, assert_contiguous=False): # ... get the function source code if not isinstance(func, FunctionType): raise TypeError('> Expecting a function') code = get_source_function(func) # ... # ... tag = random_string(6) # ... # ... module_name = 'mod_{}'.format(tag) fname = '{}.py'.format(module_name) binary = '{}.o'.format(module_name) # ... # ... if folder is None: basedir = os.getcwd() folder = '__pycache__' folder = os.path.join(basedir, folder) folder = os.path.abspath(folder) mkdir_p(folder) # ... # ... write_code(fname, code, folder=folder) # ... # ... basedir = os.getcwd() os.chdir(folder) curdir = os.getcwd() # ... # ... if compiler is None: compiler = 'gfortran' # ... # ... if fflags is None: fflags = construct_flags_pyccel(compiler, fflags=None, debug=debug, accelerator=accelerator, include=[], libdir=[]) # ... # ... convert python to fortran using pyccel # we ask for the ast so that we can get the FunctionDef node fname, ast = execute_pyccel(fname, compiler=compiler, fflags=fflags, debug=debug, verbose=verbose, accelerator=accelerator, modules=modules, convert_only=True, return_ast=True) # ... # ... construct a f2py interface for the assembly # be careful: because of f2py we must use lower case func_name = func.__name__ funcs = ast.routines + ast.interfaces func = get_function_from_ast(funcs, func_name) namespace = ast.parser.namespace.sons_scopes # ... f2py_module_name = 'f2py_{}'.format(module_name) static_func = as_static_function(func) namespace['f2py_' + func_name.lower()] = namespace[func_name] f2py_module = Module(f2py_module_name, variables=[], funcs=[static_func], interfaces=[], classes=[], imports=[]) code = fcode(f2py_module, ast.parser) filename = '{}.f90'.format(f2py_module_name) fname = write_code(filename, code, folder=folder) output, cmd = compile_f2py(filename, extra_args=extra_args, compiler=compiler, mpi=mpi, accelerator=accelerator) if verbose: print(cmd) # ... # ... # update module name for dependencies # needed for interface when importing assembly # name.name is needed for f2py settings = {'assert_contiguous': assert_contiguous} code = pycode(F2PY_FunctionInterface(static_func, f2py_module_name, func), **settings) _module_name = '__epyccel__{}'.format(module_name) filename = '{}.py'.format(_module_name) fname = write_code(filename, code, folder=folder) sys.path.append(folder) package = importlib.import_module(_module_name) sys.path.remove(folder) func = getattr(package, func_name) os.chdir(basedir) if verbose: print('> epyccel interface has been stored in {}'.format(fname)) # ... return func