c++高性能:多进程 mpi 笔记

install

  • wget https://www.mpich.org/static/downloads/4.1/mpich-4.1.tar.gz from https://www.mpich.org/static/downloads
  • tar -zxvf mpich-4.1.tar.gz
  • cd mpich-4.1/
(base) :~/MPI/mpich-4.1$ ls
aclocal.m4  CHANGES  config.log  config.status  configure     contrib       COPYRIGHT  examples  libtool  Makefile     Makefile.in  modules        mpich-doxygen.in  README.envvar  src                test
autogen.sh  confdb   config.lt   config.system  configure.ac  CONTRIBUTING  doc        lib       maint    Makefile.am  man          mpich-doxygen  README            RELEASE_NOTES  subsys_include.m4  www
  • ./configure --prefix=/usr/local/mpich-4.1 设置安装路径

  • make j4

  • sudo make install

  • vim ~/.bashrc

  • export PATH="/usr/local/mpich-4.1/bin:$PATH"

  • source ~/.bashrc

  • which mpicc , whereis mpif90

use

在这里插入图片描述

//cmake_minimum_required(VERSION 3.15)
//
//#set(CMAKE_CXX_STANDARD 11)
//
//find_package(MPI REQUIRED)
//include_directories(${MPI_INCLUDE_PATH})
//SET(CMAKE_CXX_COMPILER mpicxx)
//SET(CMAKE_C_COMPILER  mpicc)
//
//add_executable(hello main.cpp)

#include <stdio.h>
#include "mpi.h"

int main(int argc, char *argv[])
{
    int rank;
    int size;

    MPI_Init(0,0);//    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    printf("Hello world from process %d of %d\n", rank, size);
    MPI_Finalize();
    return 0;
}

run result

在这里插入图片描述在这里插入图片描述

1.clion setting(not working in my env)

  • /usr/local/mpich-4.1/bin/mpirun

  • but output only this :Hello world from process 0 of 1

[Clion 可以编译调用 MPI 并行库的项目么?
在 Ubuntu 上尝试用 cmake 和 Clion 编译一个项目,需要调用 MPI 并行计算。
也就是编译时候编译器使用 mpicc,程序运行参数为 mpirun -n 4 ./XXX 形式。
可以通过直接修改 cmake 实现么?](https://www.zhihu.com/question/40910086?utm_id=0)

clion 运行 MPI
https://blog.csdn.net/qq_34149581/article/details/88359766
Clion运行MPI程序还是很简单的,主要问题还是调试,MPI程序一直很难调试。上面的方案只能写代码+运行,目前调试还做不到。

2. run in terminal

cmake-build-debug  CMakeLists.txt  hellow  main.cpp
  • ~/MPI/hello$ ./hellow
Hello world from process 0 of 1
  • ~/MPI/hello$ mpirun -np 4 ./hellow
Hello world from process 0 of 4
Hello world from process 1 of 4
Hello world from process 3 of 4
Hello world from process 2 of 4

commuation

#include <stdio.h>
#include "mpi.h"
#include <cstring>

int main(int argc, char *argv[])
{
    int m_rank;
    int m_size;

    MPI_Init(0,0);
    MPI_Comm_rank(MPI_COMM_WORLD, &m_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &m_size);
    //printf("Hello world from process %d of %d\n", m_rank, m_size);

    char greeting[10]="hello,wor";
    if (m_size > 1)
    {
        if (m_rank == 0)
        {
            /* 从0进程向其他进程发送数据 */
            for (int rank = 1; rank < m_size; rank++)
            {
                //printf(greeting, "Greeting from process %d to %d of %d", m_rank, rank, m_size);
                printf("%d",100);
                //sleep(1);

                MPI_Send(greeting, strlen(greeting)+1, MPI_CHAR, rank, 0, MPI_COMM_WORLD);
            }
        }
        else
        {
            /* 其他进程从0进程接收数据 */
            MPI_Recv(greeting, 10, MPI_CHAR, 0, 0, MPI_COMM_WORLD, MPI_STATUSES_IGNORE);
        }
    }

    MPI_Finalize();
    return 0;
}// https://zhuanlan.zhihu.com/p/455102835

定积分 π \pi π

#include "mpi.h"
#include <stdio.h>
double f(double);
double f(double x)
{
    return (4.0/(1.0+x*x));
}
int main(int argc,char *argv[])
{
    int myid, numprocs;
    int n, i;
    double mypi, pi;
    double h, sum, x;
    MPI_Init(&argc,&argv); //todo begin   必要定义
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);// 获得总进程数
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);// 获得进程号
    printf("Process %d of %d.\n", myid, numprocs);
    n = 100;
    h = 1.0 / (double) n;
    sum = 0.0;
    for (i = myid + 1; i <= n; i += numprocs)
    {
        x = h * ((double)i - 0.5);
        sum +=f(x);
    }
    mypi = h * sum;
    // 我们可以选择使用上一章提到的MPI_SEND和MPI_RECV函数,但这在实现起来会很复杂。在这里,我们可以考虑使用规约操作。
    // 该函数可以理解为在通信域MPI_COMM_WORLD中,将各个进程的MPI_DOUBLE型变量起始地址为&mypi长度为1发送到缓冲区,并执行MPI_SUM操作,
    // 将结果返回至0进程的&pi地址中。用直白的话讲就是将域内每一个进程的mypi相加求和,并将所得的结果存入0进程中的pi变量。规约函数中有很多操作,比如求和、求积、取最大值、取最小值等等,具体可以查阅手册,这一函数会使得我们的并行程序编写变得很方便。
    MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);// 规约操作
    if (myid == 0)
    {
        printf("The result is %.10f.\n",pi);
    }
    MPI_Finalize();//todo end   必要定义
}

//mpicc -o hellow main.cpp
//mpirun -np 50 ./hellow
  • 规约操作

  • int MPI_Send(type* buf, int count, MPI_Datatype, int dest, int tag, MPI_Comm comm)

  • int MPI_Recv(type* buf, int count, MPI_Datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

参考与更多

点对点通信 , 群体通信

安卓Termux/Aid Learning搭建MPI分布式并行环境

Linux下MPI的安装与vscode的配置

how-do-i-debug-an-mpi-program

猜你喜欢

转载自blog.csdn.net/ResumeProject/article/details/129281726
mpi
今日推荐