AmpTools
LikelihoodManagerMPI.cc
Go to the documentation of this file.
1 //******************************************************************************
2 // This file is part of AmpTools, a package for performing Amplitude Analysis
3 //
4 // Copyright Trustees of Indiana University 2010, all rights reserved
5 //
6 // This software written by Matthew Shepherd, Ryan Mitchell, and
7 // Hrayr Matevosyan at Indiana University, Bloomington
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions
11 // are met:
12 // 1. Redistributions of source code must retain the above copyright
13 // notice and author attribution, this list of conditions and the
14 // following disclaimer.
15 // 2. Redistributions in binary form must reproduce the above copyright
16 // notice and author attribution, this list of conditions and the
17 // following disclaimer in the documentation and/or other materials
18 // provided with the distribution.
19 // 3. Neither the name of the University nor the names of its contributors
20 // may be used to endorse or promote products derived from this software
21 // without specific prior written permission.
22 //
23 // Creation of derivative forms of this software for commercial
24 // utilization may be subject to restriction; written permission may be
25 // obtained from the Trustees of Indiana University.
26 //
27 // INDIANA UNIVERSITY AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES,
28 // EXPRESS OR IMPLIED. By way of example, but not limitation, INDIANA
29 // UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCANTABILITY OR
30 // FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THIS SOFTWARE OR
31 // DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS,
32 // OR OTHER RIGHTS. Neither Indiana University nor the authors shall be
33 // held liable for any liability with respect to any claim by the user or
34 // any other party arising from use of the program.
35 //******************************************************************************
36 
37 #include <iostream>
38 #include <map>
39 
40 #include <mpi.h>
41 
44 #include "IUAmpToolsMPI/MPITag.h"
45 
46 void
49 {
50  m_calcMap[id] = calc;
51 }
52 
53 void
55 {
56  if( !m_mpiSetup ) setupMPI();
57 
58  if( m_isMaster ){
59 
60  cerr << "ERROR: deliverLikelihood() should not run on master node"
61  << endl;
62  assert( false );
63  }
64 
65  MPI_Status status;
66 
67  int cmnd[2];
68  int* id = &(cmnd[0]);
69  int* fitFlag = &(cmnd[1]);
70 
71  LikelihoodCalculatorMPI* likCalc;
72  map< int, LikelihoodCalculatorMPI* >::iterator mapItr;
73 
74  MPI_Recv( cmnd, 2, MPI_INT, 0, MPITag::kIntSend, MPI_COMM_WORLD, &status );
75 
76  while( *fitFlag != kExit ){
77 
78  mapItr = m_calcMap.find( *id );
79  // we must have a matching likelihood calculator to proceed
80  assert( mapItr != m_calcMap.end() );
81  likCalc = mapItr->second;
82 
83  switch( *fitFlag ){
84 
85  case kUpdateParameters:
86 
87  likCalc->updateParameters();
88  break;
89 
91 
92  likCalc->updateAmpParameter();
93  break;
94 
95  case kComputeIntegrals:
96 
97  // this actually has a return value, but serves the purpose
98  // of triggering a NI recalculation, if necessary, on the workers
99  likCalc->normIntTerm();
100  break;
101 
102  case kComputeLikelihood:
103 
104  likCalc->computeLikelihood();
105  break;
106 
107  default:
108 
109  cerr << "Unknown command flag!" << endl;
110  assert( false );
111  }
112 
113  MPI_Recv( &cmnd, 2, MPI_INT, 0, MPITag::kIntSend,
114  MPI_COMM_WORLD, &status );
115  }
116 
117  assert( *fitFlag == kExit );
118 }
119 
120 void
122 
123  if( !m_mpiSetup ) setupMPI();
124 
125  // this broadcasts a particular command to the first registered
126  // calculator -- note that there can be multiple likelihood
127  // calculators per node as there is one likelihood calculator
128  // for every reaction
129 
130  // should only be called on the master:
131  assert( m_isMaster );
132 
133  int cmnd[2];
134  cmnd[1] = command;
135 
136  map< int, LikelihoodCalculatorMPI* >::iterator mapItr = m_calcMap.begin();
137 
138  // if this is false then there are no registered calculators
139  assert( mapItr != m_calcMap.end() );
140 
141  cmnd[0] = mapItr->first;
142 
143  // this will send a command to just the first registered calculator
144  for( int i = 1; i < m_numProc; ++i ){
145 
146  MPI_Send( cmnd, 2, MPI_INT, i, MPITag::kIntSend, MPI_COMM_WORLD );
147  }
148 }
149 
150 void
151 LikelihoodManagerMPI::setupMPI()
152 {
153  int rank;
154  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
155  m_isMaster = ( rank == 0 );
156  MPI_Comm_size( MPI_COMM_WORLD, &m_numProc );
157  m_mpiSetup = true;
158 }
159 
160 bool LikelihoodManagerMPI::m_mpiSetup = false;
161 bool LikelihoodManagerMPI::m_isMaster = false;
162 int LikelihoodManagerMPI::m_numProc = 0;
163 map< int, LikelihoodCalculatorMPI* > LikelihoodManagerMPI::m_calcMap;
static void registerCalculator(int id, LikelihoodCalculatorMPI *calc)
static void broadcastToFirst(FitCommand command)