Thank you for having a look at this problem.
Problem:
seg. fault when returning from f90 subroutine that contains KINSOL solving process, after the correct computation result has been generated. No problem when the same solving process is in the main program.
Environment:
linux,
gcc,
sundials static libs
How to initiate the problem:
get the attached REDUCED test code
module moduleNonlinearSolve
integer,save::nEq
contains
subroutine solveNonlinear(u)
double precision::u(*)
integer iout(15),ier
double precision rout(2),koefScal(nEq)
koefScal(:)=1d0
call fnvinits(3,nEq,ier)
call fkinmalloc(iout,rout,ier)
call fkinspgmr(50,10,ier)
call fkinsol(u,1,koefScal,koefScal,ier)
call fkinfree()
do i=1,nEq
write(*,*),i,u(i)
end do
end subroutine
end module
subroutine fkfun(u,fval,ier)
use moduleNonlinearSolve
double precision::u(*)
double precision::fval(*)
integer::ier
forall(i=2:nEq-1)
fval(i)=-u(i-1)+2d0*u(i)-u(i+1)-1d0
end forall
fval(1)=u(1)+2d0*u(1)-u(2)-1d0
fval(nEq)=-u(nEq-1)+2d0*u(nEq)+u(nEq)-1d0
ier=0
end subroutine
program test
use moduleNonLinearSolve
double precision u(10)
nEq=size(u)
u(:)=10d0
call solveNonlinear(u)
end program``
compile
$ gfortran -c -Wall -g test.f90
$ gfortran -Wall -g -o test test.o -lsundials_fkinsol -lsundials_fnvecserial -lsundials_kinsol -lsundials_nvecserial -llapack -lblas
run
$ ./test
Note: It would work flawlessly if put all the SUNDIALS procedures in the main program.
Thank you very much for any input.
Mianzhi
According to the KINSOL documentation, the first argument of
fkinmallocmust be of the same integer type as theCtypelong int. In your case,long intis 8 bytes long, but you are passing in an array of 4 byte integers. This will lead tofkinmalloctrying to write beyond the bounds of the array, and into some other memory. This typically leads to memory corruption, which has symptoms just like what you are observing: Crash at some random later point, such as when returning from a function. You should be able to confirm this by running the program through valgrind, which will probably report invalid writes of size 8. Anyway, replacingwith
should solve the problem.