如何在给定的MPI进程中运行多个线程?

时间:2016-08-12 18:51:35

标签: mpi slurm

  • 我理解单个MPI作业启动可以在多个节点上运行的许多进程。
  • 如何使用MPI_THREAD_MULTIPLE在给定的MPI进程内运行多个线程?
  • 我无法找到与该主题相关的足够信息。

1 个答案:

答案 0 :(得分:2)

假设您使用OpenMP运行多个线程 您将像编写MPI一样编写OpenMP代码。 (此声明已经过简化)

当MPI到来时,您需要考虑您的流程如何沟通。 MPI不会向单个线程发送消息,而是向单个进程发送消息。因此,MPI提供了四种与线程交互的模式。

  1. MPI_THREAD_SINGLE:仅提供一个帖子
  2. MPI_THREAD_FUNNELED:可以提供多个线程,但只有主线程可以进行MPI调用。主线程是调用MPI_Init ...
  3. 的线程
  4. MPI_THREAD_SERIALIZED:可以提供多个线程,但一次只能有一个线程。
  5. MPI_THREAD_MULTIPE:可以提供多个线程,所有线程都可以随时拨打MPI。
  6. 您需要在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