&引用;“你好,世界”;混合使用OpenMP和MPI的C程序

&引用;“你好,世界”;混合使用OpenMP和MPI的C程序,c,mpi,openmp,C,Mpi,Openmp,我正试图得到一个“hello world”程序,它同时使用OpenMP和MPI工作。我从这里的例子开始 但我不能复制输出。以下是我使用的确切来源: #include <stdio.h> #include <mpi.h> #include <omp.h> int main(int argc, char *argv[]) { int numprocs, rank, namelen; char processor_name[MPI_MAX_PROCESS

我正试图得到一个“hello world”程序,它同时使用OpenMP和MPI工作。我从这里的例子开始

但我不能复制输出。以下是我使用的确切来源:

#include <stdio.h>
#include <mpi.h>
#include <omp.h>

int main(int argc, char *argv[]) {
  int numprocs, rank, namelen;
  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int iam = 0, np = 1;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Get_processor_name(processor_name, &namelen);

  //omp_set_num_threads(4);

#pragma omp parallel default(shared) private(iam, np)
  {
    np = omp_get_num_threads();
    iam = omp_get_thread_num();
    printf("Hello from thread %d out of %d from process %d out of %d on %s\n",
           iam, np, rank, numprocs, processor_name);
  }

  MPI_Finalize();
}
然后使用

export OMP_NUM_THREADS=4
mpirun ./hello -np 2 -x OMP_NUM_THREADS
以下是我得到的输出:

Hello from thread 0 out of 4 from process 0 out of 1 on SteinbergT5600Linux
Hello from thread 2 out of 4 from process 0 out of 1 on SteinbergT5600Linux
Hello from thread 1 out of 4 from process 0 out of 1 on SteinbergT5600Linux
Hello from thread 3 out of 4 from process 0 out of 1 on SteinbergT5600Linux
根据这个例子,我应该得到这样的东西:

Hello from thread 0 out of 4 from process 0 out of 2 on SteinbergT5600Linux
Hello from thread 2 out of 4 from process 0 out of 2 on SteinbergT5600Linux
Hello from thread 1 out of 4 from process 0 out of 2 on SteinbergT5600Linux
Hello from thread 3 out of 4 from process 0 out of 2 on SteinbergT5600Linux
Hello from thread 0 out of 4 from process 1 out of 2 on SteinbergT5600Linux
Hello from thread 2 out of 4 from process 1 out of 2 on SteinbergT5600Linux
Hello from thread 1 out of 4 from process 1 out of 2 on SteinbergT5600Linux
Hello from thread 3 out of 4 from process 1 out of 2 on SteinbergT5600Linux

谁能告诉我我做错了什么?据我所知,我完全复制了上面链接中的示例。

您将程序名指定为
mpirun
的第一个参数,因此忽略了其余参数(尤其是:
-np2
)。因此,对于
-np
,您得到的是系统范围内的默认值

更改:

mpirun ./hello -np 2 -x OMP_NUM_THREADS
进入:



旁注:我在我的机器上测试了这个。这里
-np
的默认值是
3
。在您的计算机上,默认值似乎是
1

,您需要使用MPI_Init_线程和MPI_线程,以便使用MPI和线程。哦,就是这样。。。我真傻!我应该注意到,这在没有使用Jeff的建议的情况下是有效的。但是,当我使用这两种建议时,输出略有不同。使用具有正确参数顺序的原始源代码,第一个进程上的所有四个线程总是在第二个进程的任何线程之前显示其输出。使用MPI_Init_线程而不是MPI_Init,来自不同进程线程的打印输出被分散。这表明当我只使用MPI_Init时,MPI进程可能不会并行运行。所以这似乎是必须的。所有的bug一旦被诊断和修复,都是“哑”的;-)MPI_Init_线程提供了更多的通用性/灵活性。MPI_THREAD_*的选择在某种程度上与您想要的拓扑结构有关。因为您也在使用openmp,这可能会产生影响。(例如)如果没有openmp,您可能会使用MPI_线程。但是,使用openmp,您可能更喜欢MPI\u线程\u漏斗。首先考虑你的需要。然后扭曲调用以适合它们。我通常创建一个脚本[带有基准测试],它可以概括所有可能的组合,然后根据结果分析选择最终配置。
mpirun ./hello -np 2 -x OMP_NUM_THREADS
mpirun -np 2 -x OMP_NUM_THREADS ./hello