简体   繁体   中英

MPI Deadlock with Send and Receive

my code is to enter to numbers a (lower range) and b (upper range) , then to enter number between them c and find the position of this number in the range

when run this code on ubuntu terminal , it stop running after enter the numbers a b and c , i try to comment the send and revive lines and print the position before Send statement and its work

but i want to find the position of c and send it to the master process to print it

Note: i think because send and receive are blocking functions , this may cause a deadlock or something like that ? i am not sure so appreciate any help in this problem

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

int main(int argc , char * argv[])
{
int rank,nprocess,tag=0,a,b,c,i=0,*arr,*subArr,arrSize=0,blockSize=0,pos=0,dest;
MPI_Status status;
/* Start up MPI */
MPI_Init( &argc , &argv );

/* Find out process rank */
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

/* Find out number of process */
MPI_Comm_size(MPI_COMM_WORLD, &nprocess);

if(rank==0){
    printf("Enter the lower Range and the upper Range : ");
    if(scanf("%d",&a)){};  //2
    if (scanf("%d",&b)){}; //9
    printf("Enter the search number : ");
    if(scanf("%d",&c)){}; //5

    arrSize=(b-a)+1;
    while(arrSize%nprocess!=0)arrSize++; //Enhance the array Size

    printf("array size is : %d \n",arrSize);

    arr=(int *)malloc(arrSize*sizeof(int));

    for(i=0;i<arrSize;i++){
        if(i<((b-a)+1))arr[i]=a+i;
        else { arr[i]=b;}
    }

    printf("Array is :");
    for(i=0;i<arrSize;i++){
        printf("%d ",arr[i]); //2 3 4 5 6 7 8 9 9
    }
    printf("\n");

    blockSize=arrSize/nprocess; //3

    for(i=0;i<nprocess;i++){
        dest=i;
        MPI_Recv (&pos,1,MPI_INT,dest,tag,MPI_COMM_WORLD,&status);
    }

    printf("The postion of the number %d in the range from %d to %d is : %d \n ",c,a,b,pos);

}

MPI_Bcast (&c,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast (&blockSize,1,MPI_INT,0,MPI_COMM_WORLD);


subArr=(int *) malloc(blockSize*sizeof(int));


MPI_Scatter (arr,blockSize,MPI_INT,subArr,blockSize,MPI_INT,0,MPI_COMM_WORLD);


for(i=0;i<blockSize;i++){
    if(subArr[i]==c){
        pos=(blockSize+1)*rank;
        printf("The Postion is : %d ",pos); // postion is 4 since array is 2 3 4 5 6 7 8 9 9 and I search for 5
        MPI_Send (&pos,1,MPI_INT,0,tag,MPI_COMM_WORLD);
        break;
    }
}

MPI_Finalize();
return 0;

}

Indeed, this is a deadlock. The root process tries to MPI_Recv() messages from the other processes, while the other processes are blocked at MPI_Bcast(&c,...) expecting the process 0 to broadcast something.

How about moving the MPI_Recv() after calls to MPI_Bcast() and MPI_Scatter() ?

Lastly, each call to MPI_Recv(.,.,.,source,.,.) on process to must match a correponding call to MPI_Send(.,.,.,to,.,.) on process source . Since there is only one occurence of the number you are looking for in the array, there is a single call to MPI_Send(...,0,.) . Consequently, process 0 must call MPI_Recv() only once. Since any process could have sent the message, the macro MPI_ANY_SOURCE must be used intead of source .

The following code has been corrected. It is to be compiled by mpicc main.c -o main -Wall and ran by mpirun -np 3 main .

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

int main(int argc , char * argv[])
{
    int rank,nprocess,tag=0,a,b,c,i=0,*arr,*subArr,arrSize=0,blockSize=0,pos=0,deadlock=0;
    MPI_Status status;
    /* Start up MPI */
    MPI_Init( &argc , &argv );

    /* Find out process rank */
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    /* Find out number of process */
    MPI_Comm_size(MPI_COMM_WORLD, &nprocess);

    if(rank==0){
        printf("Enter the lower Range and the upper Range : ");fflush(stdout);
        if(scanf("%d",&a)){};  //2
        if (scanf("%d",&b)){}; //9
        printf("Enter the search number : ");fflush(stdout);
        if(scanf("%d",&c)){}; //5

        arrSize=(b-a)+1;
        while(arrSize%nprocess!=0)arrSize++; //Enhance the array Size

        printf("array size is : %d \n",arrSize);

        arr=(int *)malloc(arrSize*sizeof(int));

        for(i=0;i<arrSize;i++){
            if(i<((b-a)+1))arr[i]=a+i;
            else { arr[i]=b;}
        }

        printf("Array is :");
        for(i=0;i<arrSize;i++){
            printf("%d ",arr[i]); //2 3 4 5 6 7 8 9 9
        }
        printf("\n");

        blockSize=arrSize/nprocess; //3



    }

    MPI_Bcast (&c,1,MPI_INT,0,MPI_COMM_WORLD);
    MPI_Bcast (&blockSize,1,MPI_INT,0,MPI_COMM_WORLD);


    subArr=(int *) malloc(blockSize*sizeof(int));


    MPI_Scatter (arr,blockSize,MPI_INT,subArr,blockSize,MPI_INT,0,MPI_COMM_WORLD);



    for(i=0;i<blockSize;i++){

        if(subArr[i]==c){
            pos=(blockSize)*rank+i;
            printf("The Postion is : %d ",pos); // postion is 4 since array is 2 3 4 5 6 7 8 9 9 and I search for 5
        if(rank==0){
          deadlock=1;
          break;
        }
            MPI_Send (&pos,1,MPI_INT,0,tag,MPI_COMM_WORLD);
            break;
        }
    }

    if(rank==0){

        //for(i=0;i<nprocess;i++){
        //      dest=i;
        if(deadlock==0)
        MPI_Recv (&pos,1,MPI_INT,MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&status);
        //   }

        printf("The postion of the number %d in the range from %d to %d is : %d \n ",c,a,b,pos);
        free(arr);
    }
    free(subArr);
    MPI_Finalize();
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM