我有一个Fortran程序,我指定kind数字数据类型,试图保持最低精度,无论使用什么编译器来构建程序.例如:
integer, parameter :: rsp = selected_real_kind(4)
...
real(kind=rsp) :: real_var
Run Code Online (Sandbox Code Playgroud)
问题是我使用MPI来并行化代码,我需要确保MPI通信指定具有相同精度的相同类型.我使用以下方法与我的程序中的方法保持一致:
call MPI_Type_create_f90_real(4,MPI_UNDEFINED,rsp_mpi,mpi_err)
...
call MPI_Send(real_var,1,rsp_mpi,dest,tag,MPI_COMM_WORLD,err)
Run Code Online (Sandbox Code Playgroud)
但是,我发现这个MPI例程对于不同的MPI实现并没有特别好的支持,所以它实际上使我的程序不可移植.如果我省略了MPI_Type_create例程,那么我将依赖于标准MPI_REAL和MPI_DOUBLE_PRECISION数据类型,但如果该类型与selected_real_kind最终将由MPI传递的真实类型的选择不一致,该怎么办?我是不是只使用标准real声明的数据类型,没有kind属性,如果我这样做,我保证,MPI_REAL并且real总是会有相同的精度,无论编译器和机器?
更新:
我创建了一个简单的程序,演示了当我的内部实数比MPI_DOUBLE_PRECISION类型提供的精度更高时我看到的问题:
program main
use mpi
implicit none
integer, parameter :: rsp = selected_real_kind(16)
integer :: err
integer :: rank
real(rsp) :: real_var
call MPI_Init(err)
call MPI_Comm_rank(MPI_COMM_WORLD,rank,err)
if (rank.eq.0) then
real_var = 1.123456789012345
call MPI_Send(real_var,1,MPI_DOUBLE_PRECISION,1,5,MPI_COMM_WORLD,err)
else
call MPI_Recv(real_var,1,MPI_DOUBLE_PRECISION,0,5,MPI_COMM_WORLD,&
MPI_STATUS_IGNORE,err)
end if
print …Run Code Online (Sandbox Code Playgroud) 我编译了一个Fortran代码,其中包含几个模块,使用gfortran 4.4和intel 11.1,然后尝试使用gdb和DDT进行调试.在所有情况下,我都看不到模块中声明的任何变量的值.这些全局变量具有值,因为代码仍然正确运行,但我无法看到调试器中的值是什么.局部变量很好.我在网上其他地方找不到解决这个问题的方法很困难,所以也许没有直接的解决方案,但如果我看不到任何全局变量的值,那么调试我的代码真的很困难.
我正在努力优化用Fortran编写的流体流动和传热分析程序.当我尝试运行越来越大的网格模拟时,我遇到了内存限制问题.但是,网格并不是那么大.只有500,000个单元和小花生才能运行典型的CFD代码.即使我为我的问题请求80 GB的内存,它也会因虚拟内存不足而崩溃.
我猜测阵列正在占用所有内存.特别是一个被分配给(28801,345600).如果我在计算中错了,请纠正我,但双精度数组是每个值8位.那么这个数组的大小是28801*345600*8 = 79.6 GB?
现在,我认为大多数这个数组在整个计算过程中最终都是零,所以我们不需要存储它们.我想我可以改变解决方案算法,只存储非零值,以便在更小的数组中工作.但是,我想确定我正在查看正确的数组以减小尺寸.首先,我是否正确计算了上面的数组大小?第二,有没有办法让Fortran在运行时显示MB或GB的数组大小?除了打印出大多数内存密集型数组外,我还有兴趣了解代码的内存需求在运行时是如何变化的.
据我所知,当从文件中读取数据时,Fortran将跳过以和星号(*)开头的行,假设它们是注释.好吧,我似乎在使用我创建的一个非常简单的程序实现此行为时遇到了问题.这是我简单的Fortran程序:
1 program test
2
3 integer dat1
4
5 open(unit=1,file="file.inp")
6
7 read(1,*) dat1
8
9
10 end program test
Run Code Online (Sandbox Code Playgroud)
这是"file.inp":
1 *Hello
2 1
Run Code Online (Sandbox Code Playgroud)
我建立了我的简单程序
gfortran -g -o test test.f90
Run Code Online (Sandbox Code Playgroud)
当我跑,我得到错误:
At line 7 of file test.f90 (unit = 1, file = 'file.inp')
Fortran runtime error: Bad integer for item 1 in list input
Run Code Online (Sandbox Code Playgroud)
当我删除注释行运行输入文件时,即:
1 1
Run Code Online (Sandbox Code Playgroud)
代码运行正常.因此Fortran正确解释该注释行似乎是一个问题.它必须是非常简单的东西,我在这里失踪,但我不能在谷歌上发现任何东西.
我与FORTRAN合作很多,但我从来没有正确的指令来编写源代码.我目前使用模块来存储全局变量,但我知道你也可以使用它们来存储子程序和函数.我使用的代码有很多子程序,因为它们非常庞大和复杂.所有功能和子程序都应该在模块中吗?如果是这样,为什么?
我正在尝试并行化我编写的脚本。每个过程都需要进行计算并将数据存储到数组的特定部分(列表列表)。每个进程都在计算和存储其数据,但是我无法弄清楚如何从非根进程到根进程获取数据,以便它可以将数据打印到文件中。我创建了一个脚本的最小工作示例,该脚本仅出于简化目的而设计为可在2个内核上运行:
from mpi4py import MPI
import pdb
import os
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
# Declare the array that will store all the temp results
temps = [[0 for x in xrange(5)] for x in xrange(4)]
# Loop over all directories
if rank==0:
counter = 0
for i in range(2):
for j in range(5):
temps[i][j] = counter
counter = counter + 1
else:
counter = 20
for i in range(2,4):
for j in range(5):
temps[i][j] = …Run Code Online (Sandbox Code Playgroud) 我发现由于数组大小不匹配而使用gcc v.4.4.6构建的代码无法运行,我感到非常惊讶.使用gcc v.4.7.3构建时,它工作正常.我创建了一个最小的工作示例来显示问题的根源:
program main
implicit none
integer, allocatable, dimension(:,:) :: array_a
integer, allocatable, dimension(:,:) :: array_b
allocate(array_a(5,2))
allocate(array_b(2,1))
array_a = 1
array_b = array_a
print *, array_a
print *, array_b
end program main
Run Code Online (Sandbox Code Playgroud)
使用gcc v.4.4.6构建时,它会在运行时崩溃并出现错误:
在文件main.f90的第13行Fortran运行时错误:数组绑定不匹配,数组'array_b'的维度1的大小不匹配(1/4)
使用gcc v.4.7.3构建时,它会产生以下输出:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
注意,它会自动调整'array_b'的大小以匹配'array_a'的大小.这是我所看到的更新的Fortran标准提供的"功能"吗?
我有一个代码来计算一些导体中的热传递.在一个导体中发生的事情不会影响模型中的其他导体.所以我试图让这些导体的解决方案并行运行,每个处理器采用不同的导体组.现在,我认为代码可以在一个核心上运行,直到它到达我放置命令的循环:
MPI_INIT
Run Code Online (Sandbox Code Playgroud)
然后运行的代码.但是多核心我要求再回去的命令后一个内核上运行此部分:
MPI_FINALIZE
Run Code Online (Sandbox Code Playgroud)
遇到了.但我所看到的是输入文件由两个内核读入(如果我使用2个内核),并且所有输出也被打印两次.MPI不能像我想的那样工作吗?如果没有,那么我怎样才能实现我想要的行为呢?我只希望代码的一个段在多个内核上运行代码,而不是在MPI_INIT和MPI_FINALIZE之外的任何其他子例程或代码部分中运行.
我有一个Fortran程序,通过编写大量文本文件来输出模拟数据.文本文件将为网格单元的集合和导体网格单元集合的导体数据提供流体属性数据.所以类似下面的例子.
Cell Group 1
Axial Level | Pressure | Temperature | Velocity
1 | 150.1 | 198 | 3.5
2 | 150 | 200 | 3.5
... | ... | ... |
Cell Group 2
Axial Level | Pressure | Temperature | Velocity
1 | 150.1 | 201 | 3.5
2 | 150 | 205 | 3.5
... | ... | ... |
Conductor Group 1
Axial Level | Conductivity | Temperature
1 | 19.8 | 301
2 | 19.7 …Run Code Online (Sandbox Code Playgroud) 默认通信器的名称是MPI_COMM_WORLD.我希望它在我的程序中是mpicomm.如何将通信器设置为我想要的名称?
请注意,我的程序已经使用这个变量名称'mpicomm',但我从来没有告诉程序这应该是通信器的名称.我猜MPI_COMM_WORLD的值是0,所以当我运行程序时'mpicomm'.但我不希望这种情况因侥幸而起作用.
例如:
program main
use mpi
implicit none
integer :: mpierr, mpicomm, rank
call MPI_Init(mpierr)
call MPI_Comm_rank(mpicomm,rank,mpierr)
call MPI_Finalize(mpierr)
end program main
Run Code Online (Sandbox Code Playgroud)
这是有效的,并且排名达到了正确的值; 但是,如果MPI_COMM_WORLD恰好是除零之外的某些值,我认为这不会起作用.