我能够在桌面/笔记本电脑上的OpenMP中做简单的循环(简单地简化了我实际拥有的......)
#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
%%%% #include other libraries...
int main(void){
.
.
.
%%% declare and initialize variables.
.
.
.
#pragma omp parallel for collapse(3) shared(tf, p, Fx, Fy, Fz) private(v, i,j,k,t0)
for (i = 0; i < Nx; i++){
for (j = 0; j < Ny; j++){
for (k = 0; k < Nz; k++){
v[0] = Fx[i][j][k];
v[1] = Fy[i][j][k];
v[2] = Fz[i][j][k];
///My_fn changes v and then I put it back into Fx, Fy, Fz
My_fn(v, t0, tf, p);
Fx[i][j][k] = v[0];
Fy[i][j][k] = v[1];
Fz[i][j][k] = v[2];
}
}
}
}
如果我愿意,我甚至可以指定在我的笔记本电脑上使用n_threasds = 1,2,3或4个核心,将omp_set_num_threads(n_threads);
添加到顶部,我注意到我想要的性能。但是,在使用群集时,我会对该行进行评论。
我可以访问群集,并希望在单个节点上运行代码 ,因为群集中的节点最多包含48个核心,而我的笔记本电脑只有4个。当我使用群集时,编译,我输入终端
$export OMP_NUM_THREADS=10
$bsub -n 10 ./a.out
但程序运行不正常:我输出到一个文件中,看到它花了0秒钟才能运行,而Fx,Fy和Fz的值就是它们启动它们时的值,所以看起来循环是甚至根本没有跑。
编辑:此问题由管理群集的人员解决,可能非常特定于该群集,因此我提醒人们将问题与他们的具体案例联系起来。
答案 0 :(得分:2)
在我看来,这个问题与编程无关,而是在群集上使用批处理系统(a.k.a.分布式资源管理器)。通常的做法是在脚本集OMP_NUM_THREADS
内编写一个脚本到授予的插槽数。您的批处理系统似乎是LSF(根据bsub
的存在而疯狂猜测),那么您通常希望脚本中有类似内容(让我们称之为job.sh
):
#BSUB -n 10
export OMP_NUM_THREADS=$LSB_DJOB_NUMPROC
./a.out
然后使用bsub < job.sh
提交脚本。 LSF导出LSB_DJOB_NUMPROC
环境变量中授予作业的插槽数。通过执行分配,您可以使用不同的参数提交相同的作业文件,例如:bsub -n 20 < job.sh
。您可能需要向调度程序提示您希望在同一节点上拥有所有插槽的提示。通常可以通过指定-R "span[ptile=n]"
来做到这一点。可能还有其他方法可以做到这一点,例如您可能需要指定的esub
可执行文件:
#BSUB -a openmp
请注意,Stack Overflow不是管理员存储群集文档的地方。你最好问他们,而不是我们。
答案 1 :(得分:1)
我不确定我是否正确理解您的要求,但我担心您的想法是OpenMP会自动在群集上以分布式方式运行您的应用程序。
OpenMP不适用于此类任务,它假设您在共享内存设置中运行代码。对于分布式设置(仅通过网络链路连接的处理器),还有其他工具,即MPI。但是这样的设置设置比使用openMP时习惯的#pragma
注释要复杂一些。
答案 2 :(得分:1)
Hristo是对的,但我认为你应该添加
#BSUB -R "span[hosts=1]" # run on a single node
<。>在.sh文件中。 ptile选项仅用于指定每个节点的任务数
,见即
https://doc.zih.tu-dresden.de/hpc-wiki/bin/view/Compendium/PlatformLSF
否则,取决于群集的队列设置,您可能会使用
bqueues -l
任务将在每个节点上运行,您可以使用它。
答案 3 :(得分:0)
如果节点有24个核心
#PBS -l nodes=1:ppn=24
在我的系统中。可能在您使用的群集中就像
#BSUB -l nodes=1:ppn=24