答案 0 :(得分:2)
假设您使用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返回提供的模式。确保您有一个代码可以处理它的模式。
另外,请避免使用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;
}
您必须在两个进程上运行此代码。因为&#39; MPI_THREAD_FUNNELED&#39;只选择主线程进行MPI调用。
在OpenMP数据范围处指定以下变量 因为gcc版本6.1.1需要。像4.8这样的旧版本不需要声明它们。
ompi_mpi_comm_world
ompi_mpi_char