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

时间:2013-12-19 16:45:17

标签: fortran fortran90 gfortran

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

INTEGER,PARAMETER :: totalFrames = 32000  
INTEGER,PARAMETER :: AAA=75
REAL,DIMENSION(45:AAA,1:256,1:totalFrames) :: CH_Angles

如果我使用AAA = 75的值,我可以编译此代码而不会出现任何错误,我可以获得我想要的值。但是,如果我将AAA的值更改为AAA=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

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

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

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

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

注意:我正在使用Ubuntu 11.10 64位的gfortran编译器和16 GB RAM内存。

3 个答案:

答案 0 :(得分:8)

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

gfortran for dummies: What does mcmodel=medium do exactly?

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

更好的方法是处理这个问题,但需要做更多的工作,就是动态分配任何大型数组。

答案 1 :(得分:5)

如果我记得正确的话,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

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

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

答案 2 :(得分:0)

你的数组CH_Angles正在推动一个千兆字节大小,所以索引算法将推动32位限制。 我希望事情会变得那么大。