Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*******************************************************************************
* prob3.c - implement a parallel (pipelined approach) system for the
* Sieve of Eratosthenes problem.
*
* Copyright (c) 2006, Ira W. Snyder (devel@irasnyder.com)
******************************************************************************/
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#define TAG_DATA 0x1010
#define TERMINATOR 0xffff
#define BAD_NUM -1
#define FALSE 0
#define TRUE 1
int should_pass (int num, int mynumber)
{
if (num % mynumber == 0)
return FALSE; // evenly divisible, DO NOT PASS
return TRUE; // not evenly divisible, GO AHEAD
}
void print_num (int myrank, int mynumber)
{
if (mynumber == BAD_NUM)
return;
if (myrank < 10)
printf ("Proc 0%d's Prime: %d\n", myrank, mynumber);
else
printf ("Proc %d's Prime: %d\n", myrank, mynumber);
}
void send_term (int to_proc)
{
int temp = TERMINATOR;
MPI_Send (&temp, 1, MPI_INT, to_proc, TAG_DATA, MPI_COMM_WORLD);
}
int main (int argc, char *argv[])
{
int myrank, numprocs;
int mynumber = BAD_NUM;
int temp_recv;
MPI_Status status;
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
if (myrank == 0)
{
int i;
mynumber = 2;
for (i=3; i<=100; i++)
if (should_pass (i, mynumber))
MPI_Send (&i, 1, MPI_INT, myrank+1, TAG_DATA, MPI_COMM_WORLD);
send_term (myrank+1);
}
else if (myrank < (numprocs - 1))
{
/* Save the first number we recieve */
MPI_Recv (&mynumber, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
/* Check if we need to exit early */
if (mynumber == TERMINATOR)
{
send_term (myrank+1);
goto END_NOW;
}
/* Check all subsequent numbers */
while (TRUE)
{
MPI_Recv (&temp_recv, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
if (temp_recv == TERMINATOR)
{
send_term (myrank+1);
break;
}
else
{
if (should_pass (temp_recv, mynumber))
MPI_Send (&temp_recv, 1, MPI_INT, myrank+1, TAG_DATA, MPI_COMM_WORLD);
}
}
}
else
{
/* Save the first number we recieve */
MPI_Recv (&mynumber, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
if (mynumber == TERMINATOR)
goto END_NOW;
while (TRUE)
{
MPI_Recv (&temp_recv, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
if (temp_recv == TERMINATOR)
break;
else
if (should_pass (temp_recv, mynumber))
{
printf ("ERROR: not enough processes.\n");
printf ("Prime: %d\n", temp_recv);
}
}
}
END_NOW:
print_num (myrank, mynumber);
MPI_Finalize ();
return 0;
}