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]的形式来逐个显示每个空间的值。

  • 相关阅读:
    应当将指针变量用“==”或“!=”与 NULL 比较
    不可将浮点变量用“==”或“!=”与任何数字比较
    应当将整型变量用“==”或“!=”直接与 0 比较
    不可将布尔变量直接与 TRUE、FALSE 或者 1、0 进行比较
    不要把程序中的复合表达式与“真正的数学表达式”混淆
    不要有多用途的复合表达式
    不要编写太复杂的复合表达式
    用括号确定表达式的操作顺序
    为了防止某一软件库中的一些标识符和其它软件库中的冲突
    类的数据成员加前缀 m_(表示 member)
  • 原文地址:https://www.cnblogs.com/chero/p/2464848.html
Copyright © 2011-2022 走看看