使用大型数组在Fortran中"重定位被截断以适应"错误

use*_*212 6 fortran gfortran fortran90

我编写了一个Fortran 90代码,用于从分子模拟数据中提取角度.在这段代码中,我使用了一个名字模块all_parameter.在这个模块中,我定义了一个数组,例如:CH_Angles

INTEGER,PARAMETER :: totalFrames = 32000  
INTEGER,PARAMETER :: AAA=75
REAL,DIMENSION(45:AAA,1:256,1:totalFrames) :: CH_Angles
Run Code Online (Sandbox Code Playgroud)

如果我使用的值AAA = 75,我可以编译此代码没有任何错误,我可以得到我想要的值.但是,如果我改变的价值AAAAAA=105,然后我得到了一些错误信息,如下图所示:

gfortran lipid-Tilt-Magnitude-thermo-cello.f90
/tmp/ccXOhMqQ.o: In function `__all_parameter_MOD_find_angle_ch':
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x35): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_x' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x48): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_y' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x5b): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_z' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x6e): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_x' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x81): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_y' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x94): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_z' defined in .bss section in /tmp/ccXOhMqQ.o
/tmp/ccXOhMqQ.o: In function `__all_parameter_MOD_find_mid_point_vector':
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x126): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_x' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x139): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_y' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x14c): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_z' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x15f): relocation truncated to fit: R_X86_64_32S against symbol `__all_parameter_MOD_x' defined in .bss section in /tmp/ccXOhMqQ.o
lipid-Tilt-Magnitude-thermo-cello.f90:(.text+0x172): additional relocation overflows omitted from the output
collect2: ld returned 1 exit status
vijay@glycosim:~/Simulation-Folder-Feb2013/chapter5-thermo-paper2-Vj/thermo2-Analysis/analysis-bcm-/23_acf-tail-tilt-angle-bcm-thermo2/chain1/acf-chain1-CH-bcm-thermo-all-layers$ gfortran lipid-Tilt-Magnitude-thermo-cello.f90
Run Code Online (Sandbox Code Playgroud)

我也尝试使用不同的AAA编译此代码.值为80时,编译没有错误.但是,如果AAA为85,则编译将停止并显示错误消息.

我发现AAA = 82是极限值.AAA的任何值都超过82,它会给出错误.

我无法弄清楚导致错误的原因.

反正有没有找到解决这个问题的方法?

注意:我使用的是带有16 GB RAM内存的Ubuntu 11.10 64位的gfortran编译器.

mil*_*cic 11

您获得的错误由链接器返回,因为静态分配的块的大小超出了32位寻址指令(2 GB)可以解决的范围.这与使用32位还是64位整数索引数组无关 - 问题与静态分配的数组的总大小有关.这将在下面详细解释:

gfortran for dummies:mcmodel = medium做了什么?

正如您所注意到的,为了解决这个问题,您可以使用-mcmodel=medium或编译代码-mcmodel=large.然后允许静态分配大于2 GB的阵列.

处理此问题的更好方法是动态分配任何大型数组,但涉及更多工作.


Hig*_*ark 6

如果我记得正确,gfortran,就像大多数现有的Fortran编译器一样,即使在64位硬件上仍然默认为4字节整数.除其他外,这意味着最大的数组索引将是2^312^32.由于多秩数组只是一级数组的一个方便的包装,所以我(或者@MikeDunlavey)对你的编译器在分配一个包含你想要的元素的数组时不感到惊讶.

尝试使用64位整数进行数组索引.您可以通过明确设置它们的类型来完成此操作,例如

use, intrinsic :: iso_fortran_env, only : int64
...
INTEGER(int64),PARAMETER :: totalFrames = 32000  
INTEGER(int64),PARAMETER :: AAA=75
REAL,DIMENSION(45_int64:AAA,1_int64:256_int64,1_int64:totalFrames) :: CH_Angles
Run Code Online (Sandbox Code Playgroud)

或者使用编译器标志将整数的默认大小设置为64位.对于gfortran,这将是-fdefault-integer-8.

我不保证这对gfortran有效,gfortran不是我经常使用的编译器,但它适用于英特尔Fortran.


Mik*_*vey 0

您的数组CH_Angles大小将达到 1 GB,因此索引算术将突破 32 位限制。我预计在这个规模下事情会变得有点棘手。