【发布时间】:2016-12-19 20:45:12
【问题描述】:
- 我了解单个 MPI 作业会启动许多可以在多个节点上运行的进程。
- 如何使用 MPI_THREAD_MULTIPLE 在给定 MPI 进程内运行多个线程?
- 我找不到与该主题相关的足够信息。
【问题讨论】:
【问题讨论】:
假设您使用 OpenMP 运行多个线程 您将像不使用 MPI 一样编写 OpenMP 代码。 (此说法过于简化)
当 MPI 出现时,您需要考虑您的流程将如何通信。 MPI 不是向单个线程发送消息,而是向单个进程发送消息。因此,MPI 提供了四种与线程交互的模式。
MPI_THREAD_SINGLE:只提供一个线程MPI_THREAD_FUNNELED:可以提供很多线程,但是只有主线程可以进行MPI调用。主线程是调用 MPI_Init 的线程...MPI_THREAD_SERIALIZED:可以提供多个线程,但一次只能调用一个 MPI。MPI_THREAD_MULTIPE: 可以提供很多线程,而且都可以随时进行MPI调用。你需要在 MPI_Init 指定你想要的模式,它变成:
MPI_Init_thread(&argc, &argv, HERE_PUT_THE_MODE_YOU_NEED, PROVIDED_MODE)
前任:
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPE, &provided)
在提供的字段中,MPI_Init_thread 返回提供的模式。确保你有一个你的代码可以处理的模式。
另外,避免使用 MPI_Probe 和 MPI_IProbe,因为它们不是线程保存的。您应该使用 MPI_Mprobe 和 MPI_Improbe。
这是@ab2050 提出的一个简单的“hello world”示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#include "mpi.h"
int main(int argc, char *argv[]) {
int provided;
int rank;
MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided);
if (provided != MPI_THREAD_FUNNELED) {
fprintf(stderr, "Warning MPI did not provide MPI_THREAD_FUNNELED\n");
}
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#pragma omp parallel default(none), \
shared(rank), \
shared(ompi_mpi_comm_world), \
shared(ompi_mpi_int), \
shared(ompi_mpi_char)
{
printf("Hello from thread %d at rank %d parallel region\n",
omp_get_thread_num(), rank);
#pragma omp master
{
char helloWorld[12];
if (rank == 0) {
strcpy(helloWorld, "Hello World");
MPI_Send(helloWorld, 12, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
printf("Rank %d send: %s\n", rank, helloWorld);
}
else {
MPI_Recv(helloWorld, 12, MPI_CHAR, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Rank %d received: %s\n", rank, helloWorld);
}
}
}
MPI_Finalize();
return 0;
}
您必须在两个进程上运行此代码。因为选择了“MPI_THREAD_FUNNELED”,所以只有主线程进行 MPI 调用。
以下变量在 OpenMP 数据范围内指定 因为 gcc 版本 6.1.1 需要。像 4.8 这样的旧版本不需要声明它们。
ompi_mpi_comm_world
ompi_mpi_char
【讨论】: