def render_as_module(definitions, name, declarations=(), printer_settings=None): """ Creates a ``Module`` instance and renders it as a string. This generates Fortran source code for a module with the correct ``use`` statements. Parameters ========== definitions : iterable Passed to :class:`sympy.codegen.fnodes.Module`. name : str Passed to :class:`sympy.codegen.fnodes.Module`. declarations : iterable Passed to :class:`sympy.codegen.fnodes.Module`. It will be extended with use statements, 'implicit none' and public list generated from ``definitions``. printer_settings : dict Passed to ``FCodePrinter`` (default: ``{'standard': 2003, 'source_format': 'free'}``). """ printer_settings = printer_settings or {'standard': 2003, 'source_format': 'free'} printer = FCodePrinter(printer_settings) dummy = Dummy() if isinstance(definitions, Module): raise ValueError("This function expects to construct a module on its own.") mod = Module(name, chain(declarations, [dummy]), definitions) fstr = printer.doprint(mod) module_use_str = ' %s\n' % ' \n'.join(['use %s, only: %s' % (k, ', '.join(v)) for k, v in printer.module_uses.items()]) module_use_str += ' implicit none\n' module_use_str += ' private\n' module_use_str += ' public %s\n' % ', '.join([str(node.name) for node in definitions if getattr(node, 'name', None)]) return fstr.replace(printer.doprint(dummy), module_use_str)
def test_Subroutine(): # Code to generate the subroutine in the example from # http://www.fortran90.org/src/best-practices.html#arrays r = Symbol("r", real=True) i = Symbol("i", integer=True) v_r = Variable.deduced(r, attrs=(dimension(assumed_extent), intent_out)) v_i = Variable.deduced(i) v_n = Variable("n", integer) do_loop = Do([Assignment(Element(r, [i]), literal_dp(1) / i**2)], i, 1, v_n) sub = Subroutine( "f", [v_r], [ Declaration(v_n), Declaration(v_i), Assignment(v_n, size(r)), do_loop ], ) x = Symbol("x", real=True) v_x3 = Variable.deduced(x, attrs=[dimension(3)]) mod = Module("mymod", definitions=[sub]) prog = Program( "foo", [ use(mod, only=[sub]), Declaration(v_x3), SubroutineCall(sub, [v_x3]), Print([sum_(v_x3), v_x3]), ], ) if not has_fortran(): skip("No fortran compiler found.") (stdout, stderr), info = compile_run_strings( [("a.f90", fcode(mod, standard=90)), ("b.f90", fcode(prog, standard=90))], clean=True, ) ref = [1.0 / i**2 for i in range(1, 4)] assert str(sum(ref))[:-3] in stdout for _ in ref: assert str(_)[:-3] in stdout assert stderr == ""
def test_Module(): x = Symbol('x', real=True) v_x = Variable.deduced(x) sq = FunctionDefinition(real, 'sqr', [v_x], [Return(x**2)]) mod_sq = Module('mod_sq', [], [sq]) sq_call = FunctionCall('sqr', [42.]) prg_sq = Program( 'foobar', [use('mod_sq', only=['sqr']), Print(['"Square of 42 = "', sq_call])]) if not has_fortran(): skip("No fortran compiler found.") (stdout, stderr), info = compile_run_strings( [('mod_sq.f90', fcode(mod_sq, standard=90)), ('main.f90', fcode(prg_sq, standard=90))], clean=True) assert '42' in stdout assert str(42**2) in stdout assert stderr == ''
def test_Module(): x = Symbol("x", real=True) v_x = Variable.deduced(x) sq = FunctionDefinition(real, "sqr", [v_x], [Return(x**2)]) mod_sq = Module("mod_sq", [], [sq]) sq_call = FunctionCall("sqr", [42.0]) prg_sq = Program( "foobar", [use("mod_sq", only=["sqr"]), Print(['"Square of 42 = "', sq_call])]) if not has_fortran(): skip("No fortran compiler found.") (stdout, stderr), info = compile_run_strings( [ ("mod_sq.f90", fcode(mod_sq, standard=90)), ("main.f90", fcode(prg_sq, standard=90)), ], clean=True, ) assert "42" in stdout assert str(42**2) in stdout assert stderr == ""