[SciPy-Dev] f2py, the fortran integer type, and npy_intp

Kurt Smith kwmsmith@gmail....
Mon Jul 12 11:10:04 CDT 2010


On Sat, Jul 10, 2010 at 6:33 PM, Sturla Molden <sturla@molden.no> wrote:
> Charles R Harris skrev:
>>
>> I don't think the bindings don't help, we need to have the default
>> integers in the existing pre-FORTRAN77 code in scipy compiled as
>> Py_ssize_d, and then f2py needs to be modified to generate appropriate
>> Python bindings. That's a lot of work. Even with the bindings I think
>> one would need to have a script to rewrite the FORTRAN code since the
>> c-type corresponding to Py_ssize_d isn't fixed.
> We should also beware that the problem applies to real numbers as well
> as integer. You cannot rely on standard mappings from C float to REAL
> and C double to DOUBLE PRECISION.
>
> With pre-Fortran 90, there is no way of controlling this portably. With
> Fortran 90 and later, we have the standard methods selected_real_kind
> and selected_int_kind that returns (compiler dependent) "kind" numbers,
> which can be used to declare real and integers with specific precitions.
>
>  integer, parameter :: single = selected_real_kind(p=6, r=37)
>  integer, parameter :: double = selected_real_kind(p=13)
>
>  integer, parameter :: npy_int8 = selected_int_kind(2)
>  integer, parameter :: npy_int16 = selected_int_kind(4)
>  integer, parameter :: npy_int32 = selected_int_kind(9)
>  integer, parameter :: npy_int64 = selected_int_kind(18)
>
> Now we can declare an npy_int32 like this:
>
>  integer(kind=npy_int32) :: i
>
> Still we have no ide what npy_intp would map to. We can do this in
> Fortran 2003:
>
>  use, intrinsic ::  iso_c_binding
>  integer, parameter :: npy_intp = c_intptr_t

Trouble is that 'c_intptr_t' isn't defined for some fortran compilers.
 So you first have to find which one of 'int', 'long int' or 'long
long int' corresponds to 'npy_intp' in C code, then declare a
parameter in fortran:

integer, parameter :: fort_npy_intp = c_long

for example.  Not a big deal.

>
>  integer(kind=npy_intp) ::  i
>
> Real numers and other integer sre also easier:
>
>  integer, parameter :: float = c_float
>  integer, parameter :: double = c_double
>  integer, parameter :: npy_int32 = c_int32_t
>
> Such declarations can be put in a module, and subsequently imported to
> Fortran 90.
>
> It might be that f2c is the only cure for old Fortran code. The other
> option is to write a Fortran 2003 wrapper to interface C. Then this
> wrapper will call the old Fortran code. We then need to declare the old
> Fortran routine (as an interface block) to Fortran 2003. The Fortran
> compiler is then smart enough to do the correct conversions, including
> making a local copy of an array if that is needed.

Umm, unless I misunderstand you, this isn't how many fortran compilers
behave (ifort, gfortran & g95).

Try the following:

subroutine outer()
    integer(kind=8) :: arr(10,10)

    call inner(arr)

    contains

    subroutine inner(arr)
        integer(kind=4), intent(inout) :: arr(:,:)
        arr = 1
    end subroutine
end subroutine

Compiling with gfortran 4.4.4:

    call inner(arr)
               1
Error: Type mismatch in argument 'arr' at (1); passed INTEGER(8) to INTEGER(4)

But perhaps I misunderstand you.

>
> Wasn't Kurt Smith working on this for a GSOC project?

Yes :-)

It is coming along, and being actively developed.  Many niggling
issues to work out.  We're at near-parity with f2py at the moment,
with a few enhancements, but no 'pyf' interface modules (yet).

http://fwrap.sourceforge.net/

http://fortrancython.wordpress.com/

Kurt


More information about the SciPy-Dev mailing list