Subversion Repositories programming

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
314 ira 1
/*******************************************************************************
2
 * prob3.c - implement a parallel (pipelined approach) system for the
3
 *           Sieve of Eratosthenes problem.
4
 *
5
 * Copyright (c) 2006, Ira W. Snyder (devel@irasnyder.com)
6
 ******************************************************************************/
7
 
8
#include <mpi.h>
9
#include <stdio.h>
10
#include <stdlib.h>
11
 
12
#define TAG_DATA   0x1010
13
#define TERMINATOR 0xffff
14
#define BAD_NUM    -1
15
 
16
#define FALSE 0
17
#define TRUE  1
18
 
19
int should_pass (int num, int mynumber)
20
{
21
    if (num % mynumber == 0)
22
        return FALSE; // evenly divisible, DO NOT PASS
23
 
24
    return TRUE; // not evenly divisible, GO AHEAD
25
}
26
 
27
void print_num (int myrank, int mynumber)
28
{
29
    if (mynumber == BAD_NUM)
30
        return;
31
 
32
    if (myrank < 10)
33
        printf ("Proc 0%d's Prime: %d\n", myrank, mynumber);
34
    else
35
        printf ("Proc %d's Prime: %d\n", myrank, mynumber);
36
}
37
 
38
void send_term (int to_proc)
39
{
40
    int temp = TERMINATOR;
41
    MPI_Send (&temp, 1, MPI_INT, to_proc, TAG_DATA, MPI_COMM_WORLD);
42
}
43
 
44
int main (int argc, char *argv[])
45
{
46
    int myrank, numprocs;
47
    int mynumber = BAD_NUM;
48
    int temp_recv;
49
 
50
    MPI_Status status;
51
 
52
    MPI_Init (&argc, &argv);
53
    MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
54
    MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
55
 
56
    if (myrank == 0)
57
    {
58
        int i;
59
        mynumber = 2;
60
 
61
        for (i=3; i<=100; i++)
62
            if (should_pass (i, mynumber))
63
                MPI_Send (&i, 1, MPI_INT, myrank+1, TAG_DATA, MPI_COMM_WORLD);
64
 
65
        send_term (myrank+1);
66
    }
67
    else if (myrank < (numprocs - 1))
68
    {
69
        /* Save the first number we recieve */
70
        MPI_Recv (&mynumber, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
71
 
72
        /* Check if we need to exit early */
73
        if (mynumber == TERMINATOR)
74
        {
75
            send_term (myrank+1);
76
            goto END_NOW;
77
        }
78
 
79
        /* Check all subsequent numbers */
80
        while (TRUE)
81
        {
82
            MPI_Recv (&temp_recv, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
83
 
84
            if (temp_recv == TERMINATOR)
85
            {
86
                send_term (myrank+1);
87
                break;
88
            }
89
            else
90
            {
91
                if (should_pass (temp_recv, mynumber))
92
                    MPI_Send (&temp_recv, 1, MPI_INT, myrank+1, TAG_DATA, MPI_COMM_WORLD);
93
            }
94
        }
95
    }
96
    else 
97
    {
98
        /* Save the first number we recieve */
99
        MPI_Recv (&mynumber, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
100
 
101
        if (mynumber == TERMINATOR)
102
            goto END_NOW;
103
 
104
        while (TRUE)
105
        {
106
            MPI_Recv (&temp_recv, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
107
 
108
            if (temp_recv == TERMINATOR)
109
                break;
110
            else
111
                if (should_pass (temp_recv, mynumber))
112
                {
113
                    printf ("ERROR: not enough processes.\n");
114
                    printf ("Prime: %d\n", temp_recv);
115
                }
116
        }
117
    }
118
 
119
END_NOW:
120
    print_num (myrank, mynumber);
121
 
122
    MPI_Finalize ();
123
 
124
    return 0;
125
}