8
#include "TerminationDetector.h"
11
using namespace tascel;
12
using namespace tascel::comm;
16
TerminationDetector::resetUpPhase() {
18
MPI_Irecv(&cvote[0], 1, MPI_INT, child[0], child[0], MPI_COMM_WORLD, &creq[0]);
21
MPI_Irecv(&cvote[1], 1, MPI_INT, child[1], child[1], MPI_COMM_WORLD, &creq[1]);
28
TerminationDetector::resetDownPhase() {
30
MPI_Irecv(&pdecision, 1, MPI_INT, parent, parent, MPI_COMM_WORLD, &preq);
35
TerminationDetector::TerminationDetector() {
36
child[0] = (2 * me() + 1 < nproc()) ? 2 * me() + 1 : -1;
37
child[1] = (2 * me() + 2 < nproc()) ? 2 * me() + 2 : -1;
38
parent = (me != 0) ? (me() - 1) / 2 : -1;
41
resetDownPhase(); //this should after up. we start with the up phase
44
TerminationDetector::~TerminationDetector() {
57
TerminationDetector::vote(bool _myvote) {
58
myvote = (_myvote == false) ? 0 : myvote;
62
TerminationDetector::propogateUp() {
63
int decision = myvote;
64
if (child[0] >= 0 && cvote[0] == 0) {
67
if (child[1] >= 0 && cvote[1] == 0) {
75
MPI_Send(&decision, 1, MPI_INT, parent, me(), MPI_COMM_WORLD);
81
TerminationDetector::propogateDown() {
83
MPI_Send(&pdecision, 1, MPI_INT, child[0], me(), MPI_COMM_WORLD);
86
MPI_Send(&pdecision, 1, MPI_INT, child[1], me(), MPI_COMM_WORLD);
92
TerminationDetector::progress(bool _myvote) {
94
if (pdecision == 1 || (me() == 0 && nproc() == 0 && myvote == 1)) {
95
return; //termination detected. nothing more to do
101
MPI_Test(&creq[0], &flag[0], &status[0]);
104
MPI_Test(&creq[1], &flag[1], &status[1]);
106
if (flag[0] && flag[1]) {
110
/*Tiny optimization: propogate inverts dirUp. So both dirUp and
111
!dirUp could be executed consecutively, especially for me()==0*/
116
MPI_Test(&preq, &flag, &status);
125
TerminationDetector::hasTerminated() {
127
return pdecision == 1;