OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
ConejoBalancer_inst.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
29 #include "Utility/IpplInfo.h"
30 
32 //
33 // PUBLIC FUNCTIONS
34 //
36 
37 //
38 // The constructor for ConejoBalancer.
39 // Record the number of processors in the system.
40 //
41 
43 :
44  // Initialize the pointer to the balancer to zero
45  // because we can't construct it yet.
46  m_balancer(0),
47  // Initialize the number of vnodes to -1 because we don't know that yet.
48  m_localVnodes(-1),
49  m_totalVnodes(-1),
50  // Record the number of processors.
51  m_procs( IpplInfo::getNodes() ),
52  // Record which processor is mine.
53  m_myProc( IpplInfo::myNode() )
54 {
55  // Record the number of vnodes on each processor.
56  // Start the value out with -1 so we know if it has been set or not.
57  m_vnodeCounts.resize(m_procs);
58  for (int i=0; i<m_procs; ++i)
59  m_vnodeCounts[i] = -1;
60 }
61 
63 
64 //
65 // The destructor for ConejoBalancer.
66 // Just delete the balancer.
67 //
68 
70 {
71  delete m_balancer;
72 }
73 
75 //
76 // PRIVATE FUNCTIONS
77 //
79 
80 //
81 // ConejoBalancer::sendWeights
82 //
83 // INPUTS:
84 // vnodeWeights: A vector<double> of weights for vnodes on this proc.
85 // tag: an integer tag for the message.
86 //
87 // OUTPUTS:
88 // Message is sent.
89 //
90 
91 void
92 ConejoBalancer::sendWeights(vector<double>& vnodeWeights, int tag)
93 {
94  // Build a message to be sent.
95  Message *msg = new Message();
96 
97  // Add data to the message.
98  // First the number of elements, then the elements themselves.
99  msg->put(vnodeWeights.size());
100  putMessage(*msg, vnodeWeights.begin(), vnodeWeights.end());
101 
102  // Send the message.
103  Ippl::Comm->send(msg, 0, tag);
104 }
105 
107 
108 //
109 // ConejoBalancer::receiveWeights
110 //
111 // INPUTS:
112 // vnodeWeights: A vector<double>. Initially has the data from this
113 // processor. Used as a place to put incoming data.
114 // tag: an integer tag for the messages.
115 //
116 // OUTPUTS:
117 // Updated state of the ConejoBalancer with the data from
118 // the other processors.
119 //
120 
121 void
122 ConejoBalancer::receiveWeights(vector<double>& vnodeWeights, int tag)
123 {
124  // Tell the MultiBalancer that it is about to get a new material.
126 
127  // Receive messages from all the other processors.
128  for ( int proc=0; proc < m_procs ; ++proc )
129  {
130  // Receive a message from the next proc.
131  Message *msg = Ippl::Comm->receive_block(proc,tag);
132 
133  // Get the number of vnodes.
134  long int count;
135  msg->get(count);
136 
137  // Record the number of vnodes on that proc.
138  recordVnodeCount(count,proc);
139 
140  // Allocate space for the incoming data.
141  vnodeWeights.resize( count );
142 
143  // Unpack it.
144  getMessage_iter(*msg, vnodeWeights.begin() );
145 
146  // Record it by extracting a double* from the vnodeWeights iterator.
147  double *p = &*(vnodeWeights.begin());
148  m_balancer->appendWeights(p,p+vnodeWeights.size());
149 
150  // Delete the message.
151  delete msg;
152  }
153 }
154 
156 
157 //
158 // Tell the ConejoBalancer the number of vnodes it is dealing with.
159 //
160 // INPUT:
161 // localVnodes: The number of vnodes on this processor.
162 // totalVnodes: The total number of vnodes on all the processors.
163 //
164 // OUTPUT:
165 // Updated state of the ConejoBalancer.
166 // The number of vnodes is recorded.
167 // The MultiBalancer is initialized.
168 //
169 
170 void
171 ConejoBalancer::setupVnodes(int localVnodes, int remoteVnodes)
172 {
173  // The first time through we need to record the sizes,
174  // and build the balancer
175  if ( m_balancer == 0 )
176  {
177  // Record the sizes.
178  m_localVnodes = localVnodes;
179  m_totalVnodes = localVnodes + remoteVnodes;
180 
181  // If we are processor zero, build the balancer object.
182  if ( m_myProc == 0 )
184  }
185  // If it isn't the first time, make sure this BareField
186  // is consistent with the previous.
187  else
188  {
189  PAssert_EQ(m_localVnodes, localVnodes);
190  PAssert_EQ(m_totalVnodes, localVnodes + remoteVnodes);
191  PAssert_EQ( (m_balancer!=0), (m_myProc==0 ) );
192  }
193 }
194 
196 
197 //
198 // Tell the ConejoBalancer the number of vnodes on a given processor.
199 //
200 // INPUT:
201 // count: an integer for the number of vnodes
202 // proc: an integer of the processor
203 //
204 // OUTPUT:
205 // Updated state of the ConejoBalancer.
206 // The first time it is called it records the count.
207 // After that, it checks to make sure the counts agree.
208 //
209 
210 void
212 {
213  // Make sure this processor number makes sense.
214  PAssert_GE( proc, 0 );
215 
216  // Check to see if this is the first time it is being called.
217  if ( m_vnodeCounts[proc] < 0 )
218  {
219  // First time, record the count.
220  m_vnodeCounts[proc] = count;
221  }
222  // Not the first time.
223  else
224  {
225  // Make sure this count agrees with record.
226  PAssert_EQ( m_vnodeCounts[proc], count );
227  }
228 }
229 
231 
232 //
233 // ConejoBalancer::broadcastVnodesToSend
234 //
235 // Scan through the data in the MultiBalancer and figure out
236 // which processors will be sending vnodes to where.
237 // Broadcast that information to the processors that will
238 // be sending.
239 //
240 // INPUT:
241 // tag: an integer message tag.
242 //
243 // OUTPUT:
244 // Messages sent.
245 //
246 
247 void
249 {
250  // Get a pointer to the destination processors for each vnode.
252 
253  // Loop over the source processors, sending data to each.
254  for ( int sourceProc = 0; sourceProc < m_procs; ++sourceProc )
255  {
256  // Cache the number of vnodes on this processor.
257  long int c = m_vnodeCounts[sourceProc];
258 
259  // Build the message.
260  Message *msg = new Message;
261  msg->put(c);
262  putMessage(*msg, vp, vp + c);
263 
264  // Send the message.
265  Ippl::Comm->send(msg,sourceProc,tag);
266 
267  // Increment the pointer to the destination processors.
268  vp += c;
269  }
270 }
271 
273 
274 //
275 // ConejoBalancer::receiveVnodesToSend
276 //
277 // Every processor receives from processor zero the destinations
278 // for its vnodes.
279 //
280 // INPUT:
281 // tag: an integer message tag.
282 //
283 // OUTPUT:
284 // vnodeDestinations: A vector<int>& to hold the destinations for
285 // all the vnodes on this proc.
286 //
287 
288 void
289 ConejoBalancer::receiveVnodesToSend(vector<int>& vnodeDestinations, int tag)
290 {
291  // Receive the message from proc 0.
292  int proc_zero = 0;
293  Message *msg = Ippl::Comm->receive_block(proc_zero,tag);
294 
295  // Get the number of vnodes coming in.
296  long int s;
297  msg->get(s);
298 
299  // Extract the vnode destinations.
300  vnodeDestinations.resize(s);
301  getMessage_iter(*msg, vnodeDestinations.begin() );
302 
303  // Delete the message.
304  delete msg;
305 }
306 
307 /***************************************************************************
308  * $RCSfile: ConejoBalancer_inst.cpp,v $ $Author: adelmann $
309  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
310  * IPPL_VERSION_ID: $Id: ConejoBalancer_inst.cpp,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
311  ***************************************************************************/
void sendWeights(std::vector< double > &vnodeWeights, int tag)
void receiveVnodesToSend(std::vector< int > &vnodeDestinations, int tag)
void getMessage_iter(Message &m, OutputIterator o)
Definition: Message.h:603
void receiveWeights(std::vector< double > &vnodeWeights, int tag)
void appendWeights(double *begin, double *end)
iterator begin()
MultiBalancer * m_balancer
#define PAssert_GE(a, b)
Definition: PAssert.h:124
#define PAssert_EQ(a, b)
Definition: PAssert.h:119
std::vector< int >::iterator iterator
void broadcastVnodesToSend(int tag)
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
std::vector< int > m_vnodeCounts
void setupVnodes(int localVnodes, int remoteVnodes)
void recordVnodeCount(int count, int proc)
Message & get(const T &cval)
Definition: Message.h:484
Message & put(const T &val)
Definition: Message.h:414
void putMessage(Message &m, const T &t)
Definition: Message.h:557
Message * receive_block(int &node, int &tag)
static Communicate * Comm
Definition: IpplInfo.h:93
bool send(Message *, int node, int tag, bool delmsg=true)