我正在处理可多次调用子例程(依次执行迭代)的代码。我希望并行化子例程中的迭代。mpi的问题是只允许我初始化一次。因此,我无法在子例程中对其进行初始化,该子例程被多次调用。有人可以提出解决方案吗?
我的问题大致如下:
program p
...
do i=1,10000
call subroutine s(i)
end do
end program p
subroutine s(j)
...
do i=1,10000
...
end do
end subroutine s
Run Code Online (Sandbox Code Playgroud)
我希望将这一过程并行化。
非常感谢。有帮助!但是,让我重新思考一下问题:在主程序的迭代中,连同子例程s,我必须调用另一个子例程s2(不需要并行化)。我以为可以这样做:
!initialize mpi
do i=1:1000
if rank!=0
call s
else call s2
end if
end do
!finalize mpi
Run Code Online (Sandbox Code Playgroud)
但是这里的主要问题是,尽管其余进程缓慢进行,但进程0将快速进行。因此,是否有可能让进程0在每次迭代之后等待,直到另一个进程完成其迭代呢?
我是MPI和Fortran 77菜鸟.我有一个fortran 77代码FKRPRO.f,我想使用OpenMPI并行化.该代码需要大量参数,这些参数在运行时从单独的文件中输入.编译和运行就是这样的
gfortran -o FKRPRO FKRPRO.f
./FKRPRO < Modelfile.txt
Run Code Online (Sandbox Code Playgroud)
代码中的等价行(不是我的代码)是
PARAMETER(LIN=5)
INTEGER ERROR
LOGICAL PRNTA
PRNTA=.FALSE.
READ(LIN,'(L3)') PRNTA
READ(LIN,21) M1,M2
21 FORMAT(11I5)
Run Code Online (Sandbox Code Playgroud)
等等.有人可以向我解释一下是什么READ(LIN,'(L3)') PRNTA意思.输入文件Modelfile.txt中的输入是这样的
.F.
0 64
and so on..
Run Code Online (Sandbox Code Playgroud)
我在代码中放了必要的MPI语句.
INCLUDE 'MPIF.H'
...
CALL MPI_INIT(ERROR)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,NPROCS,ERROR)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,PRANK,ERROR)
...
CALL MPI_TYPE_FREE(NEWMATRIX,ERROR)
CALL MPI_FINALIZE(ERROR)
Run Code Online (Sandbox Code Playgroud)
所有进程都无法读取输入文件.我编译并运行这样的代码
mpif77 -o bc3 FKRPROG5.f
mpirun -np 4 bc3 < Modelfile.txt
Run Code Online (Sandbox Code Playgroud)
这不起作用.我收到以下错误.只有第一个进程或等级0才能读取该文件.
At line 50 of file FKRPROG5.f (unit = 5, file = 'stdin')
Fortran runtime error: End of file …Run Code Online (Sandbox Code Playgroud) 在使用gfortran(mpif90)编译Fortran程序时,遇到以下错误:
Error: Cannot assign to INTENT (IN) variable 'x' at (1)
make[2]: [module.o] Error 1 (ignored)
Run Code Online (Sandbox Code Playgroud)
当我用PGI编译这个程序时,我没有收到这个错误.
我有两个问题.
任何建议,将不胜感激.
使用-g命令编译的任何程序是否都有可供gbd列出的源代码,即使源代码文件不可用?另外,当您在具有复杂多源文件结构的程序中的某一行设置断点时,您是否需要源代码文件的名称?
我需要帮助我的朋友.这是一项简单的任务.我需要在数组中找到一个最小的元素.
program TEST
! your code goes here
integer a(5), n, min
a = (/2, -5, 3, 5, 8/)
n = 5
min = a(1)
!reading from keyboard
!do i=1,n
!read*,a(i)
!end do
print*, 'array:'
do i=1,n
print*,a(i)
end do
!print*, '???????, ????? ????????????:'
do i=2,n
if (min .lt. a(i)) then
min = a(i)
!print*, min, a(i), ' '
end if
end do
print*, 'minimal: '
print*, min
stop
end
Run Code Online (Sandbox Code Playgroud)
所以.我根本没有alghoritm的问题.我很容易用任何其他语言来做))但不存在.问题时,我比较会出现min和a(i).
程序一直认为min < a(i).为什么?那 …
任何人都可以在Fortran中找出这些行的错误:
if (i==1) then
u(i,j+1)=u(i,j)-c*dt/2/dx*(u(i+1,j)-u(imax-1,j)) &
+ (c*c*dt*dt)/2/dx/dx*(u(i+1,j)-2*u(i,j)+u(imax-1,j))
Run Code Online (Sandbox Code Playgroud)
这里有更多代码:
select case (case_no)
C.. 1--Lax Wendroff one step scheme
case (1)
write (6,*) 'Entrance for the Lax-Wendroff one step method'
t=dt
do while (t<=18)
do i=1,41
if (i==1) then
u(i,j+1)=u(i,j)-c*dt/2/dx*(u(i+1,j)-u(imax-1,j)) &
+ c*c*dt*dt/2/dx/dx*(u(i+1,j)-2*u(i,j) &
+ u(imax-1,j))
else if (i==41) then
u(i,j+1)=u(i,j)-c*dt/2/dx*(u(i+1,j)-u(i-1,2)) &
+ c*c*dt*dt/2/dx/dx*(u(i+1,j)-2*u(i,j) &
+ u(i-1,2))
else
u(i,j+1)=u(i,j)-c*dt/2/dx*(u(i+1,j)-u(i-1,j)) &
+ c*c*dt*dt/2/dx/dx*(u(i+1,j)-2*u(i,j) &
+u(i-1,j))
end if
j=j+1
t=t+dt
end do
end do
Run Code Online (Sandbox Code Playgroud)
等式太长了,我想用'&'将它分成两行.但编译器说1.在'u(i,j + 1)'处的可分类语句2.在'+'处的名称中的无效字符
我是Fortran的新手.非常感谢.
我在这里得到了一段代码,我似乎无法找到将这段代码转换为Fortran 95等效代码的有效方法.我已经尝试了好几件事,但我总是坚持用矩阵制作一维数组,反之亦然(重点是减少计算时间,如果我转换它们,我想不出另一种方法,而不是使用循环再次:/).
这是一段代码:
do i=1,dim
do j=1,dim
Snorm(i,j)=Sval(j)/Sval(i)
Bnorm(i,j)=Bval(j)/Bval(i)
Pnorm(i,j)=Pval(j)/Pval(i)
enddo
enddo
Run Code Online (Sandbox Code Playgroud)
你会如何在Fortran95代码中编写它?
R中矩阵计算的等价物如下:
Snorm <- t(Sval %*% t(1/Sval))
Bnorm <- t(Bval %*% t(1/Bval))
Pnorm <- t(Pval %*% t(1/Pval))
Run Code Online (Sandbox Code Playgroud)
Python中的等价物是这样的:
Snorm = (numpy.dot((Svalmat.T),(1/Svalmat))).T
Bnorm = (numpy.dot((Bvalmat.T),(1/Bvalmat))).T
Pnorm = (numpy.dot((Pvalmat.T),(1/Pvalmat))).T
with Svalmat etc the equivalent of Sval, but then columnmatrix
Run Code Online (Sandbox Code Playgroud)
有人有想法吗?
所以我已经构建了我的程序但是我一遍又一遍地说同样的错误:
benchmark.f90(17): error #6451: A dummy argument name is required in this context. [N]
INTEGER, intent (in) :: N
------------------------^
benchmark.f90(18): error #6420: This array name is invalid in this context. [A]
REAL, intent (out), DIMENSION (N), allocatable :: a
--------------------------------------------------^
benchmark.f90(18): error #6646: ALLOCATABLE or POINTER attribute dictates a deferred-shape-array [A]
REAL, intent (out), DIMENSION (N), allocatable :: a
--------------------------------------------------^
benchmark.f90(17): error #6219: This variable, used in a specification expression, must be a dummy argument, a COMMON block object, …Run Code Online (Sandbox Code Playgroud) 具有可配置的工作精度的功能.
program vierkantsvergelijking
implicit none
integer, parameter :: dp = kind(0.d0)
integer, parameter :: sp = kind(0.0)
print *, algoritme1(-5771.,2.,dp)
contains
function algoritme1(b,c,wp) result( solution)
integer :: wp ! working precision
real(kind=wp) :: b,c,D
real(kind=wp), dimension(2) :: solution
D = sqrt((b/2)**2 - c)
solution(1) = -b/2 + D
solution(2) = -b/2 - D
end function algoritme1
end program
Run Code Online (Sandbox Code Playgroud)
我得到:错误:在(1)的参数'b'中键入不匹配; 将REAL(4)传递给UNKNOWN
为什么这不起作用,我怎样才能实现目标?
看一下gfortran随机数发生器播种的示例代码,我对这里的时间转换感到困惑:
call date_and_time(values=dt)
tms = (dt(1) - 1970) * 365_8 * 24 * 60 * 60 * 1000 &
+ dt(2) * 31_8 * 24 * 60 * 60 * 1000 &
+ dt(3) * 24 * 60 * 60 * 60 * 1000 &
+ dt(5) * 60 * 60 * 1000 &
+ dt(6) * 60 * 1000 + dt(7) * 1000 &
+ dt(8)
t = transfer(tms, t)
Run Code Online (Sandbox Code Playgroud)
我很好奇,为什么365和31有_8尾. …