我有一个带有例程的 FORTRAN 代码:
SUBROUTINE READ_NC_VALS(NCID, RECID, VARNAME, VARDATA)
integer ncid, recid
character*(*) varname
real*8 vardata
dimension vardata(15,45,75)
etc.
Run Code Online (Sandbox Code Playgroud)
我想为这段代码添加一些灵活性,我想我会通过首先添加一个可选的标志参数来实现:
SUBROUTINE READ_NC_VALS(NCID, RECID, VARNAME, VARDATA, how_to_calculate)
! everything the same and then ...
logical, optional :: how_to_calculate
Run Code Online (Sandbox Code Playgroud)
现在,我什至没有使用“how_to_calculate”。我只是将其放入代码中进行测试。所以我顺利地编译了代码。然后我运行它,在子例程中出现错误。具体来说,稍后代码中的某些值会“神奇地”改变为没有该可选参数的值。新值对代码逻辑没有意义,因此它会礼貌地退出并显示错误消息。让我再次强调,此时我什至没有使用这个可选参数。然后,我高兴地回到源代码中调用此例程的所有位置,即使我的新参数是可选的,我也会在所有调用中为其添加值。当我这样做时,代码运行良好。那么这是什么一回事?子例程中仅存在未使用的可选参数如何会导致其他数据被损坏?为这个可选参数添加输入参数如何再次解决问题?顺便说一句,这是用 PGI 编译的。
有任何想法吗?谢谢。
顺便说一句,很抱歉没有提供更多代码。如果我这样做的话,我的老板可能会对我不太满意。规则不是我制定的;我只是在这里工作。
我编写了一个 MPI 例程来并行化矩阵向量乘法。速度的提升已经令人失望到不存在。我在网上找到了很多例程,我处理这个的方式与大多数例程相同。我没能找到很多关于真实机器上真实加速的数据。我正在处理我认为是一个中等规模的问题——一个大小从 100x100 到 1000x1000 的矩阵和从 2 到 64 个处理器的数量。我正在以大致方形的棋盘方式分解矩阵。任何人都可以指出我在这个问题大小和处理器数量范围内可以实际希望获得什么样的加速的任何数据?谢谢。
如何写(0>x<1)ie,在 FORTRAN 中 x 必须位于 0 和 1 之间。
(0 .GE. x .LE. 1)或者(x .GE. 0 And x .LE. 1)这是正确的吗?谢谢
很抱歉对 Fortran 90 和 f2py 都不熟悉。
我使用的是 Windows 64 位、Python 3.4 64 位、gfortran。Numpy 版本是 1.9.1,我在 gnu.py 中评论了“raise NotImplementedError("Only MS compiler supported with gfortran on win64")”,如以下链接所示:http ://scientificcomputingco.blogspot.com.au /2013/02/f2py-on-64bit-windows-python27.html
我在 fortran 中有一个模块,编写如下,带有模块范围变量dp:
! testf2py.f90
module testf2py
implicit none
private
public dp, i1
integer, parameter :: dp=kind(0.d0)
contains
real(dp) function i1(m)
real(dp), intent(in) :: m(3, 3)
i1 = m(1, 1) + m(2, 2) + m(3, 3)
return
end function i1
end module testf2py
Run Code Online (Sandbox Code Playgroud)
然后,如果我跑 f2py -c testf2py.f90 -m testf2py
它会报告错误,指出未声明 …
在 Fortran 中,可以为指针分配内存,或者不能:
real(kind=jp), target :: bt(100,100)
real(kind=jp), pointer :: pt(:,:)
Run Code Online (Sandbox Code Playgroud)
但是你可以为指针分配内存pt:
allocate(pt(100,100))
Run Code Online (Sandbox Code Playgroud)
我的问题是:利弊是什么?就我所见,为指针分配内存违背了指针的目的并占用了更多内存。当然,我对指针的了解是有限的,所以如果有人能向我解释这里发生了什么,我将不胜感激。
我正在使用混合 FORTRAN 77 和 Fortran 90 代码的模型,此外,我正在使用英特尔编译器编译代码。
我被这个小问题困住了。我想知道是否可以将 bash-shell 脚本的变量传递给 f90 代码?
我编写了一段科学代码,像往常一样,这归结为计算代数特征值方程中的系数:计算这些系数需要对多维数组进行积分,这会迅速大幅增加内存使用量。一旦计算出矩阵系数,原始的预积分多维数组就可以被释放,并由智能求解器接管,因此内存使用不再是大问题。正如您所看到的,存在瓶颈,在我的 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) 如何避免在子程序中重复声明具有常量值的变量?
例如:
program test
implicit none
integer :: n
integer :: time
print*, "enter n" ! this will be a constant value for the whole program
call Calcul(time)
print*, time
end program
subroutine Calcul(Time)
implicit none
integer :: time
! i don't want to declare the constant n again and again because some times the subroutines have a lot of variables.
time = n*2
end subroutine
Run Code Online (Sandbox Code Playgroud)
有时,有很多由用户定义的常量,我会制作很多使用这些常量的子例程,所以我想存储它们并使用它们,而不是一次又一次地重新定义它们。
我正在将旧的 Fortran 代码库转换/重写为现代代码库。代码库的其中一段使用 Fourn 子程序(来自 Numerical receipies book)用于 FFT 目的。但是当我试图用 FFTW 库做那件事时,它不会产生相同的结果。我在这里很困惑。您可以在此处找到输入数据的代码: https //github.com/Koushikphy/fft_test/tree/master/notworking
使用的代码fourn:
program test
implicit none
integer, parameter :: n=65536
complex(kind=8) ::inp(n) = 0.0d0
real(kind=8) :: sn, urt(2*n)
integer :: i, ii
sn = 1.0d0/sqrt(real(n,kind=8))
do i=1,9070
read(75,'(i4, 2f20.16)') ii, inp(i)
enddo
do i=1,n
urt(2*i-1)= real(inp(i))
urt(2*i) = aimag(inp(i))
enddo
! forward
call fourn(urt,[n],1,1)
do i=1,n
write(201,'(i4, 2f20.16)')i, urt(2*i-1), urt(2*i)
enddo
end program test
SUBROUTINE FOURN(DATA,NN,NDIM,ISIGN)
INTEGER ISIGN,NDIM,NN(NDIM)
! C REAL DATA(*)
DOUBLE PRECISION DATA(*) …Run Code Online (Sandbox Code Playgroud) PROGRAM MPI
IMPLICIT NONE
INTEGER, PARAMETER :: nn=100
DOUBLE PRECISION h, L
DOUBLE PRECISION, DIMENSION (2*nn) :: y, ynew
DOUBLE PRECISION, DIMENSION (nn) :: qnew,vnew
DOUBLE PRECISION, DIMENSION (2*nn) :: k1,k2,k3,k4
INTEGER j, k
INTEGER i
INTEGER n
n=100 !particles
L=2.0d0
h=1.0d0/n
y(1)=1.0d0
DO k=1,2*n ! time loop
CALL RHS(y,k1)
CALL RHS(y+(h/2.0d0)*k1,k2)
CALL RHS(y+(h/2.0d0)*k2,k3)
CALL RHS(y+h*k3,k4)
ynew(1:2*n)=y(1:2*n) + (k1 + 2.0d0*(k2 + k3) + k4)*h/6.0d0
END DO
qnew(1:n)=ynew(1:n)
vnew(1:n)=ynew(n+1:2*n)
DO i=1,n
IF (qnew(i).GT. L) THEN
qnew(i) = qnew(i) - L …Run Code Online (Sandbox Code Playgroud)