问题
when i execute this code i have no response, it gets waiting for ever, process 1 is sending data to the root process but the root process doesn't receive it (or almost that is what i think).
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
void my_parallel_function(int v[], int size, int rank)
{
MPI_Status status;
int i;
if(rank==0)
{
MPI_Send(&v[0], 10, MPI_INT, 1, 1, MPI_COMM_WORLD);
}
else
{
MPI_Recv(&v[0], 10, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD,&status);
for(i=0;i<10;i++)
{
//change the value
v[i] = i;
//printf("hola soy nodo: %d\n", i);
}
MPI_Send(&v[0], 10, MPI_INT, 0, 2, MPI_COMM_WORLD);
}
if(rank==0)
{
MPI_Recv(&v[0], 10, MPI_INT, MPI_ANY_SOURCE, 2, MPI_COMM_WORLD,&status);
for(i=1;i<size;i++)
{
printf("\nvalue of item %d: %d\n", i, v[i]);
}
}
}
void simpleFunction()
{
printf("Hi i am a simple function\n");
}
int main(int argc, char *argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Status status;
int vect[10];
int op=1;
while(op != 0)
{
//system("clear");
printf("Welcome to example program!\n\n");
printf("\t1.- Call Parallel Function\n");
printf("\t2.- Call another Function\n");
printf("\t0.- Exit\n\t");
printf("\n\n\tEnter option:");
scanf("%d", &op);
switch(op)
{
case 1:
my_parallel_function(vect, size, rank);
printf("Parallel function called successfully\n\n");
break;
case 2:
simpleFunction();
printf("Function called successfully\n\n");
break;
}
}
MPI_Finalize();
return 0;
}
I am executing with -np 2
I think this is not woking as it should:
MPI_Recv(&v[0], 10, MPI_INT, MPI_ANY_SOURCE, 2, MPI_COMM_WORLD,&status);
Any idea? thank you very much.
EDITED: But when i remove the if(rank==0) i get all the i/o of the slave processes, that means tons of times menu printing. I am novice in OpenMPI, how can solve this problem?.
Thank you very much!.
回答1:
The proper way to implement a menu in an MPI program is:
while (op != 0)
{
if (rank == 0)
{
printf("Welcome to example program!\n\n");
printf("\t1.- Call Parallel Function\n");
printf("\t2.- Call another Function\n");
printf("\t0.- Exit\n\t");
printf("\n\n\tEnter option:");
scanf("%d", &op);
}
// Broadcast the user's choice to all other ranks
MPI_Bcast(&op, MPI_INT, 1, 0, MPI_COMM_WORLD);
switch(op)
{
case 1:
my_parallel_function(vect, size, rank);
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 0)
printf("Parallel function called successfully\n\n");
break;
case 2:
simpleFunction();
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 0)
printf("Function called successfully\n\n");
break;
}
}
The two barriers are not absolutely necessary - they just make sure that the calls have returned in all ranks.
Note that allowing rank 0 to read from the standard input is not guaranteed by the MPI standard and programs that do such kind of I/O are not portable. That said, most existing MPI implementations does indeed redirect the standard input and output of rank 0 to the standard input and output of mpiexec
/mpirun
.
回答2:
my_parallel_function
is only called when rank
is 0. Therefore when rank
is 1, nothing is sent to rank 0 and it's MPI_Recv
waits forever. Just remove the if
from your main
.
来源:https://stackoverflow.com/questions/19932496/openmpi-gets-waiting-for-ever