Miind
MPINodeCode.hpp
Go to the documentation of this file.
1 // Copyright (c) 2005 - 2012 Marc de Kamps
2 // 2012 David-Matthias Sichau
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation
9 // and/or other materials provided with the distribution.
10 // * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software
11 // without specific prior written permission.
12 //
13 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
15 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
17 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 //
19 
20 #ifndef CODE_MPILIB_MPINODE_HPP_
21 #define CODE_MPILIB_MPINODE_HPP_
22 
24 #include <iostream>
29 namespace MPILib {
30 
31 template<class Weight, class NodeDistribution>
33  const AlgorithmInterface<Weight>& algorithm,
34  NodeType nodeType,
35  NodeId nodeId,
36  const NodeDistribution& nodeDistribution,
37  const std::map<NodeId, MPINode<Weight, NodeDistribution>>& localNode,
38  const std::string& name) :
39  _pAlgorithm(algorithm.clone()), //
40  _nodeType(nodeType), //
41  _nodeId(nodeId), //
42  _rLocalNodes(localNode), //
43  _rNodeDistribution(nodeDistribution),
44  _name(name){
45 }
46 
47 template<class Weight, class NodeDistribution>
49 }
50 
51 template<class Weight, class NodeDistribution>
53  // A Node will call its Algorithm to update its state up until time 'time'. It will
54  // return the time maintained by the Algorithm. This time may be sligthly different due to
55  // rounding errors. Network::evolve will use this time to check whether Algorithms keep synchronized
56  // with the overall network within reasonable bounds.
57 
58  // MdK: 05/07/2017. removed a while loop. The algorithm is now entirely responsible
59  // for evolution up until the required time. The MPINetwork::evolve method will
60  // now check whether algorithms keep consistent time.
61 
62  ++_number_iterations;
63  _pAlgorithm->evolveNodeState(_precursorActivity, _weights, time,
64  _precursorTypes);
65  Time t_ret = _pAlgorithm->getCurrentTime();
66 
67  if (fabs(t_ret - time) > MPILib::ALGORITHM_NETWORK_DISCREPANCY ){
68  throw MPILib::utilities::Exception("There is a discrepancy between Algorithm and Network time");
69  }
70 
71  // update state
72  this->setActivity(_pAlgorithm->getCurrentRate());
73 
74  sendOwnActivity();
75  receiveData();
76 
77  return _pAlgorithm->getCurrentTime();
78 }
79 
80 template<class Weight, class NodeDistribution>
82  _pAlgorithm->prepareEvolve(_precursorActivity, _weights, _precursorTypes);
83 
84 }
85 
86 template<class Weight, class NodeDistribution>
88  const SimulationRunParameter& simParam) {
89 
90  _maximum_iterations = simParam.getMaximumNumberIterations();
91  _pAlgorithm->configure(simParam);
92 
93  // Add this line or other nodes will not get a proper input at the first simulation step!
94  this->setActivity(_pAlgorithm->getCurrentRate());
95 
96  _pHandler = std::shared_ptr<report::handler::AbstractReportHandler>(
97  simParam.getHandler().clone());
98 
99  _pHandler->initializeHandler(_nodeId);
100 }
101 
102 template<class Weight, class NodeDistribution>
104  const Weight& weight, NodeType nodeType) {
105  _precursors.push_back(nodeId);
106  _precursorTypes.push_back(nodeType);
107  _weights.push_back(weight);
108  //make sure that _precursorStates is big enough to store the data
109  _precursorActivity.resize(_precursors.size());
110 }
111 
112 template<class Weight, class NodeDistribution>
114  _successors.push_back(nodeId);
115 }
116 
117 template<class Weight, class NodeDistribution>
119  return _activity;
120 }
121 
122 template<class Weight, class NodeDistribution>
124  _activity = activity;
125 }
126 
127 template<class Weight, class NodeDistribution>
130 }
131 
132 
133 template<class Weight, class NodeDistribution>
135  int i = 0;
136 
137  for (auto it = _precursors.begin(); it != _precursors.end(); it++, i++) {
138  //do not send the data if the node is local!
139  if (_rNodeDistribution.isLocalNode(*it)) {
140  _precursorActivity[i] =
141  _rLocalNodes.find(*it)->second.getActivity();
142 
143  } else {
144  utilities::MPIProxy().irecv(_rNodeDistribution.getResponsibleProcessor(*it), *it,
145  _precursorActivity[i]);
146  }
147  }
148 }
149 
150 template<class Weight, class NodeDistribution>
152 
153  for (auto& it : _successors) {
154  //do not send the data if the node is local!
155  if (!_rNodeDistribution.isLocalNode(it)) {
156  utilities::MPIProxy().isend(_rNodeDistribution.getResponsibleProcessor(it),
157  _nodeId, _activity);
158  }
159  }
160 }
161 
162 template<class Weight, class NodeDistribution>
164  report::ReportType type) const {
165  std::vector<report::ReportValue> vec_values;
166 
167  if (type == report::RATE) {
168  report::Report report(_pAlgorithm->getCurrentTime(),
169  Rate(this->getActivity()), this->_nodeId,
170  _pAlgorithm->getGrid(this->_nodeId,false), type, vec_values, _rLocalNodes.size());
171  _pHandler->writeReport(report);
172 
173  } else if ( type == report::STATE) {
174  // We don't want getGrid to be called if there is no requirement to write the state, as this is expensive for some algorithms
175 
176  report::Report report(_pAlgorithm->getCurrentTime(),
177  Rate(this->getActivity()), this->_nodeId,
178  _pAlgorithm->getGrid(this->_nodeId,_pHandler->isStateWriteMandatory()), type, vec_values, _rLocalNodes.size());
179  _pHandler->writeReport(report);
180  }
181 }
182 
183 template<class Weight, class NodeDistribution>
185 
186  _pHandler->detachHandler(_nodeId);
187 }
188 
189 template<class Weight, class NodeDistribution>
191  return _nodeType;
192 }
193 
194 }
195 //end namespace MPILib
196 
197 #endif /* CODE_MPILIB_MPINODE_HPP_ */
NodeType
This determines an MPINode's type, which will be checked when Dale's law is set.
Definition: NodeType.hpp:31
void sendOwnActivity()
Class for nodes in an MPINetwork.
Definition: MPINode.hpp:51
ActivityType getActivity() const
void irecv(int, int, T &) const
Definition: MPIProxy.hpp:144
void clearSimulation()
A Report is sent by a MPINode when it is queried.
Definition: Report.hpp:41
double Time
MPINode(const AlgorithmInterface< Weight > &algorithm, NodeType nodeType, NodeId nodeId, const NodeDistribution &nodeDistribution, const std::map< NodeId, MPINode< Weight, NodeDistribution >> &localNode, const std::string &name="")
Definition: MPINodeCode.hpp:32
NodeType getNodeType() const
void configureSimulationRun(const SimulationRunParameter &simParam)
Definition: MPINodeCode.hpp:87
const double ALGORITHM_NETWORK_DISCREPANCY
Individual algorithms may make small errors in their time keeping compared to the network...
const report::handler::AbstractReportHandler & getHandler() const
virtual AbstractReportHandler * clone() const =0
void addSuccessor(NodeId nodeId)
unsigned int NodeId
Parameter determining how a simulation is run. Specifiying begin and end time, log file names...
void reportAll(report::ReportType type) const
Time evolve(Time time)
Definition: MPINodeCode.hpp:52
Rate ActivityType
void setActivity(ActivityType activity)
static void waitAll()
void addPrecursor(NodeId nodeId, const Weight &weight, NodeType nodeType)
void prepareEvolve()
Definition: MPINodeCode.hpp:81
The objective is find a numerical solution for this equation This requires a numerical representation of the density We will work in the state space of a two dimensional and define a mesh there We first give two examples and then define the general procedure and given in Table for given fixed Delta g see Fig and we will denote coordinates in this dimension by a small letter $v The second dimension can be used to represent parameters as varied as and will represented by $w A strip is constructed by choosing two neighbouring points in state e g and integrating the vector field for a time $T that is assumed to be an integer multiple of a period of time Delta which we assume to be a defining characteristic of the grid Let then the set of points the set of points which is quadrilateral in shape The quadrilateral should be but not necessarily as long as they are but it is convenient to number them in order of creation In the we will assume that strip numbers created by the integration procedure start and are so that the numbers i in each identify a unique strip Strip no is reserved for stationary points There may or more cells in strip The number of cells in strip $i denoted by with $i the strip number and $j the cell as the i
Definition: 2D.hpp:145
MPIProxy_ & MPIProxy()
Definition: MPIProxy.hpp:176
void isend(int, int, const T &) const
Definition: MPIProxy.hpp:156
double Rate
virtual ~MPINode()
Definition: MPINodeCode.hpp:48