I have been writing a code in FORTRAN but I am having problems using the lapack dsyevr:
http://netlib.sandia.gov/lapack/double/dsyevr.f
The problems I am getting seem to be linked to memory allocation issues, specifically I believe to do with the output arrays the dsyevr produces (including A which is an input and an output).
I have tried to write a simplified code to demonstrate the issues I am seeing. Please let me know if any of it needs clarification. The code is names prof1.f90 and calls the dsyevr function:
PROGRAM prog1
implicit none
real(kind=8), allocatable :: W(:)
real(kind=8), allocatable :: Z(:,:)
real(kind=8), allocatable :: A(:,:)
integer(kind=8) :: n, info, il, iu, m, lwork, liwork
integer(kind=8) :: i, k, p, q, nu
real(kind=8) :: abstol, vl, vu
real(kind=8), allocatable :: work(:)
integer, allocatable :: isuppz(:), iwork(:)
n = 3
allocate(W(3),Z(3,3),A(n,n),stat=info)
if (info .ne. 0) stop "error allocating arrays"
A(1,1)=3.78136524999999994E-003
A(1,2)=0.0000000000000000
A(1,3)=-7.92918150000000038E-004
A(2,1)=0.0000000000000000
A(2,2)=5.20293929999999984E-003
A(2,3)=0.0000000000000000
A(3,1)=-7.92918150000000038E-004
A(3,2)=0.0000000000000000
A(3,3)=3.78136524999999994E-003
vl = 1.06451084056294826E-313
vu = 0.0
il = 4294967297
iu = 8839891
m = 140733655445712
W(1) = 2.98844710000000001E-003
W(2) = 4.57428340000000030E-003
W(3) = 5.20293929999999984E-003
Z(1,1) = 8.65587596665713699E-317
Z(1,2) = 8.65587596665713699E-317
Z(1,3) = 1.58101006669198894E-322
Z(2,1) = 1.58101006669198894E-322
Z(2,2) = 0.0000000000000000
Z(2,3) = 8.65569415049946741E-317
Z(3,1) = 4.24400777097956191E-314
Z(3,2) = 4.79243676466009148E-322
Z(3,3) = 3.51391740150311405E-316
lwork = -1
liwork = -1
abstol = 1d-5
allocate(work(1),iwork(1),isuppz(6))
call dsyevr('V','A','U',n,A,n,vl,vu,il,iu,abstol,m,W,Z,n,isuppz,work,lwork,iwork,liwork,info)
if (info .ne. 0) stop "error obtaining work array dimensions"
lwork = work(1)
liwork = iwork(1)
deallocate(work,iwork)
allocate(work(lwork),iwork(liwork),stat=info)
if (info .ne. 0) stop "error allocating work arrays"
call dsyevr('V','A','U',n,A,n,vl,vu,il,iu,abstol,m,W,Z,n,isuppz,work,lwork,iwork,liwork,info)
if (info .ne. 0) stop "error diagonalizing the hamiltonian"
deallocate(A,work,iwork,isuppz)
END PROGRAM prog1
In the code above the dsyevr function is called twice, the first time which is just to get the dimensions of the work etc... matrices runs correctly however the second time when it is called it returns the following error
*** glibc detected *** ./PROGRAM: munmap_chunk(): invalid pointer: 0x000000000134cc20 ***
There is also a Backtrace and MemoryMap which I can provide.
If it is useful the makefile I have been using is given below. The program is created using the line:
make PROGRAM
Makefile:
FC = gfortran
FCFLAGS = -g -fbounds-check
FCFLAGS = -O2
FCFLAGS += -I/usr/include
%: %.o
$(FC) $(FCFLAGS) -o $@ $^ $(LDFLAGS)
%.o: %.f90
$(FC) $(FCFLAGS) -c $< -fno-range-check
%.o: %.F90
$(FC) $(FCFLAGS) -c $<
.PHONY: clean veryclean
PROGRAM: prog1.f90 prog1.o
$(FC) $(FCFLAGS) -o $@ prog1.o $(LIBS) -Wl,--start-group -L$(MKLROOT)/lib/intel64 -lmkl_gf_ilp64 -lmkl_core -lmkl_sequential -Wl,--end-group -lpthread
clean:
rm -f *.o *.mod *.MOD
veryclean: clean
rm -f *~ $(PROGRAM)
where $MKLROOT is /opt/intel/composer_xe_2011_sp1.8.273/mkl
If it is useful I have used valgrind:
valgrind --tool=memcheck --db-attach=yes ./PROGRAM
And I have found the following error:
==31069==
==31069== Invalid write of size 8
==31069== at 0x57B9F92: mkl_lapack_dsyevr (in /opt/intel/composer_xe_2011_sp1.8.273 /mkl/lib/intel64/libmkl_core.so)
==31069== by 0x4D9A580: DSYEVR (in /opt/intel/composer_xe_2011_sp1.8.273/mkl/lib /intel64/libmkl_gf_ilp64.so)
==31069== by 0x401163: MAIN__ (in /home/j/workbook/Test4/PROGRAM)
==31069== by 0x401F09: main (in /home/j/workbook/Test4/PROGRAM)
==31069== Address 0x6afe0b0 is 0 bytes inside a block of size 4 alloc'd
==31069== at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==31069== by 0x400FE4: MAIN__ (in /home/j/workbook/Test4/PROGRAM)
==31069== by 0x401F09: main (in /home/j/workbook/Test4/PROGRAM)
==31069==
I am not sure if the line "Invalid write of size 8" is referring to the size of the some of the integers or reals (as mentioned by Jonathan Dursi) or referring to the size of an array being passed into dsyevr.
Invalid write of size 8means write of a single element of 8 bytes. It could be both integer or real.