When I compile this silly fortran routine:
SUBROUTINE MY (C,M,NA,A,NB,B,N,V,I1,I2)
IMPLICIT NONE
INTEGER :: M, NA, NB, N, I, J, I1, I2
REAL :: C, A(NA,M), B(NB,M), V(N), X
IF(M.GT.15) THEN
DO I=1,N
X=C*V(I)
CALL DAXPY(M,X,A(I1,1),NA,B(I2,1),NB)
END DO
ELSE
DO I=1,N
X=C*V(I)
DO J=1,M
B(I2,J)=B(I2,J)+A(I1,J)
END DO
END DO
END IF
END SUBROUTINE MY
with gfortran -fsanitize=address -O2 -Wall -c a.f90 (gcc version 4.8.4) I get this warning:
a.f90: In function ‘my’:
a.f90:4:0: warning: ‘x’ may be used uninitialized in this function [-Wmaybe-uninitialized]
REAL :: C, A(NA,M), B(NB,M), V(N), X
^
and I can't see how x could ever be uninitialized (only if N < 1, but then it's never used either). The warning goes away without -fsanitize=address or -O2. Is any of these options changing my code in some "unsafe" way (such that the warning is issued)? Do more recent gfortran version give the same message?
Related
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.
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 have an legacy Fortran code that I want to mix with a new C/C++ program.
The Fortran subroutine allocates dynamically some arrays that I want to pass to c program. I will only get the size of these arrays after running the Fortran code.
After getting some tips here in this forum I arrived to the following code that I thought it would best compile, link and run.
Actually I can compile my C code and my Fortran code separately, but it doesn't link giving the following errors:
undefined reference to _gfortran_runtime_error
undefined reference to _gfortran_os_error
I'm using g++ and GFortran compilers version 5.4.0, and linking both .o files with g++ and the option -lg fortran.
fortran code:
subroutine test_allocation(outp) bind(c)
use iso_c_binding
implicit none
type (c_ptr), value :: outp
integer, target ::b(2)
integer(c_int), pointer :: a(:)
b(1)=1
b(2)=2
allocate(a(2))
a=>b
call c_f_pointer(outp, a,[2])
end subroutine
c code:
#include <iostream>
using namespace std;
extern "C" void test_allocation(int ** ptr);
int main ()
{
int* ptr;
test_allocation(&ptr);
}
EDIT:
As Vladimir F said on comments there was a mistake in my compiler option. The correct is -lgfortran.
Now it's linking but the results is not what I expect. I change a little my code to show this:
Fortran code:
subroutine test_allocation(outp) bind(c)
use iso_c_binding
implicit none
type (c_ptr), value :: outp
integer, target ::b(2)
integer(c_int), pointer :: a(:)
b(1)=1
b(2)=2
allocate(a(2))
a=>b
print*, "a(1) in Fortran: ", a(1)
print*, "a(2) in Fortran: ", a(2)
call c_f_pointer(outp, a,[2])
print*, "outp after c_f_pointer: ", outp
end subroutine
C code:
#include <iostream>
using namespace std;
extern "C" void test_allocation(int** ptr);
int main ()
{
int* ptr;
test_allocation(&ptr);
cout<<"ptr[0] in C: "<< ptr[0]<<endl;
cout<<"ptr[1] in C: "<< ptr[1]<<endl;
}
The output is:
a(1) in fortran: 1
a(2) in fortran: 2
outp after c_f_pointer: 140726088663920
ptr[0] in C: 1447122753
ptr[1] in C: 1107265857
I also tried changing the declaration of extern function to the following and it still does not work:
extern "C" void test_allocation(int*& ptr);
...
test_allocation(ptr);
The output is:
a(1) in fortran: 1
a(2) in fortran: 2
outp after c_f_pointer: 140729541703872
ptr[0] in C: 1447122753
ptr[1] in C: 1107265857
Now it works. Instead of using C_F_POINTER I used the function C_LOC.
I also removed the parameter VALUE from the TYPE(C_PTR) declaration.
Here is the code:
subroutine test_allocation(outp) bind(c)
use iso_c_binding
implicit none
type (c_ptr) :: outp
integer ::b(2)
integer,dimension(:), pointer :: a
b(1)=1
b(2)=2
allocate(a(2))
a=b
print*, "a(1) in fortran: ", a(1)
print*, "a(2) in fortran: ", a(2)
outp=c_loc(a)
print*, "outp after c_loc: ", outp
end subroutine
and it's output:
a(1) in fortran: 1
a(2) in fortran: 2
outp after c_loc: 36866928
ptr[0] in C: 1
ptr[1] in C: 2
The following link helped me a lot although I'm not using intel compiler:
https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/269660
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.