sp_pexecutor.hGo 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 |