如何在给定的 MPI 进程中 运行 多个线程?
How can I run multiple threads inside of a given MPI process?
- 我了解单个 MPI 作业会启动多个进程,这些进程可能 运行 在多个节点上。
- 如何使用 MPI_THREAD_MULTIPLE 在给定的 MPI 进程中 运行 多个线程?
- 我找不到与该主题相关的足够信息。
假设您使用 OpenMP 运行 多线程
您将像使用 MPI 一样编写 OpenMP 代码。 (这个说法过于简化了)
当 MPI 出现时,您需要考虑您的进程将如何通信。 MPI 不是向单个线程发送消息,而是向单个进程发送消息。出于这个原因,MPI 提供了四种与线程交互的模式。
MPI_THREAD_SINGLE
: 只提供一个线程
MPI_THREAD_FUNNELED
:可以提供很多线程,但是只有主线程可以进行MPI调用。主线程是调用 MPI_Init... 的线程
MPI_THREAD_SERIALIZED
: 可以提供多个线程,但一次只能调用一个线程。
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 returns 提供的模式。确保你有一个模式,你的代码可以处理它。
另外,避免使用MPI_Probe和MPI_IProbe,因为它们不是线程保存的。您应该使用 MPI_Mprobe 和 MPI_Improbe。
这是一个简单的 'hello world' 示例,@ab2050 问:
#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
- 我了解单个 MPI 作业会启动多个进程,这些进程可能 运行 在多个节点上。
- 如何使用 MPI_THREAD_MULTIPLE 在给定的 MPI 进程中 运行 多个线程?
- 我找不到与该主题相关的足够信息。
假设您使用 OpenMP 运行 多线程 您将像使用 MPI 一样编写 OpenMP 代码。 (这个说法过于简化了)
当 MPI 出现时,您需要考虑您的进程将如何通信。 MPI 不是向单个线程发送消息,而是向单个进程发送消息。出于这个原因,MPI 提供了四种与线程交互的模式。
MPI_THREAD_SINGLE
: 只提供一个线程MPI_THREAD_FUNNELED
:可以提供很多线程,但是只有主线程可以进行MPI调用。主线程是调用 MPI_Init... 的线程
MPI_THREAD_SERIALIZED
: 可以提供多个线程,但一次只能调用一个线程。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 returns 提供的模式。确保你有一个模式,你的代码可以处理它。
另外,避免使用MPI_Probe和MPI_IProbe,因为它们不是线程保存的。您应该使用 MPI_Mprobe 和 MPI_Improbe。
这是一个简单的 'hello world' 示例,@ab2050 问:
#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