zoukankan      html  css  js  c++  java
  • 学习MPI

     

     

    1. MPI_Reduce函数

    int MPI_Reduce(void *sendBuf, void *receiveBuf, int count, MPI_Datatype dataType, 

                                   MPI_Op operator, int root, MPI_Comm comm)

    每个进程从sendBuf向root进程的receiveBuf发数据,通过opration函数(例如MPI_SUM)来汇总数据。 

    2. 图型示例

    3. 举例

     

    [cpp] view plaincopy
     
    1. #include<stdio.h>  
    2. #include"mpi.h"  
    3. #define SIZE 4  
    4.   
    5. int main(int argc, char *argv[]){  
    6.         int totalNumTasks, rankID;  
    7.   
    8.         float sendBuf[SIZE][SIZE] = {  
    9.                 {1.0,   2.0,    3.0,    4.0},  
    10.                 {5.0,   6.0,    7.0,    8.0},  
    11.                 {9.0,   10.0,   11.0,   12.0},  
    12.                 {13.0,  14.0,   15.0,   16.0}  
    13.         };  
    14.   
    15.         MPI_Init(&argc, &argv);  
    16.         MPI_Comm_rank(MPI_COMM_WORLD, &rankID);  
    17.         MPI_Comm_size(MPI_COMM_WORLD, &totalNumTasks);  
    18.   
    19.         float totalSum;  
    20.         if(totalNumTasks == SIZE){  
    21.                 int source = 0;  
    22.                 int sendCount = SIZE;  
    23.                 int recvCount = SIZE;  
    24.                 float recvBuf[SIZE];  
    25.                 //scatter data from source process to all processes in MPI_COMM_WORLD  
    26.                 MPI_Scatter(sendBuf, sendCount, MPI_FLOAT,   
    27.                             recvBuf, recvCount, MPI_FLOAT, source, MPI_COMM_WORLD);  
    28.   
    29.                 float sumPerProcess = recvBuf[0] + recvBuf[1] + recvBuf[2] + recvBuf[3];  
    30.                 printf("my rankID = %d, receive Results: %f %f %f %f, totalOnMe = %f\n",   
    31.                         rankID, recvBuf[0], recvBuf[1], recvBuf[2], recvBuf[3], sumPerProcess);  
    32.   
    33.                 int count = 1;  
    34.                 int root = 0;  
    35.                 MPI_Reduce(&sumPerProcess, &totalSum, count, MPI_FLOAT, MPI_SUM, root, MPI_COMM_WORLD);  
    36.                 printf("Process %d is done.\n", rankID);  
    37.                 fflush(stdout);  
    38.         }  
    39.         else  
    40.                 printf("Please specify -n %d\n", SIZE);  
    41.   
    42.         MPI_Finalize();  
    43.         if(rankID == 0) printf("totalSum = %f\n", totalSum);  
    44.         return 0;  
    45. }  

     

    4. 编译执行

     

    [plain] view plaincopy
     
    1. [amao@amao991 mpi-study]$ mpicc scatterReducer.c   
    2. [amao@amao991 mpi-study]$ mpiexec -n 4 -f machinefile ./a.out   
    3. my rankID = 0, receive Results: 1.000000 2.000000 3.000000 4.000000, totalOnMe = 10.000000  
    4. my rankID = 1, receive Results: 5.000000 6.000000 7.000000 8.000000, totalOnMe = 26.000000  
    5. Process 1 is done.  
    6. my rankID = 3, receive Results: 13.000000 14.000000 15.000000 16.000000, totalOnMe = 58.000000  
    7. Process 3 is done.  
    8. Process 0 is done.  
    9. my rankID = 2, receive Results: 9.000000 10.000000 11.000000 12.000000, totalOnMe = 42.000000  
    10. Process 2 is done.  
    11. totalSum = 136.000000  

     

    5. 总结

    (1)本例先通过MPI_Scatter函数把数组分发给4个进程(每个进程收到4个float值),每个进程对自己收到的4个数据求和

    (2)然后通过MPI_Reduce函数汇总4个进程的数据,得到总和totalSum值。

    (3)本例典型地说明了数据分发个多个进程/每个进程单独求解/然后汇总。

    ----------------------------------------------------------------

    1. MPI_Gather函数

    MPI_Gather (&sendbuf,sendcnt,sendtype,&recvbuf, recvcount,recvtype,root,comm) 

    Gathers distinct messages from each task in the group to a single destination task. This routine is the reverse operation of MPI_Scatter. 

    2. 图示

    3. 举例

     

    [cpp] view plaincopy
     
    1. #include<stdio.h>  
    2. #include<stdlib.h>  
    3. #include"mpi.h"  
    4.   
    5. int main(int argc, char *argv[]){  
    6.         int rankID, totalNumTasks;  
    7.   
    8.         MPI_Init(&argc, &argv);  
    9.         MPI_Barrier(MPI_COMM_WORLD);  
    10.         double elapsed_time = -MPI_Wtime();  
    11.   
    12.         MPI_Comm_rank(MPI_COMM_WORLD, &rankID);  
    13.         MPI_Comm_size(MPI_COMM_WORLD, &totalNumTasks);  
    14.   
    15.         int* gatherBuf = (int *)malloc(sizeof(int) * totalNumTasks);  
    16.         if(gatherBuf == NULL){  
    17.                 printf("malloc error!");  
    18.                 exit(-1);  
    19.                 MPI_Finalize();  
    20.         }  
    21.   
    22.         int sendBuf = rankID; //for each process, its rankID will be sent out  
    23.   
    24.         int sendCount = 1;  
    25.         int recvCount = 1;  
    26.         int root = 0;  
    27.         MPI_Gather(&sendBuf, sendCount, MPI_INT, gatherBuf, recvCount, MPI_INT, root, MPI_COMM_WORLD);  
    28.   
    29.         elapsed_time += MPI_Wtime();  
    30.         if(!rankID){  
    31.                 int i;  
    32.                 for(i = 0; i < totalNumTasks; i++){  
    33.                         printf("gatherBuf[%d] = %d, ", i, gatherBuf[i]);  
    34.                 }  
    35.                 putchar('\n');  
    36.                 printf("total elapsed time = %10.6f\n", elapsed_time);  
    37.         }  
    38.   
    39.         MPI_Finalize();  
    40.         return 0;  
    41. }  

     

    4. 编译执行


     

    [plain] view plaincopy
     
    1. [amao@amao991 mpi-study]$ mpicc gather.c  
    2. [amao@amao991 mpi-study]$ mpiexec -f machinefile -n 5 ./a.out  
    3. gatherBuf[0] = 0, gatherBuf[1] = 1, gatherBuf[2] = 2, gatherBuf[3] = 3, gatherBuf[4] = 4,  
    4. total elapsed time =   0.009653  

     

    5. 总结

    (1) 本例用了malloc在heap中开辟连续空间(数组)

    int* gatherBuf = (int *)malloc(sizeof(int) * totalNumTasks);     而后用gatherBuf[i]的形式来逐个显示每个空间的值。

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    微信小程序TodoList
    C语言88案例-找出数列中的最大值和最小值
    C语言88案例-使用指针的指针输出字符串
  • 原文地址:https://www.cnblogs.com/chero/p/2464848.html
Copyright © 2011-2022 走看看