f2py on module with allocatable string - fortran

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

Related

Multi dimensional integration with quadpack results in recursive call to nonrecursive procedure 'dqage'

I am attempting to perform a 2D integral numerically using the quadpack double library. Since this website does not have a Latex engine integrated I attach a picture with the math.
I also attach below my implementation of this operation in the test_module module.
module test_module
use f90_kind ! defines dp
use physconst ! defines pi
use global_variables ! defines the variables for quadpack
use csv_file ! allows me to write to a csv file
implicit none
real(dp) :: a, b, c ! parameters I want to set
contains
real(dp) function multi_val_func(theta)
real(dp), intent(in) :: theta
multi_val_func = exp(theta**2 + c*theta)
end function multi_val_func
real(dp) function theta_integral(phi)
real(dp), intent(in) :: phi
c = phi*(a+b)
! Quadpack variables
epsabs = 1.0E-14_dp
epsrel = 0.0E0_dp
key = 6
ilow = 0.0E0_dp
ihigh = 2.0E0_dp*pi
call dqage(multi_val_func, ilow, ihigh, epsabs, epsrel, key, limit, &
res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)
theta_integral = res
end function theta_integral
subroutine phi_integral(final_result)
real(dp),intent(out) :: final_result
a = 1.0E0_dp
b = 1.0E0_dp
! Quadpack variables
epsabs = 1.0E-14_dp
epsrel = 0.0E0_dp
key = 6
ilow = 0.0E0_dp
ihigh = pi
call dqage(theta_integral, ilow, ihigh, epsabs, epsrel, key, limit, &
res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)
final_result = res
print *, final_result
end subroutine phi_integral
end module test_module
In the main file I define the result variable and thereafter call phi_integral(result). I compile this code using the following makefile
FFLAGS = -O0 -fcheck=all -ffree-line-length-none
debug:
gfortran -c $(FFLAGS) $(srcdir)/f90_kind.f90
gfortran -c $(FFLAGS) $(srcdir)/physconst.f90
gfortran -c $(FFLAGS) $(srcdir)/global_variables.f90
gfortran -c $(FFLAGS) $(extlib_qp)/quadpack_double.f90
gfortran -c $(FFLAGS) $(extlib_csv)/csv_file.f90
gfortran -c $(FFLAGS) $(srcdir)/multi_var_integration.f90
gfortran -c $(FFLAGS) $(srcdir)/main.f90
gfortran *.o -o debug -lblas -llapack
rm -f *.o *.mod
The code compiles but when I run it I receive the following error:
Fortran runtime error: Recursive call to nonrecursive procedure 'dqage'
Error termination. Backtrace:
#0 0x103a28d3d
#1 0x103a299f5
#2 0x103a29fd6
#3 0x1039f94b6
#4 0x1039dee59
#5 0x1039fad68
#6 0x1039f9948
#7 0x1039dec7d
#8 0x1039def61
#9 0x1039defa3
Any suggestion for dealing with this is greatly appreciated.
Not every subroutine or function in Fortran is re-entrant or, as Fortran calls it, "recursive". Before Fortran 2018 a subroutine that can be called, when already inside itself (even if indirectly) must be marked by the recursive attribute.
Even if a subroutine is marked that way, it may not work as expected if it contains static (saved) data or if it uses global (common blocks, module) variables.
I cannot immediately see any such static data used in http://www.netlib.no/netlib/quadpack/dqage.f so it might actually work after adding recursive.
However, as francescalus pointed out, you should be better off with a dedicated 2d quadrature library.
The theta integral can be done via the error function erf. See wolfram alpha.
The result of that is a function of one variable phi which can be evaluated via quadpack. Thus, you don't need a multidimensional integral routine after all.

Error when running Fortran program (forrtl: severe (157): Program Exception - access violation)

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.

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
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

f2py Fortran function interfaces compiling error

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.

Fortran Call Errors

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.