Jannick
Jannick

Reputation: 1046

Compiling a module with f2py with an interface

I am trying to compile a fortran module with f2py. It is the following code

module my_log_mod

   implicit none

    interface my_log
        module procedure my_log_array
        module procedure my_log_vector
    end interface my_log

   private  ! hides items not listed on public statement 
   public :: my_log


contains

    subroutine my_log_array(a,res)
        double precision, dimension (:,:), intent (in) :: a
        double precision, dimension (:,:), intent (out) :: res

        where (a>1.0)
            res = log(a)
        else where
            res = 0.D0
        end where
    end subroutine  

    subroutine my_log_vector(a,res)
        double precision, dimension (:), intent (in) :: a
        double precision, dimension (:), intent (out) :: res

        where (a>1.0)
            res = log(a)
        else where
            res = 0.D0
        end where
    end subroutine  

end module my_log_mod   

that I compile with the following command

f2py.py -c -m my_log_mod_comp my_log_mod.f90

and it results in the following error

C:\Users\weisshau\AppData\Local\Temp\tmpf0apqa7s\src.win32-3.6\my_log_mod_comp-f2pywrappers2.f90:7:28:

       use my_log_mod, only : my_log_array
                            1
Error: Symbol 'my_log_array' referenced at (1) not found in module 'my_log_mod'
C:\Users\weisshau\AppData\Local\Temp\tmpf0apqa7s\src.win32-3.6\my_log_mod_comp-f2pywrappers2.f90:18:28:

       use my_log_mod, only : my_log_vector
                            1
Error: Symbol 'my_log_vector' referenced at (1) not found in module 'my_log_mod'

I don't really know much about fortran and f2py, so I don't have any idea what is happening. If i use the module in pure fortran it works nicely

Upvotes: 1

Views: 1105

Answers (1)

F2py appears to be creating another wrapper code which uses the subroutines in your module.

But it calls directly the subroutines my_log_vector and my_log_array. It seems f2py does not support private. I would delete the private.

Also be prepared that you won't be able to use the generic my_log in Python. This concept of generics is alien to Python. You may need to delete the generic interface if deleting private does not make it compilable. You should definitely delete the public :: my_log.

Unfortunately, f2py does not support all features of modern Fortran.

The code I tested:

module my_log_mod

   implicit none

    interface my_log
        module procedure my_log_array
        module procedure my_log_vector
    end interface my_log

contains

    subroutine my_log_array(a,res)
        double precision, dimension (:,:), intent (in) :: a
        double precision, dimension (:,:), intent (out) :: res

        where (a>1.0)
            res = log(a)
        else where
            res = 0.D0
        end where
    end subroutine  

    subroutine my_log_vector(a,res)
        double precision, dimension (:), intent (in) :: a
        double precision, dimension (:), intent (out) :: res

        where (a>1.0)
            res = log(a)
        else where
            res = 0.D0
        end where
    end subroutine  

end module my_log_mod   

compilation:

f2py -c -m my_log_mod_comp my_log_mod.f90

...

Post-processing...
        Block: my_log_mod_comp
                        Block: my_log_mod
                                Block: my_log
                                Block: my_log_array
                                Block: my_log_vector
Post-processing (stage 2)...
        Block: my_log_mod_comp
                Block: unknown_interface
                        Block: my_log_mod
                                Block: my_log_array
                                Block: my_log_vector
Building modules...
        Building module "my_log_mod_comp"...
                Constructing F90 module support for "my_log_mod"...
                Creating wrapper for Fortran subroutine "my_log_array"
                      res = my_log_array(a)
                          res = my_log_array(a)
                Creating wrapper for Fortran subroutine "my_log_vector"("my_log_vector")...
                        Constructing wrapper function "my_log_mod.my_log_vector"...
                          res = my_log_vector(a)
        Wrote C/API module "my_log_mod_comp" to file "/tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_compmodule.c"
        Fortran 90 wrappers are saved to "/tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_comp-f2pywrappers2.f90"

...

gfortran:f90: /tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_comp-f2pywrappers2.f90
/usr/bin/gfortran -Wall -g -Wall -g -shared /tmp/tmp7e5v0u/tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_compmodule.o /tmp/tmp7e5v0u/tmp/tmp7e5v0u/src.linux-x86_64-2.7/fortranobject.o /tmp/tmp7e5v0u/my_log_mod.o /tmp/tmp7e5v0u/tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_comp-f2pywrappers2.o -L/usr/lib64 -lpython2.7 -lgfortran -o ./my_log_mod_comp.so
Removing build directory /tmp/tmp7e5v0u

Upvotes: 2

Related Questions