Mpi with C , using mpi_comm_spawn() can't run the latter program

Viewed 34

I implemented the following code on C:

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

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

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

int main(int argc, char** argv) {
    int rank, size, tmpNmb1, tmpNmb2, 
            notOrderedFlag = 0, tmpI = 0,
            nbFinalArray, tmpRetrieveArray[3],
            count, row1 = 0, col1 = 0;
    struct fields *myFields;
    MPI_Status status;
    setbuf(stdout, NULL);
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);   

    if (rank == 0){                   
        myFields = start(rank, size);
        //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); 
        }

        for (int i = 1; i < size; i++){ 
            MPI_Send(&(myFields->hostNumber), 1, MPI_INT,  i, 1000, MPI_COMM_WORLD); 
            MPI_Send(myFields->numberArray, myFields->hostNumber, MPI_INT, i, 1001, MPI_COMM_WORLD);
        }
        
  
    }   

    if (rank != 0){
        myFields = (struct fields *)malloc(sizeof(struct fields));
        if (myFields == NULL){
            printf("Error while allocating memory for myFields structure!!!\n");
         
            MPI_Abort(MPI_COMM_WORLD, 0);                                  
        }

        MPI_Recv((&(myFields->hostNumber)), 1, MPI_INT, 0, 1000, MPI_COMM_WORLD, &status);
        MPI_Get_count(&status, MPI_INT, &count);
        //printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);
        //printf("number = %d\n", myFields->hostNumber);

        myFields->numberArray = (int *)malloc(sizeof(struct fields) * (myFields->hostNumber));
        MPI_Recv((myFields->numberArray), (myFields-> hostNumber), MPI_INT, 0, 1001, MPI_COMM_WORLD, &status); //Why this is not running?
        MPI_Get_count(&status, MPI_INT, &count);            
        //printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);

        /*for (int i = 0 ; i < myFields->hostNumber ; i++){
            printf("%d\n",(*(myFields->numberArray)));
            (myFields->numberArray)++;
        }*/

        /*for (int i = 0 ; i < myFields->hostNumber ; i++){
            printf("%d\n",((myFields->numberArray)[i]));
        }*/
    }

    tmpNmb1 = ((myFields->hostNumber) / size);
    tmpNmb2 = ((myFields->hostNumber) % size);
    int row = (rank * tmpNmb1);    
    //printf("tmpNb1=%d\n",tmpNmb1);
    //printf("tmpNb2=%d\n",tmpNmb2);
    //printf("row=%d\n",row);

    if (tmpNmb2 == 0){
        nbFinalArray = size;
    }
    else{
        nbFinalArray = (size + 1);
    }

    int finalArray[nbFinalArray];
    int retrieveArray[size - 1][3];

    for (int i = row ; i < ((row + tmpNmb1) - 1); i++){
        if (((myFields->numberArray)[i]) <= ((myFields->numberArray)[i+1])){
            notOrderedFlag = 0; //Ordered
            if (rank == 0) finalArray[rank] = myFields->numberArray[tmpNmb1 -1];
        } 
        else{
            notOrderedFlag = 1; // Not Ordered
            tmpI = i;
            break;
        } 
    }    

    if (notOrderedFlag == 1){
        if (rank == 0){
            printf("From Proccess 0 - Position %d. The Array is not Ordered!\n", tmpI);
      
            MPI_Abort(MPI_COMM_WORLD, 0);
        }
        else if (rank != 0){                
            int tmpArray[3] = {rank, notOrderedFlag, tmpI};
            MPI_Send(tmpArray, 3, MPI_INT,  0, 1000, MPI_COMM_WORLD); //wrong Array
        }
    }

    if (rank == 0){
        for (int i = 1; i < size ; i++){
            MPI_Recv(tmpRetrieveArray, 3, MPI_INT, i, 1000, MPI_COMM_WORLD, &status);
            MPI_Get_count(&status, MPI_INT, &count);
            //printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);
            //for (int i = 0; i < 3; i++) printf("Array[%d] = %d\n", i, tmpRetrieveArray[i]);
            for (int j = 0; j < 3; j ++){
                retrieveArray[row1][col1] = tmpRetrieveArray[j];
                col1++;
            }
            row1++;
            col1 = 0;                
        }
        row1 = col1 = 0;
        /*for (int i = 0 ;i < (size-1);i++){
            for (int j = 0;j<3;j++){
                printf("aa = %d, ", retrieveArray[i][j]);
            }
            printf("\n");
        }*/
    }

    if (rank != 0){
        if (notOrderedFlag == 0){
            int tmpArray[3] = {rank, notOrderedFlag, ((myFields->numberArray)[(row + tmpNmb1) - 1])};
     
            MPI_Send(tmpArray, 3, MPI_INT,  0, 1000, MPI_COMM_WORLD); //Right Array
        }
    }

    if (rank == 0){
        for ( int row1 = 0; row1 < size; row1++ )
            if (retrieveArray[row1][1] == 1){
                printf("From Proccess %d - Position %d. The Array is not Ordered!\n", retrieveArray[row1][0], retrieveArray[row1][2]);
            
                MPI_Abort(MPI_COMM_WORLD, 0);
            }
            else if (retrieveArray[row1][1] == 0){
                finalArray[retrieveArray[row1][0]] = retrieveArray[row1][2];
            }
        //for (int i = 0 ; i < size; i ++) printf("finalArray[%d] = %d\n", i, finalArray[i]);
    }

    if ((tmpNmb2 != 0) && (rank == 0)){
    for (int i = ((myFields->hostNumber) - tmpNmb2); i < ((myFields->hostNumber) - 1); i++){
           if (((myFields->numberArray)[i]) > ((myFields->numberArray)[i+1])){
                printf("From Proccess 0 - Position %d. The Array is not Ordered!\n", i);
      
                MPI_Abort(MPI_COMM_WORLD, 0);
            }
        }
        finalArray[nbFinalArray - 1] = myFields->numberArray[myFields->hostNumber - 1];
        for (int i = 0 ; i < size; i ++) printf("finalArray[%d] = %d\n", i, finalArray[i]);
    }

    if (rank == 0){
        for (int i = 0 ; i < (nbFinalArray -1); i++){
            if (finalArray[i] > finalArray[i+1]){
                printf("Final Array is NOT ORDRED. From Proccess 0 - Position %d\n", i);
         
                MPI_Abort(MPI_COMM_WORLD, 0);
            }      
        }
    
        printf("The Array is Ordered!!!\n");
    }

    MPI_Finalize();
    return 0;
}

struct fields *start(int rank, int size){
  int input;
  struct fields *myFields;
   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, size);
           break;
       case 2:
       default:
          //free(myFields);
          MPI_Abort(MPI_COMM_WORLD, 0);
}

//for (int i = 0 ; i < myFields->hostNumber ; i++) printf("%d\n",((myFields->numberArray)[i]));
  return myFields;
}

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

  myFields = (struct fields *)malloc(sizeof(struct fields));
  if (myFields == NULL){
    printf("Error while alloction memory for myFields struct!!!\n");
 
    MPI_Abort(MPI_COMM_WORLD, 0);
 }
    
 if (rank == 0){         
    printf("Give the host of the number to be checked if they are ordered:");
    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];

 //for (int i = 0 ; i < host ; i++) printf("%d\n",((myFields->numberArray)[i]));
 return myFields;
  
}

Now I have to repeatedly call the program again every time it exits. So I amtrying to use MPI_Comm_Spawn. But I couldn't find an implementation on the internet and followed this link: https://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node98.htm

So mycode becomes as (Exercise1 project):

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

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

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

int main(int argc, char** argv) {
    int rank, size, universe_size, 
            *universe_sizep, flag;
    char worker_program[200] = {'/','h','o','m','e','/','k','o','n','s','t','a','n','t','i','n','o','s',
                                'd','m','s','/','N','e','t','B','e','a','n','s','P','r','o','j','e','c','t','s',
                                '/','E','x','e','r','c','i','s','e','1','_','1','/','m','a','i','n'};
    struct fields *myFields;
    setbuf(stdout, NULL);
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm everyone; /* intercommunicator */ 
    //MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, &universe_sizep, &flag);
   
  //  while(1){
        system("clear");
        if (rank == 0){
            if (size != 1){
                printf("Error Manager Process should be only one!!!\n");
                MPI_Abort(MPI_COMM_WORLD, 0);
            }                
            myFields = start(rank, size, universe_sizep, flag);
            //for (int i = 0 ; i < myFields->hostNumber ; i++) printf("%d\n",((myFields->numberArray)[i]));
                           
            if ((myFields->hostNumber) < ((myFields->universeSize) - 1)){
                printf("Error!!! Number of Processes is more than number of Elements.\n");
                MPI_Abort(MPI_COMM_WORLD, 0); 
            }

            if (myFields->hostNumber < (2 * ((myFields->universeSize) - 1))){
                printf("Error!!! The Host of Numbers should be at least double of the number  of Processes!!!\n");
                MPI_Abort(MPI_COMM_WORLD, 0); 
            }
      
            MPI_Comm_spawn(worker_program, MPI_ARGV_NULL, ((myFields->universeSize)-1), MPI_INFO_NULL, 0, 
                           MPI_COMM_SELF, &everyone, MPI_ERRCODES_IGNORE);
           
            
            for (int i = 1; i < ((myFields->universeSize) - 1); i++){ 
                MPI_Send(&(myFields->hostNumber), 1, MPI_INT,  i, 1000, everyone); 
                MPI_Send(myFields->numberArray, myFields->hostNumber, MPI_INT, i, 1001, everyone);
            }
        }   
   // }
    MPI_Finalize();
    return 0;
}

struct fields *start(int rank,int size,int *universe_sizep,int flag){
 int input;
 struct fields *myFields;
 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, size, universe_sizep, flag);
        break;
    case 2:
    default:
        MPI_Abort(MPI_COMM_WORLD, 0);
}

//for (int i = 0 ; i < myFields->hostNumber ; i++) printf("%d\n",((myFields->numberArray)[i]));
 return myFields;
}

struct fields *gatherData(int rank,int size,int *universe_sizep,int flag){
 int host, universe_size;
 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){
    //if (!flag) { 
        printf("This MPI does not support UNIVERSE_SIZE. How many\n processes total?\n"); 
        scanf("%d", &universe_size); 
    //} else universe_size = *universe_sizep; 

    if (universe_size == 1){
        printf("No room to start workers!!!\n");
        MPI_Abort(MPI_COMM_WORLD, 0);
    } 

    printf("Give the host of the number to be checked if they are ordered:");
    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];
    myFields->universeSize = universe_size;
 }

  //for (int i = 0 ; i < host ; i++) printf("%d\n",((myFields->numberArray)[i]));
  return myFields;      
}

And Exercise1_1 Project:

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

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

int main(int argc, char** argv) {
    int rank, remote_size, tmpNmb1, tmpNmb2, 
            notOrderedFlag = 0, tmpI = 0,
            nbFinalArray, tmpRetrieveArray[3],
            count, row1 = 0, col1 = 0;
    struct fields *myFields;
    MPI_Status status;
    setbuf(stdout, NULL);
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm parent; 
    MPI_Comm_get_parent(&parent); 
    MPI_Comm_remote_size(parent, &remote_size);       
    
    if (rank == 0){
        if (parent == MPI_COMM_NULL){
            printf("Error!!! while getting Parent Comuniacator.\n");
            MPI_Abort(MPI_COMM_WORLD, 0);  
        }        
     
        if (remote_size != 1){
            printf("Error Manager - Parent Process should be only one!!!\n");
            MPI_Abort(MPI_COMM_WORLD, 0);
        }
    }   

    if (rank == 0){
        myFields = (struct fields *)malloc(sizeof(struct fields));
        if (myFields == NULL){
            printf("Error while allocating memory for myFields structure!!!\n");
            MPI_Abort(MPI_COMM_WORLD, 0);                                  
        }
        
        MPI_Recv((&(myFields->hostNumber)), 1, MPI_INT, 0, 1000, parent, &status);
        MPI_Get_count(&status, MPI_INT, &count);
        printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);
        printf("number = %d\n", myFields->hostNumber);

        myFields->numberArray = (int *)malloc(sizeof(struct fields) * (myFields->hostNumber));
        MPI_Recv((myFields->numberArray), (myFields-> hostNumber), MPI_INT, 0, 1001, parent, &status);
        MPI_Get_count(&status, MPI_INT, &count);            
        //printf("Process %d received %d int(s) from Process %d with tag %d \n", rank, count, status.MPI_SOURCE, status.MPI_TAG);

        /*for (int i = 0 ; i < myFields->hostNumber ; i++){
            printf("%d\n",(*(myFields->numberArray)));
            (myFields->numberArray)++;
        }*/

        /*for (int i = 0 ; i < myFields->hostNumber ; i++){
            printf("%d\n",((myFields->numberArray)[i]));
        }*/

    //All other code are comments
    MPI_Finalize();
    return 0;
}

The problem is that at the first case I can't use free(myFields), as the code shows, I get error when MPI_Abort(). Is this allocation deallocated when the program Abort? Second I can't make the program run either at the seconde case when I use MPI_spawn nor at the last one. When The worker processes are initialized do they have rank = 0 to whatever rank i specify? The mesage at the second case is being send from manager but the workers does not respond. The console freezes.

Any suggestion?

0 Answers
Related