f2py
f2py copied to clipboard
Using user defined type
Hi
I am trying to generate a wrapper for my f90 code using f2py. It works for common types like int, real, etc but when i have user defined type I get the following error:
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "mc79reorder" sources
creating /tmp/tmpDnh_3K/src.linux-x86_64-2.7
f2py options: []
f2py: mc79sign.pyf
Reading fortran codes...
Reading file 'mc79sign.pyf' (format:free)
Post-processing...
Block: mc79reorder
Block: hsl_mc79_integer
Block: unknown_type
Block: mc79_matching
Post-processing (stage 2)...
Block: mc79reorder
Block: unknown_interface
Block: hsl_mc79_integer
Block: unknown_type
Block: mc79_matching
Building modules...
Building module "mc79reorder"...
Constructing F90 module support for "hsl_mc79_integer"...
Skipping type unknown_type
Creating wrapper for Fortran subroutine "mc79_matching"("mc79_matching")...
Constructing wrapper function "hsl_mc79_integer.mc79_matching"...
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: No C-type found in "{'attrspec': [], 'typename': 'mc79_control', 'intent': ['in'], 'typespec': 'type'}", assuming void.
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="<C typespec>")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
getctype: No C-type found in "{'attrspec': [], 'typename': 'mc79_control', 'intent': ['in'], 'typespec': 'type'}", assuming void.
getctype: No C-type found in "{'attrspec': [], 'typename': 'mc79_control', 'intent': ['in'], 'typespec': 'type'}", assuming void.
Traceback (most recent call last):
File "/home/eogbe/anaconda2/bin/f2py", line 28, in
Is there any work around derived data types? I 'm using f2py with gfortran and python 2.7 on centOS. Emmanuel
The solution is provided in https://sysbio.ioc.ee/projects/f2py2e/FAQ.html#q-what-if-fortran-90-code-uses-type-spec-kind-kind
Maybe we could catch the KeyError
and provide a more helpful error message?
@pearu Could you please elaborate using the sample I have below?
MODULE example
IMPLICIT NONE
PRIVATE
! ---------------------------------------------------
! Derived type definitions
! ---------------------------------------------------
TYPE, PUBLIC :: userdefined
INTEGER :: lp = 6
INTEGER :: mp = 6
END TYPE mc79_control
PUBLIC hsl
CONTAINS
SUBROUTINE hsl(m,n,ptr,row,rowmatch,colmatch,control)
INTEGER (userdefined), INTENT (IN) :: m
INTEGER (userdefined), INTENT (IN) :: n
INTEGER (userdefined), INTENT (IN) :: ptr(n+1)
INTEGER (userdefined), INTENT (IN) :: row(:)
INTEGER (userdefined), INTENT (OUT) :: rowmatch(m)
INTEGER (userdefined), INTENT (OUT) :: colmatch(n)
TYPE (userdefined), INTENT (IN) :: control
lp = control%lp
mp = control%mp
END SUBROUTINE hsl
END MODULE example
How do I generate the fortran to c map for this? Emmanuel
Try create a file
/home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap
with the following content:
{'integer':{'userdefined':'int'}}
Btw, shouldn't
END TYPE mc79_control
be
END TYPE userdefined
?
Yes my bad. It is "end userdefined" in my code.
How do i call the code after creating .f2py_f2cmap? f2py -m mc79reorder -h hsl_79.pyf example.f90 .f2py_f2cmap didn't seem to work.
I used message
getctype: "integer(kind=myint_mc79)" is mapped to C "int" (to override define dict(integer = dict(myint_mc79="")) in /home/eogbe/Documents/solvers/hslcodes/hsl_mc79-1.1.0/src/test/newtest/.f2py_f2cmap file).
as a hint for the proper .f2py_f2cmap
location.
When you created the .f2py_f2cmap
, were there any effect? Were there any changes in error messages, for instance?
("Does not seem to work" is not really useful for giving useful feedback.)
Running f2py -m mc79reorder -h hsl_79.pyf example.f90 .f2py_f2cmap I get the output:
Reading .f2py_f2cmap ... Mapping "integer(kind=userdefined)" to "int" Successfully applied user defined changes from .f2py_f2cmap Reading fortran codes... Reading file 'example.f90' (format:free) Line #9 in example.f90:" TYPE, PUBLIC :: userdefined" analyzeline: No name/args pattern found for line. Reading file '.f2py_f2cmap' (format:free) Post-processing... Block: mc79reorder Block: example Block: unknown_type Block: hsl Post-processing (stage 2)... Block: mc79reorder Block: unknown_interface Block: example Block: unknown_type Block: hsl Saving signatures to file "./hsl_79.pyf" {'attrspec': ['private', 'public']} In: :mc79reorder:example.f90:example vars2fortran: No typespec for argument "hsl".
It successfully applies the user defined changes but still reports "no typespec" for "hsl" When i tried to create the .so file with the command "f2py -c --fcompiler=gnu95 hsl_79.pyf example.f90 .f2py_f2cmap" i get the "getctype: no c type found " error as before (without using .f2py_f2cmap):
Reading .f2py_f2cmap ...
Mapping "integer(kind=userdefined)" to "int"
Successfully applied user defined changes from .f2py_f2cmap
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "mc79reorder" sources
creating /tmp/tmpTCBdVF/src.linux-x86_64-2.7
f2py options: []
f2py: hsl_79.pyf
Reading fortran codes...
Reading file 'hsl_79.pyf' (format:free)
Post-processing...
Block: mc79reorder
Block: example
Block: unknown_type
Block: hsl
Post-processing (stage 2)...
Block: mc79reorder
Block: unknown_interface
Block: example
Block: unknown_type
Block: hsl
Building modules...
Building module "mc79reorder"...
Constructing F90 module support for "example"...
Skipping type unknown_type
Creating wrapper for Fortran subroutine "hsl"("hsl")...
Constructing wrapper function "example.hsl"...
getctype: No C-type found in "{'attrspec': [], 'typename': 'userdefined', 'intent': ['in'], 'typespec': 'type'}", assuming void.
getctype: No C-type found in "{'attrspec': [], 'typename': 'userdefined', 'intent': ['in'], 'typespec': 'type'}", assuming void.
getctype: No C-type found in "{'attrspec': [], 'typename': 'userdefined', 'intent': ['in'], 'typespec': 'type'}", assuming void.
Traceback (most recent call last):
File "/home/eogbe/anaconda2/bin/f2py", line 28, in
There is something i am doing wrong i think.
The problems is in argument control
:
TYPE (userdefined), INTENT (IN) :: control
f2py currently does not support wrapping functions with derived type arguments.
That's what i initially thought. I was thinking there was a way around it or any suggestions to help me accomplish my task.
Thanks, Emmanuel
The solution is provided in https://sysbio.ioc.ee/projects/f2py2e/FAQ.html#q-what-if-fortran-90-code-uses-type-spec-kind-kind
This link is dead.
The relevant piece of documentation can be found in github history, for instance: https://github.com/numpy/numpy/blob/a859492c7b07dac0a56d9a08d6739e006a528f87/numpy/f2py/docs/FAQ.txt#L258
@pearu Could you please elaborate using the sample I have below? `module example implicit none
!---------------------------------- ! type define !----------------------------------
type array_car
integer :: N1, N2, N3
complex(kind=8), allocatable :: c_1d(:)
real(kind=8), allocatable :: r_1d(:)
integer,allocatable :: i_1d(:)
end type array_car
subroutine construct_qlist(e) implicit none type(array_car) :: out real(kind=8) :: t(3,3),tt(3,3), q1(3), q2(3) end subroutine hsl end module example `