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 1int should_pass (int num, int mynumber){if (num % mynumber == 0)return FALSE; // evenly divisible, DO NOT PASSreturn 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);elseprintf ("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;elseif (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;}