this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Copyright: 7 * Christian Schulte, 2016 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34namespace Gecode { 35 36 /** 37 * \brief Which events to trace 38 * \ingroup TaskTrace 39 */ 40 enum TraceEvent { 41 /// \name Events for view tracers 42 //@{ 43 TE_INIT = 1 << 0, ///< Trace init events 44 TE_PRUNE = 1 << 1, ///< Trace prune events 45 TE_FIX = 1 << 2, ///< Trace fixpoint events 46 TE_FAIL = 1 << 3, ///< Trace fail events 47 TE_DONE = 1 << 4, ///< Trace done events 48 //@} 49 /// \name Events for general tracers 50 TE_PROPAGATE = 1 << 5, ///< Trace propagator executions 51 TE_COMMIT = 1 << 6, ///< Trace commit operations by branchers 52 TE_POST = 1 << 7 ///< Trace propagator posting 53 }; 54 55 /** 56 * \brief Propagator for recording view trace information 57 * \ingroup TaskTrace 58 */ 59 template<class View> 60 class ViewTraceRecorder : public Propagator { 61 public: 62 /// The corresponding duplicate view type 63 typedef typename TraceTraits<View>::TraceView TraceView; 64 /// The corresponding trace delta type 65 typedef typename TraceTraits<View>::TraceDelta TraceDelta; 66 /// The corresponding slack value type 67 typedef typename TraceTraits<View>::SlackValue SlackValue; 68 /// Collection of slack values 69 class Slack { 70 template<class ViewForTraceRecorder> friend class ViewTraceRecorder; 71 protected: 72 /// The initial slack value 73 SlackValue i; 74 /// Slack value at previous event (fixpoint or init) 75 SlackValue p; 76 /// Current slack value 77 SlackValue c; 78 public: 79 /// Return initial slack value 80 SlackValue initial(void) const; 81 /// Return previous slack value 82 SlackValue previous(void) const; 83 /// Return current slack value 84 SlackValue current(void) const; 85 }; 86 protected: 87 /// Advisor with index information 88 class Idx : public Advisor { 89 protected: 90 /// Index information 91 int _idx; 92 public: 93 /// Constructor for creation 94 Idx(Space& home, Propagator& p, Council<Idx>& c, int i); 95 /// Constructor for cloning \a a 96 Idx(Space& home, Idx& a); 97 /// Get index of view 98 int idx(void) const; 99 }; 100 /// Duplicate views (old information) 101 ViewArray<TraceView> o; 102 /// Original views (new information) 103 ViewArray<View> n; 104 /// The advisor council 105 Council<Idx> c; 106 /// The trace filter 107 TraceFilter tf; 108 /// Which events to trace 109 int te; 110 /// The actual tracer 111 ViewTracer<View>& t; 112 /// Slack information 113 Slack s; 114 /// Constructor for cloning \a p 115 ViewTraceRecorder(Space& home, ViewTraceRecorder& p); 116 public: 117 /// Constructor for creation 118 ViewTraceRecorder(Home home, ViewArray<View>& x, 119 TraceFilter tf, int te, ViewTracer<View>& t); 120 /// Copy propagator during cloning 121 virtual Propagator* copy(Space& home); 122 /// Cost function (record so that propagator runs last) 123 virtual PropCost cost(const Space& home, const ModEventDelta& med) const; 124 /// Schedule function 125 virtual void reschedule(Space& home); 126 /// Give advice to propagator 127 virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d); 128 /// Perform propagation 129 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 130 /// Delete propagator and return its size 131 virtual size_t dispose(Space& home); 132 /// Post recorder propagator 133 static ExecStatus post(Home home, ViewArray<View>& x, 134 TraceFilter tf, int te, ViewTracer<View>& t); 135 /// \name Trace information 136 //@{ 137 /// Return variable being traced at position \a i 138 const typename View::VarType operator [](int i) const; 139 /// Return number of variables being traced 140 int size(void) const; 141 /// Provide access to slack information 142 const Slack& slack(void) const; 143 //@} 144 }; 145 146 /** 147 * \brief Propagator for recording trace information 148 * 149 * This propagator is actually never run. It only provides access 150 * to information needed for tracing. 151 * 152 * \ingroup TaskTrace 153 */ 154 class TraceRecorder : public Propagator { 155 public: 156 /// The trace filter 157 TraceFilter tf; 158 /// Which events to trace 159 int te; 160 /// The actual tracer 161 Tracer& t; 162 /// Constructor for cloning \a p 163 TraceRecorder(Space& home, TraceRecorder& p); 164 public: 165 /// Constructor for creation 166 TraceRecorder(Home home, TraceFilter tf, int te, Tracer& t); 167 /// Copy propagator during cloning 168 virtual Propagator* copy(Space& home); 169 /// Cost function (record so that propagator runs last) 170 virtual PropCost cost(const Space& home, const ModEventDelta& med) const; 171 /// Schedule function 172 virtual void reschedule(Space& home); 173 /// Perform propagation 174 virtual ExecStatus propagate(Space& home, const ModEventDelta& med); 175 /// Delete propagator and return its size 176 virtual size_t dispose(Space& home); 177 /// Post propagator 178 static ExecStatus post(Home home, TraceFilter tf, int te, Tracer& t); 179 /// \name Trace information 180 //@{ 181 /// Return trace filter 182 const TraceFilter& filter(void) const; 183 /// Which events to trace 184 int events(void) const; 185 /// Return tracer 186 Tracer& tracer(void) const; 187 //@} 188 }; 189 190 191 /* 192 * Functions for trace support 193 * 194 */ 195 template<class View> 196 forceinline const typename View::VarType 197 ViewTraceRecorder<View>::operator [](int i) const { 198 const typename View::VarType x(n[i].varimp()); 199 return x; 200 } 201 template<class View> 202 forceinline int 203 ViewTraceRecorder<View>::size(void) const { 204 return n.size(); 205 } 206 template<class View> 207 forceinline const typename ViewTraceRecorder<View>::Slack& 208 ViewTraceRecorder<View>::slack(void) const { 209 return s; 210 } 211 212 213 /* 214 * Functions for access to slack 215 * 216 */ 217 template<class View> 218 forceinline typename ViewTraceRecorder<View>::SlackValue 219 ViewTraceRecorder<View>::Slack::initial(void) const { 220 return i; 221 } 222 template<class View> 223 forceinline typename ViewTraceRecorder<View>::SlackValue 224 ViewTraceRecorder<View>::Slack::previous(void) const { 225 return p; 226 } 227 template<class View> 228 forceinline typename ViewTraceRecorder<View>::SlackValue 229 ViewTraceRecorder<View>::Slack::current(void) const { 230 return c; 231 } 232 233 234 /* 235 * Advisor for tracer 236 * 237 */ 238 239 template<class View> 240 forceinline 241 ViewTraceRecorder<View>::Idx::Idx(Space& home, Propagator& p, 242 Council<Idx>& c, int i) 243 : Advisor(home,p,c), _idx(i) {} 244 template<class View> 245 forceinline 246 ViewTraceRecorder<View>::Idx::Idx(Space& home, Idx& a) 247 : Advisor(home,a), _idx(a._idx) { 248 } 249 template<class View> 250 forceinline int 251 ViewTraceRecorder<View>::Idx::idx(void) const { 252 return _idx; 253 } 254 255 256 /* 257 * Posting of tracer propagator 258 * 259 */ 260 template<class View> 261 forceinline 262 ViewTraceRecorder<View>::ViewTraceRecorder(Home home, ViewArray<View>& x, 263 TraceFilter tf0, int te0, 264 ViewTracer<View>& t0) 265 : Propagator(home), o(home,x.size()), n(x), c(home), 266 tf(tf0), te(te0), t(t0) { 267 home.notice(*this, AP_VIEW_TRACE); 268 home.notice(*this, AP_DISPOSE); 269 for (int i=0; i<n.size(); i++) { 270 o[i] = TraceView(home,n[i]); 271 if (!n[i].assigned()) 272 n[i].subscribe(home,*new (home) Idx(home,*this,c,i)); 273 } 274 View::schedule(home,*this,ME_GEN_ASSIGNED); 275 s.i = TraceView::slack(n[0]); 276 for (int i=1; i<n.size(); i++) 277 s.i += TraceView::slack(n[i]); 278 s.p = s.i; 279 if ((te & TE_INIT) != 0) 280 t._init(home,*this); 281 } 282 283 284 template<class View> 285 forceinline ExecStatus 286 ViewTraceRecorder<View>::post(Home home, ViewArray<View>& x, 287 TraceFilter tf, int te, ViewTracer<View>& t) { 288 if ((x.size() > 0) && 289 (te & (TE_INIT | TE_PRUNE | TE_FIX | TE_FAIL | TE_DONE))) 290 (void) new (home) ViewTraceRecorder(home,x,tf,te,t); 291 return ES_OK; 292 } 293 294 295 /* 296 * Propagation for trace recorder 297 * 298 */ 299 template<class View> 300 forceinline 301 ViewTraceRecorder<View>::ViewTraceRecorder(Space& home, ViewTraceRecorder& p) 302 : Propagator(home,p), tf(p.tf), te(p.te), t(p.t), s(p.s) { 303 o.update(home, p.o); 304 n.update(home, p.n); 305 c.update(home, p.c); 306 } 307 308 template<class View> 309 Propagator* 310 ViewTraceRecorder<View>::copy(Space& home) { 311 return new (home) ViewTraceRecorder(home, *this); 312 } 313 314 template<class View> 315 inline size_t 316 ViewTraceRecorder<View>::dispose(Space& home) { 317 home.ignore(*this, AP_VIEW_TRACE); 318 home.ignore(*this, AP_DISPOSE); 319 tf.~TraceFilter(); 320 // Cancel remaining advisors 321 for (Advisors<Idx> as(c); as(); ++as) 322 n[as.advisor().idx()].cancel(home,as.advisor()); 323 c.dispose(home); 324 (void) Propagator::dispose(home); 325 return sizeof(*this); 326 } 327 328 template<class View> 329 PropCost 330 ViewTraceRecorder<View>::cost(const Space&, const ModEventDelta&) const { 331 return PropCost::record(); 332 } 333 334 template<class View> 335 void 336 ViewTraceRecorder<View>::reschedule(Space& home) { 337 View::schedule(home,*this,ME_GEN_ASSIGNED); 338 } 339 340 template<class View> 341 ExecStatus 342 ViewTraceRecorder<View>::advise(Space& home, Advisor& _a, const Delta& d) { 343 Idx& a = static_cast<Idx&>(_a); 344 int i = a.idx(); 345 if (((te & TE_PRUNE) != 0) && !disabled() && tf(a(home)) ) { 346 TraceDelta td(o[i],n[i],d); 347 t._prune(home,*this,a(home),i,td); 348 } 349 o[i].prune(home,n[i],d); 350 if (n[a.idx()].assigned()) 351 a.dispose(home,c); 352 return ES_NOFIX; 353 } 354 355 template<class View> 356 ExecStatus 357 ViewTraceRecorder<View>::propagate(Space& home, const ModEventDelta&) { 358 s.c = TraceView::slack(n[0]); 359 for (int i=1; i<n.size(); i++) 360 s.c += TraceView::slack(n[i]); 361 if (home.failed() && ((te & TE_FAIL) != 0) && !disabled()) { 362 t._fail(home,*this); 363 return ES_FIX; 364 } 365 if ((te & TE_FIX) != 0) 366 t._fix(home,*this); 367 s.p = s.c; 368 if (c.empty()) { 369 if ((te & TE_DONE) != 0) 370 t._done(home,*this); 371 return home.ES_SUBSUMED(*this); 372 } 373 return ES_FIX; 374 } 375 376 377 378 /* 379 * Functions for trace support 380 * 381 */ 382 forceinline const TraceFilter& 383 TraceRecorder::filter(void) const { 384 return tf; 385 } 386 forceinline int 387 TraceRecorder::events(void) const { 388 return te; 389 } 390 forceinline Tracer& 391 TraceRecorder::tracer(void) const { 392 return t; 393 } 394 395 396 /* 397 * Trace recorder propagator 398 * 399 */ 400 forceinline 401 TraceRecorder::TraceRecorder(Home home, TraceFilter tf0, int te0, 402 Tracer& t0) 403 : Propagator(home), tf(tf0), te(te0), t(t0) { 404 home.notice(*this, AP_DISPOSE); 405 home.notice(*this, AP_TRACE); 406 } 407 408 forceinline ExecStatus 409 TraceRecorder::post(Home home, TraceFilter tf, int te, Tracer& t) { 410 if (te & (TE_PROPAGATE | TE_COMMIT | TE_POST)) 411 (void) new (home) TraceRecorder(home,tf,te,t); 412 return ES_OK; 413 } 414 415 forceinline 416 TraceRecorder::TraceRecorder(Space& home, TraceRecorder& p) 417 : Propagator(home,p), tf(p.tf), te(p.te), t(p.t) { 418 } 419 420} 421 422// STATISTICS: kernel-trace