Code Monkey home page Code Monkey logo

f90wrap's People

Contributors

abouchero avatar adcroft avatar bernardopacini avatar davidovitch avatar eli-schwartz avatar fzahle avatar gkenway avatar haettig avatar inoelloc avatar jameskermode avatar jamesorr avatar jmp75 avatar jphill4 avatar krystophny avatar mcuntz avatar mlange05 avatar mryann avatar opeil avatar pdebuyl avatar perrette avatar reuterbal avatar seb45tian avatar shaoxc avatar stenczelt avatar sunt05 avatar tilmantroester avatar yagweb avatar yvesch avatar zhucaoxiang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

f90wrap's Issues

PY3 support

hi,

do you have any intend to support PY3?

Hai

object-bound procedures...

...do not seem to be supported.
I mean here:

module mod1_api
  implicit none

  type typ1
    integer :: n = 2
  contains
    procedure :: inc
  end type

contains

  subroutine inc(self) 
    class(typ1), intent(inout) :: self
    t%n = t%n + 1
  end subroutine

end module

e.g. of use in fortran:

program  prog
  use mod1_api
  type(typ1) :: t
  call t%inc()
  print*, t%n
end program

Note it is a secondary issue (there seem to be more advantages not using this feature than otherwise in fortran...), so it would be only justified to work on that if this would require only minor work (e.g. in the wrapper, replace back class with type, remove the contains part of the type and use information provided by procedure :: inc or procedure :: inc => typ1_inc to add methods to the corresponding python class...)

This would be quite handy on the python side though.

pointer variables results in skipped function, without warning

If a function uses pointer variables, the function is skipped, without warning.
Minimal example :

module module_calcul
contains
subroutine evaluer_valeur(x)
real,dimension(:,:),pointer :: x
return
end subroutine evaluer_valeur
end module module_calcul

Type mismatch when wrapping fortran code using f90wrap

I m trying to wrap a fortran code hsl_example.f90 to python using f90wrap (because I have some user defined types) and I run into problems with type mismatch.

When i run f90wrap -m hsl_example hsl_example.f90 i get a wrapper file f90wrap_hsl_example.f90 with some of the variable types different from than in hsl_example.f90, e.g. integer is converted to real.

For example, running f2py-f90wrap -c -m _hsl_example f90wrap_hsl_example.f90 results in the following error:

f90wrap_hsl_example.f90:590.45:

call find_max_match(m=m, n=n, ne=ne, ptr=ptr, row=row, rowset=rowset, &
                                         1

Error: Type mismatch in argument 'ptr' at (1); passed REAL(4) to INTEGER(4)
f90wrap_hsl_example.f90:614.40:

call find_rect(m=m, n=n, ne=ne, ptr=ptr, col=col, marked=marked, &
                                    1

Error: Type mismatch in argument 'ptr' at (1); passed REAL(4) to INTEGER(4)
f90wrap_hsl_example.f90:647.48:

call find_conn_comps(m=m, n=n, ne=ne, a_ptr=a_ptr, a_col=a_col, d_ptr=d_ptr
                                            1

Error: Type mismatch in argument 'a_ptr' at (1); passed REAL(4) to INTEGER(4)
f90wrap_hsl_example.f90:680.48:

call find_conn_comp_sq(m=m, n=n, ne=ne, ptr=ptr, idx=idx, nhcols=nhcols, &
                                            1

Error: Type mismatch in argument 'ptr' at (1); passed REAL(4) to INTEGER(4)
f90wrap_hsl_example.f90:590.45:

call find_max_match(m=m, n=n, ne=ne, ptr=ptr, row=row, rowset=rowset, &
                                         1

Error: Type mismatch in argument 'ptr' at (1); passed REAL(4) to INTEGER(4)
f90wrap_hsl_example.f90:614.40:

call find_rect(m=m, n=n, ne=ne, ptr=ptr, col=col, marked=marked, &
                                    1

Error: Type mismatch in argument 'ptr' at (1); passed REAL(4) to INTEGER(4)
f90wrap_hsl_example.f90:647.48:

call find_conn_comps(m=m, n=n, ne=ne, a_ptr=a_ptr, a_col=a_col, d_ptr=d_ptr
                                            1

Error: Type mismatch in argument 'a_ptr' at (1); passed REAL(4) to INTEGER(4)
f90wrap_hsl_example.f90:680.48:

call find_conn_comp_sq(m=m, n=n, ne=ne, ptr=ptr, idx=idx, nhcols=nhcols, &
                                            1

Error: Type mismatch in argument 'ptr' at (1); passed REAL(4) to INTEGER(4)

The original fortran file hsl_example.f90

hsl_example.txt

is attached. Thanks.

Add support for Fortran 2003 "extends" keyword

Reported by Bob Fischer. OO-style Fortran extension derived types don't work. In this case, I have a Fortran derived type:

type :: DebugType
    .....
end type DebugType

Then I extend it:

type, extends(DebugType) :: Debug_heat_eq
   ....
end type Debug_heat_eq

In the .py file that gets generated, the corresponding Python class Debug_Heat_Eq needs to extend the Python class Debugtype. Instead, it just extends f90wrap.runtime.FortranDerviedType, which messes things up

arguments when calling routine with output variables intent(out)

I am trying to get going with f90wrap. On my system (Arch Linux 64 bit) the example mockderivetype does not pass all its tests. I am running in a pip updated virtualenv (python 2.7). For reference, the traceback I get is:

File "f90wrap/examples/mockderivetype/test.py", line 30, in <module>
    result = use_a_type.do_stuff(8)

TypeError: do_stuff() takes exactly 2 arguments (1 given)

As far as I understand the error, the arguments list in the Fortran sources contains both input and output variables, where intent(in/out) specifies the nature of the specific arguments. For the case above see f90wrap/examples/mockderivetype/fwrap.f90 line 19. But the Python call also requires to pass on the output variable. From the generated mockdt.py I get:

@staticmethod
def do_stuff(factor, out):
    """
    do_stuff(factor, out)


    Defined at fwrap.fpp lines 23-64

    Parameters
    ----------
    factor : float
    out : float

    This is the module which defines the type 'atype'
    Here's a routine that does something
    """
    _mockdt.f90wrap_do_stuff(factor=factor, out=out)

Is that the intended behaviour, or maybe I am missing something obvious here (I have experience with Python, but only some basic Fortran)?

Example `recursive_type`does not compile

The example recursive_type does not compile.
Platform: macOS
Python 3.7.3
GNU Fortran (Homebrew GCC 8.2.0) 8.2.0
Apple LLVM version 10.0.1 (clang-1001.0.46.4)

This is the relevant error message:

f90wrap_tree.f90:9:22:

     type node_ptr_type
                      1
Error: Derived type definition of 'node_ptr_type' at (1) has already been defined
f90wrap_tree.f90:11:7:

     end type node_ptr_type
       1
Error: Expecting END SUBROUTINE statement at (1)
f90wrap_tree.f90:28:22:

     type node_ptr_type
                      1
Error: Derived type definition of 'node_ptr_type' at (1) has already been defined
f90wrap_tree.f90:30:7:

     end type node_ptr_type
       1
Error: Expecting END SUBROUTINE statement at (1)
f90wrap_tree.f90:47:22:

     type node_ptr_type
                      1
Error: Derived type definition of 'node_ptr_type' at (1) has already been defined
f90wrap_tree.f90:49:7:

     end type node_ptr_type
       1
Error: Expecting END SUBROUTINE statement at (1)
f90wrap_tree.f90:66:22:

     type node_ptr_type
                      1
Error: Derived type definition of 'node_ptr_type' at (1) has already been defined
f90wrap_tree.f90:68:7:

     end type node_ptr_type
       1
Error: Expecting END SUBROUTINE statement at (1)

This is the generated f90wrap_tree.f90 with code cause the error:

! Module tree defined in file tree.fpp

subroutine f90wrap_node__get__left(this, f90wrap_left)
    use tree, only: node
    implicit none
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    integer, intent(in)   :: this(2)
    type(node_ptr_type) :: this_ptr
    integer, intent(out) :: f90wrap_left(2)
    type(node_ptr_type) :: left_ptr
    
    this_ptr = transfer(this, this_ptr)
    left_ptr%p => this_ptr%p%left
    f90wrap_left = transfer(left_ptr,f90wrap_left)
end subroutine f90wrap_node__get__left

subroutine f90wrap_node__set__left(this, f90wrap_left)
    use tree, only: node
    implicit none
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    integer, intent(in)   :: this(2)
    type(node_ptr_type) :: this_ptr
    integer, intent(in) :: f90wrap_left(2)
    type(node_ptr_type) :: left_ptr
    
    this_ptr = transfer(this, this_ptr)
    left_ptr = transfer(f90wrap_left,left_ptr)
    this_ptr%p%left = left_ptr%p
end subroutine f90wrap_node__set__left

subroutine f90wrap_node__get__right(this, f90wrap_right)
    use tree, only: node
    implicit none
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    integer, intent(in)   :: this(2)
    type(node_ptr_type) :: this_ptr
    integer, intent(out) :: f90wrap_right(2)
    type(node_ptr_type) :: right_ptr
    
    this_ptr = transfer(this, this_ptr)
    right_ptr%p => this_ptr%p%right
    f90wrap_right = transfer(right_ptr,f90wrap_right)
end subroutine f90wrap_node__get__right

subroutine f90wrap_node__set__right(this, f90wrap_right)
    use tree, only: node
    implicit none
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    integer, intent(in)   :: this(2)
    type(node_ptr_type) :: this_ptr
    integer, intent(in) :: f90wrap_right(2)
    type(node_ptr_type) :: right_ptr
    
    this_ptr = transfer(this, this_ptr)
    right_ptr = transfer(f90wrap_right,right_ptr)
    this_ptr%p%right = right_ptr%p
end subroutine f90wrap_node__set__right

subroutine f90wrap_treeallocate(root)
    use tree, only: treeallocate, node
    implicit none
    
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    type(node_ptr_type) :: root_ptr
    integer, intent(out), dimension(2) :: root
    allocate(root_ptr%p)
    call treeallocate(root=root_ptr%p)
    root = transfer(root_ptr, root)
end subroutine f90wrap_treeallocate

subroutine f90wrap_treedeallocate(root)
    use tree, only: treedeallocate, node
    implicit none
    
    type node_ptr_type
        type(node), pointer :: p => NULL()
    end type node_ptr_type
    type(node_ptr_type) :: root_ptr
    integer, intent(in), dimension(2) :: root
    root_ptr = transfer(root, root_ptr)
    call treedeallocate(root=root_ptr%p)
    deallocate(root_ptr%p)
end subroutine f90wrap_treedeallocate

! End of module tree defined in file tree.fpp


f90warp*.f90 created with missing variable

Hi,
I have a code that compiled with f90warp version 0.1.0
but not with 0.1.4

I think the problem is coming from the creation _Xnpartclass_Array classes

In the f90 code I used allocatable array of structure.
and when creating the file f90warp*.f90
function with name like f90wrap_part_xn_part_array__array_getitem__items()
are created with dimension for the structure that are not defined

I understand this is not really clear, but this reflect my understanding of the problem
happy to provide more info

in the meantime, would that be possible to access later version of f90wrap through pip or conda?

Thanks
Ronan

Symbols not found

With the following command lines, the module compiles, but can not be imported in python because "Symbol not found" for the functions inside the module :

f90wrap -v -m maxwell functions.f90
f2py3 -c -m _maxwell f90wrap*.f90

If I add *.o to the f2py3 command, it works with a minimal test case. However, with the complex fortran code I am trying to use, the commands

f90wrap -v -m maxwell functions.f90
f2py3 -c -m _maxwell f90wrap*.f90 *.o

the "import maxwell" command produces the error "Symbol not found: f90wrap_abort".

So i can have a link to my own functions or to the f90wrapper functions, but not both. What am i doing wrong ?

Improve handling of continuation lines

For example, the following doesn't work:

recursive &
subroutine sub(...)

Probably removing all "&" symbols all and joining into long lines before doing any parsing would be safer.

Initializing data structures in Windows

When instantiating data structures from Python (through f90wrap), the default definition of derived types is all in lower case in Windows (vs. upper case in Unix). Not a big deal, but if its a quick fix, could you please fix in a new update of f90wrap?

xyz = module containing definition of derived type(s)
when I do

print dir(xyz)

on Windows, I get

['class', 'delattr', 'dict', 'doc', 'format', 'getattribute', 'hash', 'init', 'metaclass', 'module', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_arrays', '_dt_array_initialisers', '_objs', 'contour_prop_def', 'cross_section_def', 'material_type_def', 'rotor_info_def', 'skin_info_def', 'spar_info_def']

On Linux, the same command yields

['Contour_Prop_Def', 'Cross_Section_Def', 'Material_Type_Def', 'Rotor_Info_Def', 'Skin_Info_Def', 'Spar_Info_Def', 'class', 'delattr', 'dict', 'doc', 'format', 'getattribute', 'hash', 'init', 'metaclass', 'module', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_arrays', '_dt_array_initialisers', '_objs']

Note the differences between capitalization rules for data structures on
Ubuntu (left) vs. windows (right)

Contour_Prop_Def vs. contour_prop_def
Cross_Section_Def vs. cross_section_def
Material_Type_Def vs. material_type_def
Rotor_Info_Def vs. rotor_info_def
Skin_Info_Def vs. skin_info_def
Spar_Info_Def vs. spar_info_def

Support for non-default argument follows default argument

Currently Fortran supports optional arguments before default arguments, see program below:

program test
  call wrap(def = 2)

  contains

  subroutine wrap(opt, def)
    implicit none

    integer :: def
    integer, optional :: opt

    print *, 'present(opt) = ', present(opt)
    print *, 'def = ', def

    if (present(opt)) print *, 'opt = ', opt

  end subroutine
end program test

This compiles and runs fine.
f90wrap also runs fine:

f90wrap -m test main.F90

But if I import the program:

$ python

>>> import test
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/theory/phukgm/Documents/test/test.py", line 5
    def wrap(opt=None, def_):
            ^
SyntaxError: non-default argument follows default argument
>>>

Is it possible to add optional before default arguments support to this module?

no issue: this was an programming error (optional intent(out) paramater array returned with wrong values)

Hi,

I have a Fortran routine with some input characters of type "characters" and some optional ouput array parameters. When the caller (in Python) passes one optional array, that array is filled correctly by the called subroutine. If the caller passes all optional arrays, they all return filled with the same values (which is wrong for all of them but one).

The same calling program in Fortran does not show this problem.

Here is the fortran routine :

MODULE mvars
CONTAINS
SUBROUTINE vars(N, optCON, optT, optP, &
pco2_deriv, fco2_deriv )

IMPLICIT NONE
INTEGER, PARAMETER :: r4 = KIND(1.0)

! Input variables
!> number of records
INTEGER, INTENT(in) :: N

CHARACTER(6), INTENT(in) :: optCON
CHARACTER(7), INTENT(in) :: optT
CHARACTER(2), INTENT(in) :: optP

! Optional output variables:
REAL(kind=r4), OPTIONAL, INTENT(out), DIMENSION(6,N) :: pco2_deriv
REAL(kind=r4), OPTIONAL, INTENT(out), DIMENSION(6,N) :: fco2_deriv

! Local variables
INTEGER :: j

IF (PRESENT(pco2_deriv)) THEN
DO j=1,6
pco2_deriv(J,:) = REAL(N)+REAL(J)
END DO
ENDIF
IF (PRESENT(fco2_deriv)) THEN
DO j=1,6
fCO2_deriv(J,:) = REAL(N)+REAL(J)+1
END DO
ENDIF

RETURN
END SUBROUTINE vars

END MODULE mvars

Here is a calling Fortran program that works :

PROGRAM test_vars

USE mvars
IMPLICIT NONE
INTEGER, PARAMETER :: r4 = KIND(1.0)
REAL(kind=r4), DIMENSION(6,1) :: ph_deriv, pco2_deriv, fco2_deriv

call vars(1, optCON='mol/kg', optT='Tinsitu', optP='db', &
pco2_deriv=pco2_deriv)
write (,) "pco2_deriv[1,0]", pco2_deriv(2,1)

call vars(1, optCON='mol/kg', optT='Tinsitu', optP='db', &
pco2_deriv=pco2_deriv, fco2_deriv=fco2_deriv)
write (,) "pco2_deriv[1,0]", pco2_deriv(2,1)

STOP

END PROGRAM test_vars

It outputs:
pco2_deriv[1,0] 3.00000000
pco2_deriv[1,0] 3.00000000
Twice the same value = 3, which is correct.

And here is a Python program that fails :

change this as appropriate

mocsy_dnad_dir = "/home/jean-marie/Documents/DNAD/mocsy-bug"

Preliminaries

import sys
import numpy as np
sys.path.append (mocsy_dnad_dir)
import mocsy

derivatives w/ respect to 6 input variables

pco2_deriv = np.zeros((6,)).astype('f')
fco2_deriv = np.zeros((6,)).astype('f')

pco2_deriv = pco2_deriv.reshape ((6,1), order='F')
fco2_deriv = pco2_deriv.reshape ((6,1), order='F')

Call subroutine 'vars()' with one optionnal output parameter (pco2_deriv)

mocsy.mvars.vars(n=1,optcon="mol/kg",optt='Tinsitu',optp='db',
pco2_deriv=pco2_deriv )

Result OK

print "pco2_deriv[1,0]", pco2_deriv[1,0]

Call subroutine 'vars()' with all optionnal output parameters (xxx_deriv, yyy_deriv, ...)

mocsy.mvars.vars(n=1,optcon="mol/kg",optt='Tinsitu',optp='db',
pco2_deriv=pco2_deriv, fco2_deriv=fco2_deriv)

Result for pco2_deriv is wrong

print "pco2_deriv[1,0]", pco2_deriv[1,0]

It outputs :
pco2_deriv[1,0] 3.0
pco2_deriv[1,0] 4.0

I have simplified my program as much as I could. I hope I have not made any mistake.
It looks like first optional output array is overwritten with values of the second optional array.

Best regards,
Jean-Marie

f90wrap with Python 2.7 on windows: installation fails

So I also tried python setup.py install from source, and ran into a "multiple_definition" error with Windows 10, Python 2.7 and mingw-w64.

F:/Programs/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-atonexit.o):atonexit.c:(.text+0xc0): multiple definition of atexit' F:\Programs\Python\libs/libmsvcr90.a(deoks01081.o):(.text+0x0): first defined here F:/Programs/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-mingw_helpers.o):mingw_helpers.c:(.text+0x0): multiple definition of _decode_pointer'
F:\Programs\Python\libs/libmsvcr90.a(deoks00231.o):(.text+0x0): first defined here
F:/Programs/mingw/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-mingw_helpers.o):mingw_helpers.c:(.text+0x10): multiple definition of `_encode_pointer'
F:\Programs\Python\libs/libmsvcr90.a(deoks00241.o):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
error: Command "gcc -g -shared build\temp.win-amd64-2.7\Release\f90wrap\arraydatamodule.o build\temp.win-amd64-2.7\Release\programs\python\lib\site-packages\numpy\f2py\src\fortranobject.o -LF:\Programs\Python\libs -LF:\Programs\Python\PCbuild\amd64 -lpython27 -lmsvcr90 -o build\lib.win-amd64-2.7\f90wrap\arraydata.pyd" failed with exit status 1

"different_types" mismatch in test_set_derived_type(__main__.LibTests)

In test_set_derived_type(self) in derivedtypes/tests.py, the line

self.assert_(isinstance(dt, self.lib.datatypes.different_types))

passes for LibTestsPkg (for which lib = ExampleDerivedTypes_pkg) but FAILS for LibTests (for which lib = ExampleDerivedTypes).

type(dt) gives

<class 'ExampleDerivedTypes_pkg.datatypes.different_types'>

for both LibTests and LibTestsPkg but self.lib.datatypes.different_types can be either

<class 'ExampleDerivedTypes.Datatypes.different_types'>
<class 'ExampleDerivedTypes_pkg.datatypes.different_types'>

for LibTests and LibTestsPkg respectively, and which are not the same. Hence isinstance(dt, ...) is False for LibTests and the assertion fails.

This is one of four failures running make test, and seen in Travis build 169.5, with commit 04d81b5.

import setuptools to create package that plays nice with pip

Currently, setup.py uses setup from numpy.distutils:

from numpy.distutils.core import setup, Extension
from numpy.distutils.system_info import get_info

However, you can still rely on setuptools in combination with numpy.distutils (which is required for the compiled extensions). This happens when setuptools is imported before numpy.distutils:

import setuptools
from numpy.distutils.core import setup, Extension
from numpy.distutils.system_info import get_info

I am not aware of the details, but I found in an old mailing list entry [1] that numpy.distutils figures out import setuptools happened before its own import and therefore magic happens... The result is still the same, but now the packaging is just slightly cleaner and you can actually properly uninstall f90wrap with pip from a virtual environment. I think the latter is real bonus.

[1] http://comments.gmane.org/gmane.comp.python.f2py.user/707

Abstract classes

Looks like abstract classes are not parsed properly. The code snippet

type, abstract :: shapes
    integer :: shapetype = 0
end type

is parsed as type(abstract) instead of an abstract type(shapes). However, since this is an abstract class, the f90wrap_shapes__get__shapetype(this, shapetype) subroutine would probably have to be handled differently.

Exception catching f90wrap_error_abort

Hi James,

Great project, much potential to solve common annoyances when wrapping modern *f90 code. Both type-passing (f90wrap) and Exception catching are very useful features, actuallly all of f2py-f90wrap are useful !

When testing it out though, exception catching did not work as smoothly as hoped: just calling stop did crash the fortran program, as with f2py. Calling f90wrap_error_abort or even quippy_error_abort (as grepped in f90wrap/patch_f2py) did not help either ...

So what's your approach?

Thanks again.

32 / 64 bits array strikes again

Hello.
I'm working again on my fortran to python wrapping and come across the 32/64 bit problem again:
I initialize variables in python with numpy.zeros, which produces 64bit floats by default. When the array is of size 1, this works for fortran integer or real transparently. However, with size > 1 I have to explicitly use zeros(xxx, int32) (or float32) to be accepted by fortran. Note that I use in/out arrays, courtesy to the --default-to-inout flag. In the simple (in) mode, there is no problem but I don't recover any value ;)

Is this a f90-wrap internal conversion issue, or an f2py conversion issue ? Or maybe should we compile all fortran sources with some flag to enforce 64 bit fortran variables, to be compatible with their python counterparts ?

FORTRAN file

module module_test

INTEGER,PARAMETER :: n=12

	contains

	subroutine testf(x)
		integer, dimension(n) :: x
		x(2) = 4
	end subroutine testf

	subroutine testf2(x)
		integer :: x
		x = 4
	end subroutine testf2

end module module_test

PYTHON file

import test3_python
from numpy import zeros, int32

b = zeros(1)
test3_python.module_test.testf2(b)
assert b == 4

a = zeros(12, int32)
test3_python.module_test.testf(a)
assert all(a == [0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

MAKE file

test3 : clean
	gfortran -c -O3 -fPIC test3.f90
	f90wrap --default-to-inout -m test3_python test3.f90
	f2py-f90wrap -c -m _test3_python f90wrap_* *.o
	python test3.py
clean :
	rm -rf *.o *.mod *.so *python.py f90wrap* ./build

crash in pywrapgen.py

Hello,

I have a problem running f90wrap on both examples included in the package. As documented, I tried to run make for the examples, but the test fail with an error inside pywrapgen.py:

  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 468, in write_repr                                                                                                     
    self.write(r"ret = ['<{}>".format(node.name) + r"{\n']")                                                            
ValueError: zero length field name in format                                                                            

I reverted to a version before the commit of May 9, 2015 by rpfische, and could build the examples; the example2 ran successfully, but there is still another issue with mockderivetype example that I try to understand now.

FYI, here is the full log of make:

(f90wrap_test3)yvesc@tethys->tethys:/home/yvesc/test/languages/python/f90wrap_install/f90wrap/examples/mockderivetype> make                                                                                                                     
gfortran -x f95-cpp-input -fPIC -c leveltwomod.f90 -o leveltwomod.o                                                     
gfortran -x f95-cpp-input -fPIC -c define.f90 -o define.o                                                               
gfortran -x f95-cpp-input -fPIC -c fwrap.f90 -o fwrap.o                                                                 
ar src libsrc.a leveltwomod.o define.o fwrap.o                                                                          
gfortran -E -x f95-cpp-input -fPIC leveltwomod.f90  -o leveltwomod.fpp                                                  
gfortran -E -x f95-cpp-input -fPIC define.f90  -o define.fpp                                                            
gfortran -E -x f95-cpp-input -fPIC fwrap.f90  -o fwrap.fpp                                                              
f90wrap -m mockdt leveltwomod.fpp define.fpp fwrap.fpp -k kind_map -v                                                   
Kind map read from file "'kind_map'" : (also saved to .f2py_f2cmap)                                                     
{'complex': {'': 'complex_float',                                                                                       
             '8': 'complex_double',                                                                                     
             'dp': 'complex_double'},                                                                                   
 'integer': {'': 'int', '8': 'long_long', 'dp': 'long_long'},                                                           
 'real': {'': 'float', '8': 'double', 'dp': 'double'}}                                                                  

Constructors:
('initialise_ptr', 'initialise', 'allocate')

Destructors:
('finalise', 'deallocate')

Short names for derived types read from file "None"
{}                                                 

String lengths read from file "None":
{}                                   

Initialisation lines for derived types read from file "None":
{}                                                           

Argument name map:
{}                

Size of Fortran derived type pointers is 2 bytes.

Parsing Fortran source files ['leveltwomod.fpp', 'define.fpp', 'fwrap.fpp'] ...
DEBUG:root:processing file leveltwomod.fpp                                     
INFO:root:parser reading type leveltwo                                         
DEBUG:root:    type leveltwo                                                   
DEBUG:root:  module leveltwomod                                                
DEBUG:root:processing file define.fpp                                          
INFO:root:parser reading type atype                                            
DEBUG:root:    type atype                                                      
INFO:root:parser reading type unused_type                                      
DEBUG:root:    type unused_type                                                
DEBUG:root:    module subroutine use_set_vars                                  
DEBUG:root:    module function return_a_type_func                              
DEBUG:root:    module subroutine return_a_type_sub                             
DEBUG:root:  module define_a_type                                              
DEBUG:root:  subroutine top_level                                              
INFO:root:parser reading type horrible_type                                    
DEBUG:root:    type horrible_type                                              
DEBUG:root:  module horrible                                                   
DEBUG:root:processing file fwrap.fpp                                           
DEBUG:root:    module subroutine do_stuff                                      
DEBUG:root:    module subroutine not_used                                      
DEBUG:root:  module use_a_type                                                 
done parsing source.                                                           

DEBUG:root:type leveltwo defined in module leveltwomod
DEBUG:root:type atype defined in module define_a_type 
DEBUG:root:type unused_type defined in module define_a_type
DEBUG:root:type horrible_type defined in module horrible   
Derived types detected in Fortran source files:            
{'atype': Type(name=atype),                                
 'horrible_type': Type(name=horrible_type),                
 'leveltwo': Type(name=leveltwo),                          
 'type(atype)': Type(name=atype),                          
 'type(horrible_type)': Type(name=horrible_type),          
 'type(leveltwo)': Type(name=leveltwo),                    
 'type(unused_type)': Type(name=unused_type),              
 'unused_type': Type(name=unused_type)}                    

DEBUG:root:marking public symbol leveltwo
DEBUG:root:marking public symbol rl      
DEBUG:root:marking public symbol atype   
DEBUG:root:marking public symbol bool    
DEBUG:root:marking public symbol integ   
DEBUG:root:marking public symbol rl      
DEBUG:root:marking public symbol vec     
DEBUG:root:marking public symbol dtype   
DEBUG:root:marking public symbol unused_type
DEBUG:root:marking public symbol a_set_real 
DEBUG:root:marking public symbol a_set_bool 
DEBUG:root:marking public symbol use_set_vars
DEBUG:root:marking public symbol return_a_type_func
DEBUG:root:marking public symbol return_a_type_sub 
DEBUG:root:marking public symbol horrible_type     
DEBUG:root:marking public symbol x                 
DEBUG:root:marking public symbol a_real            
DEBUG:root:marking public symbol p                 
DEBUG:root:marking public symbol p_array           
DEBUG:root:marking public symbol vector            
DEBUG:root:marking public symbol do_stuff          
DEBUG:root:marking public symbol not_used          
DEBUG:root:visiting Module(name=leveltwomod)       
DEBUG:root:visiting Type(name=leveltwo)            
DEBUG:root:visiting Module(name=define_a_type)     
DEBUG:root:visiting Type(name=atype)               
DEBUG:root:visiting Type(name=unused_type)         
DEBUG:root:visiting Module(name=horrible)          
DEBUG:root:visiting Type(name=horrible_type)       
DEBUG:root:visiting Module(name=use_a_type)        
INFO:root:adding missing constructor for leveltwo  
INFO:root:adding missing constructor for atype     
INFO:root:adding missing constructor for unused_type
INFO:root:adding missing constructor for horrible_type
INFO:root:adding missing destructor for leveltwo      
INFO:root:adding missing destructor for atype         
INFO:root:adding missing destructor for unused_type   
INFO:root:adding missing destructor for horrible_type 
Reading .f2py_f2cmap ...                              
        Warning: redefinition of {'real':{'':'float'->'float'}}
        Mapping "real(kind=)" to "float"                       
        Warning: redefinition of {'real':{'8':'double'->'double'}}
        Mapping "real(kind=8)" to "double"                        
        Mapping "real(kind=dp)" to "double"                       
        Warning: redefinition of {'integer':{'':'int'->'int'}}    
        Mapping "integer(kind=)" to "int"                         
        Warning: redefinition of {'integer':{'8':'long_long'->'long_long'}}
        Mapping "integer(kind=8)" to "long_long"                           
        Mapping "integer(kind=dp)" to "long_long"                          
        Warning: redefinition of {'complex':{'':'complex_float'->'complex_float'}}
        Mapping "complex(kind=)" to "complex_float"                               
        Warning: redefinition of {'complex':{'8':'complex_float'->'complex_double'}}
        Mapping "complex(kind=8)" to "complex_double"                               
        Mapping "complex(kind=dp)" to "complex_double"                              
Succesfully applied user defined changes from .f2py_f2cmap                          
DEBUG:root:allocating arg "ret_a" in return_a_type_func                             
DEBUG:root:allocating arg "this" in leveltwo_initialise                             
DEBUG:root:deallocating arg "this" in leveltwo_finalise                             
DEBUG:root:allocating arg "this" in atype_initialise                                
DEBUG:root:deallocating arg "this" in atype_finalise                                
DEBUG:root:allocating arg "this" in unused_type_initialise                          
DEBUG:root:deallocating arg "this" in unused_type_finalise                          
DEBUG:root:allocating arg "this" in horrible_type_initialise                        
DEBUG:root:deallocating arg "this" in horrible_type_finalise                        
INFO:root:PythonWrapperGenerator visiting module leveltwomod                        
INFO:root:PythonWrapperGenerator visiting type leveltwo                             
INFO:root:PythonWrapperGenerator visiting routine leveltwo_initialise               
INFO:root:PythonWrapperGenerator visiting routine leveltwo_finalise                 
Traceback (most recent call last):                                                  
  File "/home/yvesc/test/languages/python/f90wrap_test3/bin/f90wrap", line 244, in main
    init_file=args.init_file).visit(py_tree)                                           
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 445, in visit                                                                                                            
    result = visitor(node)                                                                                              
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 168, in visit_Root                                                                                                     
    self.generic_visit(node)                                                                                            
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 453, in generic_visit                                                                                                    
    self.visit(item)                                                                                                    
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 445, in visit                                                                                                            
    result = visitor(node)                                                                                              
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 204, in visit_Module                                                                                                   
    self.generic_visit(node)                                                                                            
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 453, in generic_visit                                                                                                    
    self.visit(item)                                                                                                    
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 445, in visit                                                                                                            
    result = visitor(node)                                                                                              
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 407, in visit_Type                                                                                                     
    self.write_repr(node, properties)                                                                                   
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 468, in write_repr                                                                                                     
    self.write(r"ret = ['<{}>".format(node.name) + r"{\n']")                                                            
ValueError: zero length field name in format                                                                            
f90wrap: ValueError('zero length field name in format',)                                                                
         for help use --help                                                                                            
Traceback (most recent call last):                                                                                      
  File "/home/yvesc/test/languages/python/f90wrap_test3/bin/f90wrap", line 264, in                              
    sys.exit(main())                                                                                                    
  File "/home/yvesc/test/languages/python/f90wrap_test3/bin/f90wrap", line 244, in main                                 
    init_file=args.init_file).visit(py_tree)                                                                            
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 445, in visit                                                                                                            
    result = visitor(node)                                                                                              
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 168, in visit_Root                                                                                                     
    self.generic_visit(node)                                                                                            
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 453, in generic_visit                                                                                                    
    self.visit(item)                                                                                                    
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 445, in visit                                                                                                            
    result = visitor(node)                                                                                              
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 204, in visit_Module                                                                                                   
    self.generic_visit(node)                                                                                            
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 453, in generic_visit                                                                                                    
    self.visit(item)                                                                                                    
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/fortran.py", line 445, in visit                                                                                                            
    result = visitor(node)                                                                                              
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 407, in visit_Type                                                                                                     
    self.write_repr(node, properties)                                                                                   
  File "/bira-iasb/home/yvesc/test/languages/python/f90wrap_test/lib/python2.6/site-packages/f90wrap/pywrapgen.py", line 468, in write_repr                                                                                                     
    self.write(r"ret = ['<{}>".format(node.name) + r"{\n']")                                                            
ValueError: zero length field name in format                                                                            
make: *** [_mockdt.so] Error 1                                                                                          

where is the executable f90wrap.exe file on windows10

I have installed f90wrap by cloning the repository from GitHub and running the setup.py script in anaconda prompt. The f90wrap can already be imported in python as module however the f90wrap can not be found if I call it directly in the anaconda prompt (or terminal). error message below:
'f90wrap' is not recognized as an internal or external command, operable program or batch file.
can not find the usable f90wrap.exe file to be added as environment variable

implicit arguments are skipped, resulting in compilation error

Hi James. As it is, I am still struggling to use some fortran code in Python ...

It seems that implicit arguments are skipped in the f90wrap files, instead of following the fortran implicit declaration rules (which f2py seems to know). Is there something I am missing, or do I have to explicitly declare all subroutine arguments ?

In python, what is the equivalent of the cell type data used in Fortran?

I have created a python wrapper for a LARGE fortran library of code using f2py. One of the problem I have is to call one of the subroutines function(cell) which takes in a cell as input and then update the input cell at the end of the subroutine [intent(inout)]. what is correct way of calling this kind of subroutine? Is the equivalent of the cell in python a dictionary? its a unitcell that contains many attributes (properties) of an object. this unitcell is later exported as an hdf5 data set

Fortran source code:

subroutine function_name(cell)
use ...
IMPLICIT NONE
type(unitcell),intent(inout) :: cell
cell%name1=a
cell%name2=b
...
end subroutine function_name

Python help(function_name)
function_name(self)
function_name(self)
Defined at function_name.f90 lines ...
Parameters

cell : Unitcell

Probelm with interface type checking

Wrapping of interfaces was implemented recently by relying on the wrapped code to raise exceptions when the wrong one is being used and continue to the next one. Currently the f2py-generated code is not raising the TypeError and hence the first function that is tried can succeed and RuntimeError is found when the wrong type is encountered later while using the values in fortran.

The solution would be to check the number of args and types in the python code that calls the interface and decide based on that.

'Program' object has no attribute 'uses'

I'm running into the following error while trying to wrap this fortran module

DEBUG:root:    module subroutine fida_weights_los
DEBUG:root:    module subroutine checking npa_weights
DEBUG:root:    module subroutine npa_weights
DEBUG:root:  module libfida
Traceback (most recent call last):
  File "/home/lstagner/anaconda3/bin/f90wrap", line 187, in main
    parse_tree = fparse.read_files(args.files)
  File "/home/lstagner/anaconda3/lib/python3.5/site-packages/f90wrap/parser.py", line 1316, in read_files
    check = check_program(cline, file)
  File "/home/lstagner/anaconda3/lib/python3.5/site-packages/f90wrap/parser.py", line 369, in check_program
    out.uses.append(check[0])
AttributeError: 'Program' object has no attribute 'uses'

Should the Program object have a uses atttribute?

ImportError on modules with callbacks from fortran to python functions

First, thank you for f90wrap.

I'd like to get a callback mechanism to capture Fortran messages and display them in a jupyter cell output (stdout is captured by a python console but SFAIK no easy way with jupyter).

I note f90wrap has a 'callback' CLI option but I am not sure how to use it. Say I have in cbfunc.f90 :

module cbfunc
    implicit none
    public
contains

subroutine f1()
    print *, "in f1, calling f2 twice.."
    call f2()
    call f2()
    return
 end
 
subroutine f2()
    !f2py    intent(callback, hide) fpy
    external fpy
    print *, "in f2, calling f2py.."
    call fpy()
    return
end
end module

and using

F90_FILES="cbfunc.f90"
OBJ_FILES="cbfunc.o"
MODULE_NAME=CBF
rm f90wrap_*.f90 *.o
rm _${MODULE_NAME}*
rm ${MODULE_NAME}.py
rm -rf __pycache__
f90wrap -m ${MODULE_NAME} $F90_FILES --callback fpy
gfortran -c $F90_FILES -fPIC
f2py-f90wrap -c -m _${MODULE_NAME} f90wrap_*.f90 $OBJ_FILES

Then in python import CBF fails with ImportError: /xxx/yyy/ff/_CBF.cpython-37m-x86_64-linux-gnu.so: undefined symbol: fpy_

The callback mechanism works if using only f2py i.e. f2py -c -m ${MODULE_NAME} cbfunc.f90 and in python:

import CBF
dir(CBF.cbfunc)
CBF.cbfunc.f2()

def f(): print("python f")

# CBF.cbfunc.fpy = f #nope ?
CBF.fpy = f
CBF.cbfunc.f2()
CBF.cbfunc.f1()

I'll see if I can find a fix or workaround.

Derived Types with recursive definition

I'm in the process of wrapping a Fortran code that uses a derived type within the same the derived type, ie. it is recursive. This causes problems when the wrapper is written as there are two definitions of the same type.

I've written a simple example that replicates the issue.
f90wrap_test.tar.gz

This should give the error:

gfortran:f90: f90wrap_tree_test.f90
f90wrap_tree_test.f90:11.22:

    type node_ptr_type
                      1
Error: Derived type definition of 'node_ptr_type' at (1) has already been defined

I've found that it can be fixed by modifying the line in the _write_scalar_wrapper routine in the f90wrapgen.py file. Replace:

if el.type.startswith('type'):
    self.write_type_lines(el.type)

with

if el.type.startswith('type') and (ft.strip_type(t.name) != ft.strip_type(el.type)):
    self.write_type_lines(el.type)

There may be other places where this would be an issue, but this seemed to fix the scalar case for me at least.

Clean up unit tests

  1. Make them all use a combination of CMake or Python's setup tools. This will ensure they compile with the correct compilers that match the Python distro being tested with. Avoid raw Makefiles.
  2. Make "nosetests" works.

double precision type unknown

Hi,

I test a subroutine with double precision as input, but the python module gives a comment "unknown" for the double precision. The module still works, but the comment is not right.

f90 code:

module test_double_precision
  implicit none
contains
subroutine set_double_precision(dp,rl)
  implicit none
  double precision, intent(in) :: dp
  real, intent(in) :: rl
  write(*,*) "The double precision number is: ",dp
  write(*,*) "The real number is: ",rl
end subroutine
end module

makefile:

#=======================================================================
#       define the compiler names and flags
#=======================================================================

CC = gcc
F90 = gfortran
FPP = gfortran -E
F90FLAGS = -x f95-cpp-input -fPIC
CFLAGS = -fPIC

all: mod

double_precision.o: 
	${F90} ${F90FLAGS} -c double_precision.f90

mod: double_precision.o
	f90wrap -m double_precision double_precision.f90 -k kind_map
	f2py-f90wrap -c -m _double_precision f90wrap_double_precision.f90 double_precision.o 

clean:
	-rm double_precision.py
	-rm f90wrap*.f90 *.o *.pyc *.mod
	-rm _double_precision.so

kind_map:

{
 'double precision':     {   '' : 'double'},
 'real':     {   '' : 'float',
                '4' : 'float',
              'isp' : 'float',
                '8' : 'double',
               'dp' : 'double',
              'idp' : 'double'}
}

(edited to add syntax highlighting)

problem with external subroutine when interfaced

Hello:
I am facing a problem. The f90wrap is not making wrapper for the subroutines that has interfaced another subroutine. For example, I have tried odeint from the following pdf

https://homepage.univie.ac.at/mario.barbatti/papers/NRF/bookf90pdf/chap16f9.pdf

SUBROUTINE derivs(x,y,dydx)
USE nrtype
IMPLICIT NONE
REAL(SP), INTENT(IN) :: x
REAL(SP), DIMENSION(:), INTENT(IN) :: y
REAL(SP), DIMENSION(:), INTENT(OUT) :: dydx
END SUBROUTINE derivs

derivs is interfaced here. If I keep it, it does not produce the wrapper. If I write external derivs, it treats derivs as a float and I get problem in executing f2py-f90wrap step.

Do you have any suggestions ?
This type of routines are not provided in examples.

Thanks in advance,
Dhiraj

incorrect constructors if type is a varname

With a derived type containing a variable called type, f90wrap produces __get__type_bn and __set__type_bn.
f2py3 then has the error : 'type_bn' at (1) is not a member of the structure.
Minimal example f90 file :

module module_structure

type type_face
    integer :: type
end type type_face

end module module_structure

Error in windows 7 64 bit and intel fortran.

Hi,
I try to use f90wrap with windows7 64bit, intel fortran and anaconda2(python2.7), but failed. The fortran file is example.f90 under the examples\interface directory. So, why? very thanks!

G:\Source\Python\collections\f90wrap\f90wrap-master\examples\interface>python "C
:\Anaconda2\Scripts\f90wrap" -v -m example example.f90
Kind map (also saved to .f2py_f2cmap)
{}

Constructors:
('initialise_ptr', 'initialise', 'allocate')

Destructors:
('finalise', 'deallocate')

Short names for derived types:
{}

String lengths:
{}

Initialisation lines for derived types
{}

Python module name remapping
{}
Class names remapping
{}

Argument name map:
{}

Size of Fortran derived type pointers is 2 bytes.

Parsing Fortran source files ['example.f90'] ...
DEBUG:root:processing file example.f90
INFO:root:marking module class_example as default private
DEBUG:root: interface return_example
INFO:root:parser reading type Example
DEBUG:root: type Example
DEBUG:root: module function checking return_example_first
DEBUG:root: implicit type of "return_example_first" inferred from its nam
e as "real"
DEBUG:root: module function return_example_first
DEBUG:root: module function checking return_example_second
DEBUG:root: implicit type of "return_example_second" inferred from its na
me as "real"
DEBUG:root: module function return_example_second
DEBUG:root: module function checking return_example_third
DEBUG:root: implicit type of "return_example_third" inferred from its nam
e as "real"
DEBUG:root: module function return_example_third
DEBUG:root: module class_example
done parsing source.

DEBUG:root:type example defined in module class_example
Derived types detected in Fortran source files:
{'example': Type(name=example), 'type(example)': Type(name=example)}

Class name mapping:
{'example': 'Example', 'type(example)': 'Example'}
Modules for each type:
{'class_example': 'class_example'}
Traceback (most recent call last):
File "c:\anaconda2\lib\site-packages\f90wrap-0.1.4-py2.7-win-amd64.egg\EGG-INF
O\scripts\f90wrap", line 298, in main
remove_optional_arguments)
TypeError: transform_to_generic_wrapper() takes exactly 12 arguments (14 given)
f90wrap: TypeError('transform_to_generic_wrapper() takes exactly 12 arguments (1
4 given)',)
for help use --help
Traceback (most recent call last):
File "C:\Anaconda2\Scripts\f90wrap", line 4, in
import('pkg_resources').run_script('f90wrap==0.1.4', 'f90wrap')
File "C:\Anaconda2\lib\site-packages\pkg_resources_init_.py", line 738, in
run_script
self.require(requires)[0].run_script(script_name, ns)
File "C:\Anaconda2\lib\site-packages\pkg_resources_init_.py", line 1499, in
run_script
exec(code, namespace, namespace)
File "c:\anaconda2\lib\site-packages\f90wrap-0.1.4-py2.7-win-amd64.egg\EGG-INF
O\scripts\f90wrap", line 341, in
sys.exit(main())
File "c:\anaconda2\lib\site-packages\f90wrap-0.1.4-py2.7-win-amd64.egg\EGG-INF
O\scripts\f90wrap", line 298, in main
remove_optional_arguments)
TypeError: transform_to_generic_wrapper() takes exactly 12 arguments (14 given)

Wrapping of intent(out) arrays inconsistent with f2py

f90wrap converts intent(out) arrays to intent(in, out). This was a deliberate design decision to allow allocatable and automatic arrays to be used. It’s hard in general to work out what size array needs to be allocated, so I decided that relying on the the user to pre-allocate from Python seemed the safest solution to reduce the chance of memory leaks.

It would be quite useful to have an option where the behaviour of f90wrap can be told to follow that of f2py, i.e., returning intent(out) arrays. The main interest is for consistency with the default for standard functions in python.

AttributeError("'Prototype' object has no attribute 'mod_name'",)

File "/Users/chaoyizhu/anaconda/lib/python3.6/site-packages/f90wrap/pywrapgen.py", line 456, in visit_Interface
proc_name += proc.mod_name.title() + '.'
AttributeError: 'Prototype' object has no attribute 'mod_name'
f90wrap: AttributeError("'Prototype' object has no attribute 'mod_name'",)

I am using f90wrap for a library of fortran source code. I got the above error message. what are the things to check in order to fix this error?

Method overloading via interfaces and type mistmatch

First off, allow me to compliment you on this nice python library and f2py extension. After some work, I got it working for my library, but I did run into a few issues:

Interfaced functions of a f90 module are translated to static methods in the auto generate python class, however in the function list for the overloaded call loop, the function names are not prefixed by Class_name, i.e.
[Class_name.method1(a,b), Class_name.method1(a,b,c), ... ]

Another issue I found was that asterisks inserted after a type are not handled correctly, and instead the parameter containing the asterisk is ignored completely. For example,

subroutine foo(a,b) 
    real*8, intent(in) :: a
    integer :: b
    print *, a*b
end subroutine foo

is parsed by f90wrap as

subroutine f90wrap_foo(b)
    integer :: b
    ....
end subroutine

If I instead use real(kind=8), f90wrap will include the parameter, but will translate it to the wrong type. In the f90wrap_ file it will be listed as real(4).

--move-methods causes wrong "use" statements

Coming back to f90wrap. Renewed congrats.
I really like the convenience --move-methods options, but apparently it assumes that all methods with the type as first argument come from the same module as the type in question. Here a case where it will cause an error:

debug_move_methods.f90:

module basemod
	!! base module, where the type is defined
	implicit none
	type param_t
		integer :: a
	end type
contains
	subroutine increment_a(p)
		type(param_t), intent(inout) :: p
		p%a = p%a + 1
	end subroutine
end module

module extmod
	!! extension module, adding non essential functionality
	implicit none
	use basemod, only: param_t
contains	
	subroutine print_a(p)
		type(param_t), intent(in) :: p
		print*, p%a
	end subroutine
end module

The standard procedure works like a charm:

gfortran -c debug_move_methods.f90 -fPIC
f90wrap -m debug debug_move_methods.f90
f2py-f90wrap -c -m _debug debug_move_methods.o f90wrap_debug_move_methods.f90

But the --move-methods variant fails:

f90wrap -m debug debug_move_methods.f90 --move-methods
f2py-f90wrap -c -m _debug debug_move_methods.o f90wrap_debug_move_methods.f90  # FAILS

because of unified (wrong) module use in f90wrap_debug_move_methods.f90

use basemod, only: param_t, print_a

Whereas print_a is defined in the extension module extmod, not in basemod.

I am not saying my design is the best ever (maybe the use of new submodule feature might achieve something similar -- but is it supported by f90wrap?), but I assume this bug should easy to fix? Thanks in any case.

elemental function problem

Hi,
First of all: what a great idea! I have a collaborator who can only work with Fortran, and we have been re-inventing the proverbial wheel for all the simple (in Python) things that are tedious in Fortran.

I was trying f90wrap and noticed that a simple elemental function poses a problem.
Example:

module elemental_module
implicit none
contains
elemental real(kind=8) function sinc(x)
real(kind=8), intent(in) :: x
if(abs(x).gt.1d-5) then
sinc = sin(x)/x
else
sinc = 1.0d0
endif
return
end function sinc
end module elemental_module

I have used the following commands to build it
f90wrap -m elmod elemental_module.f90 -k kind_map -v
f2py-f90wrap --fcompiler=gfortran -I. --build-dir . -c -m _elmod elemental_module.f90 f90wrap*.f90

The problem is, I believe in f90wrap_elemental_module.f90 as it uses elemental as a type for ret_sinc

Cheers

Piotr

Using f90wrap with distutils

It would be handy to use f90wrap from distutils directly, as is now possible with f2py.

Any plan in this direction?

Never checked the internals, it must not be too complicated...
It is about subclassing the distutils.extension.Extension class, or/and provide a new setup script, or, like cython does, defining a build_ext function to pass to setup's cmd_class.
An example here: https://github.com/perrette/python-fortran-cpp-template/blob/master/setup.py.

I will take a look at some point in 2016...

modification of pointer in Fortran for the f90wrap

replace pointer with intent(inout). in addition to that, add a directive for the f2py
!f2py intent(in,out) :: var (is this modification to the Fortran source code needed in the f90wrap?)

does it seem reasonable?

Linked list type definition fails compilation

The type definition:

  TYPE queued_node
      INTEGER  :: node_index
      TYPE(queued_node),POINTER:: next_node
  END TYPE queued_node

produces a f90wrap_*f90 file that produces an error when trying to compile with f2py-f90wrap.

The error is as follows:

Error: Derived type definition of ‘queued_node_ptr_type’ at (1) has already been defined

And is down to the queued_node_ptr_type being defined twice in two of the subroutines:

    use tort_mod, only: queued_node
    implicit none
    type queued_node_ptr_type
        type(queued_node), pointer :: p => NULL()
    end type queued_node_ptr_type
    type queued_node_ptr_type
        type(queued_node), pointer :: p => NULL()
    end type queued_node_ptr_type
    integer, intent(in)   :: this(2)
    type(queued_node_ptr_type) :: this_ptr
    integer, intent(out) :: f90wrap_next_node(2)
    type(queued_node_ptr_type) :: next_node_ptr

    this_ptr = transfer(this, this_ptr)
    next_node_ptr%p => this_ptr%p%next_node
    f90wrap_next_node = transfer(next_node_ptr,f90wrap_next_node)
end subroutine f90wrap_queued_node__get__next_node

subroutine f90wrap_queued_node__set__next_node(this, f90wrap_next_node)
    use tort_mod, only: queued_node
    implicit none
    type queued_node_ptr_type
        type(queued_node), pointer :: p => NULL()
    end type queued_node_ptr_type
    type queued_node_ptr_type
        type(queued_node), pointer :: p => NULL()
    end type queued_node_ptr_type
    integer, intent(in)   :: this(2)
    type(queued_node_ptr_type) :: this_ptr
    integer, intent(in) :: f90wrap_next_node(2)
    type(queued_node_ptr_type) :: next_node_ptr

    this_ptr = transfer(this, this_ptr)
    next_node_ptr = transfer(f90wrap_next_node,next_node_ptr)
    this_ptr%p%next_node = next_node_ptr%p
end subroutine f90wrap_queued_node__set__next_node

If you remove one of these in each subroutine it compiles fine.

Does anyone know how to avoid this issue?

Thanks!

Array of derived_type makes function skipped, without any warning

If a function uses an array of some derived type, the function is simply skipped by f90wrap, and no warning is issued.
Minimal example :

module module_calcul
type type_ptmes
integer :: y
end type type_ptmes
contains
subroutine recup_point(x)
type(type_ptmes) :: x(2)
return
end subroutine recup_point
end module module_calcul

--only and --skip switches bug

Hi James : )
The --only and --skip are buggy:
The "kept_modules" variable is defined in the file "f90wrap.py" as a set, to ensure a non-redundant list along the various appends.
But sets only work for hashable object. So the "Module" class needs a "hash()" function for your code to work as intended. All seems to work by adding the following function to the "Module" class, in the "fortran.py" file:

# Required for the Module object to be hashable so one can create sets of Modules
# So this function should return a unique imprint of the object.
# I guess the filename + the module name should be unique enough ?
# Also, hash requires an integer, so we convert the characters to integers with the
# same number of digits to ensure one-to-one conversion.
# This is maybe unnecessarily long ?
def __hash__(self):
    return int(''.join(str(ord(x)).zfill(3) for x in self.filename + self.name))

I felt the is not worth a complete pull request, especially since I am tinkering with other files to handle arrays of derived types.

Array in class gives wrong values in simetrical positions

I have a fortran module as:

`module gen 
  use ISO_C_BINDING
  use parm

  real (type_r8), allocatable :: xg(:)

  end module gen`

And f2py-f90wrap produces the following python class/def:

` class Gen(f90wrap.runtime.FortranModule):

Module gen
Defined at ../src/gen.f lines 1-1607

@property
def xg(self):
  
    Element xg ftype=real (type_r8) pytype=float
    Defined at ../src/gen.f line 150
    
   
    array_ndim, array_type, array_shape, array_handle = \
        _min3p.f90wrap_gen__array__xg(f90wrap.runtime.empty_handle)
    if array_handle in self._arrays:
        xg = self._arrays[array_handle]
    else:
        xg = f90wrap.runtime.get_array(f90wrap.runtime.sizeof_fortran_t,
                                f90wrap.runtime.empty_handle,
                                _min3p.f90wrap_gen__array__xg)
        self._arrays[array_handle] = xg
    return xg

@xg.setter
def xg(self, xg):
    self.xg[...] = xg`

It looks fine, however when I ask my python main to print it, it gives something like:

1.96938765049 -1.32611814684e+23 1.97448968887 -1.86322722022e+26 1.97959172726 -2.61938127341e+29 1.98469376564 -3.57632946796e+32 1.98979580402 -5.15415206355e+35 1.99489784241 4.20389539297e-45

That looks like a right value followed by a wrong value... Does anyone know what is going on there?

Cheers!

array function error

Consider the simple fortran function:

function array(n)
  implicit none
  integer, intent(in) :: n
  integer :: array(n)
  integer :: i
  do i = 1,n
    array(i) = i
  enddo
end function

The f90wrap wrapper yields two parmeters n and n0 for some reason (does not dare to guess the output size, I suppose this is related to issue #33).

subroutine f90wrap_array(ret_array, n, n0)
    implicit none
    external array
    integer array

    integer, intent(out), dimension(n0) :: ret_array
    integer, intent(in) :: n
    integer :: n0
    ret_array = array(n)
end subroutine f90wrap_array

but the corresponding python wrapper is inconsistent (import and doc removed for brevety), lacking the n0 parameter.

def array(n):
    array = _testfunction.f90wrap_array(n=n)
    return array

So far my workaround is to use sed to fix the python wrapper:

sed -i "s/_testfunction.f90wrap_array(n=n)/_testfunction.f90wrap_array(n=n, n0=n)/" *.py

But something less ad-hoc would be preferable of course.

Note that in this example the fortran wrapper fails (segmentation fault), but it works well when used in a module.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.