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

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6