def test_assembly_linear_form_2d_1(): b = LinearForm(v, integral(domain, v*cos(x))) ast = AST(b) stmt = parse(ast.expr, settings={'dim': ast.dim, 'nderiv': ast.nderiv}) print(pycode(stmt)) print()
def test_assembly_bilinear_form_2d_1(): a = BilinearForm((u,v), integral(domain, dot(grad(u), grad(v)))) ast = AST(a) stmt = parse(ast.expr, settings={'dim': ast.dim, 'nderiv': ast.nderiv}) print(pycode(stmt)) print()
def test_eval_field_2d_1(): # ... args = [dx1(u), dx2(u)] # TODO improve stmts = [AugAssign(ProductGenerator(MatrixQuadrature(i), index_quad), '+', Mul(coeff,AtomicNode(i))) for i in args] # ... # ... nderiv = 1 body = construct_logical_expressions(u, nderiv) # ... # ... stmts = body + stmts loop = Loop((l_quad, a_basis), index_quad, stmts) # ... # ... stmts = [loop] loop = Loop((l_basis, l_coeff), index_dof, stmts) # ... # TODO do we need nderiv here? stmt = parse(loop, settings={'dim': domain.dim, 'nderiv': nderiv}) print(pycode(stmt)) print()
def test_global_quad_basis_span_2d_2(): # ... nderiv = 2 stmts = construct_logical_expressions(u, nderiv) expressions = [dx(u), dx(dy(u)), dy(dy(u))] stmts += [ComputePhysicalBasis(i) for i in expressions] # ... # ... stmts += [Reduction('+', ComputePhysicalBasis(dx(u)*dx(v)))] # ... # ... loop = Loop((l_quad, a_basis), index_quad, stmts) # ... # ... stmts = [loop] loop = Loop(l_basis, index_dof, stmts) # ... # ... stmts = [loop] loop = Loop((g_quad, g_basis, g_span), index_element, stmts) # ... stmt = parse(loop, settings={'dim': domain.dim, 'nderiv': nderiv}) print(pycode(stmt)) print()
def test_loop_local_quad_2d_1(): stmts = [] loop = Loop(l_quad, index_quad, stmts) stmt = parse(loop, settings={'dim': domain.dim}) print(pycode(stmt)) print()
def test_global_quad_basis_span_2d_1(): # ... stmts = [] loop = Loop((g_quad, g_basis, g_span), index_element, stmts) # ... # TODO do we need nderiv here? stmt = parse(loop, settings={'dim': domain.dim, 'nderiv': 2}) print(pycode(stmt)) print()
def test_loop_global_local_quad_2d_1(): # ... stmts = [] loop = Loop(l_quad, index_quad, stmts) # ... # ... stmts = [loop] loop = Loop(g_quad, index_element, stmts) # ... stmt = parse(loop, settings={'dim': domain.dim, 'nderiv': 2}) print(pycode(stmt)) print()
def test_loop_local_quad_geometry_2d_1(): # ... nderiv = 1 stmts = [] loop = Loop((l_quad, GeometryExpressions(M, nderiv)), index_quad, stmts) # ... settings = {'dim': domain.dim, 'nderiv': nderiv, 'mapping': M} _parse = lambda expr: parse(expr, settings=settings) stmt = _parse(loop) print() print(pycode(stmt)) print()
def test_loop_local_dof_quad_2d_1(): # ... stmts = [] loop = Loop((l_quad, a_basis), index_quad, stmts) # ... # ... stmts = [loop] loop = Loop(l_basis, index_dof, stmts) # ... # TODO bug when nderiv=0 stmt = parse(loop, settings={'dim': domain.dim, 'nderiv': 1}) print() print(pycode(stmt)) print()
def test_global_quad_basis_span_2d_matrix_2(): # ... nderiv = 1 stmts = construct_logical_expressions(u, nderiv) expressions = [dx(v), dy(v), dx(u), dy(u)] stmts += [ComputePhysicalBasis(i) for i in expressions] # ... # ... loop = Loop((l_quad, a_basis, GeometryExpressions(M, nderiv)), index_quad, stmts) # ... # ... loop = Reduce('+', ComputeKernelExpr(dx(u)*dx(v)), ElementOf(l_mat), loop) # ... # ... loop over trials stmts = [loop] loop = Loop(l_basis, index_dof_trial, stmts) # ... # ... loop over tests stmts = [loop] loop = Loop(l_basis_v, index_dof_test, stmts) # ... # ... body = (Reset(l_mat), loop) stmts = Block(body) # ... # ... loop = Loop((g_quad, g_basis, g_basis_v, g_span), index_element, stmts) # ... # ... body = (Reset(g_mat), Reduce('+', l_mat, g_mat, loop)) stmt = Block(body) # ... stmt = parse(stmt, settings={'dim': domain.dim, 'nderiv': nderiv, 'mapping': M}) print(pycode(stmt)) print()
def test_loop_local_dof_quad_2d_3(): # ... stmts = [dx1(u)] stmts = [ComputeLogicalBasis(i) for i in stmts] # ... # ... loop = Loop((l_quad, a_basis), index_quad, stmts) # ... # ... stmts = [loop] loop = Loop(l_basis, index_dof, stmts) # ... stmt = parse(loop, settings={'dim': domain.dim, 'nderiv': 3}) print() print(pycode(stmt)) print()
def test_global_quad_basis_span_2d_vector_2(): # ... nderiv = 1 stmts = construct_logical_expressions(v, nderiv) # expressions = [dx(v), v] # TODO Wrong result expressions = [dx(v), dy(v)] stmts += [ComputePhysicalBasis(i) for i in expressions] # ... # ... case with mapping <> identity loop = Loop((l_quad, a_basis, GeometryExpressions(M, nderiv)), index_quad, stmts) # ... # ... loop = Reduce('+', ComputeKernelExpr(dx(v)*cos(x+y)), ElementOf(l_vec), loop) # ... # ... loop over tests stmts = [loop] loop = Loop(l_basis_v, index_dof_test, stmts) # ... # ... body = (Reset(l_vec), loop) stmts = Block(body) # ... # ... loop = Loop((g_quad, g_basis_v, g_span), index_element, stmts) # ... # ... body = (Reset(g_vec), Reduce('+', l_vec, g_vec, loop)) stmt = Block(body) # ... stmt = parse(stmt, settings={'dim': domain.dim, 'nderiv': nderiv, 'mapping': M}) print(pycode(stmt)) print()
def test_global_quad_basis_span_2d_vector_1(): # ... nderiv = 2 stmts = construct_logical_expressions(v, nderiv) expressions = [dx(v), dx(dy(v)), dy(dy(v))] stmts += [ComputePhysicalBasis(i) for i in expressions] # ... # ... loop = Loop((l_quad, a_basis), index_quad, stmts) # ... # ... loop = Reduce('+', ComputeKernelExpr(dx(v)*cos(x+y)), ElementOf(l_vec), loop) # ... # ... loop over tests stmts = [loop] loop = Loop(l_basis_v, index_dof_test, stmts) # ... # ... body = (Reset(l_vec), loop) stmts = Block(body) # ... # ... loop = Loop((g_quad, g_basis_v, g_span), index_element, stmts) # ... # ... body = (Reset(g_vec), Reduce('+', l_vec, g_vec, loop)) stmt = Block(body) # ... stmt = parse(stmt, settings={'dim': domain.dim, 'nderiv': nderiv}) print(pycode(stmt)) print()
def _lambdify(func, namespace={}, **kwargs): if not isinstance(func, FunctionType): raise TypeError('Expecting a lambda function') # ... get the function source code func_code = get_source_function(func) # ... # ... syntax_only = kwargs.pop('syntax_only', False) L = parse_lambda(func_code) if syntax_only: return L # ... # ... TODO move this to semantic parser user_functions = {} for f_name, f in namespace.items(): # ... check if a user function decorators = get_decorators(f) if f_name in decorators.keys(): decorators = decorators[f_name] if 'types' in decorators: # TODO f_symbolic = f user_functions[f_name] = f_symbolic setattr(f_symbolic, '_imp_', f) else: raise ValueError('{} given without a type'.format(f_name)) else: raise NotImplementedError('') typed_functions = _parse_typed_functions(list(user_functions.values())) # ... # ... semantic analysis semantic_only = kwargs.pop('semantic_only', False) parser = SemanticParser(L, typed_functions=typed_functions) dtype = parser.doit() # ######### DEBUG # print('=======================') # parser.inspect() # print('=======================') if semantic_only: return dtype # ... # ... ast ast_only = kwargs.pop('ast_only', False) ast = AST(parser, **kwargs) func = ast.doit() with_interface = len(func.m_results) > 0 if ast_only: return func # ... # ... printing of a python function without interface printing_only = kwargs.pop('printing_only', False) if printing_only: return pycode(func) # ... # ... imports = [] # ... # ... get math functions and constants math_elements = math_atoms_as_str(func) math_imports = [] for e in math_elements: math_imports += [Import(e, 'numpy')] imports += math_imports # convert to a string imports = '\n'.join([pycode(i) for i in imports]) # ... # ... print python code code = get_pyccel_imports_code() code += '\n' + imports + '\n' code += get_dependencies_code(list(user_functions.values())) code += '\n\n' code += pycode(func) # ... # ... folder = kwargs.pop('folder', None) if folder is None: basedir = os.getcwd() folder = '__pycache__' folder = os.path.join( basedir, folder ) folder = os.path.abspath( folder ) mkdir_p(folder) # ... # ... func_name = str(func.name) module_name = 'mod_{}'.format(func_name) write_code('{}.py'.format(module_name), code, folder=folder) # print(code) # sys.exit(0) sys.path.append(folder) package = importlib.import_module( module_name ) sys.path.remove(folder) # ... # we return a module, that will processed by epyccel # ... module case from pyccel.epyccel import epyccel accelerator = kwargs.pop('accelerator', None) verbose = kwargs.pop('verbose', False) # verbose = kwargs.pop('verbose', True) f2py_package = epyccel ( package, accelerator = accelerator, verbose = verbose ) f2py_func_name = func_name f2py_func = getattr(f2py_package, f2py_func_name) # ####### DEBUG # return f2py_func if not func.is_procedure: return f2py_func # ... # .............................................. # generate a python interface # .............................................. f2py_module_name = os.path.basename(f2py_package.__file__) f2py_module_name = os.path.splitext(f2py_module_name)[0] # ... create a python interface with an optional 'out' argument # à la numpy interface = LambdaInterface(func, Import(f2py_func_name, f2py_module_name)) # ... # ... code = pycode(interface) # print(code) # ... # ... func_name = str(interface.name) # ... # TODO this is a temporary fix g = {} exec(code, g) f = g[func_name] return f
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