pearu / f2py

Automatically exported from code.google.com/p/f2py
Other
54 stars 37 forks source link

Using user defined type #49

Open eogbe opened 5 years ago

eogbe commented 5 years ago

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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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="")) 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 main() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/f2py/f2py2e.py", line 648, in main run_compile() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/f2py/f2py2e.py", line 633, in run_compile setup(ext_modules=[ext]) File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/core.py", line 169, in setup return old_setup(**new_attr) File "/home/eogbe/anaconda2/lib/python2.7/distutils/core.py", line 151, in setup dist.run_commands() File "/home/eogbe/anaconda2/lib/python2.7/distutils/dist.py", line 953, in run_commands self.run_command(cmd) File "/home/eogbe/anaconda2/lib/python2.7/distutils/dist.py", line 972, in run_command cmd_obj.run() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build.py", line 47, in run old_build.run(self) File "/home/eogbe/anaconda2/lib/python2.7/distutils/command/build.py", line 127, in run self.run_command(cmd_name) File "/home/eogbe/anaconda2/lib/python2.7/distutils/cmd.py", line 326, in run_command self.distribution.run_command(command) File "/home/eogbe/anaconda2/lib/python2.7/distutils/dist.py", line 972, in run_command cmd_obj.run() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build_src.py", line 148, in run self.build_sources() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build_src.py", line 165, in build_sources self.build_extension_sources(ext) File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build_src.py", line 327, in build_extension_sources sources = self.f2py_sources(sources, ext) File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build_src.py", line 544, in f2py_sources

Is there any work around derived data types? I 'm using f2py with gfortran and python 2.7 on centOS. Emmanuel

pearu commented 5 years ago

The solution is provided in https://sysbio.ioc.ee/projects/f2py2e/FAQ.html#q-what-if-fortran-90-code-uses-type-spec-kind-kind

mattip commented 5 years ago

Maybe we could catch the KeyError and provide a more helpful error message?

eogbe commented 5 years ago

@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

pearu commented 5 years ago

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 ?

eogbe commented 5 years ago

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.

pearu commented 5 years ago

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.)

eogbe commented 5 years ago

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 main() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/f2py/f2py2e.py", line 648, in main run_compile() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/f2py/f2py2e.py", line 633, in run_compile setup(ext_modules=[ext]) File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/core.py", line 169, in setup return old_setup(**new_attr) File "/home/eogbe/anaconda2/lib/python2.7/distutils/core.py", line 151, in setup dist.run_commands() File "/home/eogbe/anaconda2/lib/python2.7/distutils/dist.py", line 953, in run_commands self.run_command(cmd) File "/home/eogbe/anaconda2/lib/python2.7/distutils/dist.py", line 972, in run_command cmd_obj.run() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build.py", line 47, in run old_build.run(self) File "/home/eogbe/anaconda2/lib/python2.7/distutils/command/build.py", line 127, in run self.run_command(cmd_name) File "/home/eogbe/anaconda2/lib/python2.7/distutils/cmd.py", line 326, in run_command self.distribution.run_command(command) File "/home/eogbe/anaconda2/lib/python2.7/distutils/dist.py", line 972, in run_command cmd_obj.run() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build_src.py", line 148, in run self.build_sources() File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build_src.py", line 165, in build_sources self.build_extension_sources(ext) File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build_src.py", line 327, in build_extension_sources sources = self.f2py_sources(sources, ext) File "/home/eogbe/anaconda2/lib/python2.7/site-packages/numpy/distutils/command/build_src.py", line 544, in f2py_sources

There is something i am doing wrong i think.

pearu commented 5 years ago

The problems is in argument control:

TYPE (userdefined), INTENT (IN) :: control

f2py currently does not support wrapping functions with derived type arguments.

eogbe commented 5 years ago

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

lamorton commented 3 years ago

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.

pearu commented 3 years ago

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

cuijie-nano commented 4 months ago

@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 `