CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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 <map>
00028 #include <exception>
00029 #include <sstream>
00030 
00031 #include "FWCore/Framework/src/RunStopwatch.h"
00032 
00033 namespace edm {
00034   class EventPrincipal;
00035   class RunPrincipal;
00036   class LuminosityBlockPrincipal;
00037   class EarlyDeleteHelper;
00038 
00039   class Path {
00040   public:
00041     typedef hlt::HLTState State;
00042 
00043     typedef std::vector<WorkerInPath> WorkersInPath;
00044     typedef WorkersInPath::size_type        size_type;
00045     typedef boost::shared_ptr<HLTGlobalStatus> TrigResPtr;
00046 
00047     Path(int bitpos, std::string const& path_name,
00048          WorkersInPath const& workers,
00049          TrigResPtr trptr,
00050          ActionTable const& actions,
00051          boost::shared_ptr<ActivityRegistry> reg,
00052          bool isEndPath);
00053 
00054     template <typename T>
00055     void processOneOccurrence(typename T::MyPrincipal&, EventSetup const&);
00056 
00057     int bitPosition() const { return bitpos_; }
00058     std::string const& name() const { return name_; }
00059 
00060     std::pair<double, double> timeCpuReal() const {
00061       if(stopwatch_) {
00062         return std::pair<double, double>(stopwatch_->cpuTime(), stopwatch_->realTime());
00063       }
00064       return std::pair<double, double>(0., 0.);
00065     }
00066 
00067     std::pair<double, double> timeCpuReal(unsigned int const i) const {
00068       return workers_.at(i).timeCpuReal();
00069     }
00070 
00071     void clearCounters();
00072 
00073     int timesRun() const { return timesRun_; }
00074     int timesPassed() const { return timesPassed_; }
00075     int timesFailed() const { return timesFailed_; }
00076     int timesExcept() const { return timesExcept_; }
00077     //int abortWorker() const { return abortWorker_; }
00078     State state() const { return state_; }
00079 
00080     size_type size() const { return workers_.size(); }
00081     int timesVisited(size_type i) const { return workers_.at(i).timesVisited(); }
00082     int timesPassed (size_type i) const { return workers_.at(i).timesPassed() ; }
00083     int timesFailed (size_type i) const { return workers_.at(i).timesFailed() ; }
00084     int timesExcept (size_type i) const { return workers_.at(i).timesExcept() ; }
00085     Worker const* getWorker(size_type i) const { return workers_.at(i).getWorker(); }
00086     
00087     void setEarlyDeleteHelpers(std::map<const Worker*,EarlyDeleteHelper*> const&);
00088 
00089     void useStopwatch();
00090   private:
00091     RunStopwatch::StopwatchPointer stopwatch_;
00092     int timesRun_;
00093     int timesPassed_;
00094     int timesFailed_;
00095     int timesExcept_;
00096     //int abortWorker_;
00097     State state_;
00098 
00099     int bitpos_;
00100     std::string name_;
00101     TrigResPtr trptr_;
00102     boost::shared_ptr<ActivityRegistry> actReg_;
00103     ActionTable const* act_table_;
00104 
00105     WorkersInPath workers_;
00106     std::vector<EarlyDeleteHelper*> earlyDeleteHelpers_;
00107 
00108     bool isEndPath_;
00109 
00110     // Helper functions
00111     // nwrwue = numWorkersRunWithoutUnhandledException (really!)
00112     bool handleWorkerFailure(cms::Exception & e,
00113                              int nwrwue,
00114                              bool isEvent,
00115                              bool begin,
00116                              BranchType branchType,
00117                              CurrentProcessingContext const& cpc,
00118                              std::string const& id);
00119     static void exceptionContext(cms::Exception & ex,
00120                                  bool isEvent,
00121                                  bool begin,
00122                                  BranchType branchType,
00123                                  CurrentProcessingContext const& cpc,
00124                                  std::string const& id);
00125     void recordStatus(int nwrwue, bool isEvent);
00126     void updateCounters(bool succeed, bool isEvent);
00127     
00128     void handleEarlyFinish(EventPrincipal&);
00129     void handleEarlyFinish(RunPrincipal&) {}
00130     void handleEarlyFinish(LuminosityBlockPrincipal&) {}
00131   };
00132 
00133   namespace {
00134     template <typename T>
00135     class PathSignalSentry {
00136     public:
00137       PathSignalSentry(ActivityRegistry *a,
00138                        std::string const& name,
00139                        int const& nwrwue,
00140                        hlt::HLTState const& state) :
00141       a_(a), name_(name), nwrwue_(nwrwue), state_(state) {
00142         if (a_) T::prePathSignal(a_, name_);
00143       }
00144       ~PathSignalSentry() {
00145         HLTPathStatus status(state_, nwrwue_);
00146         if(a_) T::postPathSignal(a_, name_, status);
00147       }
00148     private:
00149       ActivityRegistry* a_;
00150       std::string const& name_;
00151       int const& nwrwue_;
00152       hlt::HLTState const& state_;
00153     };
00154   }
00155 
00156   template <typename T>
00157   void Path::processOneOccurrence(typename T::MyPrincipal& ep, EventSetup const& es) {
00158 
00159     //Create the PathSignalSentry before the RunStopwatch so that
00160     // we only record the time spent in the path not from the signal
00161     int nwrwue = -1;
00162     PathSignalSentry<T> signaler(actReg_.get(), name_, nwrwue, state_);
00163 
00164     // A RunStopwatch, but only if we are processing an event.
00165     RunStopwatch stopwatch(T::isEvent_ ? stopwatch_ : RunStopwatch::StopwatchPointer());
00166 
00167     if (T::isEvent_) {
00168       ++timesRun_;
00169     }
00170     state_ = hlt::Ready;
00171 
00172     // nwrue =  numWorkersRunWithoutUnhandledException
00173     bool should_continue = true;
00174     CurrentProcessingContext cpc(&name_, bitPosition(), isEndPath_);
00175 
00176     WorkersInPath::size_type idx = 0;
00177     // It seems likely that 'nwrwue' and 'idx' can never differ ---
00178     // if so, we should remove one of them!.
00179     for (WorkersInPath::iterator i = workers_.begin(), end = workers_.end();
00180           i != end && should_continue;
00181           ++i, ++idx) {
00182       ++nwrwue;
00183       assert (static_cast<int>(idx) == nwrwue);
00184       try {
00185         try {
00186           cpc.activate(idx, i->getWorker()->descPtr());
00187           should_continue = i->runWorker<T>(ep, es, &cpc);
00188         }
00189         catch (cms::Exception& e) { throw; }
00190         catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00191         catch (std::exception& e) { convertException::stdToEDM(e); }
00192         catch(std::string& s) { convertException::stringToEDM(s); }
00193         catch(char const* c) { convertException::charPtrToEDM(c); }
00194         catch (...) { convertException::unknownToEDM(); }
00195       }
00196       catch(cms::Exception& ex) {
00197         // handleWorkerFailure may throw a new exception.
00198         std::ostringstream ost;
00199         ost << ep.id();
00200         should_continue = handleWorkerFailure(ex, nwrwue, T::isEvent_, T::begin_, T::branchType_, cpc, ost.str());
00201       }
00202     }
00203     if (not should_continue) {
00204       handleEarlyFinish(ep);
00205     }
00206     updateCounters(should_continue, T::isEvent_);
00207     recordStatus(nwrwue, T::isEvent_);
00208   }
00209 
00210 }
00211 
00212 #endif