我已经在编写FORTRAN代码用于应用物理问题的数值模拟两年多了,我试图遵循Fortran Best Practices中描述的约定.
更具体地说,我将参数定义为
integer, parameter:: dp=kind(0.d0)
Run Code Online (Sandbox Code Playgroud)
然后在我的代码中将它用于所有双打.
但是,我发现(在这个论坛上)如果使用其他编译器编译代码,使用KIND参数不一定能提供相同的精度.在这个问题中,我读到一个可能的解决方案是使用SELECTED_REAL_KIND和SELECTED_INT_KIND,它遵循一些约定,据我所知.
不过,后来我发现了ISO_FORTRAN_ENV模块,该模块定义了REAL32,REAL64和REAL128 KIND参数.
我猜这些确实是可移植的,因为它们属于FORTRAN 2008标准(虽然受GNU支持),我想我应该使用这些?
因此,如果有更多知识和经验的人清除混乱,我将不胜感激.
另外,我有一个关于在HDF5中使用这些KIND的后续问题.我正在使用H5T_NATIVE_DOUBLE,它确实工作正常(据我所知)但是,在本文档中声明这是一个过时的功能,不应该使用.相反,它们提供了一种功能
INTEGER(HID_T) FUNCTION h5kind_to_type(kind, flag) RESULT(h5_type) .
Run Code Online (Sandbox Code Playgroud)
当我使用它,并打印出对应于REAL64的HID_T整数的精确数值给我50331972,而H5T_NATIVE_DOUBLE给我50331963,这是不同的.
如果我然后尝试使用H5kind_to_type计算的值,HDF5库运行就好了,使用XDMF,我可以在VisIt或Paraview中绘制输出,而无需修改附带的.xmf文件.
所以我的第二个问题是(再次):这是正确的用法吗?
我编写了一段科学代码,像往常一样,这归结为计算代数特征值方程中的系数:计算这些系数需要对多维数组进行积分,这会迅速大幅增加内存使用量。一旦计算出矩阵系数,原始的预积分多维数组就可以被释放,并由智能求解器接管,因此内存使用不再是大问题。正如您所看到的,存在瓶颈,在我的 64 位、4 核、8 线程、8GB 内存笔记本电脑上,程序因内存不足而崩溃。
因此,我正在实现一个系统,通过限制 MPI 处理在计算某些特征值矩阵元素时可以承担的任务的大小来控制内存使用情况。完成后,他们将寻找剩余的工作来完成,以便矩阵仍然被填充,但以更顺序和更少并行的方式。
因此,我正在检查可以分配多少内存,这就是混乱开始的地方:我分配大小为 8 字节的双精度数(使用 检查sizeof(1))并查看分配状态。
虽然我有 8 GB 的可用内存来运行只有 1 个进程的测试,但我可以分配一个最大为 size 的数组(40000,40000),这对应于大约 13GB 的内存!我的第一个问题是:这怎么可能?虚拟内存有这么多吗?
其次,我意识到我也可以对多个进程做同样的事情:最多16 个进程可以同时分配这些海量数组!
这不可能吧?
有人明白为什么会发生这种情况吗?我是否做错了什么?
编辑:
这是产生上述奇迹的代码,至少在我的机器上是这样。然而,当我将数组的元素设置为某个值时,它确实会按预期运行并崩溃——或者至少开始运行得很慢,我猜这是因为使用了缓慢的虚拟内存?
program test_miracle
use ISO_FORTRAN_ENV
use MPI
implicit none
! global variables
integer, parameter :: dp = REAL64 ! double precision
integer, parameter :: max_str_ln = 120 ! maximum length of filenames
integer :: ierr ! error variable
integer :: n_procs ! …Run Code Online (Sandbox Code Playgroud)