Skip to content

Instantly share code, notes, and snippets.

@perrette
Last active June 3, 2017 08:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save perrette/7da3b5ac72fa846dad6d to your computer and use it in GitHub Desktop.
Save perrette/7da3b5ac72fa846dad6d to your computer and use it in GitHub Desktop.
conflict between fortran+iso_c_binding (via ctypes or cython) and matplotlib when reading namelist
module mylib
use iso_c_binding, only: c_double
implicit none
double precision :: g
contains
subroutine read_par() bind(c, name="read_par")
namelist /block/ g
open(8, file='namelist.nml')
read(8, nml=block)
close(8)
end subroutine
subroutine print_par() bind(c, name="print_par")
print*, 'g', g
end subroutine
subroutine set_par(x) bind(c, name="set_par")
real(c_double), intent(in), value :: x
g = x
end subroutine
end module
cdef extern:
void read_par()
void print_par()
void set_par(double *g)
def read_par2():
read_par()
def print_par2():
print_par()
def set_par2(double g):
set_par(&g)
PYDIR=$(HOME)/anaconda/include/python2.7
ctypes:
gfortran --shared lib.f90 -o lib.so -fPIC
cython:
gfortran -c lib.f90 -o lib.so -fPIC
cython -a lib.pyx
gcc -shared lib.f90 -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I$(PYDIR) -o lib.so lib.c -lgfortran
clean:
rm -rf build *.mod *.so *.o *.c *.html
&block
g = 9.81
/
from ctypes import CDLL, c_double
import matplotlib.pyplot as plt
f = CDLL('./lib.so')
print "Read param and print to screen"
f.read_par()
f.print_par()
# calling matplotlib's plot command seem to prevent
# subsequent namelist reading
print "Call matplotlib.pyplot's plot"
plt.plot([1,2],[3,4])
print "Print param just to be sure: everything is fine"
f.print_par()
print "But any new read will lose decimals on the way!"
f.read_par()
f.print_par()
print "Directly set parameter works fine"
f.set_par(c_double(9.81))
f.print_par()
print "But reading from namelist really does not work anymore"
f.read_par()
f.print_par()
import matplotlib.pyplot as plt
from lib import read_par2 as read_par, print_par2 as print_par, set_par2 as set_par
print "Read param and print to screen"
read_par()
print_par()
# calling matplotlib's plot command seem to prevent
# subsequent namelist reading
print "Call matplotlib.pyplot's plot"
plt.plot([1,2],[3,4])
print "Print param just to be sure: everything is fine"
print_par()
print "But any new read will lose decimals on the way!"
read_par()
print_par()
print "Directly set parameter works fine"
set_par(9.81)
print_par()
print "But reading from namelist really does not work anymore"
read_par()
print_par()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment