【问题标题】:MPI_Bcast into a while loopMPI_Bcast 进入 while 循环
【发布时间】:2021-03-26 09:41:57
【问题描述】:

我有这段代码:

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

struct fields{
  int hostNumber;
  int *numberArray;
}; 

struct fields *start(int);
struct fields *gatherData(int);

int main(int argc, char** argv) {
    int rank, size, count, *tmpArray, tmpNumOfArray;
     
    struct fields *myFields;      
    setbuf(stdout, NULL);        
    
    MPI_Init(&argc, &argv);
    MPI_Status status;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);        
   
    while(1){            
        if (rank == 0){
            //printf("I am parent-process with rank = %d, size = %d\n", rank, size);
                     
            myFields = start(rank);
            //for (int i = 0 ; i < myFields->hostNumber ; i++) printf("%d\n",((myFields->numberArray)[i]));
                           
            if ((myFields->hostNumber) < size){
                printf("Error!!! Number of Processes is more than number of Elements.\n");
                MPI_Abort(MPI_COMM_WORLD, 0);  
            }

            if ((myFields->hostNumber) < (2 * size)){
                printf("Error!!! The Host of Numbers should be at least double of the number  of Processes!!!\n");
                MPI_Abort(MPI_COMM_WORLD, 0);  
            }
      
            tmpNumOfArray = myFields->hostNumber;
            MPI_Bcast(&tmpNumOfArray, 1, MPI_INT, 0, MPI_COMM_WORLD);
        }
        
        MPI_Barrier(MPI_COMM_WORLD);            
        printf("process = %d, tmpNumOfArray = %d\n", rank, tmpNumOfArray);
        sleep(5);    
    }
    
    MPI_Finalize(); 
    return 0;
}

struct fields *start(int rank){
  int input;
  struct fields *myFields;
  system("clear");
  printf("1) Type 1 For Execution\n");
  printf("2) Type 2 For Exit\n");
  printf("Give your choice:");     
  scanf("%d",&input);

  switch(input){
    case 1:
        myFields = gatherData(rank);
        break;
    case 2:
    default:
        MPI_Abort(MPI_COMM_WORLD, 0); 
}
  return myFields;
}

struct fields *gatherData(int rank){
int host;
struct fields *myFields;

myFields = (struct fields *)malloc(sizeof(struct fields));    
if (myFields == NULL){
    printf("Cannot allocate memory for myFields struct!\n");
    MPI_Abort(MPI_COMM_WORLD, 0);     
}

if (rank == 0){
    printf("Give the host of the numbers to be statically checked: ");
    scanf("%d",&host);

    int *nmbArray = (int *)malloc(sizeof(nmbArray) * host);   
    for (int i = 0; i < host; i++){
        printf("Give the %d number:", i);
        scanf("%d", (&(nmbArray[i])));
    }  
    
    myFields->hostNumber = host;
    myFields->numberArray = &nmbArray[0];
}
  return myFields;      
}

当我运行它时,我得到以下信息:

process = 2, tmpNumOfArray = 0
process = 0, tmpNumOfArray = 10
process = 1, tmpNumOfArray = 0
process = 3, tmpNumOfArray = 0

我是什么:

process = 2, tmpNumOfArray = 10
process = 0, tmpNumOfArray = 10
process = 1, tmpNumOfArray = 10
process = 3, tmpNumOfArray = 10

有什么建议吗?不要专注于 gatherData()start() 函数,因为它们运行完美,问题在于 main() 到 MPI_Bcast() 函数。我也试过 MPI_COMM_SPAWN 但我认为它不能从父母广播给孩子。 先谢谢了!!!

【问题讨论】:

    标签: c performance parallel-processing mpi hpc


    【解决方案1】:

    MPI_Bcast

    将消息从具有“root”等级的进程广播到所有其他进程 沟通者的进程

    MPI_Bcast 广播例程是集体通信。 Hence:

    集体沟通是一种沟通方式,它涉及 一个通信器中所有进程的参与。

    您的代码的问题是只有rank=0 的进程正在调用MPI_Bcast;相反,所有涉及的进程也应该调用该 MPI 例程。

    通过相应地移动该调用来修复您的代码,即:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include "mpi.h"
    
    struct fields{
      int hostNumber;
      int *numberArray;
    }; 
    
    struct fields *start(int);
    struct fields *gatherData(int);
    
    int main(int argc, char** argv) {
        int rank, size, count, *tmpArray, tmpNumOfArray;
         
        struct fields *myFields;      
        setbuf(stdout, NULL);        
        
        MPI_Init(&argc, &argv);
        MPI_Status status;
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &size);        
       
        while(1){            
            if (rank == 0)
            {          
                myFields = start(rank);
                if ((myFields->hostNumber) < size){
                    printf("Error!!! Number of Processes is more than number of Elements.\n");
                    MPI_Abort(MPI_COMM_WORLD, 0);  
                }
    
                if ((myFields->hostNumber) < (2 * size)){
                    printf("Error!!! The Host of Numbers should be at least double of the number  of Processes!!!\n");
                    MPI_Abort(MPI_COMM_WORLD, 0);  
                }
                tmpNumOfArray = myFields->hostNumber;
            }
            
            MPI_Bcast(&tmpNumOfArray, 1, MPI_INT, 0, MPI_COMM_WORLD); // Move this part
            MPI_Barrier(MPI_COMM_WORLD);            
            printf("process = %d, tmpNumOfArray = %d\n", rank, tmpNumOfArray);
            sleep(5); 
        }
        
        MPI_Finalize(); 
        return 0;
    }
    
    struct fields *start(int rank){
      int input;
      struct fields *myFields;
      system("clear");
      printf("1) Type 1 For Execution\n");
      printf("2) Type 2 For Exit\n");
      printf("Give your choice:");     
      scanf("%d",&input);
    
      switch(input){
        case 1:
            myFields = gatherData(rank);
            break;
        case 2:
        default:
            MPI_Abort(MPI_COMM_WORLD, 0); 
      }
      return myFields;
    }
    
    struct fields *gatherData(int rank){
    int host;
    struct fields *myFields;
    
    myFields = (struct fields *)malloc(sizeof(struct fields));    
    if (myFields == NULL){
        printf("Cannot allocate memory for myFields struct!\n");
        MPI_Abort(MPI_COMM_WORLD, 0);     
    }
    
    if (rank == 0){
        printf("Give the host of the numbers to be statically checked: ");
        scanf("%d",&host);
    
        int *nmbArray = (int *)malloc(sizeof(nmbArray) * host);   
        for (int i = 0; i < host; i++){
            printf("Give the %d number:", i);
            scanf("%d", (&(nmbArray[i])));
        }  
        
        myFields->hostNumber = host;
        myFields->numberArray = &nmbArray[0];
    }
      return myFields;      
    }
    

    【讨论】:

    • 是的,你是对的,但认为我尝试过但没有用,现在没关系。谢谢。
    猜你喜欢
    • 2015-03-08
    • 2012-08-26
    • 2013-04-01
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多