Parallel processing 如何指定哪些进程在并行程序的哪个节点上运行

Parallel processing 如何指定哪些进程在并行程序的哪个节点上运行,parallel-processing,mpi,Parallel Processing,Mpi,我正在Intel Sandy Bridge群集上的16节点分区上运行我的MPI程序。每个节点有两个处理器,每个处理器有8个内核。我用“mpirun-n256./myprogram”开始了一次跑步。现在,我需要在每个节点上有一个代表性的进程来报告该节点的两个处理器所消耗的功率(使用RAPL)。我的问题是如何选择这个过程。例如,如果保证将进程分配给节点,如1-16、17-32、33-48等,那么我可以检查进程的MPI等级,并决定它是否应该报告功率。numactl可以用于跨多个节点绑定大量进程吗 MP

我正在Intel Sandy Bridge群集上的16节点分区上运行我的MPI程序。每个节点有两个处理器,每个处理器有8个内核。我用“mpirun-n256./myprogram”开始了一次跑步。现在,我需要在每个节点上有一个代表性的进程来报告该节点的两个处理器所消耗的功率(使用RAPL)。我的问题是如何选择这个过程。例如,如果保证将进程分配给节点,如1-16、17-32、33-48等,那么我可以检查进程的MPI等级,并决定它是否应该报告功率。numactl可以用于跨多个节点绑定大量进程吗

MPI标准未涵盖(AFAIK)在特定节点上放置特定列组的问题。但是,每个实现和/或机器都可以/可能提出此功能。例如,可以通过MPI启动器的选项(
mpirun
mpiexec
srun
prun
ortrun
,[add here your preferred MPI launcher],…)或通过批处理计划程序(如果适用)实现。因此,为了获得这些特定信息,我建议您参考MPI库文档、批处理调度器文档或机器文档

但是,您想要的功能独立于实际的MPI进程放置。无论进程如何放置在计算节点上,您都可以非常轻松地实现它。这可以通过以下方式实现:

mpirun -ppn 2 numa_bind.sh my_mpi_binary [my_mpi_binary options]
  • 通过
    MPI\u Get\u processor\u name()
    gethostname()
    或您认为合适的任何其他方式查询当前进程运行的节点的名称
    MPI\u Get\u processor\u name()
    作为MPI标准,出于可移植性的原因,我建议使用它
  • 通过
    MPI\u Allgather()
    收集每个进程的值,以了解彼此的节点名称
  • 对于在每个节点上运行的最小秩进程,请执行报告功率测量所需的任何操作
  • 这可能是这样的:

    #include <mpi.h>
    #include <iostream>
    #include <cstring>
    
    bool amIFirstOnNode() {
        int rank, size;
        MPI_Comm_rank( MPI_COMM_WORLD, &rank );
        MPI_Comm_size( MPI_COMM_WORLD, &size );
        char names[size][MPI_MAX_PROCESSOR_NAME];
        int len;
        MPI_Get_processor_name( names[rank], &len );
        MPI_Allgather( MPI_IN_PLACE, 0, 0, names[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, MPI_COMM_WORLD );
        int lower = 0;
        while ( std::strncmp( names[rank], names[lower], MPI_MAX_PROCESSOR_NAME ) != 0 ) {
            lower++;
        }
        return lower == rank;
    }
    
    int main( int argc, char *argv[] ) {
    
        MPI_Init( &argc, &argv );
        int rank;
        MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    
        bool nodeMaster = amIFirstOnNode();
        if ( nodeMaster ) {
            std::cout << "[" << rank << "] master process on the node\n";
        }
        else {
            std::cout << "[" << rank << "] not master process on the node\n";
        }
        MPI_Finalize();
    
        return 0;
    }
    
    这就是所谓的:

    mpirun -ppn 2 numa_bind.sh my_mpi_binary [my_mpi_binary options]
    

    但是,当然,这假设您的环境将
    PMI\u ID
    或等效的…

    如果您使用MPI 3.x实现,您可以使用
    MPI\u Comm\u split\u type
    [1]和
    MPI\u Comm\u type\u SHARED
    作为
    split\u type
    参数。这会将通信器(在您的情况下,当然是
    MPI\u COMM\u WORLD
    )拆分为子通信器,这些子通信器正是集群的共享内存区域。然后,每个子通信器都有一个本地根,它可以是您的代表进程


    [1] 第247-248页,MPI:消息传递接口标准(版本3.0或3.1)

    Nice标准。我不知道,但很高兴你提到了。谢谢你提供的信息。我发现我们还没有MPI3.x。但是拥有这个功能真的很有用。不客气。因此,在您的情况下,我知道的唯一其他解决方案是使用@Gilles所述的
    MPI\u Get\u processor\u name()
    。非常感谢您的详细回复。这对我有用。