Generated on Tue Apr 18 10:22:07 2017 for Gecode by doxygen 1.6.3

trace-recorder.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2016
00008  *
00009  *  Last modified:
00010  *     $Date: 2017-03-17 23:04:57 +0100 (Fri, 17 Mar 2017) $ by $Author: schulte $
00011  *     $Revision: 15597 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 namespace Gecode {
00039 
00044   enum TraceEvent {
00046 
00047     TE_INIT  = 1 << 0, 
00048     TE_PRUNE = 1 << 1, 
00049     TE_FIX   = 1 << 2, 
00050     TE_FAIL  = 1 << 3, 
00051     TE_DONE  = 1 << 4, 
00052 
00053 
00054     TE_PROPAGATE = 1 << 5, 
00055     TE_COMMIT    = 1 << 6  
00056   };
00057 
00062   template<class View>
00063   class ViewTraceRecorder : public Propagator {
00064   public:
00066     typedef typename TraceTraits<View>::TraceView TraceView;
00068     typedef typename TraceTraits<View>::TraceDelta TraceDelta;
00070     typedef typename TraceTraits<View>::SlackValue SlackValue;
00072     class Slack {
00073       template<class ViewForTraceRecorder> friend class ViewTraceRecorder;
00074     protected:
00076       SlackValue i;
00078       SlackValue p;
00080       SlackValue c;
00081     public:
00083       SlackValue initial(void) const;
00085       SlackValue previous(void) const;
00087       SlackValue current(void) const;
00088     };
00089   protected:
00091     class Idx : public Advisor {
00092     protected:
00094       int _idx;
00095     public:
00097       Idx(Space& home, Propagator& p, Council<Idx>& c, int i);
00099       Idx(Space& home, bool share, Idx& a);
00101       int idx(void) const;
00102     };
00104     ViewArray<TraceView> o;
00106     ViewArray<View> n;
00108     Council<Idx> c;
00110     TraceFilter tf;
00112     int te;
00114     ViewTracer<View>& t;
00116     Slack s;
00118     ViewTraceRecorder(Space& home, bool share, ViewTraceRecorder& p);
00119   public:
00121     ViewTraceRecorder(Home home, ViewArray<View>& x,
00122                       TraceFilter tf, int te, ViewTracer<View>& t);
00124     virtual Propagator* copy(Space& home, bool share);
00126     virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00128     virtual void reschedule(Space& home);
00130     virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
00132     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00134     virtual size_t dispose(Space& home);
00136     static ExecStatus post(Home home, ViewArray<View>& x,
00137                            TraceFilter tf, int te, ViewTracer<View>& t);
00139 
00140 
00141     const typename View::VarType operator [](int i) const;
00143     int size(void) const;
00145     const Slack& slack(void) const;
00147   };
00148 
00157   class TraceRecorder : public Propagator {
00158   public:
00160     TraceFilter tf;
00162     int te;
00164     Tracer& t;
00166     TraceRecorder(Space& home, bool share, TraceRecorder& p);
00167   public:
00169     TraceRecorder(Home home, TraceFilter tf, int te, Tracer& t);
00171     virtual Propagator* copy(Space& home, bool share);
00173     virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00175     virtual void reschedule(Space& home);
00177     virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00179     virtual size_t dispose(Space& home);
00181     static ExecStatus post(Home home, TraceFilter tf, int te, Tracer& t);
00183 
00184 
00185     const TraceFilter& filter(void) const;
00187     int events(void) const;
00189     Tracer& tracer(void) const;
00191   };
00192 
00193 
00194   /*
00195    * Functions for trace support
00196    *
00197    */
00198   template<class View>
00199   forceinline const typename View::VarType
00200   ViewTraceRecorder<View>::operator [](int i) const {
00201     const typename View::VarType x(n[i].varimp());
00202     return x;
00203   }
00204   template<class View>
00205   forceinline int
00206   ViewTraceRecorder<View>::size(void) const {
00207     return n.size();
00208   }
00209   template<class View>
00210   forceinline const typename ViewTraceRecorder<View>::Slack&
00211   ViewTraceRecorder<View>::slack(void) const {
00212     return s;
00213   }
00214 
00215 
00216   /*
00217    * Functions for access to slack
00218    *
00219    */
00220   template<class View>
00221   forceinline typename ViewTraceRecorder<View>::SlackValue
00222   ViewTraceRecorder<View>::Slack::initial(void) const {
00223     return i;
00224   }
00225   template<class View>
00226   forceinline typename ViewTraceRecorder<View>::SlackValue
00227   ViewTraceRecorder<View>::Slack::previous(void) const {
00228     return p;
00229   }
00230   template<class View>
00231   forceinline typename ViewTraceRecorder<View>::SlackValue
00232   ViewTraceRecorder<View>::Slack::current(void) const {
00233     return c;
00234   }
00235 
00236 
00237   /*
00238    * Advisor for tracer
00239    *
00240    */
00241 
00242   template<class View>
00243   forceinline
00244   ViewTraceRecorder<View>::Idx::Idx(Space& home, Propagator& p,
00245                                     Council<Idx>& c, int i)
00246     : Advisor(home,p,c), _idx(i) {}
00247   template<class View>
00248   forceinline
00249   ViewTraceRecorder<View>::Idx::Idx(Space& home, bool share, Idx& a)
00250     : Advisor(home,share,a), _idx(a._idx) {
00251   }
00252   template<class View>
00253   forceinline int
00254   ViewTraceRecorder<View>::Idx::idx(void) const {
00255     return _idx;
00256   }
00257 
00258 
00259   /*
00260    * Posting of tracer propagator
00261    *
00262    */
00263   template<class View>
00264   forceinline
00265   ViewTraceRecorder<View>::ViewTraceRecorder(Home home, ViewArray<View>& x,
00266                                              TraceFilter tf0, int te0,
00267                                              ViewTracer<View>& t0)
00268     : Propagator(home), o(home,x.size()), n(x), c(home),
00269       tf(tf0), te(te0), t(t0) {
00270     home.notice(*this, AP_VIEW_TRACE);
00271     home.notice(*this, AP_DISPOSE);
00272     for (int i=n.size(); i--; ) {
00273       o[i] = TraceView(home,n[i]);
00274       if (!n[i].assigned())
00275         n[i].subscribe(home,*new (home) Idx(home,*this,c,i));
00276     }
00277     View::schedule(home,*this,ME_GEN_ASSIGNED);
00278     s.i = TraceView::slack(n[n.size()-1]);
00279     for (int i=n.size()-1; i--; )
00280       s.i += TraceView::slack(n[i]);
00281     s.p = s.i;
00282     if ((te & TE_INIT) != 0)
00283       t._init(home,*this);
00284   }
00285 
00286 
00287   template<class View>
00288   forceinline ExecStatus
00289   ViewTraceRecorder<View>::post(Home home, ViewArray<View>& x,
00290                                 TraceFilter tf, int te, ViewTracer<View>& t) {
00291     if ((x.size() > 0) &&
00292         (te & (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE)))
00293       (void) new (home) ViewTraceRecorder(home,x,tf,te,t);
00294     return ES_OK;
00295   }
00296 
00297 
00298   /*
00299    * Propagation for trace recorder
00300    *
00301    */
00302   template<class View>
00303   forceinline
00304   ViewTraceRecorder<View>::ViewTraceRecorder(Space& home, bool share,
00305                                              ViewTraceRecorder& p)
00306     : Propagator(home,share,p), te(p.te), t(p.t), s(p.s) {
00307     o.update(home, share, p.o);
00308     n.update(home, share, p.n);
00309     c.update(home, share, p.c);
00310     tf.update(home, share, p.tf);
00311   }
00312 
00313   template<class View>
00314   Propagator*
00315   ViewTraceRecorder<View>::copy(Space& home, bool share) {
00316     return new (home) ViewTraceRecorder(home, share, *this);
00317   }
00318 
00319   template<class View>
00320   inline size_t
00321   ViewTraceRecorder<View>::dispose(Space& home) {
00322     home.ignore(*this, AP_VIEW_TRACE);
00323     home.ignore(*this, AP_DISPOSE);
00324     tf.~TraceFilter();
00325     // Cancel remaining advisors
00326     for (Advisors<Idx> as(c); as(); ++as)
00327       n[as.advisor().idx()].cancel(home,as.advisor());
00328     c.dispose(home);
00329     (void) Propagator::dispose(home);
00330     return sizeof(*this);
00331   }
00332 
00333   template<class View>
00334   PropCost
00335   ViewTraceRecorder<View>::cost(const Space&, const ModEventDelta&) const {
00336     return PropCost::record();
00337   }
00338 
00339   template<class View>
00340   void
00341   ViewTraceRecorder<View>::reschedule(Space& home) {
00342     View::schedule(home,*this,ME_GEN_ASSIGNED);
00343   }
00344 
00345   template<class View>
00346   ExecStatus
00347   ViewTraceRecorder<View>::advise(Space& home, Advisor& _a, const Delta& d) {
00348     Idx& a = static_cast<Idx&>(_a);
00349     int i = a.idx();
00350     if (((te & TE_PRUNE) != 0) && !disabled() && tf(a(home)) ) {
00351       TraceDelta td(o[i],n[i],d);
00352       t._prune(home,*this,a(home),i,td);
00353     }
00354     o[i].prune(home,n[i],d);
00355     if (n[a.idx()].assigned())
00356       a.dispose(home,c);
00357     return ES_NOFIX;
00358   }
00359 
00360   template<class View>
00361   ExecStatus
00362   ViewTraceRecorder<View>::propagate(Space& home, const ModEventDelta&) {
00363     s.c = TraceView::slack(n[n.size()-1]);
00364     for (int i=n.size()-1; i--; )
00365       s.c += TraceView::slack(n[i]);
00366     if (home.failed() && ((te & TE_FAIL) != 0) && !disabled()) {
00367       t._fail(home,*this);
00368       return ES_FIX;
00369     }
00370     if ((te & TE_FIX) != 0)
00371       t._fix(home,*this);
00372     s.p = s.c;
00373     if (c.empty()) {
00374       if ((te & TE_DONE) != 0)
00375         t._done(home,*this);
00376       return home.ES_SUBSUMED(*this);
00377     }
00378     return ES_FIX;
00379   }
00380 
00381 
00382 
00383   /*
00384    * Functions for trace support
00385    *
00386    */
00387   forceinline const TraceFilter&
00388   TraceRecorder::filter(void) const {
00389     return tf;
00390   }
00391   forceinline int
00392   TraceRecorder::events(void) const {
00393     return te;
00394   }
00395   forceinline Tracer&
00396   TraceRecorder::tracer(void) const {
00397     return t;
00398   }
00399 
00400 
00401   /*
00402    * Trace recorder propagator
00403    *
00404    */
00405   forceinline
00406   TraceRecorder::TraceRecorder(Home home, TraceFilter tf0, int te0,
00407                                Tracer& t0)
00408     : Propagator(home), tf(tf0), te(te0), t(t0) {
00409     home.notice(*this, AP_DISPOSE);
00410     home.notice(*this, AP_TRACE);
00411   }
00412 
00413   forceinline ExecStatus
00414   TraceRecorder::post(Home home, TraceFilter tf, int te, Tracer& t) {
00415     if (te & (TE_PROPAGATE | TE_COMMIT))
00416       (void) new (home) TraceRecorder(home,tf,te,t);
00417     return ES_OK;
00418   }
00419 
00420   forceinline
00421   TraceRecorder::TraceRecorder(Space& home, bool share,
00422                                TraceRecorder& p)
00423     : Propagator(home,share,p), te(p.te), t(p.t) {
00424     tf.update(home, share, p.tf);
00425   }
00426 
00427 }
00428 
00429 // STATISTICS: kernel-trace