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, 2017
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 { namespace Search {
35
36 /// Recorder for engine events (for access control)
37 class WrapTraceRecorder {
38 public:
39 /// Register engine
40 static void engine(SearchTracer* tracer,
41 SearchTracer::EngineType t, unsigned int n);
42 };
43
44 /// Simple recorder for a search tracer
45 class TraceRecorder {
46 protected:
47 /// The actual tracer
48 SearchTracer& tracer;
49 /// The engine id
50 unsigned int _eid;
51 /// The worker id
52 unsigned int _wid;
53 /// The next free node id
54 unsigned int _nid;
55 public:
56 /// Class for storing identifiers
57 class ID {
58 protected:
59 /// The actual identifier
60 unsigned int _id;
61 public:
62 /// Do not initialize
63 ID(void);
64 /// Initialize
65 ID(unsigned int id);
66 /// Access
67 operator unsigned int(void) const;
68 };
69 /// Initialize
70 TraceRecorder(SearchTracer* t);
71 /// Register engine
72 void engine(SearchTracer::EngineType t, unsigned int n);
73 /// Register worker
74 void worker(void);
75 /// Generate new node id
76 unsigned int nid(void);
77 /// Return worker id
78 unsigned int wid(void) const;
79 /// The workers goes to a next round (restart or next iteration in LDS)
80 void round(void);
81 /// The engine skips an edge
82 void skip(const SearchTracer::EdgeInfo& ei);
83 /// The engine creates a new node with information \a ei and \a ni
84 void node(const SearchTracer::EdgeInfo& ei,
85 const SearchTracer::NodeInfo& ni);
86 /// The worker is done
87 void done(void);
88 /// Whether this is a real tracer
89 operator bool(void) const;
90 };
91
92 /// Recorder for a search tracer with edge information
93 class EdgeTraceRecorder : public TraceRecorder {
94 protected:
95 /// Edge information
96 SearchTracer::EdgeInfo _ei;
97 public:
98 /// Initialize
99 EdgeTraceRecorder(SearchTracer* t);
100 /// Invalidate edge information
101 void invalidate(void);
102 /// Provide access to edge information
103 SearchTracer::EdgeInfo* ei(void);
104 };
105
106 /// Empty trace recorder
107 class NoTraceRecorder {
108 public:
109 /// Class for storing node identifiers
110 class ID {
111 public:
112 /// Do not initialize
113 ID(void);
114 /// Initialize
115 ID(unsigned int id);
116 /// Access
117 operator unsigned int(void) const;
118 };
119 /// Initialize
120 NoTraceRecorder(SearchTracer* t);
121 /// Register engine
122 void engine(SearchTracer::EngineType t, unsigned int n);
123 /// Register worker
124 void worker(void);
125 /// Return worker id
126 unsigned int wid(void) const;
127 /// Generate new node id
128 unsigned int nid(void);
129 /// Invalidate edge information
130 void invalidate(void);
131 /// Provide access to edge information
132 SearchTracer::EdgeInfo* ei(void);
133 /// The workers goes to a next round (restart or next iteration in LDS)
134 void round(void);
135 /// The engine skips an edge
136 void skip(const SearchTracer::EdgeInfo& ei);
137 /// The engine creates a new node with information \a ei and \a ni
138 void node(const SearchTracer::EdgeInfo& ei,
139 const SearchTracer::NodeInfo& ni);
140 /// The worker is done
141 void done(void);
142 /// Whether this is a real tracer
143 operator bool(void) const;
144 };
145
146
147 /*
148 * Recorder for engine events
149 *
150 */
151 forceinline void
152 WrapTraceRecorder::engine(SearchTracer* tracer,
153 SearchTracer::EngineType t, unsigned int n) {
154 if (tracer) tracer->engine(t,n);
155 }
156
157
158 /*
159 * Simple trace recorder for a search tracer
160 *
161 */
162 forceinline
163 TraceRecorder::ID::ID(void) {}
164
165 forceinline
166 TraceRecorder::ID::ID(unsigned int id) : _id(id) {}
167
168 forceinline
169 TraceRecorder::ID::operator unsigned int(void) const {
170 return _id;
171 }
172
173 forceinline
174 TraceRecorder::TraceRecorder(SearchTracer* t)
175 : tracer(*t), _eid(0U), _wid(0U), _nid(0U) {}
176
177 forceinline void
178 TraceRecorder::engine(SearchTracer::EngineType t, unsigned int n) {
179 tracer.engine(t,n);
180 }
181
182 forceinline void
183 TraceRecorder::worker(void) {
184 tracer.worker(_wid,_eid);
185 }
186
187 forceinline unsigned int
188 TraceRecorder::nid(void) {
189 return _nid++;
190 }
191
192 forceinline unsigned int
193 TraceRecorder::wid(void) const {
194 return _wid;
195 }
196
197 forceinline void
198 TraceRecorder::round(void) {
199 tracer._round(_eid);
200 }
201
202 forceinline void
203 TraceRecorder::skip(const SearchTracer::EdgeInfo& ei) {
204 tracer._skip(ei);
205 }
206
207 forceinline void
208 TraceRecorder::node(const SearchTracer::EdgeInfo& ei,
209 const SearchTracer::NodeInfo& ni) {
210 tracer._node(ei,ni);
211 }
212
213 forceinline void
214 TraceRecorder::done(void) {
215 tracer.worker();
216 }
217
218 forceinline
219 TraceRecorder::operator bool(void) const {
220 return true;
221 }
222
223
224 /*
225 * Recorder for a search tracer with edge information
226 *
227 */
228 forceinline
229 EdgeTraceRecorder::EdgeTraceRecorder(SearchTracer* t)
230 : TraceRecorder(t) {}
231
232 forceinline void
233 EdgeTraceRecorder::invalidate(void) {
234 _ei.invalidate();
235 }
236
237 forceinline SearchTracer::EdgeInfo*
238 EdgeTraceRecorder::ei(void) {
239 return &_ei;
240 }
241
242
243 /*
244 * Empty trace recorder
245 *
246 */
247 forceinline
248 NoTraceRecorder::ID::ID(void) {}
249
250 forceinline
251 NoTraceRecorder::ID::ID(unsigned int) {}
252
253 forceinline
254 NoTraceRecorder::ID::operator unsigned int(void) const {
255 return 0U;
256 }
257
258 forceinline
259 NoTraceRecorder::NoTraceRecorder(SearchTracer*) {}
260
261 forceinline void
262 NoTraceRecorder::engine(SearchTracer::EngineType, unsigned int) {}
263
264 forceinline void
265 NoTraceRecorder::worker(void) {}
266
267 forceinline unsigned int
268 NoTraceRecorder::wid(void) const {
269 return 0U;
270 }
271
272 forceinline unsigned int
273 NoTraceRecorder::nid(void) {
274 return 0U;
275 }
276
277 forceinline void
278 NoTraceRecorder::invalidate(void) {}
279
280 forceinline SearchTracer::EdgeInfo*
281 NoTraceRecorder::ei(void) {
282 return nullptr;
283 }
284
285 forceinline void
286 NoTraceRecorder::round(void) {}
287
288 forceinline void
289 NoTraceRecorder::skip(const SearchTracer::EdgeInfo&) {}
290
291 forceinline void
292 NoTraceRecorder::node(const SearchTracer::EdgeInfo&,
293 const SearchTracer::NodeInfo&) {
294 }
295
296 forceinline void
297 NoTraceRecorder::done(void) {
298 }
299
300 forceinline
301 NoTraceRecorder::operator bool(void) const {
302 return false;
303 }
304
305}}
306
307// STATISTICS: search-trace