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

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen