CTypes, Python Callback, and FORTRAN -
i new python (and fortran well) happen writing interface fortran solver call python code. using python 3 right , trying use ctypes write interface. since solver subroutine has around 40 parameters, show question using simple example in fortran , python.
first, consider main fortran subroutine in ex3_func.f
subroutine ex3_func (pp,num,dim,funptrobjfun) implicit none integer, intent(in) :: num, dim real(8), intent(inout) :: pp(num,dim) external funptrobjfun pp = (pp+pp)*3.0 call funptrobjfun(pp,num,dim) return end subroutine
compiling using: $> gfortran -c ex3_func.f gives no problem @ all.
i have c interface subroutine, module in ex3_cfunc.f
module cwrapper_ex3cfunc use iso_c_binding, only: c_int, c_double, c_funptr implicit none contains subroutine ex3_cfunc(pp, num, dim, ptrfunobjfun) bind(c) integer(c_int), intent(in) :: num, dim real(c_double), intent(inout) :: pp(num,dim) type(c_funptr), intent(inout) :: ptrfunobjfun call ex3_func(pp,num,dim,ptrfunobjfun) return end subroutine end module
compiling using: $> gfortran -c ex3_cfunc.f gives no problems well.
finally, run: $> gfortran -shared -o2 ex3_func.o ex3_cfunc.o -o lib_ex3func.so -fpic
which gives no problems , generates file lib_ex3func.so
before moving python code, note funptrobjfunc (a pointer function) call python function called writetomatrix() -- see below-- in main python program.
here python code call fortran lib.
import ctypes ct import numpy np num=3 dim=4 aa = ((ct.c_double *dim) *num) print(type(aa)) print(aa) xx = aa() <class '_ctypes.pycarraytype'> <class '__main__.c_double_array_4_array_3'> #fill xx anything: in range(0,num): j in range(0,dim): xx[i][j]= (i+1)*(j+1) def writetomatrix (ff,num,dim): print("num x dim : ",num[0],dim[0]) print(ff) print(np.shape(ff),'\n') #write element ff[2][3]=99.0 print(np.ctypeslib.as_array(ff)) ptrfunc = ct.cfunctype(none,aa,ct.pointer(ct.c_int),ct.pointer(ct.c_int)) fortran = ct.cdll.loadlibrary('lib_ex3func.so') #execution! fortran.ex3_cfunc(xx,ct.byref(ct.c_int(num)),ct.byref(ct.c_int(dim)),ptrfunc(writetomatrix)) #output num x dim : 3 4 <__main__.c_double_array_4_array_3 object @ 0x106de1840> (3, 4) [[ 2.16962762e-314 1.97626258e-323 6.95321987e-310 2.16813588e-314] [ 6.95321987e-310 6.95321987e-310 6.95321987e-310 6.95321987e-310] [ 6.95321987e-310 2.16918622e-314 2.12199579e-314 9.90000000e+001]] # can see (above) writetomatrix can't see nor access original xx. # prints garbage , 99.0 value in last element! fortran # procedure, however, it's suppoosed do, , answer below # correct. question how writetomatrix can access xx , modify it's # elements? zz=np.ctypeslib.as_array(xx) zz array([[ 6., 12., 18., 24.], [ 12., 24., 36., 48.], [ 18., 36., 54., 72.]])
my question , problem need access elements of xx , modify elements of xx writetomatrix(). couldn't figure out how it. python code, fortran code, or both?! appreciate , explanation :)
thank taking time read this!
Comments
Post a Comment