adevs
adevs_par_simulator.h
1 
31 #ifndef __adevs_par_simulator_h_
32 #define __adevs_par_simulator_h_
33 #include "adevs_abstract_simulator.h"
34 #include "adevs_msg_manager.h"
35 #include "adevs_lp.h"
36 #include "adevs_lp_graph.h"
37 #include <cassert>
38 #include <cstdlib>
39 #include <iostream>
40 #include <vector>
41 #include <cstdio>
42 
43 namespace adevs
44 {
45 
55 template <class X, class T = double> class ParSimulator:
56  public AbstractSimulator<X,T>
57 {
58  public:
69  ParSimulator(Devs<X,T>* model, MessageManager<X>* msg_manager = NULL);
76  ParSimulator(Devs<X,T>* model, LpGraph& g,
77  MessageManager<X>* msg_manager = NULL);
79  T nextEventTime();
85  void execUntil(T stop_time);
91  ~ParSimulator();
92  private:
93  LogicalProcess<X,T>** lp;
94  int lp_count;
95  MessageManager<X>* msg_manager;
96  void init(Devs<X,T>* model);
97  void init_sim(Devs<X,T>* model, LpGraph& g);
98 };
99 
100 template <class X, class T>
102  AbstractSimulator<X,T>(),msg_manager(msg_manager)
103 {
104  // Create an all to all coupling
105  lp_count = omp_get_max_threads();
106  LpGraph g;
107  for (int i = 0; i < lp_count; i++)
108  {
109  for (int j = 0; j < lp_count; j++)
110  {
111  if (i != j)
112  {
113  g.addEdge(i,j);
114  g.addEdge(j,i);
115  }
116  }
117  }
118  init_sim(model,g);
119 }
120 
121 template <class X, class T>
123  MessageManager<X>* msg_manager):
124  AbstractSimulator<X,T>(),msg_manager(msg_manager)
125 {
126  init_sim(model,g);
127 }
128 
129 template <class X, class T>
131 {
132  if (msg_manager == NULL) msg_manager = new NullMessageManager<X>();
133  lp_count = g.getLPCount();
134  if (omp_get_max_threads() < lp_count)
135  {
136  char buffer[1000];
137  sprintf(buffer,"More LPs than threads. Set OMP_NUM_THREADS=%d.",
138  lp_count);
139  exception err(buffer);
140  throw err;
141  }
142  omp_set_num_threads(lp_count);
143  lp = new LogicalProcess<X,T>*[lp_count];
144  for (int i = 0; i < lp_count; i++)
145  {
146  lp[i] = new LogicalProcess<X,T>(i,g.getI(i),g.getE(i),
147  lp,this,msg_manager);
148  }
149  init(model);
150 }
151 
152 template <class X, class T>
154 {
155  Time<T> tN = Time<T>::Inf();
156  for (int i = 0; i < lp_count; i++)
157  {
158  if (lp[i]->getNextEventTime() < tN)
159  tN = lp[i]->getNextEventTime();
160  }
161  return tN.t;
162 }
163 
164 template <class X, class T>
166 {
167  for (int i = 0; i < lp_count; i++)
168  delete lp[i];
169  delete [] lp;
170  delete msg_manager;
171 }
172 
173 template <class X, class T>
175 {
176  #pragma omp parallel
177  {
178  lp[omp_get_thread_num()]->run(tstop);
179  }
180 }
181 
182 template <class X, class T>
184 {
185  if (model->getProc() >= 0 && model->getProc() < lp_count)
186  {
187  lp[model->getProc()]->addModel(model);
188  return;
189  }
190  Atomic<X,T>* a = model->typeIsAtomic();
191  if (a != NULL)
192  {
193  int lp_assign = a->getProc();
194  if (lp_assign < 0 || lp_assign >= lp_count)
195  lp_assign =
196  ((unsigned long int)(a)^(unsigned long int)(this))%lp_count;
197  lp[lp_assign]->addModel(a);
198  }
199  else
200  {
201  Set<Devs<X,T>*> components;
202  model->typeIsNetwork()->getComponents(components);
203  typename Set<Devs<X,T>*>::iterator iter = components.begin();
204  for (; iter != components.end(); iter++)
205  {
206  init(*iter);
207  }
208  }
209 }
210 
211 } // end of namespace
212 
213 #endif
static adevs::Time< T > Inf()
Value for infinity.
Definition: adevs_time.h:58
Definition: adevs_abstract_simulator.h:45
Definition: adevs_msg_manager.h:63
Definition: adevs_par_simulator.h:55
T nextEventTime()
Get the model's next event time.
Definition: adevs_par_simulator.h:153
int getProc()
Definition: adevs_models.h:130
Definition: adevs_lp_graph.h:46
Definition: adevs_exception.h:43
Definition: adevs_msg_manager.h:41
~ParSimulator()
Definition: adevs_par_simulator.h:165
Definition: adevs_time.h:53
virtual Network< X, T > * typeIsNetwork()
Definition: adevs_models.h:81
const std::vector< int > & getI(int B)
Get the influencers of node B.
Definition: adevs_lp_graph.h:66
virtual Atomic< X, T > * typeIsAtomic()
Returns NULL if this is not an atomic model; returns itself otherwise.
Definition: adevs_models.h:83
Definition: adevs_models.h:63
void execUntil(T stop_time)
Definition: adevs_par_simulator.h:174
int getLPCount() const
Get the number of LPs.
Definition: adevs_lp_graph.h:64
void addEdge(int A, int B)
Create an edge from node A to node B.
Definition: adevs_lp_graph.h:52
const std::vector< int > & getE(int A)
Get the influencees of node A.
Definition: adevs_lp_graph.h:68
ParSimulator(Devs< X, T > *model, MessageManager< X > *msg_manager=NULL)
Definition: adevs_par_simulator.h:101