OpenMP和MPI混合程序

Ita*_*alo 9 mpi openmp

我有一台8处理器的机器.我想在我的代码上使用OpenMP和MPI替代,如下所示:

OpenMP阶段:

  • 排名1-7等待MPI_Barrier
  • rank 0使用OpenMP的所有8个处理器

MPI阶段:

  • 等级0达到障碍,所有等级各使用一个处理器

到目前为止,我已经完成了:

  • 设置I_MPI_WAIT_MODE 1,以便1-7级在屏障上不使用CPU.
  • 在等级0上设置omp_set_num_threads(8),以便它启动8个OpenMP线程.

这一切都奏效了.排名0确实启动了8个线程,但所有线程都限制在一个处理器上.在OpenMP阶段,我从一个处理器上运行的0级中获得8个线程,而所有其他处理器都处于空闲状态.

如何告诉MPI允许0级使用其他处理器?我正在使用英特尔MPI,但如果需要,可以切换到OpenMPI或MPICH.

Hri*_*iev 13

以下代码显示了有关如何在OpenMP部件之前保存CPU关联掩码的示例,将其更改为在并行区域的持续时间内允许所有CPU,然后还原以前的CPU关联掩码.代码是特定于Linux的,如果你没有通过MPI库启用进程固定而没有任何意义 - 通过传递或进入Open MPI 激活 ; 通过设置为Intel MPI 来禁用(4.x上的默认设置是引脚处理).--bind-to-core--bind-to-socketmpiexecI_MPI_PINdisable

#define _GNU_SOURCE

#include <sched.h>

...

cpu_set_t *oldmask, *mask;
size_t size;
int nrcpus = 256; // 256 cores should be more than enough
int i;

// Save the old affinity mask
oldmask = CPU_ALLOC(nrcpus);
size = CPU_ALLOC_SIZE(nrcpus);
CPU_ZERO_S(size, oldmask);
if (sched_getaffinity(0, size, oldmask) == -1) { error }

// Temporary allow running on all processors
mask = CPU_ALLOC(nrcpus);
for (i = 0; i < nrcpus; i++)
   CPU_SET_S(i, size, mask);
if (sched_setaffinity(0, size, mask) == -1) { error }

#pragma omp parallel
{
}

CPU_FREE(mask);

// Restore the saved affinity mask
if (sched_setaffinity(0, size, oldmask) == -1) { error }

CPU_FREE(oldmask);

...
Run Code Online (Sandbox Code Playgroud)

您还可以调整OpenMP运行时的固定参数.因为GCC/libgomp关联性由GOMP_CPU_AFFINITY环境变量控制,而对于英特尔编译器,它是KMP_AFFINITY.如果OpenMP运行时将提供的关联掩码与进程的关联掩码相交,则仍可以使用上面的代码.

仅为了完整性 - 在Windows上保存,设置和恢复关联掩码:

#include <windows.h>

...

HANDLE hCurrentProc, hDupCurrentProc;
DWORD_PTR dwpSysAffinityMask, dwpProcAffinityMask;

// Obtain a usable handle of the current process
hCurrentProc = GetCurrentProcess();
DuplicateHandle(hCurrentProc, hCurrentProc, hCurrentProc,
                &hDupCurrentProc, 0, FALSE, DUPLICATE_SAME_ACCESS);

// Get the old affinity mask
GetProcessAffinityMask(hDupCurrentProc,
                       &dwpProcAffinityMask, &dwpSysAffinityMask);

// Temporary allow running on all CPUs in the system affinity mask
SetProcessAffinityMask(hDupCurrentProc, &dwpSysAffinityMask);

#pragma omp parallel
{
}

// Restore the old affinity mask
SetProcessAffinityMask(hDupCurrentProc, &dwpProcAffinityMask);

CloseHandle(hDupCurrentProc);

...
Run Code Online (Sandbox Code Playgroud)

应该使用单个处理器组(最多64个逻辑处理器).


Ita*_*alo 0

感谢大家的评论和回答。你没事吧。这都是关于“PIN”选项的。

为了解决我的问题,我只需要:

I_MPI_WAIT_MODE=1

I_MPI_PIN_DOMAIN=omp

就那么简单。现在,所有处理器都可供所有等级使用。

选项

I_MPI_DEBUG=4

显示每个等级获得哪些处理器。