Main Page | Class Hierarchy | Class List | File List | Class Members

/home/nutarojj/Desktop/adevs/include/adevs_par_simulator.h

00001 /***************
00002 Copyright (C) 2009 by James Nutaro
00003 
00004 This library is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU Lesser General Public
00006 License as published by the Free Software Foundation; either
00007 version 2 of the License, or (at your option) any later version.
00008 
00009 This library is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 Lesser General Public License for more details.
00013 
00014 You should have received a copy of the GNU Lesser General Public
00015 License along with this library; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 Bugs, comments, and questions can be sent to nutaro@gmail.com
00019 ***************/
00020 #ifndef __adevs_par_simulator_h_
00021 #define __adevs_par_simulator_h_
00022 #include "adevs_abstract_simulator.h"
00023 #include "adevs_msg_manager.h"
00024 #include "adevs_lp.h"
00025 #include "adevs_lp_graph.h"
00026 #include <cassert>
00027 #include <cstdlib>
00028 #include <iostream>
00029 #include <vector>
00030 
00031 namespace adevs
00032 {
00033 
00052 template <class X> class ParSimulator:
00053    public AbstractSimulator<X>  
00054 {
00055         public:
00061                 ParSimulator(Devs<X>* model, MessageManager<X>* msg_manager = NULL);
00068                 ParSimulator(Devs<X>* model, LpGraph& g, MessageManager<X>* msg_manager = NULL);
00070                 double nextEventTime();
00076                 void execUntil(double stop_time);
00082                 ~ParSimulator();
00083         private:
00084                 LogicalProcess<X>** lp;
00085                 int lp_count;
00086                 MessageManager<X>* msg_manager;
00087                 void init(Devs<X>* model);
00088                 void init_sim(Devs<X>* model, LpGraph& g);
00089 }; 
00090 
00091 template <class X>
00092 ParSimulator<X>::ParSimulator(Devs<X>* model, MessageManager<X>* msg_manager):
00093         AbstractSimulator<X>(),msg_manager(msg_manager)
00094 {
00095         // Create an all to all coupling
00096         lp_count = omp_get_max_threads();
00097         LpGraph g;
00098         for (int i = 0; i < lp_count; i++)
00099         {
00100                 for (int j = 0; j < lp_count; j++)
00101                 {
00102                         if (i != j)
00103                         {
00104                                 g.addEdge(i,j);
00105                                 g.addEdge(j,i);
00106                         }
00107                 }
00108         }
00109         init_sim(model,g);
00110 }
00111 
00112 template <class X>
00113 ParSimulator<X>::ParSimulator(Devs<X>* model, LpGraph& g, MessageManager<X>* msg_manager):
00114         AbstractSimulator<X>(),msg_manager(msg_manager)
00115 {
00116         init_sim(model,g);
00117 }
00118 
00119 template <class X>
00120 void ParSimulator<X>::init_sim(Devs<X>* model, LpGraph& g)
00121 {
00122         if (msg_manager == NULL) msg_manager = new NullMessageManager<X>();
00123         lp_count = omp_get_max_threads();
00124         lp = new LogicalProcess<X>*[lp_count];
00125         for (int i = 0; i < lp_count; i++)
00126         {
00127                 lp[i] = new LogicalProcess<X>(i,g.getI(i),g.getE(i),lp,this,msg_manager);
00128         }
00129         init(model);
00130 }
00131 
00132 template <class X>
00133 double ParSimulator<X>::nextEventTime()
00134 {
00135         Time tN = Time::Inf();
00136         for (int i = 0; i < lp_count; i++)
00137         {
00138                 if (lp[i]->getNextEventTime() < tN)
00139                         tN = lp[i]->getNextEventTime();
00140         }
00141         return tN.t;
00142 }
00143 
00144 template <class X>
00145 ParSimulator<X>::~ParSimulator<X>()
00146 {
00147         for (int i = 0; i < lp_count; i++)
00148                 delete lp[i];
00149         delete [] lp;
00150    delete msg_manager;  
00151 }
00152 
00153 template <class X>
00154 void ParSimulator<X>::execUntil(double tstop)
00155 {
00156         #pragma omp parallel
00157         {
00158                 lp[omp_get_thread_num()]->run(tstop);
00159         }
00160 }
00161 
00162 template <class X>
00163 void ParSimulator<X>::init(Devs<X>* model)
00164 {
00165         if (model->getProc() >= 0 && model->getProc() < lp_count)
00166         {
00167                 lp[model->getProc()]->addModel(model);
00168                 return;
00169         }
00170         Atomic<X>* a = model->typeIsAtomic();
00171         if (a != NULL)
00172         {
00173                 int lp_assign = a->getProc();
00174                 if (lp_assign < 0 || lp_assign >= lp_count)
00175                         lp_assign = ((long int)a)%lp_count;
00176                 lp[lp_assign]->addModel(a);
00177         }
00178         else
00179         {
00180                 Set<Devs<X>*> components;
00181                 model->typeIsNetwork()->getComponents(components);
00182                 typename Set<Devs<X>*>::iterator iter = components.begin();
00183                 for (; iter != components.end(); iter++)
00184                 {
00185                         init(*iter);
00186                 }
00187         }
00188 }
00189 
00190 } // End of namespace
00191 
00192 #endif

Generated on Mon Jun 1 09:53:42 2009 for adevs by  doxygen 1.3.9.1