我有一个使用Fotran 2003编写的Fortran程序并使用编译
英特尔(R)Fortran编译器XE,适用于在IA-32,版本12.1.2.273 Build 20111128上运行的应用程序
在长时间运行我的程序之后(这是一个物理计算)我读完了:
没有足够的内存来分配Fortran RTL消息缓冲区,消息
我猜想它与我的程序中的内存泄漏有关我如何找出泄漏发生的位置以及如何解决?
我手边有以下程序
program foo
type bar
real, dimension(2) :: vector
end type
type(bar), dimension(3) :: bararray
call doSomething(bararray%vector)
end program
subroutine doSomething(v)
real, dimension(3,2), intent(inout) :: v
...
end subroutine
Run Code Online (Sandbox Code Playgroud)
现在这给了我一个编译错误.
Error: Two or more part references with nonzero rank must not be specified at (1)
Run Code Online (Sandbox Code Playgroud)
如果我将呼叫更改为
call doSomething((/bararray%vector(1), bararray%vector(2)/))
Run Code Online (Sandbox Code Playgroud)
一切顺利.问题是,这似乎有点麻烦,所以问题是,是否还有其他方法来编写子程序的参数?
提前致谢.
我有一些Fortran代码,我正在与MPI并行化,这正在做着真正奇怪的事情.首先,我有一个变量nstartg,我从老板流程向所有工人广播:
call mpi_bcast(nstartg,1,mpi_integer,0,mpi_comm_world,ierr)
Run Code Online (Sandbox Code Playgroud)
该程序中的变量nstartg永远不会再次更改.后来,我让老板进程向工人发送eproc一个数组元素edge:
if (me==0) then
do n=1,ntasks-1
(determine the starting point estart and the number eproc
of values to send)
call mpi_send(edge(estart),eproc,mpi_integer,n,n,mpi_comm_world,ierr)
enddo
endif
Run Code Online (Sandbox Code Playgroud)
如果me非零,则匹配的receive语句.(为了便于阅读,我遗漏了一些其他代码;我有一个很好的理由不使用scatterv.)
事情变得奇怪:变量nstartg被改变n而不是保持其实际值.例如,在进程1上,在mpi_recv之后nstartg = 1,在进程2上它等于2,依此类推.此外,如果我将上面的代码更改为
call mpi_send(edge(estart),eproc,mpi_integer,n,n+1234567,mpi_comm_world,ierr)
Run Code Online (Sandbox Code Playgroud)
并在匹配调用mpi_recv时相应地更改标记,然后在进程1,nstartg = 1234568; 在过程2,nstartg = 1234569等
到底是怎么回事?我改变的是mpi_send/recv用于识别消息的标签; 如果标签是唯一的,那么消息不会混淆,这不应该改变任何东西,但它改变了一个完全不相关的变量.
在老板的过程中,nstartg没有改变,所以我可以通过再次播放来解决这个问题,但这不是一个真正的解决方案.最后,我应该提一下,使用电栅编译和运行此代码并没有发现任何缓冲区溢出,也没有--fbounds-check向我抛出任何东西.
我正在使用Fortran对大量数据集进行计算,这些数据集被分成许多文件.文件名是:
maltoLyo12per-reimage-set1.traj
maltoLyo12per-reimage-set2.traj
maltoLyo12per-reimage-set3.traj
Run Code Online (Sandbox Code Playgroud)
我编写的代码用于计算如下:
fileLoop: do j = 31, 34
OPEN(unit=31,status='old',file=fileplace//'maltoLyo12per-reimage-set1.traj')
OPEN(unit=32,status='old',file=fileplace//'maltoLyo12per-reimage-set2.traj')
OPEN(unit=33,status='old',file=fileplace//'maltoLyo12per-reimage-set3.traj')
OPEN(unit=34,status='old',file=fileplace//'maltoLyo12per-reimage-set4.traj')
... operation....
close (j)
end do fileLoop
Run Code Online (Sandbox Code Playgroud)
在运行期间,我希望代码一次打开每个文件,并在完成计算后关闭它们.但是上面的代码将立即打开所有文件,并在完成计算后逐个关闭它们.
所以我试着改变代码,如下所示:
fileLoop: do j = 31, 34
OPEN(unit=j,status='old',file=fileplace//'maltoLyo12per-reimage-set1.traj')
close (j)
end do fileLoop
Run Code Online (Sandbox Code Playgroud)
但在这里我遇到了文件名的问题.每次循环运行时,文件名都不会因文件名中的短语"set1"而改变.我希望文件名中的数字更改为set1,set2,set3等,随后文件单元号为31,32,33,34等.
我正在使用一些遗留的FORTRAN代码.作者定义了一个名为REDUCE_VEC()的函数(不是子程序,而是一个重要的函数).它接受一维数组并返回一个标量实数*8.因此,如果您想"减少"矢量,则可以调用该函数
RV = REDUCE_VEC(V1)
Run Code Online (Sandbox Code Playgroud)
一切都很好.但偶尔,他的线条看起来像
CALL REDUCE_VEC(V2)
Run Code Online (Sandbox Code Playgroud)
那么,有两个问题:1)这第二种形式的电话有什么作用?(注意,没有办法返回数据.)2)这甚至不会在gfortran下编译,即使它与PGI一起编译,所以这甚至是合法的FORTRAN?
谢谢.
有一个文件有1000帧.每个帧包含不同数量的行.每行有两列整数.但是,我不知道每帧包含多少行.每个帧由一个空行分隔.我想读取这些值并将它们存储在一个数组中.但是,我无法分配数组大小,因为我不知道每帧有多少行.所以,我有两个问题:
1 2
2 1
3 2
2 8
4 5
4 17
2 10
Run Code Online (Sandbox Code Playgroud)
等等...
有什么建议?
在程序中有许多嵌套子程序Fortran 90,我想将这些嵌套级别打印到压缩长度与级别成比例的文件中(即嵌套子程序中打印的信息比调用子程序具有更高的缩进).将写入包括不同数据类型的其他信息(字符串,整数,...).
我想到了不同的方法(在这个例子中,lev是级别,只是在循环中构建,但在每个子例程中以其他方式更新):
Program adaptIndent
INTEGER :: lev
CHARACTER (LEN=*), PARAMETER :: fmt1 = '(I1,'': ''A)'
CHARACTER (LEN=*), PARAMETER :: fmt2 = '(I2,'': ''A)'
DO lev=1,10
CALL printindent1
!CALL printindent2
!CALL printindent3
ENDDO
CONTAINS
SUBROUTINE printindent1 !convert everything (incl. indent and lev) to CHAR
CHARACTER(LEN=lev) :: indent
CHARACTER(LEN=2) :: strlev
WRITE(indent, '(A)') ' '
WRITE(strlev, '(I2)') lev
WRITE(*, '(A)') indent//TRIM(ADJUSTL(strlev))//': this is my level'
END SUBROUTINE printindent1
SUBROUTINE printindent2 !build a new format defining the indentation …Run Code Online (Sandbox Code Playgroud) 在下面的代码中,我将865398.78和-865398.78加在一起.我希望得到0,但我得到-0.03.

源代码:
program main
real(8) :: x
open(10,file="test.txt")
read(10,*)x
print *,"x=",x
x=x+865398.78
print *,"x+865398.78=",x
end program
Run Code Online (Sandbox Code Playgroud)
结果:
x= -865398.780000000
x+865398.78= -3.000000002793968E-002
Run Code Online (Sandbox Code Playgroud)
我对"读取"代码或其他东西的使用有误吗?
如问题中所述:Fortran(90及更高版本)中的complex * 16自变量是否具有等效的DEXP?
我有一个简单的Fortran 95程序
include "sandboxlib.f95"
program sandbox
implicit none
write(*, *) 'abc'
end program
Run Code Online (Sandbox Code Playgroud)
以及一个包含函数的简单模块
module sandboxlib
integer, parameter :: dp = kind(1.d0)
contains
function cumsum(mat, m, n) result(c)
implicit none
real(dp), intent(in) :: mat
integer, intent(in) :: m, n
integer i, j
real(dp), dimension(m, n) :: c
c(:, 1) = 0.d0
do i = 2, m
do j = 1, n
c(i, j) = c(i-1, j) + mat(i, j)
end do
end do
end function
end module
Run Code Online (Sandbox Code Playgroud)
我sandbox.f95用这个命令编译 …
fortran ×10
fortran90 ×10
gfortran ×2
fortran77 ×1
fortran95 ×1
indentation ×1
memory-leaks ×1
mpi ×1