Subversion Repositories programming

Rev

Rev 314 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 314 Rev 315
Line 14... Line 14...
14
#define BAD_NUM    -1
14
#define BAD_NUM    -1
15
 
15
 
16
#define FALSE 0
16
#define FALSE 0
17
#define TRUE  1
17
#define TRUE  1
18
 
18
 
-
 
19
/* Check if we should pass num on, based on mynumber */
19
int should_pass (int num, int mynumber)
20
int should_pass (int num, int mynumber)
20
{
21
{
21
    if (num % mynumber == 0)
22
    if (num % mynumber == 0)
22
        return FALSE; // evenly divisible, DO NOT PASS
23
        return FALSE; /* evenly divisible, DO NOT PASS */
23
 
24
 
24
    return TRUE; // not evenly divisible, GO AHEAD
25
    return TRUE; /* not evenly divisible, GO AHEAD */
25
}
26
}
26
 
27
 
-
 
28
/* Print out this processes number nicely.
-
 
29
 * Ignore processes that don't have a number. */
27
void print_num (int myrank, int mynumber)
30
void print_num (int myrank, int mynumber)
28
{
31
{
29
    if (mynumber == BAD_NUM)
32
    if (mynumber == BAD_NUM)
30
        return;
33
        return;
31
 
34
 
Line 33... Line 36...
33
        printf ("Proc 0%d's Prime: %d\n", myrank, mynumber);
36
        printf ("Proc 0%d's Prime: %d\n", myrank, mynumber);
34
    else
37
    else
35
        printf ("Proc %d's Prime: %d\n", myrank, mynumber);
38
        printf ("Proc %d's Prime: %d\n", myrank, mynumber);
36
}
39
}
37
 
40
 
-
 
41
/* Send the terminator to to_proc */
38
void send_term (int to_proc)
42
void send_term (int to_proc)
39
{
43
{
40
    int temp = TERMINATOR;
44
    int temp = TERMINATOR;
41
    MPI_Send (&temp, 1, MPI_INT, to_proc, TAG_DATA, MPI_COMM_WORLD);
45
    MPI_Send (&temp, 1, MPI_INT, to_proc, TAG_DATA, MPI_COMM_WORLD);
42
}
46
}
Line 51... Line 55...
51
 
55
 
52
    MPI_Init (&argc, &argv);
56
    MPI_Init (&argc, &argv);
53
    MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
57
    MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
54
    MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
58
    MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
55
 
59
 
56
    if (myrank == 0)
60
    if (myrank == 0) /* root */
57
    {
61
    {
58
        int i;
62
        int i;
59
        mynumber = 2;
63
        mynumber = 2;
60
        
64
     
-
 
65
        /* Send numbers [3,100] through the pipe, in order */   
61
        for (i=3; i<=100; i++)
66
        for (i=3; i<=100; i++)
-
 
67
            /* p0 is part of the pipe, so check numbers here, too */
62
            if (should_pass (i, mynumber))
68
            if (should_pass (i, mynumber))
63
                MPI_Send (&i, 1, MPI_INT, myrank+1, TAG_DATA, MPI_COMM_WORLD);
69
                MPI_Send (&i, 1, MPI_INT, myrank+1, TAG_DATA, MPI_COMM_WORLD);
64
 
70
 
-
 
71
        /* Done with all the numbers, so send the terminator through the pipe */
65
        send_term (myrank+1);
72
        send_term (myrank+1);
66
    }
73
    }
67
    else if (myrank < (numprocs - 1))
74
    else if (myrank < (numprocs - 1)) /* middle of pipeline */
68
    {
75
    {
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)
76
        while (TRUE)
81
        {
77
        {
-
 
78
            /* Recieve a number */
82
            MPI_Recv (&temp_recv, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
79
            MPI_Recv (&temp_recv, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
83
 
80
 
-
 
81
            /* If what we recieved was the terminator, send the terminator on,
-
 
82
             * then leave the loop. */
84
            if (temp_recv == TERMINATOR)
83
            if (temp_recv == TERMINATOR)
85
            {
84
            {
86
                send_term (myrank+1);
85
                send_term (myrank+1);
87
                break;
86
                break;
88
            }
87
            }
-
 
88
 
-
 
89
            /* If this was not a terminator, and we don't have a number already,
-
 
90
             * then the number that came through must be prime, so store it. */
89
            else
91
            if (mynumber == BAD_NUM)
90
            {
92
                mynumber = temp_recv;
-
 
93
 
-
 
94
            /* Check any number that comes in to see if it's prime, and forward
-
 
95
             * it through the pipe if it is a prime number */
91
                if (should_pass (temp_recv, mynumber))
96
            if (should_pass (temp_recv, mynumber))
92
                    MPI_Send (&temp_recv, 1, MPI_INT, myrank+1, TAG_DATA, MPI_COMM_WORLD);
97
                MPI_Send (&temp_recv, 1, MPI_INT, myrank+1, TAG_DATA, MPI_COMM_WORLD);
93
            }
-
 
94
        }
98
        }
95
    }
99
    }
96
    else 
100
    else /* end of pipeline */
97
    {
101
    {
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)
102
        while (TRUE)
105
        {
103
        {
-
 
104
            /* Recieve a number */
106
            MPI_Recv (&temp_recv, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
105
            MPI_Recv (&temp_recv, 1, MPI_INT, myrank-1, TAG_DATA, MPI_COMM_WORLD, &status);
107
 
106
 
-
 
107
            /* If what we recieved was the terminator, leave the loop now.
-
 
108
             * No need to forward it, since we are the end of the pipeline. */
108
            if (temp_recv == TERMINATOR)
109
            if (temp_recv == TERMINATOR)
109
                break;
110
                break;
-
 
111
 
-
 
112
            /* If this was not a terminator, and we don't have a number already,
110
            else
113
             * then the number that came through must be prime, so store it. */
111
                if (should_pass (temp_recv, mynumber))
114
            if (mynumber == BAD_NUM)
112
                {
115
                mynumber = temp_recv;
-
 
116
 
113
                    printf ("ERROR: not enough processes.\n");
117
            /* Check any number that comes in to see if it's prime, and print an
114
                    printf ("Prime: %d\n", temp_recv);
118
             * error if we should pass it on, since we don't have anywhere to
115
                }
119
             * forward it to. */
-
 
120
            if (should_pass (temp_recv, mynumber))
-
 
121
                printf ("ERROR: not enough processes. Number = %d\n", temp_recv);
116
        }
122
        }
117
    }
123
    }
118
 
124
 
119
END_NOW:
-
 
-
 
125
    /* Every process should print it's prime number */
120
    print_num (myrank, mynumber);
126
    print_num (myrank, mynumber);
121
 
127
 
122
    MPI_Finalize ();
128
    MPI_Finalize ();
123
 
129
 
124
    return 0;
130
    return 0;
125
}
131
}
-
 
132