f2py gives an error when I try compile FORTRAN subroutine, from which I call another FORTRAN function passing array to it.
I simplified code to leave the problem only.
SUBROUTINE MAS (matrix, a)
IMPLICIT NONE
INTERFACE
LOGICAL FUNCTION LTRY(input_array)
IMPLICIT NONE
INTEGER*4 :: input_array(:,:)
END FUNCTION LTRY
END INTERFACE
INTEGER*4 :: matrix (:,:)
!f2py INTENT(INOUT) :: matrix(:,:)
INTEGER*4 a
!f2py INTENT(INOUT) :: a
a = 1
IF ( LTRY (matrix)) a = 2
END SUBROUTINE
LOGICAL FUNCTION LTRY(input_array)
IMPLICIT NONE
INTEGER*4 :: input_array (:,:)
IF ( ANY(input_array == 0)) LTRY = .FALSE.
END FUNCTION LTRY
After I try to compile this using
f2py -c -m ptest ptest.f90
I get a tremendous number of errors. What's wrong?
Using Ubuntu and gfortran compiler.
Here is compiler output (part with error reports):
gfortran:f77: /tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:16.35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:18.72:
integer, dimension(:,:) :: input
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:19.72:
logical :: ltry
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:20.17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:40.32:
ltryf2pywrap = .not.(.not.ltry(input_array))
1
Error: Operand of .not. operator at (1) is INTEGER(4)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:16.35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:18.72:
integer, dimension(:,:) :: input
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:19.72:
logical :: ltry
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:20.17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:40.32:
ltryf2pywrap = .not.(.not.ltry(input_array))
1
Error: Operand of .not. operator at (1) is INTEGER(4)
error: Command "/usr/bin/gfortran -Wall -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops -I/tmp/tmpSZHMCR/src.linux-i686-2.7 -I/usr/lib/python2.7/dist-packages/numpy/core/include -I/usr/include/python2.7 -c -c /tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f -o /tmp/tmpSZHMCR/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.o" failed with exit status 1
Compilation failed.
Some errors look quite strange. For example compiler considers logical function as an integer.
Unfortunately, you have not indicated which type of error you get.
I have tried to compile it on my system, and I do get error messages:
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:16:35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:18:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:19:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:20:17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:16:35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:18:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:19:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:20:17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
Looking into the wrapped file, we see that the wrapper has made a very dubious decision: It has added comments at the end of the line, but then line-wrapped the comment without declaring it a comment in the second line:
C -*- fortran -*-
C This file is autogenerated with f2py (version:2)
C It contains Fortran 77 wrappers to fortran functions.
subroutine f2pywrapmas (matrix, a, f2py_matrix_d0, f2py_matr
&ix_d1)
integer*4 a
integer f2py_matrix_d0
integer f2py_matrix_d1
integer*4 matrix(f2py_matrix_d0,f2py_matrix_d1)
interface
subroutine mas(matrix,a)
integer*4, dimension(:,:) :: matrix
integer*4 :: a
interface ! in :ptest:ptest.f90:mas
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
&wn_interface
integer, dimension(:,:) :: input
logical :: ltry
end function ltry
end interface
end subroutine mas
end interface
call mas(matrix, a)
end
I don't know how to help you, though. But I do suggest you post your actual error messages in the question.
Related
I have written a very simple module (test.f90)
module tt
implicit none
character(:),allocatable :: hh
contains
subroutine test()
implicit none
integer :: i
end subroutine
end module tt
I want now to wrap it into an object for Python using f2py.
I use the following commands:
gfortran-9 -c test.f90 -Wall
f2py -m g -c test.f90
But I obtain the following errors. These errors seems to be correlated with the allocatable string and I am currently not able to find a solution to remove it.
/var/folders/fg/53phbn8n6nd3vrhm3sh_36w40000gn/T/tmpjtueazku/src.macosx-10.7-x86_64-3.6/g-f2pywrappers2.f90:25:17:
25 | allocate(d(s(1)))
| 1
Error: Shape specification for allocatable scalar at (1)
/var/folders/fg/53phbn8n6nd3vrhm3sh_36w40000gn/T/tmpjtueazku/src.macosx-10.7-x86_64-3.6/g-f2pywrappers2.f90:16:22:
16 | if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then
| 1
Error: 'array' argument of 'size' intrinsic at (1) must be an array
/var/folders/fg/53phbn8n6nd3vrhm3sh_36w40000gn/T/tmpjtueazku/src.macosx-10.7-x86_64-3.6/g-f2pywrappers2.f90:29:24:
29 | s(i) = size(d,i)
| 1
Error: 'array' argument of 'size' intrinsic at (1) must be an array
I have a C program that has a function named get_name. This function returns a string (i.e. char *) and changes the argument size (passed to it) with the size of the string:
char *get_name(int &size)
{
*size = strlen(name); // name is a C global variable declared as a char *
return name;
}
I have created the following Fortran module to be able to call the C function get_name:
MODULE X
USE, INTRINSIC :: iso_c_binding, ONLY: c_intptr_t
IMPLICIT NONE
INTERFACE
TYPE(c_ptr) FUNCTION get_name_(size) BIND(C, name = "get_name")
USE, INTRINSIC :: iso_c_binding, ONLY: c_int, c_ptr
INTEGER(c_int), INTENT(OUT) :: size
END FUNCTION
END INTERFACE
CONTAINS
FUNCTION get_name()
USE, INTRINSIC :: iso_c_binding, ONLY: c_int, c_char, c_f_pointer, c_ptr, c_associated
!DEC$ ATTRIBUTES DLLEXPORT :: get_name
CHARACTER(LEN = :), ALLOCATABLE :: get_name
INTEGER(c_int) :: size
TYPE(c_ptr) :: c_string
c_string = get_name_(size)
IF (c_associated(c_string)) THEN
BLOCK
CHARACTER(KIND = c_char, LEN = size), POINTER :: f_string
CALL c_f_pointer(c_string, f_string)
get_name = f_string
END BLOCK
ELSE
get_name = ""
END IF
END FUNCTION
END MODULE
I can successfully compile this Fortran module using IFORT 2016 in Windows, IFORT 2016 in Linux, and gfortran in Linux.
To test things, I have created a short Fortran program:
PROGRAM Test
USE X
WRITE(*, *) "Name: ", get_name()
END PROGRAM
I can successfully compile this Fortran program using IFORT 2016 in Windows, IFORT 2016 in Linux, and gfortran in Linux.
Now, when running the program it works well in IFORT 2016 for Linux, gfortran in Linux, but not in IFORT 2016 for Windows. It actually gives the following error:
forrtl: severe (157): Program Exception - access violation
Any idea how this error can be solved?
I assume your C function is char *get_name(int *size) instead of using a C++ reference.
Then this code works here on Windows and Linux with Ifort 16 and gcc-6.3.1 or Visual Studio 2015.
Please add your used C compiler and command lines to compile the code. I used:
cl -c testc.c && ifort -c testf.f /extend-source:132 && ifort testm.f testf.obj testc.obj /extend-source:132 && testm.exe
Btw: If you are using this function in parallel code I would suggest to avoid the block construct - I had bad experience using this in parallel (OpenMP) code with Ifort 16.
I'm experiencing a problem since I'm trying to run my fortran code with ifort, which was previously compiled with gfortran. One of my code's functions is using an other function as an argument, as shown below. Compiling the code with gfortran/ifort do not generate any errors.
module mod_rk4_2
implicit none
contains
!rk4 temporal scheme
function rk4(f,dt,func) result(f_new)
double precision, dimension(:,:), intent(in) :: f
double precision, intent(in) :: dt
double precision, dimension(size(f,1),size(f,2)) :: f_new
double precision, dimension(:,:), allocatable :: k1, k2, k3, k4
interface
function func(f) result(res)
double precision, dimension(:,:), intent(in) :: f
double precision, dimension(size(f,1),size(f,2)) :: res
end function func
end interface
allocate(k1(size(f,1),size(f,2)),k2(size(f,1),size(f,2)),k3(size(f,1),size(f,2)),k4(size(f,1),size(f,2)))
k1=func(f)
k2=func(f+dt*k1/2)
k3=func(f+dt*k2/2)
k4=func(f+dt*k3)
f_new=f+dt/6*(k1+2*k2+2*k3+k4)
deallocate(k1,k2,k3,k4)
end function rk4
end module mod_rk4_2
Running the code compiled with gfortran is fine, but when compiled with ifort, the code crashes at the first call of the forementioned function, with a stack overflow error message. Any ideas ?
forrtl: severe (170): Program Exception - stack overflow
Image PC Routine Line Source
main 00007FF779CCAE38 Unknown Unknown Unknown
main 00007FF779C564E0 Unknown Unknown Unknown
main 00007FF779CCAC02 Unknown Unknown Unknown
main 00007FF779CCB04C Unknown Unknown Unknown
KERNEL32.DLL 00007FF9D8EC1FE4 Unknown Unknown Unknown
ntdll.dll 00007FF9D99BEFC1 Unknown Unknown Unknown
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
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
In my Fortran code, I have the commands:
CALL EXPECTATION(X, 0.5D0*SIGMAZ, Z_EXPECTATION)
WRITE(1,*) T, Z_EXPECTATION
CALL EXPECTATION(X, 0.5D0*SIGMAY, Y_EXPECTATION)
WRITE(4,*) T, Y_EXPECTATION
for which I get the errors:
Error: Symbol ‘sigmay’ at (1) has no IMPLICIT type
Error: Symbol ‘sigmaz’ at (1) has no IMPLICIT type
But I get no error for a similar command:
CALL EXPECTATION(X, 0.5D0*SIGMAX, X_EXPECTATION)
WRITE(3,*) T, X_EXPECTATION
What could be the issue? I am calling the variables from the same subroutine and I have defined them to be
COMPLEX*16, DIMENSION(2,2) :: SIGMAX, SIGMAY SIGMAZ
You forgot a comma in the declaration between SIGMAY and SIGMAZ. Since Fortran doesn't care about whitespaces, it created only two complex variables: SIGMAX and SIGMAYSIGMAZ.
Just add the comma and your code should compile fine.