2

Sorry about being new to both Fortran 90 and f2py.

I am using Windows 64 bit, Python 3.4 64 bit, gfortran. Numpy version is 1.9.1, and I commented the "raise NotImplementedError("Only MS compiler supported with gfortran on win64")" in the gnu.py, as instructed on this link: http://scientificcomputingco.blogspot.com.au/2013/02/f2py-on-64bit-windows-python27.html

I have a module in fortran, written as follows, with a module-scope variable dp:

! testf2py.f90
module testf2py
    implicit none
    private
    public dp, i1
    integer, parameter :: dp=kind(0.d0)
contains
    real(dp) function i1(m)
        real(dp), intent(in) :: m(3, 3)
        i1 = m(1, 1) + m(2, 2) + m(3, 3)
        return
    end function i1
end module testf2py

Then, if I run f2py -c testf2py.f90 -m testf2py

It would report an error, stating that dp was not declared.

If I copy the module-scope to the function-scope, it would work.

! testf2py.f90
module testf2py
    implicit none
    private
    public i1
    integer, parameter :: dp=kind(0.d0)
contains
    real(dp) function i1(m)
        integer, parameter :: dp=kind(0.d0)
        real(dp), intent(in) :: m(3, 3)
        i1 = m(1, 1) + m(2, 2) + m(3, 3)
        return
    end function i1
end module testf2py

However, this does not look like the best coding practice though, as it is pretty "wet".

Any ideas?

Yuxiang Wang
  • 8,095
  • 13
  • 64
  • 95

1 Answers1

5

Here's a work-around, in which dp is moved to a types module, and the use types statement is added to the function i1.

! testf2py.f90

module types
    implicit none
    integer, parameter :: dp=kind(0.d0)
end module types

module testf2py
    implicit none
    private
    public i1
contains
    real(dp) function i1(m)
        use types
        real(dp), intent(in) :: m(3, 3)
        i1 = m(1, 1) + m(2, 2) + m(3, 3)
        return
    end function i1
end module testf2py

In action:

In [6]: import numpy as np

In [7]: m = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])

In [8]: import testf2py

In [9]: testf2py.testf2py.i1(m)
Out[9]: 150.0

The change is similar to the third option that I described in this answer: f2py: Specifying real precision in fortran when interfacing with python?

Community
  • 1
  • 1
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • Nice. I approve (and miss my f2py fortran-python days ... :-/). – mgilson Jan 27 '15 at 04:45
  • @Warren Thank you for your response! And sorry about the late response. I also got the email from the mailing list, but figured that a discussion here would probably be accessible to more people. I do have a question, that I do not understand why this is happening. I do understand that f2py does not take where `kind=kind(0.d0)` because a function call of `kind()` is used. My questions are: – Yuxiang Wang Jan 30 '15 at 17:55
  • 1) if we compile the module `types` first, why would `dp` be OK in this way? Is it because it is compiled first so it no longer is a function call? 2) Why would it fail if the `use types, only : dp` statement was at the module level? And why would it work if it is placed at the function level? – Yuxiang Wang Jan 30 '15 at 17:56
  • All good questions; I wish I had the answers. Maybe @mgilson can revive his f2py fortran-python skills and provide some wisdom. :-) – Warren Weckesser Jan 30 '15 at 19:04
  • @ShawnWang -- Mostly I'm guessing that this is a result of the f2py parser not being a full language parser. Out of curiosity, what happens if you move the "integer, parameter" declaration _above_ the public dp statement in your original post? – mgilson Jan 30 '15 at 19:08
  • @mgilson Thanks for your answer! And sorry for the late response! I just tried that, and it remained the same - dp was not found. Well, I guess then I have to switched to a "f2py" coding style then :) I use to think that I can remain my old f90 coding style, where I only import module scope variables at module level... – Yuxiang Wang Feb 02 '15 at 19:38