Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory 使用LAPACK DSYEVR时内存访问/分配出现问题。使用的代码是FORTRAN_Memory_Fortran_Lapack - Fatal编程技术网

Memory 使用LAPACK DSYEVR时内存访问/分配出现问题。使用的代码是FORTRAN

Memory 使用LAPACK DSYEVR时内存访问/分配出现问题。使用的代码是FORTRAN,memory,fortran,lapack,Memory,Fortran,Lapack,我一直在用FORTRAN编写代码,但在使用lapack dsyevr时遇到问题: 我遇到的问题似乎与内存分配问题有关,特别是我认为与dsyevr产生的输出阵列有关(包括作为输入和输出的阵列) 我试图编写一个简化的代码来演示我所看到的问题。如果需要澄清,请告诉我。代码名为prof1.f90并调用dsyevr函数: PROGRAM prog1 implicit none real(kind=8), allocatable :: W(:) real(kind=8), allocatable :

我一直在用FORTRAN编写代码,但在使用lapack dsyevr时遇到问题:

我遇到的问题似乎与内存分配问题有关,特别是我认为与dsyevr产生的输出阵列有关(包括作为输入和输出的阵列)

我试图编写一个简化的代码来演示我所看到的问题。如果需要澄清,请告诉我。代码名为prof1.f90并调用dsyevr函数:

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
在上面的代码中,dsyevr函数被调用了两次,第一次只是为了得到工件的尺寸等。。。矩阵正确运行,但第二次调用时返回以下错误

*** glibc detected *** ./PROGRAM: munmap_chunk(): invalid pointer: 0x000000000134cc20 ***
我还可以提供一个回溯和记忆映射

如果有用的话,下面给出了我一直使用的makefile。程序是使用以下行创建的:

make PROGRAM
生成文件:

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)
我发现了以下错误:

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

我不确定行“大小为8的无效写入”是否指的是某些整数或实数的大小(如Jonathan Dursi所述),或者指的是传递到dsyevr的数组的大小

从文档中看不明显,但是必须分配
isuppz
,即使对于
lwork=-1
的初始调用也是如此。如果在第一次调用之前将isuppz分配移动到,则代码将成功完成

之后,由于您使用的是MKL的ILP(8字节整数)版本,例如带有8字节整数索引的LAPACK,因此LAPACK例程的所有整数参数必须是相同的长类型,因此您需要

integer(kind=8), allocatable :: isuppz(:), iwork(:)

我要注意的是,对于两者和整数,kind=8实际上是标准的一部分,您应该真正使用所选的int/real\u kind或
iso\u fortran\u env
模块和
int64
,等等。

从文档中看不明显,但必须分配
isuppz
,甚至对于
lwork=-1
的初始调用。如果在第一次调用之前将isuppz分配移动到,则代码将成功完成

之后,由于您使用的是MKL的ILP(8字节整数)版本,例如带有8字节整数索引的LAPACK,因此LAPACK例程的所有整数参数必须是相同的长类型,因此您需要

integer(kind=8), allocatable :: isuppz(:), iwork(:)

我要注意的是,对于两者和整数,kind=8实际上是标准的一部分,您应该真正使用所选的int/real\u kind或
iso\u fortran\u env
模块和
int64
,等等。

从文档中看不明显,但必须分配
isuppz
,甚至对于
lwork=-1
的初始调用。如果在第一次调用之前将isuppz分配移动到,则代码将成功完成

之后,由于您使用的是MKL的ILP(8字节整数)版本,例如带有8字节整数索引的LAPACK,因此LAPACK例程的所有整数参数必须是相同的长类型,因此您需要

integer(kind=8), allocatable :: isuppz(:), iwork(:)

我要注意的是,对于两者和整数,kind=8实际上是标准的一部分,您应该真正使用所选的int/real\u kind或
iso\u fortran\u env
模块和
int64
,等等。

从文档中看不明显,但必须分配
isuppz
,甚至对于
lwork=-1
的初始调用。如果在第一次调用之前将isuppz分配移动到,则代码将成功完成

之后,由于您使用的是MKL的ILP(8字节整数)版本,例如带有8字节整数索引的LAPACK,因此LAPACK例程的所有整数参数必须是相同的长类型,因此您需要

integer(kind=8), allocatable :: isuppz(:), iwork(:)

我要注意的是,对于这两个模块和整数,kind=8实际上是标准的一部分,您应该使用selected_int/real_kind或
iso_fortran_env
模块和
int64
,等等。

非常感谢您的帮助。我已经做了此更正(并更新了我的问题),但不幸的是,我仍然看到相同的错误。我无法重现您现在得到的错误-works w/gfortran(或ifort)+MKL。这很奇怪,是否使用了与我现在的问题完全相同的代码和生成文件?你介意告诉我你的$MKLROOT和我的一样吗?(我自己也见过这个函数在ifort上工作,但是它试图用gfortran编译它,这样就可以用一堆其他代码来编译它,我认为这些代码在ifort上不会很快编译)还有一个问题(奇怪的是,ifort没有体现出来?)--你所有的整数都必须是长整数。我在我的问题中添加了一些valgrind的输出,可能与此有关。非常感谢你的帮助。我已经做了此更正(并更新了我的问题),但不幸的是,我仍然看到相同的错误。我无法重现您现在得到的错误-works w/gfortran(或ifort)+MKL。这很奇怪,是否使用了与我现在的问题完全相同的代码和生成文件?你介意告诉我你的$MKLROOT和我的一样吗?(我自己也见过这个函数在ifort上工作,但是它试图用gfortran编译它,这样就可以用一堆其他代码来编译它,我认为这些代码在ifort上不会很快编译)还有一个问题(奇怪的是,ifort没有体现出来?)--你所有的整数都必须是长整数。我在我的问题中添加了一些valgrind的输出,可能与此有关。非常感谢你的帮助。我已经做了此更正(并更新了我的问题),但不幸的是,我仍然看到相同的错误。我无法重现您现在得到的错误-works w/gfortran(或ifort)+MKL。这很奇怪,是否使用了与我现在的问题完全相同的代码和生成文件?你介意告诉我你的$MKLROOT和我的一样吗?(我已经看到这个函数在ifort上如何工作