def mod_arrays(tmp): # Working directory cwd = os.path.dirname(__file__) copy(os.path.join(cwd, 'Makefile'), tmp) copy(os.path.join(cwd, 'mod_arrays.f90'), tmp) copy(os.path.join(cwd, 'test_arrays.f90'), tmp) os.mkdir(os.path.join(tmp, 'static')) os.mkdir(os.path.join(tmp, 'shared')) os.chdir(tmp) os.system('make') fort_mod = FortranModule('test_arrays', 'mod_arrays', path=tmp) fort_mod.fdef(""" subroutine test_vector(vec) double precision, dimension(:) :: vec end subroutine subroutine test_array_2d(arr) double precision, dimension(:,:) :: arr end subroutine """) fort_mod.compile() # recreate module to check if it works independently now fort_mod = FortranModule('test_arrays', 'mod_arrays', path=tmp) fort_mod.load() return fort_mod
def setup(tmp): # Working directory cwd = os.path.dirname(__file__) copy(os.path.join(cwd, 'Makefile'), tmp) copy(os.path.join(cwd, 'ex02_pseudoclass.f90'), tmp) os.chdir(tmp) os.system('make') lib = FortranLibrary('pseudoclass', path=tmp) classmod = FortranModule(lib, 'class_circle') classmod.fdef(""" type Circle double precision :: radius complex(8), dimension(:), allocatable :: alloc_array end type subroutine circle_print(self) type(Circle), intent(in) :: self end subroutine subroutine circle_alloc_member(self) type(Circle), intent(inout) :: self end subroutine """) lib.compile()
def uqp(): cwd = os.path.dirname(__file__) os.chdir(cwd) fort_mod = FortranModule('uqp', 'mod_unqu') fort_mod.fdef(""" integer :: np, nall, npar, nt, iflag_run, iflag_mod, iflag_pol subroutine allocate_params end subroutine init_uq end subroutine set_legendre_borders(kpar, lower, upper) integer, intent(in) :: kpar double precision, intent(in) :: lower, upper end subroutine set_hermite_mean_std(kpar, mean0, std) integer, intent(in) :: kpar double precision, intent(in) :: mean0, std end subroutine pre_uq(axi) double precision, intent(inout) :: axi(:,:) end subroutine run_uq end """) fort_mod.compile(verbose=1) fort_mod.load() return fort_mod
def test_compile(tmp_path): cwd = os.path.dirname(__file__) copy(os.path.join(cwd, 'Makefile'), tmp_path) copy(os.path.join(cwd, 'mod_arrays.f90'), tmp_path) copy(os.path.join(cwd, 'test_arrays.f90'), tmp_path) os.mkdir(os.path.join(tmp_path, 'static')) os.mkdir(os.path.join(tmp_path, 'shared')) os.chdir(tmp_path) os.system('make') # Initialize mod_arrays = FortranModule('test_arrays', 'mod_arrays', path=tmp_path) # This will use fortran_module.fdef instead of cdef in the future. # Ideally, the actual Fortran source file would be parsed as an # option instead of code containing only the signatures. mod_arrays.cdef(""" void {mod}_test_vector(array_1d *vec); void {mod}_test_array_2d(array_2d *arr); """) mod_arrays.compile(tmpdir=tmp_path, verbose=True)
def fort_mod(tmp_path, cwd): copy(os.path.join(cwd, 'test_parser.f90'), tmp_path) copy(os.path.join(cwd, 'Makefile'), tmp_path) os.chdir(tmp_path) os.system('make') return FortranModule('test_parser', 'test_parser_mod', path=tmp_path)
""" Created: Thu Jul 25 12:29:27 2019 @author: Christopher Albert <*****@*****.**> """ # %% Import, compile and load from numpy import array, linspace from fffi import FortranLibrary, FortranModule libfortmod = FortranLibrary('fortmod') fortmod = FortranModule(libfortmod, 'fortmod') # member variable and subroutine definition stub # TODO: parse fortmod.f90 automatically and strip away implementation with open('fortmod.f90', 'r') as f: code = f.read() fortmod.fdef(code) libfortmod.compile() # only required when Fortran library has changed fortmod.load() # %% Try some stuff print('Before init(): member = {}'.format(fortmod.member)) fortmod.init() print('After init(): member = {}'.format(fortmod.member)) a = fortmod.member_array # this is a mutable reference print('Before side_effects(): member_array = {}'.format(a)) fortmod.side_effects() print('After side_effects(): member_array = {}'.format(a))
""" Created: Tue Mar 26 09:45:46 2019 @author: Christopher Albert <*****@*****.**> """ from profit import uq import numpy as np from fffi import FortranModule from time import time mean1 = 5.0 std1 = 0.1 mean2 = 2.0 std2 = 0.2 uqp = FortranModule('uqp', 'mod_unqu') uqp.fdef(""" integer :: nporder, nall, npar, nt, iflag_run, iflag_mod, iflag_pol subroutine allocate_params end subroutine init_uq end subroutine set_legendre_borders(kpar, lower, upper) integer, intent(in) :: kpar double precision, intent(in) :: lower, upper end subroutine set_hermite_mean_std(kpar, mean0, std) integer, intent(in) :: kpar double precision, intent(in) :: mean0, std
from fffi import FortranLibrary, FortranModule lib = FortranLibrary('pseudoclass') classmod = FortranModule(lib, 'class_circle') classmod.fdef(""" type Circle double precision :: radius end type subroutine circle_print(self) type(Circle), intent(in) :: self end """) lib.compile() classmod.load() cir = classmod.new('Circle') cir.radius = 3.0 print('Radius: {}'.format(cir.radius)) print('Fortran output:') classmod.circle_print(cir) # # To print Fortran stdout in Jupyter/IPython REPL: # # from wurlitzer import sys_pipes() # with sys_pipes(): # required to print Fortran stdout in Jupyter # classmod.circle_print(cir)
from fparser.two.utils import walk_ast from fparser.two.Fortran2003 import ( Subroutine_Stmt, Dummy_Arg_List, Type_Declaration_Stmt, Entity_Decl, Name, Intrinsic_Type_Spec, Entity_Decl, Explicit_Shape_Spec ) ffi = FFI() libuq = ffi.dlopen('/home/calbert/code/uqp/libuq.so') #libuq = ffi.dlopen('/Users/ert/code/uqp/libuq.so') #%% from fffi import FortranModule, fdef, f2003_parser, debug from fparser.common.readfortran import FortranStringReader mod_index = FortranModule(libuq, 'mod_index') code = """ subroutine test(nfterme, npterme, np, mmax) integer, dimension(0:np) :: jterme, jtermo integer :: jterme2(0:np), jterme3(4) integer nfterme, npterme, mmax integer np end subroutine """ fortmod = mod_index fcode = code tree = f2003_parser(FortranStringReader(fcode)) func = walk_ast(tree.content, [Subroutine_Stmt])[0]
def classmod(lib): fortmod = FortranModule(lib, 'class_circle') fortmod.load() return fortmod