-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbarrier.c
More file actions
109 lines (97 loc) · 2.75 KB
/
Copy pathbarrier.c
File metadata and controls
109 lines (97 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include <mpi_samples.h>
#define DEBUG
#undef DEBUG
void barr(int rank, int world) {
// master-slave
if (rank == 0) {
for (int i = 1; i < world; i++){
MPI_Recv(0, 0, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
for (int i = 1; i < world; i++){
MPI_Send(0, 0, MPI_INT, i, 0, MPI_COMM_WORLD);
}
} else {
MPI_Send(0, 0, MPI_INT, 0, 0, MPI_COMM_WORLD);
MPI_Recv(0, 0, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
void barr2(int rank, int world) {
/*
tree based barrier
1. parent waits for their children
2. children notify parent (and it's propagated to the root)
3. children wait for parent's response
4. when both children are ready parent notifies both children
indexing as in heap (below)
*/
int node = rank + 1;
int left = 2*node;
int right = 2*node+1;
int parent = node / 2;
// 1. parents wait for their children
if (left <= world) {
#ifdef DEBUG
LOG_WITH_RANK("Waiting for left child\n");
#endif
MPI_Recv(0, 0, MPI_INT, left-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
#ifdef DEBUG
LOG_WITH_RANK("Received left child\n");
#endif
}
#ifdef DEBUG
else {
LOG_WITH_RANK("Leaf\n");
}
#endif
if (right <= world) {
#ifdef DEBUG
LOG_WITH_RANK("Waiting for right child\n");
#endif
MPI_Recv(0, 0, MPI_INT, right-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
#ifdef DEBUG
LOG_WITH_RANK("Received right child\n");
#endif
}
#ifdef DEBUG
else {
LOG_WITH_RANK("Leaf\n");
}
#endif
// 2. children notify the parent
if (rank != 0) {
MPI_Send(0, 0, MPI_INT, parent-1, 0, MPI_COMM_WORLD);
}
// 3. children wait for the parent
if (rank != 0) {
#ifdef DEBUG
LOG_WITH_RANK("Waiting for parent\n");
#endif
MPI_Recv(0, 0, MPI_INT, parent-1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
#ifdef DEBUG
LOG_WITH_RANK("Received parent\n");
#endif
}
// 4. parent notifies the children
if (left <= world) {
MPI_Send(0, 0, MPI_INT, left-1, 0, MPI_COMM_WORLD);
}
if (right <= world) {
MPI_Send(0, 0, MPI_INT, right-1, 0, MPI_COMM_WORLD);
}
}
static void barrier(int _) {
int rank, world;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &world);
LOG_WITH_RANK("before %f \n", MPI_Wtime());
sleep(2*rank);
barr2(rank, world);
LOG_WITH_RANK("after %f \n", MPI_Wtime());
MPI_Finalize();
}
SAMPLE(barrier, 0)