Reputation: 508
I'm trying to sort large arrays by reversal and coding with MPI on C.
Basically, my program splits the array to portions for workers and each worker finds its own increasing and decreasing strips and sends strips back to root. Root makes some reversals by finding and using max and min elements of these strips. The program ends when there is no break point left, which means the array is sorted.
It was a very long code, so I simplified for my problem:
int *ARRAY;
int main(int argc, char *argv[])
{
int p_id, n_procs, flag = 1;
MPI_Init(&argc, &argv);
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &p_id);
MPI_Comm_size(MPI_COMM_WORLD, &n_procs);
if(p_id == 0) {
ARRAY = createRandomArray(N_DATA);
// PRINT UNSORTED ARRAY
while(hasBreakPoints(ARRAY, N_DATA)) {
for(i=1;i<n_procs; i++)
// SEND PORTIONS TO WORKERS
for(i=1;i<n_procs; i++)
// RECEIVE EACH STRIP FROM WORKERS
// FIND MAX AND MIN OF STRIPS
// MAKE REVERSALS ON "ARRAY"
}
flag = 0;
// PRINT SORTED ARRAY
}
else {
while(flag == 1) {
// RECEIVE PORTION FROM ROOT
// FIND MY OWN STRIPS
// SEND MY OWN STRIPS TO ROOT
}
}
MPI_Finalize();
return 0;
}
As you can see, I need to use a while
loop to run program until no break point left. I know that the number of MPI_Send
commands have to be equal to the number of MPI_Receive
commands. So, I simply created a flag to run ROOT
and WORKERS
equal times.
By use of this lazy approach, the program is working without error but never ending and doesn't goes into MPI_Finalize
. Is there any fix on this or more efficient way to use? Thanks for help.
Upvotes: 2
Views: 8688
Reputation: 9489
Your flag
variable being local to each process, you have to find a way of transferring its value from process #0 to the other processes when it changes.
Well actually, you can solve this issue by playing with message tags for example. Your worker processes could just just receive from root using MPI_ANY_TAG
and decide what to do next, i.e sending back data or just finishing, depending on the actual tag value received. This could be look like this (not tested):
int *ARRAY;
int main(int argc, char *argv[])
{
int p_id, n_procs, flag = 1;
MPI_Init(&argc, &argv);
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &p_id);
MPI_Comm_size(MPI_COMM_WORLD, &n_procs);
const int COMPUTE=1, STOP=2;
if(p_id == 0) {
ARRAY = createRandomArray(N_DATA);
// PRINT UNSORTED ARRAY
while(hasBreakPoints(ARRAY, N_DATA)) {
for(i=1;i<n_procs; i++)
// SEND PORTIONS TO WORKERS using tag COMPUTE
MPI_Send(......, COMPUTE, ...);
for(i=1;i<n_procs; i++)
// RECEIVE EACH STRIP FROM WORKERS
// FIND MAX AND MIN OF STRIPS
// MAKE REVERSALS ON "ARRAY"
}
// send the STOP message using tag STOP
for(i=1;i<n_procs; i++)
MPI_Send(...., STOP, ...);
// PRINT SORTED ARRAY
}
else {
while(flag == 1) {
// RECEIVE PORTION FROM ROOT using MPI_ANY_TAG
MPI_Recv(..., MPI_ANY_TAG, ..., &status);
if ( status.MPI_TAG == COMPUTE ) {
// FIND MY OWN STRIPS
// SEND MY OWN STRIPS TO ROOT
}
else
flag = 0;
}
}
MPI_Finalize();
return 0;
}
Upvotes: 4
Reputation: 508
As Gilles pointed out, flag can't be usable for my program. I solved the problem by checking that array is sorted or not in both ROOT
's and WORKER
's part. To do this, I have to pass ARRAY
to workers from ROOT
. And, optionally I keep ARRAY
in worker part as LOCAL
.
int *ARRAY;
int main(int argc, char *argv[])
{
int p_id, n_procs;
MPI_Init(&argc, &argv);
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &p_id);
MPI_Comm_size(MPI_COMM_WORLD, &n_procs);
if(p_id == 0) {
ARRAY = createRandomArray(N_DATA);
// PRINT UNSORTED ARRAY
while(hasBreakPoints(ARRAY, N_DATA)) {
for(i=1;i<n_procs; i++)
// SEND WHOLE ARRAY TO ALL WORKERS
for(i=1;i<n_procs; i++)
// SEND PORTIONS TO WORKERS
for(i=1;i<n_procs; i++)
// RECEIVE EACH STRIP FROM WORKERS
// FIND MAX AND MIN OF STRIPS
// MAKE REVERSALS ON "ARRAY"
}
// PRINT SORTED ARRAY
}
else {
int *LOCAL;
// RECEIVE ARRAY TO LOCAL
while(hasBreakPoints(LOCAL, N_DATA) {
// RECEIVE PORTION FROM ROOT
// FIND MY OWN STRIPS
// SEND MY OWN STRIPS TO ROOT
}
}
MPI_Finalize();
return 0;
}
Although I can't understand how, this solved my problem. I am still open for your opinions. Thanks.
Upvotes: 0