libFAUDES

Sections

Index

sp_pexecutor.h

Go to the documentation of this file.
00001 /** @file sp_pexecutor.h Executor for multiple synchronized timed generators  */
00002 
00003 /* 
00004    FAU Discrete Event Systems Library (libfaudes)
00005 
00006    Copyright (C) 2007, 2008 Thomas Moor
00007    Copyright (C) 2007 Ruediger Berndt
00008    Exclusive copyright is granted to Klaus Schmidt
00009 
00010 */
00011 
00012 
00013 
00014 #ifndef FAUDES_PEXECUTOR_H
00015 #define FAUDES_PEXECUTOR_H
00016 
00017 #include "corefaudes.h"
00018 #include "tp_include.h"
00019 #include "sp_executor.h"
00020 #include "sp_simconditionset.h"
00021 
00022 
00023 namespace faudes {
00024 
00025 /**
00026  * Synchronized parallel execution of tGenerators
00027  *
00028  * \section SecSimulatorPEX1 Synchronisation
00029  *
00030  * The ParallelExecutor executes a family of timed generators with synchronized shared
00031  * events according to Alur semantics. That is, we assume disjoint clock sets and synchronize 
00032  * shared events w.r.t. occurence at clock time. 
00033  *
00034  * \section SecSimulatorPEX2 Implementation
00035  *
00036  * The external interface of a ParallelExecutor is the same as the single Executor, in that 
00037  * it indicats enabled events and in that it provides methods for executing
00038  * events or letting time pass.
00039  *
00040  * Technically, a ParallelExecutor is a vector of executors. Clocks 
00041  * are treated on a per executor basis. That is,  values of clocks in one generator are
00042  * not effected by the reset of another generator, even if the respestive clock variables 
00043  * have the same index and name.
00044  *
00045  * \section SecSimulatorPEX3 File IO
00046  *
00047  * For token IO, the ParallelExecutor reads and writes the generators to execute within a
00048  * section with default label "Executor". For disk space efficiency, the token IO 
00049  * format will use refernces by (relative) filename if the latter is known. Since tGenerators
00050  * read any generator type from file, so does the ParallelExecutor. Example:
00051  *
00052  * \code
00053  * <Executor>
00054  * <Generators>
00055  * "./some_generator.gen"
00056  * "./other_generator.gen"
00057  * </Generators>
00058  * </Executor>
00059  * \endcode
00060  *
00061  * @ingroup SimulatorPlugin 
00062  */
00063 
00064 class ParallelExecutor : public Type {    
00065 
00066  public:
00067   /** Typedef for parallel discrete state*/
00068   typedef std::vector<Idx> ParallelState;
00069   
00070   /** Typedef for parallel clock values */
00071   typedef std::vector< std::map<Idx,tpTime::Type> > ParallelClock;
00072 
00073   /** Typedef for parallel timed state, incl token io */
00074   class ParallelTimedState : public Type {
00075   public:
00076     ParallelState State;
00077     ParallelClock Clock;
00078   protected:
00079     virtual void DoRead(TokenReader& rTr,  const std::string& rLabel = "", const Type* pContext=0);
00080     virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="",const Type* pContext=0) const;
00081   };
00082 
00083   /** Provide typedef from Executor */
00084   typedef Executor::TimedState TimedState;
00085 
00086   /**
00087    * Construct an emtpy ParallelExecuter
00088    */
00089   ParallelExecutor(void);
00090 
00091   /**
00092    * Construct from file.
00093    *
00094    * This constructor uses the DoRead method to initialize from file.
00095    *
00096    * @param rFileName
00097    *   Filename
00098    *
00099    * @exception Exception
00100    *   - non-deteministic generator (id 501)
00101    *   - token mismatch (id 502)
00102    *   - IO errors (id 1)
00103    */
00104   ParallelExecutor(const std::string& rFileName);
00105 
00106 
00107   /**
00108    * Explicit destructor.
00109    */
00110   virtual ~ParallelExecutor(void);
00111 
00112   /**
00113    * Clear all data. Removes  all generators/executors and resets the
00114    * current state to a void value.
00115    *
00116    */
00117   virtual void Clear(void);
00118 
00119   /**
00120    * Number of tGenerators
00121    *
00122    */
00123   Idx Size(void) const;
00124 
00125         
00126   /**
00127    * Add a tGenerator from file.  This method uses the tGenerator's read to
00128    * find the first generator in the file. If the generator found is not a tGenerator,
00129    * timing data defaults to infinite invariants/guards and empty resets.
00130    * After inserting generators and before starting to execute, you must call Reset() to update
00131    * internal datastructures.
00132    *
00133    * @param rFileName
00134    *   File to read
00135    *
00136    * @exception Exception
00137    *   - non-deteministic generator (id 501)
00138    *   - token mismatch (id 502)
00139    *   - IO errors (id 1)
00140    */
00141   void Insert(const std::string& rFileName);
00142 
00143   /**
00144    * Add a tGenerator. 
00145    * After inserting generators and before starting to execute, you must call Reset() to update
00146    * internal datastructures.
00147    *
00148    * @param rGen
00149    *   Generator to add
00150    *
00151    * @exception Exception
00152    *   - non-deteministic generator (id 501)
00153    */
00154   void Insert(const tGenerator& rGen);
00155 
00156   /** 
00157    * Overall alphabet. 
00158    *
00159    */
00160   const EventSet& Alphabet(void) const;
00161 
00162   /** 
00163    * Goto initial state. Reset all clock values to zero, assign initial states to each executor. 
00164    */
00165   virtual void Reset(void);
00166 
00167 
00168 
00169   /** 
00170    * Read-only access to individual executors. 
00171    * 
00172    */ 
00173   typedef std::vector<Executor>::const_iterator Iterator;
00174   Iterator       Begin(void) const       { return mExecutors.begin(); };
00175   Iterator       End(void)   const      { return mExecutors.end(); };
00176   const Executor& At(int i)  const { return mExecutors.at(i); };
00177 
00178 
00179   /**
00180    * Event index lookup.
00181    *
00182    * This convenience method refers to the global event symbol table.
00183    * 
00184    * @param rName
00185    *    Name of event to lookup
00186    *
00187    * @return 
00188    *   Valid index or 0 if non-existent
00189    */
00190   Idx EventIndex(const std::string& rName) const { return mAlphabet.Index(rName); };
00191 
00192   /** 
00193    * Event name lookup 
00194    *
00195    * This convenience method refers to the global event symbol table.
00196    *
00197    * @param index
00198    *   Index of event to look up
00199    *
00200    * @return 
00201    *   Name or empty std::string if non-existent
00202    */
00203   std::string EventName(Idx index) const { return mAlphabet.SymbolicName(index); };
00204    
00205   /** 
00206    * Get clock time.
00207    *
00208    */
00209   tpTime::Type CurrentTime(void) const;
00210 
00211   /** 
00212    * Get logical time, ie number of transitions so far,
00213    *
00214    */
00215   int CurrentStep(void) const;
00216 
00217   /** 
00218    * Test for deadlocked.
00219    *
00220    * The parallel executor is deadlocked if neither time can pass nor an event can
00221    * be executed. Prototypical examples for such a situation is that the indvidual
00222    * executers fail to agree on a common time interval, at which shaered events are
00223    * enabled.
00224    *
00225    *  @return True/false
00226    */
00227   bool IsDeadlocked() const;
00228 
00229   /** 
00230    * Check validity of executors.
00231    *
00232    * This is currently not implemented.
00233    *
00234    * @return 
00235    *   True on success
00236    */
00237    virtual bool Valid(void) const {return true;};
00238 
00239   /** 
00240    * Get current state of the ParallelExecutor.
00241    *
00242    * With "the current state" w refer to all data relevant for 
00243    * events generated in future. This data consists of a discrete
00244    * state vector and a mapping from clocks to closk values. 
00245    *
00246    *  @return 
00247    *    Discrete state vector and clock value maps
00248    */
00249   const ParallelTimedState& CurrentParallelTimedState(void) const;
00250 
00251   /** 
00252    * Get current discrete state vector of the ParallelExecutor 
00253    *
00254    * By "the current discrete state" we refer to a vector of indices
00255    * that indicate the current state of the untimed transition structure.
00256    *
00257    *   @return 
00258    *      Discrete state vector
00259    */
00260   const ParallelState& CurrentParallelState(void) const;
00261 
00262   /** 
00263    * Set clock time. 
00264    * This does not affect clocks and, hence, is purely cosmetic.
00265    * The trace buffer will record an invalid event.
00266    *
00267    *  @param time
00268    *  New clock time 
00269    */
00270   virtual void CurrentTime(tpTime::Type time);
00271 
00272   /** 
00273    * Set logical time (# of steps)
00274    *
00275    * This does not affect clocks and, hence, is purely cosmetic.
00276    * Note that, in contrast to clock time, the individual
00277    * generators do not agree in logical time. 
00278    * The trace buffer will get out of order and should be cleared.
00279    *
00280    *  @param step
00281    *   New logical time 
00282    */
00283   virtual void CurrentStep(int step);
00284 
00285   /** 
00286    * Set current state of the ParallelExecutor.
00287    *
00288    * This resets the parallel executor to the given state, incl clock values.
00289    * Both, clock time and logical time is also reset (to 0).
00290    *
00291    *  @return 
00292    *    True for success
00293    */
00294    virtual bool CurrentParallelTimedState(const ParallelTimedState& ptstate);
00295 
00296   /** 
00297    * Let time pass without executing a transition. Return false if the duration specified  
00298    * cannot elapse without an event being executed.
00299    *
00300    * @param duration
00301    *    Amount of time that shall elapse.
00302    * @return
00303    *   True for success
00304    */
00305   virtual bool ExecuteTime(tpTime::Type duration);
00306 
00307   /** 
00308    * Execute transition.
00309    *
00310    * Returns false if the transition
00311    * cannot be executed at the current time.
00312    *
00313    * @param event
00314    *   Indicate transition to execute
00315    * @return
00316    *   True on success
00317    */
00318   virtual bool ExecuteEvent(Idx event);
00319 
00320   /**
00321    * Get maximal duration that can pass without executing an event.
00322    *
00323    *  @return TimeInterval 
00324    *  
00325    */
00326   const TimeInterval& EnabledTime() const;
00327 
00328   /**
00329    *  Get events that are enabled at current (timed) state.
00330    *   
00331    *  By "enabled" we refer to the synchronizes timed generators,
00332    * that is, we do care about clock values, invariants and guards.
00333    *
00334    *
00335    *  @return 
00336    *     Set of enabled events
00337    */
00338   const EventSet& EnabledEvents() const;
00339 
00340   /**
00341    * Get events that are disabled at current (timed) state
00342    *
00343    *  By "disabled" we refer to the synchronizes timed generators,
00344    * that is, we do care about clock values, invariants and guards.
00345    *
00346    *  @return 
00347    *     Set of disabled events
00348    */
00349   const EventSet& DisabledEvents() const;
00350 
00351   /**
00352    *  Get an interval on which the set of enabled events is constant.
00353    *  Note: while this implementation tries to come up with a potentially large
00354    *  interval, it is not guaranteed to be maximal.
00355    *
00356    *  @return TimeInterval 
00357    *  
00358    */
00359   const TimeInterval& EnabledInterval() const;
00360 
00361   /**
00362    *  Get interval on which the specified event is enabled.
00363    *
00364    *  Returns empty, if the event is not active or never 
00365    *  simultanuosly enabled in all executors.
00366    *
00367    *  @param event
00368    *
00369    *  @return TimeInterval 
00370    *  
00371    */
00372   TimeInterval EnabledEventTime(Idx event) const;
00373 
00374   /**
00375    *  Get interval on which the respective guard is satisfied.
00376    *
00377    *  Returns empty, if the event is not active or if the guards  
00378    *  are never simultanuosly satisfied in all executors.
00379    *
00380    *  @param event
00381    *
00382    *  @return TimeInterval 
00383    *  
00384    */
00385   TimeInterval EnabledGuardTime(Idx event) const;
00386 
00387   /** 
00388    * Get events that are active in all tGenerators.
00389    *
00390    * By "active" we refer to the untimed transition structure,
00391    * that is, we ignore clock values etc.
00392    *
00393    *  @param stateVec
00394    *     Discrete state
00395    *  @return 
00396    *     Active EventSet
00397    */
00398   EventSet ActiveEventSet(const ParallelState& stateVec) const;
00399 
00400   /**  
00401    * Test whether an event is active in a given discrete state.
00402    *
00403    * By "active" we refer to the untimed transition structure,
00404    * that is, we ignore clock values etc.
00405    *
00406    *   @param ev
00407    *     Event to test 
00408    *   @param stateVec
00409    *     ParallelState
00410    *
00411    *   @return 
00412    *     True for active in all generators
00413    */
00414   bool Active(Idx ev, const ParallelState& stateVec) const;   
00415 
00416   /**
00417    * Test whether an event is active at current (discrete) state.
00418    *
00419    * By "active" we refer to the untimed transition structure,
00420    * that is, we ignore clock values etc.
00421    *
00422    *   @param ev
00423    *      Event ro test
00424    *
00425    *   @return 
00426    *      True for active in all generators
00427    */
00428   bool Active(Idx ev) const;
00429 
00430   /** 
00431    * Pretty printable string of timed parallel state
00432    */
00433   std::string PTSStr(const ParallelTimedState& ptstate) const;
00434 
00435   /** 
00436    * Pretty printable string of parallel state
00437    */
00438   std::string PSStr(const ParallelState& pstate) const;
00439 
00440   /** 
00441    * Pretty printable string of timed event
00442    */
00443   std::string TEStr(const TimedEvent& tevent) const;
00444 
00445   /** 
00446    * Pretty printable string of clock name
00447    */
00448   std::string CStr(Idx clock) const;
00449 
00450   /** 
00451    * Pretty printable string of event
00452    */
00453   std::string EStr(Idx event) const;
00454 
00455   /** 
00456    * Pretty printable string of current state
00457    */
00458   std::string CurrentParallelTimedStateStr(void) const; 
00459 
00460   /** 
00461    * Pretty printable string of parallel state          
00462    */
00463   std::string CurrentParallelStateStr(void) const;
00464 
00465   /** Compute enabled events and enabled interval (fake const) */
00466   /** this is public only for performance experiments --- dont use */
00467   void ComputeEnabled(void) const;
00468 
00469   /** Compute enabled core routine (non const) */
00470   void ComputeEnabledNonConst(void);
00471 
00472 
00473 
00474 protected:
00475 
00476   /**
00477    * Reads parallel executor from TokenReader, see also public wrappers Read() in faudes::Type.
00478    *
00479    * @param rTr
00480    *   TokenReader to read from
00481    * @param rLabel
00482    *   Section to read, defaults to "Executor"
00483    * @param pContext
00484    *   Read context to provide contextual information (ignored)
00485    *
00486    * @exception Exception
00487    *   - non-deterministic generator(s) (id 501)
00488    *   - token mismatch (id 502)
00489    *   - IO error (id 1)
00490    */
00491   virtual void DoRead(TokenReader& rTr,  const std::string& rLabel = "",  const Type* pContext=0);
00492  
00493   /**
00494    * Write to TokenWriter, see also public wrappers Write() in faudes::Type.
00495    *
00496    *
00497    * @param rTw
00498    *   Reference to TokenWriter
00499    * @param rLabel
00500    *   Label of section to write, defaults to "Executor"
00501    * @param pContext
00502    *   Write context to provide contextual information (ignored)
00503    *
00504    * @exception Exception 
00505    *   - IO errors (id 2)
00506    */
00507   virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const;
00508 
00509   /**
00510    * Reads generator files section from TokenReader
00511    *
00512    * @param rTr
00513    *   TokenReader to read from
00514    *
00515    * @exception Exception
00516    *   - non-deterministic generator(s) (id 501)
00517    *   - token mismatch (id 502)
00518    *   - IO error (id 1)
00519    */
00520   virtual void DoReadGenerators(TokenReader& rTr);
00521  
00522   /**
00523    * Write generator files section to TokenWriter
00524    *
00525    * @param rTw
00526    *   Reference to TokenWriter
00527    *
00528    * @exception Exception 
00529    *   - IO errors (id 2)
00530    */
00531   virtual void DoWriteGenerators(TokenWriter& rTw) const;
00532 
00533 
00534   /** compile internal data (eg overall alphabet) */
00535   virtual void Compile();
00536 
00537 
00538   /** recent event */
00539   Idx mRecentEvent;
00540 
00541 private:
00542      
00543   /** list of executors */
00544   std::vector<Executor> mExecutors;
00545 
00546   /** list of executors */
00547   std::vector<std::string> mExecutorNames;
00548 
00549   /** Internal non-const iterator */
00550   typedef std::vector<Executor>::iterator iterator;
00551 
00552   /** overall alphabet */
00553   EventSet mAlphabet;
00554 
00555   /** global time (real) */
00556   tpTime::Type mCurrentTime;
00557 
00558   /** global time (step)*/
00559   int mCurrentStep;
00560 
00561   /** enabled time */
00562   TimeInterval mETime;
00563 
00564   /** enabled events */
00565   EventSet mEEvents;
00566 
00567   /** disabled events */
00568   EventSet mDEvents;
00569 
00570   /** enabled interval */
00571   TimeInterval mEInterval;
00572 
00573   /** validity flag for fevents and ftime */
00574   bool mEValid;
00575 
00576   /** current state */
00577   ParallelTimedState mCurrentParallelTimedState;
00578 
00579   /** update parallel timed state() */
00580   void UpdateParallelTimedState(void);
00581 
00582 
00583 
00584 
00585 }; // end class ParallelExecutor
00586 
00587 
00588 
00589 } // namespace faudes
00590 
00591 
00592 #endif
00593 

libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3