Skip to content

Instantly share code, notes, and snippets.

@perrette
Last active December 18, 2015 17:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save perrette/22550c5f99f64ddbcb2b to your computer and use it in GitHub Desktop.
Save perrette/22550c5f99f64ddbcb2b to your computer and use it in GitHub Desktop.
Try out f90wrap module ! (https://github.com/jameskermode/f90wrap)
# requires: https://github.com/jameskermode/f90wrap
# basically this is a wrapper around f2py...:
# - the fortran code is rewritten by f90wrap into a f90wrap_module.f90
# so that there is no type defined (which are not supported by f2py break)
# - the same step also produces a python module that wraps the newly written f90wrap_module.f90 into fortran
# - compile the fortran wrapper with a few nice additions such as
# handling optional arguments, and defining the f90wrap_abort() function to raise an error in python
# without crashing the program...
# name of python module to be created
NAME=mod1
# basic command: needs mod1.py and compiled library _mod1.so
main: $(NAME).py _$(NAME).so
# the % sign is used instead of $(NAME).py because the latter
# is not recognized as a valid target by the makefile, for some reason
%.py: module.f90
f90wrap -m $(NAME) module.f90 # create wrapper $(NAME).py module and f90wrap_module.f90
_$(NAME).so: module.o f90wrap_module.f90
f2py-f90wrap -c -m _$(NAME) $^
module.o: module.f90
gfortran -fPIC -c module.f90
clean:
rm *.o f90wrap*.f90 *.mod *.pyc -f
cleanall: clean
rm $(NAME).py _$(NAME).so -f
module mod1_api
implicit none
private
public :: typ1
public :: typ1_repr
public :: typ1_inc
public :: raise_error
type typ1
real :: a = 6.
integer :: n = 2
end type
contains
function typ1_repr(t) result(repr)
type(typ1), intent(in) :: t
character(len=64) :: repr
write(repr, '("{ a: ",F10.3,", b: ",I6,"}" )') t%a, t%n
end function
subroutine typ1_inc(t)
type(typ1), intent(inout) :: t
t%n = add(t%n, 1)
end subroutine
integer function add(i, j)
!! private function
integer :: i, j
add = i + j
end function
subroutine raise_error(msg)
character(len=*), intent(in) :: msg
call f90wrap_abort(msg)
end subroutine
end module
"""Test the module in python
"""
from mod1 import mod1_api
# create a type instance
t = mod1_api.Typ1()
print 'Typ1 instance t:', t
print 't.a:', t.a
print 't.n:', t.n
print 'call inc(t)'
mod1_api.typ1_inc(t)
print 't.n:', t.n
print 'repr(t)', mod1_api.typ1_repr(t)
try:
mod1_api.raise_error('This is an error message')
print "this is never executed"
except RuntimeError as error:
print "Caught fortran exception in python !"
print str(error)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment