CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/FWCore/Framework/src/Path.h

Go to the documentation of this file.
00001 #ifndef FWCore_Framework_Path_h
00002 #define FWCore_Framework_Path_h
00003 
00004 /*
00005   Author: Jim Kowalkowski 28-01-06
00006 
00007   An object of this type represents one path in a job configuration.
00008   It holds the assigned bit position and the list of workers that are
00009   an event must pass through when this parh is processed.  The workers
00010   are held in WorkerInPath wrappers so that per path execution statistics
00011   can be kept for each worker.
00012 */
00013 
00014 #include "FWCore/Framework/interface/CurrentProcessingContext.h"
00015 #include "FWCore/Framework/src/WorkerInPath.h"
00016 #include "FWCore/Framework/src/Worker.h"
00017 #include "DataFormats/Common/interface/HLTenums.h"
00018 #include "DataFormats/Common/interface/TriggerResults.h"
00019 #include "FWCore/Utilities/interface/BranchType.h"
00020 #include "FWCore/Utilities/interface/Exception.h"
00021 #include "FWCore/Utilities/interface/ConvertException.h"
00022 
00023 #include "boost/shared_ptr.hpp"
00024 
00025 #include <string>
00026 #include <vector>
00027 #include <exception>
00028 #include <sstream>
00029 
00030 #include "FWCore/Framework/src/RunStopwatch.h"
00031 
00032 namespace edm {
00033 
00034   class Path {
00035   public:
00036     typedef hlt::HLTState State;
00037 
00038     typedef std::vector<WorkerInPath> WorkersInPath;
00039     typedef WorkersInPath::size_type        size_type;
00040     typedef boost::shared_ptr<HLTGlobalStatus> TrigResPtr;
00041 
00042     Path(int bitpos, std::string const& path_name,
00043          WorkersInPath const& workers,
00044          TrigResPtr trptr,
00045          ActionTable const& actions,
00046          boost::shared_ptr<ActivityRegistry> reg,
00047          bool isEndPath);
00048 
00049     template <typename T>
00050     void processOneOccurrence(typename T::MyPrincipal&, EventSetup const&);
00051 
00052     int bitPosition() const { return bitpos_; }
00053     std::string const& name() const { return name_; }
00054 
00055     std::pair<double, double> timeCpuReal() const {
00056       if(stopwatch_) {
00057         return std::pair<double, double>(stopwatch_->cpuTime(), stopwatch_->realTime());
00058       }
00059       return std::pair<double, double>(0., 0.);
00060     }
00061 
00062     std::pair<double, double> timeCpuReal(unsigned int const i) const {
00063       return workers_.at(i).timeCpuReal();
00064     }
00065 
00066     void clearCounters();
00067 
00068     int timesRun() const { return timesRun_; }
00069     int timesPassed() const { return timesPassed_; }
00070     int timesFailed() const { return timesFailed_; }
00071     int timesExcept() const { return timesExcept_; }
00072     //int abortWorker() const { return abortWorker_; }
00073     State state() const { return state_; }
00074 
00075     size_type size() const { return workers_.size(); }
00076     int timesVisited(size_type i) const { return workers_.at(i).timesVisited(); }
00077     int timesPassed (size_type i) const { return workers_.at(i).timesPassed() ; }
00078     int timesFailed (size_type i) const { return workers_.at(i).timesFailed() ; }
00079     int timesExcept (size_type i) const { return workers_.at(i).timesExcept() ; }
00080     Worker const* getWorker(size_type i) const { return workers_.at(i).getWorker(); }
00081 
00082     void useStopwatch();
00083   private:
00084     RunStopwatch::StopwatchPointer stopwatch_;
00085     int timesRun_;
00086     int timesPassed_;
00087     int timesFailed_;
00088     int timesExcept_;
00089     //int abortWorker_;
00090     State state_;
00091 
00092     int bitpos_;
00093     std::string name_;
00094     TrigResPtr trptr_;
00095     boost::shared_ptr<ActivityRegistry> actReg_;
00096     ActionTable const* act_table_;
00097 
00098     WorkersInPath workers_;
00099 
00100     bool isEndPath_;
00101 
00102     // Helper functions
00103     // nwrwue = numWorkersRunWithoutUnhandledException (really!)
00104     bool handleWorkerFailure(cms::Exception & e,
00105                              int nwrwue,
00106                              bool isEvent,
00107                              bool begin,
00108                              BranchType branchType,
00109                              CurrentProcessingContext const& cpc,
00110                              std::string const& id);
00111     static void exceptionContext(cms::Exception & ex,
00112                                  bool isEvent,
00113                                  bool begin,
00114                                  BranchType branchType,
00115                                  CurrentProcessingContext const& cpc,
00116                                  std::string const& id);
00117     void recordStatus(int nwrwue, bool isEvent);
00118     void updateCounters(bool succeed, bool isEvent);
00119   };
00120 
00121   namespace {
00122     template <typename T>
00123     class PathSignalSentry {
00124     public:
00125       PathSignalSentry(ActivityRegistry *a,
00126                        std::string const& name,
00127                        int const& nwrwue,
00128                        hlt::HLTState const& state) :
00129       a_(a), name_(name), nwrwue_(nwrwue), state_(state) {
00130         if (a_) T::prePathSignal(a_, name_);
00131       }
00132       ~PathSignalSentry() {
00133         HLTPathStatus status(state_, nwrwue_);
00134         if(a_) T::postPathSignal(a_, name_, status);
00135       }
00136     private:
00137       ActivityRegistry* a_;
00138       std::string const& name_;
00139       int const& nwrwue_;
00140       hlt::HLTState const& state_;
00141     };
00142   }
00143 
00144   template <typename T>
00145   void Path::processOneOccurrence(typename T::MyPrincipal& ep, EventSetup const& es) {
00146 
00147     //Create the PathSignalSentry before the RunStopwatch so that
00148     // we only record the time spent in the path not from the signal
00149     int nwrwue = -1;
00150     PathSignalSentry<T> signaler(actReg_.get(), name_, nwrwue, state_);
00151 
00152     // A RunStopwatch, but only if we are processing an event.
00153     RunStopwatch stopwatch(T::isEvent_ ? stopwatch_ : RunStopwatch::StopwatchPointer());
00154 
00155     if (T::isEvent_) {
00156       ++timesRun_;
00157     }
00158     state_ = hlt::Ready;
00159 
00160     // nwrue =  numWorkersRunWithoutUnhandledException
00161     bool should_continue = true;
00162     CurrentProcessingContext cpc(&name_, bitPosition(), isEndPath_);
00163 
00164     WorkersInPath::size_type idx = 0;
00165     // It seems likely that 'nwrwue' and 'idx' can never differ ---
00166     // if so, we should remove one of them!.
00167     for (WorkersInPath::iterator i = workers_.begin(), end = workers_.end();
00168           i != end && should_continue;
00169           ++i, ++idx) {
00170       ++nwrwue;
00171       assert (static_cast<int>(idx) == nwrwue);
00172       try {
00173         try {
00174           cpc.activate(idx, i->getWorker()->descPtr());
00175           should_continue = i->runWorker<T>(ep, es, &cpc);
00176         }
00177         catch (cms::Exception& e) { throw; }
00178         catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00179         catch (std::exception& e) { convertException::stdToEDM(e); }
00180         catch(std::string& s) { convertException::stringToEDM(s); }
00181         catch(char const* c) { convertException::charPtrToEDM(c); }
00182         catch (...) { convertException::unknownToEDM(); }
00183       }
00184       catch(cms::Exception& ex) {
00185         // handleWorkerFailure may throw a new exception.
00186         std::ostringstream ost;
00187         ost << ep.id();
00188         should_continue = handleWorkerFailure(ex, nwrwue, T::isEvent_, T::begin_, T::branchType_, cpc, ost.str());
00189       }
00190     }
00191     updateCounters(should_continue, T::isEvent_);
00192     recordStatus(nwrwue, T::isEvent_);
00193   }
00194 
00195 }
00196 
00197 #endif