关于MPI并行循环的问题
嘿, 我有一个关于 fortran 中 openmpi 的简短问题:我有这样的代码:
I) definitions of vars & linear code, setting up some vars for later usage
II) a while loop which works like that in pseudocode:
nr=1
while(true)
{
filename='result'//nr//'.bin' (nr converted to string)
if(!file_exists(filename))
goto 100
// file exists... so do something with it
// calculations, read/write...
nr=nr+1
}
100 continue
III) some more linear code...
现在我想用 openmpi 进行并行计算。 I) 和 III) 中的线性代码应该只计算一次,而 while 循环应该在多个处理器上运行......如何最好地实现它? 我的问题是 while 循环如何工作:例如,当处理器 1 计算 result1.bin 时,如何直接告诉处理器 2 计算 result2.bin?如果有 30 个文件并且我使用
mpirun -n 10 my_program ,
它将如何工作? MPI 如何“知道”完成计算一个文件后,还有更多文件“等待”处理:一旦一个处理器结束处理一个文件,该处理器就应该直接开始处理队列中的下一个文件。
到目前为止谢谢!
#编辑:
#嘿,又是我...我也想尝试一下 OpenMP,所以我使用了一段代码来读取现有文件,然后循环它们(并处理它们):
nfiles = 0
do
write(filename,FMT='(A,I0,A)'), prefix, nfiles+1, suffix
inquire(file=trim(filename),exist=exists)
if (not(exists)) exit
nfiles = nfiles + 1
enddo
现在我尝试了以下代码:
call omp_set_num_threads(2)
!$OMP PARALLEL
!$OMP DO
do i=startnum, endnum
write(filename,FMT='(A,I0,A)'), prefix, i, suffix
...CODE DIRECTLY HERE TO PROCESS THE FILE...
enddo
!$OMP END DO
!$OMP END PARALLEL
但它总是给我这样的错误: “从与 Open MP DO 或 PARALLEL DO 指令关联的 DO 循环中分支出来是非法的。”
总是关于此类代码的代码行:
read (F_RESULT,*,ERR=1) variable
其中 F_RESULT 是文件句柄...它可能有什么问题? 变量是在循环块之外定义的,我已经尝试将 OpenMP 指令设置为,
private(variable)
以便每个线程都有自己的副本,但这没有成功! 到目前为止感谢您的帮助!
hey there,
I have a short question about openmpi in fortran: i have a code like this:
I) definitions of vars & linear code, setting up some vars for later usage
II) a while loop which works like that in pseudocode:
nr=1
while(true)
{
filename='result'//nr//'.bin' (nr converted to string)
if(!file_exists(filename))
goto 100
// file exists... so do something with it
// calculations, read/write...
nr=nr+1
}
100 continue
III) some more linear code...
Now I want to make this a parallel computation with openmpi. The linear code from I) and III) should only be computed once and the while-loops should be run on several processors... How to best realize it?
my problem is how the while-loop works: E.g. when processor 1 computes result1.bin, how to directly tell processor 2 to compute result2.bin? and how would it work if there are 30 files and I use
mpirun -n 10 my_program
? how does MPI "know" that after finishing computing one file, there are more files "waiting" to be processed: as soon as one processor has ended processing one file, THIS procesor should directly start over processing the next file in the queue..
thanks so far!
#
EDIT:
#
Hey there, it's me again... I wanted to give OpenMP a try too, so I used a chunk of your code which reads the existing files and afterwards loops them (and processes them):
nfiles = 0
do
write(filename,FMT='(A,I0,A)'), prefix, nfiles+1, suffix
inquire(file=trim(filename),exist=exists)
if (not(exists)) exit
nfiles = nfiles + 1
enddo
now I tried the following code:
call omp_set_num_threads(2)
!$OMP PARALLEL
!$OMP DO
do i=startnum, endnum
write(filename,FMT='(A,I0,A)'), prefix, i, suffix
...CODE DIRECTLY HERE TO PROCESS THE FILE...
enddo
!$OMP END DO
!$OMP END PARALLEL
But it gives me always errors like that:
"It is illegal to branch out of a DO loop associated with an Open MP DO or PARALLEL DO directive."
Always about the codelines with this sort of code:
read (F_RESULT,*,ERR=1) variable
Where F_RESULT is a filehandle...What could be wrong about it?
variable is defined outside of the loop block, and I already tried to set OpenMP directive to
private(variable)
so that each thread has his own copy, but that didn't work out!
Thanks so far for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
也许最明智的方法是让其中一个进程预先计算文件总数,广播该数据,然后让每个人执行“他们的”文件:
然后进行一个简单的测试:
更新添加补充的 OpenMP 问题:
因此,第一个循环是在文件并行处理开始之前计算文件数量的地方。文件的计数需要在文件并行处理之前完成,否则就不可能在处理器之间分配工作;在划分工作之前,您需要知道有多少个“工作单元”。 (这绝对不是唯一的方法,但它是最简单的)。
类似地,
OMP DO
循环需要相当结构化的循环 - 需要一个像do i=1,n
这样的简单循环,然后可以在线程之间轻松分解。n
不需要编译进去,增量甚至不需要是 1,但它必须是在循环实际执行之前可以确定的事情。因此,例如,由于某些外部原因(例如文件不存在),您无法退出循环。因此,您想要使用 OpenMP 执行相同的文件计数,然后离开仅此而已,但随后在处理循环中使用并行 do 构造。因此,在去掉 MPI 的内容后,您将得到如下所示的内容:
但其他一切都将是相同的。再说一次,如果您想“内联”处理文件(例如,不在 sburoutine 中),您可以将文件处理代码放在“call processfile()”行所在的位置。
Probably the most sensible way to do this is to have one of the processes count the total number of files beforehand, broadcast that, and then have everyone do "their" files:
And then a simple test:
Updated to add the supplementary OpenMP question:
So that first loop is where the number of files is calculated, before the parallel processing of the files starts. That counting of the files needs to be done before the parallel processing of files can happen, because otherwise it's not possible to divide up the work between the processors; you need to know how many "work units" there are going to be before partitioning the work. (This isn't absolutely the only way to do things, but it's the most straightforward).
Similarly,
OMP DO
loops require quite structured loops -- there needs to be a simple loop likedo i=1,n
that can then be easily broken up between threads.n
doesn't need to be compiled in, and the increment doesn't even need to be one, but it must be the sort of thing that can be known for sure before the loop is actually executed. So, for instance, you can't exit out of the loop because of some external cause (like the non-presence of a file.)So what you'd want to do with OpenMP is to do the same file counting, and leave that alone, but then in the processing loop, use a parallel do construct. So, after stripping out the MPI stuff, you'd have something that looks like:
but everything else would be the same. And again, if you want to process the files "inline" (eg, not in a sburoutine), you'd put the file-processing code in where the 'call processfile()' line is.