【问题标题】:How can I run multiple threads inside of a given MPI process?如何在给定的 MPI 进程中运行多个线程?
【发布时间】:2016-12-19 20:45:12
【问题描述】:
  • 我了解单个 MPI 作业会启动许多可以在多个节点上运行的进程。
  • 如何使用 MPI_THREAD_MULTIPLE 在给定 MPI 进程内运行多个线程?
  • 我找不到与该主题相关的足够信息。

【问题讨论】:

    标签: mpi slurm


    【解决方案1】:

    假设您使用 OpenMP 运行多个线程 您将像不使用 MPI 一样编写 OpenMP 代码。 (此说法过于简化)

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

    1. MPI_THREAD_SINGLE:只提供一个线程
    2. MPI_THREAD_FUNNELED:可以提供很多线程,但是只有主线程可以进行MPI调用。主线程是调用 MPI_Init 的线程...
    3. MPI_THREAD_SERIALIZED:可以提供多个线程,但一次只能调用一个 MPI。
    4. 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
    

    【讨论】:

    • 你有示例代码 sn-ps 可以用来指导我的开发过程吗?
    • 你的意思是像“hello world”程序吗?
    猜你喜欢
    • 2013-06-22
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    相关资源
    最近更新 更多