def _set_kind(self): """Finds the source code kind.""" cls = (Header, EmptyNode, NewLine, Comment, CommentBlock, Module) is_module = all(isinstance(i, cls) for i in self.ast.body) if is_module: self._kind = 'module' else: self._kind = 'program' # ... # ... expr = None if self.is_module: expr = Module(self.name, self.variables, self.routines, self.interfaces, self.classes, imports=self.imports) elif self.is_program: expr = Program(self.name, self.variables, self.body.body, imports=self.imports) else: raise NotImplementedError('TODO') self._expr = expr
def pyccelize(expr, **settings): """.""" # ... with_mpi = False if 'with_mpi' in settings: with_mpi = settings['with_mpi'] # ... # ... with_openmp = False if 'with_openmp' in settings: with_openmp = settings['with_openmp'] # ... # ... with_openacc = False if 'with_openacc' in settings: with_openacc = settings['with_openacc'] # ... # ... ignored_modules = [] if 'ignored_modules' in settings: ignored_modules = settings['ignored_modules'] # ... # ... if not isinstance(expr, (Module, Program)): raise NotImplementedError('') # ... # ... if isinstance(expr, (Module, Program)): # ... name = expr.name variables = expr.variables funcs = expr.funcs classes = expr.classes imports = [] modules = [] body = [] decs = [] metavars = {} info = {} # ... # ... for stmt in expr.imports: name = str(stmt.fil) if not (name in ignored_modules): imports += [stmt] # ... # # ... # def _construct_prelude(stmt): # preludes = '' # if isinstance(stmt, (list, tuple, Tuple)): # for dec in stmt: # preludes += _construct_prelude(dec) # if isinstance(stmt, (For, While)): # preludes += _construct_prelude(stmt.body) # if isinstance(stmt, Block): # for dec in stmt.declarations: # preludes += printer(dec) + "\n" # return preludes # # preludes += _construct_prelude(expr.body) # # ... # ... _hidden_stmts = (Eval, Load) if isinstance(expr, Program): for stmt in expr.body: # Variable is also ignored, since we can export them in headers if isinstance(stmt, (Variable, Lambda)): continue elif isinstance(stmt, Assign): if isinstance(stmt.rhs, (Range, Tensor)): continue elif isinstance(stmt.lhs, Variable): if (isinstance(stmt.lhs.name, str) and stmt.lhs.name.startswith('__')): metavars[stmt.lhs.name] = stmt.rhs else: body += [stmt] else: body += [stmt] elif isinstance(stmt, _hidden_stmts): continue elif isinstance(stmt, Block): # TODO - now we can apply printer to Block directly. must be # updated here => remove the body loop # - printer(stmt) must return only body code, then preludes # are treated somewhere? for s in stmt.body: body += [stmt] # for dec in stmt.declarations: # preludes += "\n" + printer(dec) + "\n" else: body += [stmt] # ... # ... if isinstance(expr, Module): expr = Module(name, variables, funcs, classes, imports=imports) else: expr = Program(name, variables, funcs, classes, body, imports=imports, modules=modules) # ... info['metavars'] = metavars # ... # ... if with_mpi: expr = mpify(expr) # ... # ... if with_openmp: expr = ompfy(expr) # ... # ... if with_openacc: expr = accfy(expr) # ... return expr, info
def __init__(self, \ filename=None, \ output_dir=None, \ name=None, \ imports=None, \ preludes=None, \ body=None, \ routines=None, \ classes=None, \ modules=None): """Constructor for the Codegen class. filename: str name of the file to parse. name: str name of the generated module or program. if not given, 'main' will be used in the case of a program, and 'pyccel_m_${filename}' in the case of a module. output_dir: str output directory to store pyccel files and generated files imports: list list of imports statements as strings. preludes: list list of preludes statements. body: list list of body statements. routines: list list of all routines (functions/subroutines) definitions. classes: list list of all classes definitions. modules: list list of used modules. """ # ... TODO improve once TextX will handle indentation clean(filename) # check if the file is a header is_header = (filename.split('.')[-1] == 'pyh') filename_tmp = make_tmp_file(filename, output_dir=output_dir) preprocess(filename, filename_tmp) # file extension is changed to .pyccel filename = filename_tmp # ... if body is None: body = [] if routines is None: routines = [] if classes is None: classes = [] if modules is None: modules = [] self._filename = filename self._filename_out = None self._language = None self._imports = imports self._name = name self._body = body self._preludes = preludes self._routines = routines self._classes = classes self._modules = modules self._printer = None self._output_dir = output_dir self._namespace = None self._headers = None self._is_header = is_header # ... pyccel = PyccelParser() ast = pyccel.parse_from_file(filename) self._ast = ast # ... # ... this is important to update the namespace # old namespace namespace_user = get_namespace() stmts = ast.expr # new namespace self._namespace = get_namespace() self._headers = get_headers() # ... # ................................................... # reorganizing the code to get a Module or a Program # ................................................... variables = [] funcs = [] classes = [] imports = [] modules = [] body = [] decs = [] # ... TODO update Declare so that we don't use a list of variables for key, dec in list(ast.declarations.items()): decs += [dec] variables += [dec.variables[0]] # ... # ... for stmt in stmts: if isinstance(stmt, FunctionDef): funcs += [stmt] elif isinstance(stmt, ClassDef): classes += [stmt] elif isinstance(stmt, Import): imports += [stmt] else: body += [stmt] # ... # ... _stmts = (Header, EmptyLine, Comment) ls = [i for i in body if not isinstance(i, _stmts)] is_module = (len(ls) == 0) # ... # ... expr = None if is_module: expr = Module(name, variables, funcs, classes, imports=imports) else: expr = Program(name, variables, funcs, classes, body, imports=imports, modules=modules) self._expr = expr # ... # ................................................... # ... cleaning clean_namespace()
def ompfy(stmt, **options): """ Converts some statements to OpenMP statments. stmt: stmt, list statement or a list of statements """ if isinstance(stmt, (list, tuple, Tuple)): return [ompfy(i, **options) for i in stmt] if isinstance(stmt, Tensor): # TODO to implement return stmt if isinstance(stmt, ForIterator): iterable = ompfy(stmt.iterable, **options) target = stmt.target body = ompfy(stmt.body, **options) info, clauses = get_for_clauses(iterable) if (clauses is None): return ForIterator(target, iterable, body, strict=False) else: loop = ForIterator(target, iterable, body, strict=False) nowait = info['nowait'] return OMP_For(loop, clauses, nowait) if isinstance(stmt, For): iterable = ompfy(stmt.iterable, **options) target = stmt.target body = ompfy(stmt.body, **options) return For(target, iterable, body, strict=False) if isinstance(stmt, list): return [ompfy(a, **options) for a in stmt] if isinstance(stmt, While): test = ompfy(stmt.test, **options) body = ompfy(stmt.body, **options) return While(test, body) if isinstance(stmt, With): test = ompfy(stmt.test, **options) body = ompfy(stmt.body, **options) settings = ompfy(stmt.settings, **options) clauses = get_with_clauses(test) if (clauses is None): return With(test, body, settings) else: # TODO to be defined variables = [] return OMP_Parallel(clauses, variables, body) if isinstance(stmt, If): args = [] for block in stmt.args: test = block[0] stmts = block[1] t = ompfy(test, **options) s = ompfy(stmts, **options) args.append((t,s)) return If(*args) if isinstance(stmt, FunctionDef): name = ompfy(stmt.name, **options) arguments = ompfy(stmt.arguments, **options) results = ompfy(stmt.results, **options) body = ompfy(stmt.body, **options) local_vars = ompfy(stmt.local_vars, **options) global_vars = ompfy(stmt.global_vars, **options) return FunctionDef(name, arguments, results, body, local_vars, global_vars) if isinstance(stmt, ClassDef): name = ompfy(stmt.name, **options) attributs = ompfy(stmt.attributs, **options) methods = ompfy(stmt.methods, **options) options = ompfy(stmt.options, **options) return ClassDef(name, attributs, methods, options) if isinstance(stmt, Module): name = ompfy(stmt.name, **options) variables = ompfy(stmt.variables, **options) funcs = ompfy(stmt.funcs , **options) classes = ompfy(stmt.classes , **options) imports = ompfy(stmt.imports , **options) imports += [Import('omp_lib')] return Module(name, variables, funcs, classes, imports=imports) if isinstance(stmt, Program): name = ompfy(stmt.name, **options) variables = ompfy(stmt.variables, **options) funcs = ompfy(stmt.funcs , **options) classes = ompfy(stmt.classes , **options) imports = ompfy(stmt.imports , **options) body = ompfy(stmt.body , **options) modules = ompfy(stmt.modules , **options) imports += [Import('omp_lib')] return Program(name, variables, funcs, classes, body, imports=imports, modules=modules) if isinstance(stmt, ParallelBlock): variables = stmt.variables body = stmt.body clauses = stmt.clauses return OMP_Parallel(clauses, variables, body) return stmt
def mpify(stmt, **options): """ Converts some statements to MPI statments. stmt: stmt, list statement or a list of statements """ if isinstance(stmt, (list, tuple, Tuple)): return [mpify(i, **options) for i in stmt] if isinstance(stmt, MPI): return stmt if isinstance(stmt, Tensor): options['label'] = stmt.name return stmt if isinstance(stmt, ForIterator): iterable = mpify(stmt.iterable, **options) target = stmt.target body = mpify(stmt.body, **options) return ForIterator(target, iterable, body, strict=False) if isinstance(stmt, For): iterable = mpify(stmt.iterable, **options) target = stmt.target body = mpify(stmt.body, **options) return For(target, iterable, body, strict=False) if isinstance(stmt, list): return [mpify(a, **options) for a in stmt] if isinstance(stmt, While): test = mpify(stmt.test, **options) body = mpify(stmt.body, **options) return While(test, body) if isinstance(stmt, If): args = [] for block in stmt.args: test = block[0] stmts = block[1] t = mpify(test, **options) s = mpify(stmts, **options) args.append((t, s)) return If(*args) if isinstance(stmt, FunctionDef): return stmt # TODO uncomment this # name = mpify(stmt.name, **options) # arguments = mpify(stmt.arguments, **options) # results = mpify(stmt.results, **options) # body = mpify(stmt.body, **options) # local_vars = mpify(stmt.local_vars, **options) # global_vars = mpify(stmt.global_vars, **options) # # return FunctionDef(name, arguments, results, \ # body, local_vars, global_vars) if isinstance(stmt, ClassDef): name = mpify(stmt.name, **options) attributs = mpify(stmt.attributs, **options) methods = mpify(stmt.methods, **options) options = mpify(stmt.options, **options) return ClassDef(name, attributs, methods, options) if isinstance(stmt, Assign): if isinstance(stmt.rhs, Tensor): lhs = stmt.lhs options['label'] = lhs.name rhs = mpify(stmt.rhs, **options) return Assign(lhs, rhs, \ strict=stmt.strict, \ status=stmt.status, \ like=stmt.like) if isinstance(stmt, Del): variables = [mpify(a, **options) for a in stmt.variables] return Del(variables) if isinstance(stmt, Ones): if stmt.grid: lhs = stmt.lhs shape = stmt.shape grid = mpify(stmt.grid, **options) return Ones(lhs, grid=grid) if isinstance(stmt, Zeros): if stmt.grid: lhs = stmt.lhs shape = stmt.shape grid = mpify(stmt.grid, **options) return Zeros(lhs, grid=grid) if isinstance(stmt, Module): name = mpify(stmt.name, **options) variables = mpify(stmt.variables, **options) funcs = mpify(stmt.funcs, **options) classes = mpify(stmt.classes, **options) imports = mpify(stmt.imports, **options) imports += [Import('mpi')] # TODO add stdlib_parallel_mpi module return Module(name, variables, funcs, classes, imports=imports) if isinstance(stmt, Program): name = mpify(stmt.name, **options) variables = mpify(stmt.variables, **options) funcs = mpify(stmt.funcs, **options) classes = mpify(stmt.classes, **options) imports = mpify(stmt.imports, **options) body = mpify(stmt.body, **options) modules = mpify(stmt.modules, **options) imports += [Import('mpi')] # TODO improve this import, without writing 'mod_...' # maybe we should create a new class for this import imports += [Import('mod_pyccel_stdlib_parallel_mpi')] return Program(name, variables, funcs, classes, body, imports=imports, modules=modules) return stmt