| 355 |
ira |
1 |
/*******************************************************************************
|
|
|
2 |
* hw4_prob1.c - implement a partitioning algorithm for Problem 1 of
|
|
|
3 |
* CS370 Homework #4.
|
|
|
4 |
******************************************************************************/
|
|
|
5 |
|
|
|
6 |
#include <mpi.h>
|
|
|
7 |
#include <stdlib.h>
|
|
|
8 |
#include <stdio.h>
|
|
|
9 |
|
|
|
10 |
const int ROOT_NODE = 0;
|
|
|
11 |
|
|
|
12 |
#define TAG_LESS_NUM 0xaaaa
|
|
|
13 |
#define TAG_LESS_DATA 0xbbbb
|
|
|
14 |
#define TAG_MORE_NUM 0xcccc
|
|
|
15 |
#define TAG_MORE_DATA 0xdddd
|
|
|
16 |
|
|
|
17 |
int main (int argc, char *argv[])
|
|
|
18 |
{
|
|
|
19 |
int myid, p;
|
|
|
20 |
|
|
|
21 |
const int n = 1000; // or whatever you want
|
|
|
22 |
|
|
|
23 |
int *array;
|
|
|
24 |
int *less, *more;
|
|
|
25 |
|
|
|
26 |
int i,j,k;
|
|
|
27 |
int seed;
|
|
|
28 |
int recv_num;
|
|
|
29 |
|
|
|
30 |
MPI_Status status;
|
|
|
31 |
|
|
|
32 |
MPI_Init (&argc, &argv);
|
|
|
33 |
MPI_Comm_rank (MPI_COMM_WORLD, &myid);
|
|
|
34 |
MPI_Comm_size (MPI_COMM_WORLD, &p);
|
|
|
35 |
|
|
|
36 |
if (myid == ROOT_NODE)
|
|
|
37 |
{
|
|
|
38 |
// Allocate n elements in array[]
|
|
|
39 |
array = allocate (n);
|
|
|
40 |
|
|
|
41 |
// Initialize the elements in array[]
|
|
|
42 |
|
|
|
43 |
seed = array[0];
|
|
|
44 |
}
|
|
|
45 |
else
|
|
|
46 |
{
|
|
|
47 |
// Allocate n/p elements in array[]
|
|
|
48 |
array = allocate (n/p);
|
|
|
49 |
}
|
|
|
50 |
|
|
|
51 |
// Allocate n/p elements in less[] and more[]
|
|
|
52 |
less = allocate (n/p);
|
|
|
53 |
more = allocate (n/p);
|
|
|
54 |
|
|
|
55 |
// Send the seed to everyone
|
|
|
56 |
MPI_Bcast (&seed, 1, MPI_INT, ROOT_NODE, MPI_COMM_WORLD);
|
|
|
57 |
|
|
|
58 |
// Block partition to each process
|
|
|
59 |
MPI_Scatter (array, n/p, MPI_INT, array, n/p, MPI_INT, ROOT_NODE, MPI_COMM_WORLD);
|
|
|
60 |
|
|
|
61 |
j=0; // "less" index
|
|
|
62 |
k=0; // "more" index
|
|
|
63 |
|
|
|
64 |
for (i=0; i<n/p; i++)
|
|
|
65 |
{
|
|
|
66 |
if (array[i] < seed)
|
|
|
67 |
{
|
|
|
68 |
less[j] = array[i];
|
|
|
69 |
j++;
|
|
|
70 |
}
|
|
|
71 |
else if (array[i] > seed)
|
|
|
72 |
{
|
|
|
73 |
more[k] = array[i];
|
|
|
74 |
k++;
|
|
|
75 |
}
|
|
|
76 |
}
|
|
|
77 |
|
|
|
78 |
if (myid == ROOT_NODE)
|
|
|
79 |
{
|
|
|
80 |
// Copy j elements from less[] into array[] (root node only)
|
|
|
81 |
memcpy (array, less, j*sizeof(int));
|
|
|
82 |
|
|
|
83 |
// recieve "less" array from each node, in turn
|
|
|
84 |
for (i=1; i<p; i++)
|
|
|
85 |
{
|
|
|
86 |
MPI_Recv (&recv_num, 1, MPI_INT, i, TAG_LESS_NUM, MPI_COMM_WORLD, &status);
|
|
|
87 |
MPI_Recv (&array[j], recv_num, MPI_INT, i, TAG_LESS_DATA, MPI_COMM_WORLD, &status);
|
|
|
88 |
j += recv_num; // update index
|
|
|
89 |
}
|
|
|
90 |
|
|
|
91 |
// Copy k elements from more[] into array[] (root node only)
|
|
|
92 |
memcpy (array, more, (n-k)*sizeof(int));
|
|
|
93 |
k = n-k;
|
|
|
94 |
|
|
|
95 |
// recieve "more" array from each node, in turn
|
|
|
96 |
for (i=1; i<p; i++)
|
|
|
97 |
{
|
|
|
98 |
MPI_Recv (&recv_num, 1, MPI_INT, i, TAG_MORE_NUM, MPI_COMM_WORLD, &status);
|
|
|
99 |
k -= recv_num;
|
|
|
100 |
MPI_Recv (&array[k], recv_num, MPI_INT, i, TAG_MORE_DATA, MPI_COMM_WORLD, &status);
|
|
|
101 |
}
|
|
|
102 |
|
|
|
103 |
// Since we've got every element > seed and
|
|
|
104 |
// every element < seed, so the only thing remaining
|
|
|
105 |
// is the seed itself (possibly more than 1)
|
|
|
106 |
while (j < k)
|
|
|
107 |
{
|
|
|
108 |
array[j] = seed;
|
|
|
109 |
j++;
|
|
|
110 |
}
|
|
|
111 |
}
|
|
|
112 |
else
|
|
|
113 |
{
|
|
|
114 |
// Send the "less" array
|
|
|
115 |
MPI_Send (&j, 1, MPI_INT, 0, TAG_LESS_NUM, MPI_COMM_WORLD);
|
|
|
116 |
MPI_Send (less, j, MPI_INT, 0, TAG_LESS_DATA, MPI_COMM_WORLD);
|
|
|
117 |
|
|
|
118 |
// Send the "more" array
|
|
|
119 |
MPI_Send (&k, 1, MPI_INT, 0, TAG_MORE_NUM, MPI_COMM_WORLD);
|
|
|
120 |
MPI_Send (more, k, MPI_INT, 0, TAG_MORE_DATA, MPI_COMM_WORLD);
|
|
|
121 |
}
|
|
|
122 |
|
|
|
123 |
if (myid == ROOT_NODE)
|
|
|
124 |
{
|
|
|
125 |
// Print the results, or whatever you want
|
|
|
126 |
// to do with the data here
|
|
|
127 |
}
|
|
|
128 |
|
|
|
129 |
// Free all of the memory we used
|
|
|
130 |
free (less);
|
|
|
131 |
free (more);
|
|
|
132 |
free (array);
|
|
|
133 |
|
|
|
134 |
MPI_Finalize ();
|
|
|
135 |
return 0;
|
|
|
136 |
}
|
|
|
137 |
|