Generated on Thu Jan 16 2025 00:00:00 for Gecode by doxygen 1.14.0
message.hpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Maxim Shishmarev <maxim.shishmarev@monash.edu>
5 *
6 * Contributing authors:
7 * Guido Tack <tack@gecode.org>
8 * Kevin Leo <kevin.leo@monash.edu>
9 *
10 * Copyright:
11 * Maxim Shishmarev, 2017
12 * Guido Tack, 2017
13 * Kevin Leo, 2017
14 *
15 * This file is part of Gecode, the generic constraint
16 * development environment:
17 * http://www.gecode.org
18 *
19 * Permission is hereby granted, free of charge, to any person obtaining
20 * a copy of this software and associated documentation files (the
21 * "Software"), to deal in the Software without restriction, including
22 * without limitation the rights to use, copy, modify, merge, publish,
23 * distribute, sublicense, and/or sell copies of the Software, and to
24 * permit persons to whom the Software is furnished to do so, subject to
25 * the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be
28 * included in all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 *
38 */
39
40#include <vector>
41#include <string>
42#include <cassert>
43#include <cstdint>
44
45namespace Gecode { namespace CPProfiler {
46
48 static const int32_t PROFILER_PROTOCOL_VERSION = 3;
49
52 SOLVED = 0,
53 FAILED = 1,
54 BRANCH = 2,
56 };
57
59 enum class MsgType {
60 NODE = 0,
61 DONE = 1,
62 START = 2,
64 };
65
67 template <class T>
68 class Option {
69 protected:
73 bool present{false};
74 public:
76 bool valid(void) const;
78 void set(const T& t);
80 void unset(void);
82 const T& value(void) const;
84 T& value(void);
85 };
86
87 template <class T>
88 forceinline bool
89 Option<T>::valid(void) const {
90 return present;
91 }
92 template <class T>
93 forceinline void
94 Option<T>::set(const T& t) {
95 present = true; value_ = t;
96 }
97 template <class T>
98 forceinline void
100 present = false;
101 }
102 template <class T>
103 forceinline const T&
104 Option<T>::value(void) const {
105 assert(present); return value_;
106 }
107 template <class T>
108 forceinline T&
110 assert(present); return value_;
111 }
112
114 struct NodeUID {
116 int32_t nid;
118 int32_t rid;
120 int32_t tid;
121 };
122
124 class Message {
125 protected:
127
130 int32_t _alt;
131 int32_t _kids;
133
134 bool _have_label{false};
135 std::string _label;
136
137 bool _have_nogood{false};
138 std::string _nogood;
139
140 bool _have_info{false};
141 std::string _info;
142
143 bool _have_version{false};
144 int32_t _version; // PROFILER_PROTOCOL_VERSION;
145
146 public:
147 bool isNode(void) const { return _type == MsgType::NODE; }
148 bool isDone(void) const { return _type == MsgType::DONE; }
149 bool isStart(void) const { return _type == MsgType::START; }
150 bool isRestart(void) const { return _type == MsgType::RESTART; }
151
152 NodeUID nodeUID(void) const { return _node; }
153 void set_nodeUID(const NodeUID& n) { _node = n; }
154
155 NodeUID parentUID(void) const { return _parent; }
156 void set_parentUID(const NodeUID& p) { _parent = p; }
157
158 int32_t alt(void) const { return _alt; }
159 void set_alt(int32_t alt) { _alt = alt; }
160
161 int32_t kids(void) const { return _kids; }
162 void set_kids(int32_t kids) { _kids = kids; }
163
164 NodeStatus status(void) const { return _status; }
166
167 void set_label(const std::string& label) {
168 _have_label = true;
169 _label = label;
170 }
171
172 void set_info(const std::string& info) {
173 _have_info = true;
174 _info = info;
175 }
176
177 void set_nogood(const std::string& nogood) {
178 _have_nogood = true;
179 _nogood = nogood;
180 }
181
182 void set_version(int32_t v) {
183 _have_version = true;
184 _version = v;
185 }
186
187 bool has_version(void) const { return _have_version; }
188 int32_t version(void) const { return _version; }
189
190 bool has_label(void) const { return _have_label; }
191 const std::string& label() const { return _label; }
192
193 bool has_nogood(void) const { return _have_nogood; }
194 const std::string& nogood(void) const { return _nogood; }
195
196 // generic optional fields
197 bool has_info(void) const { return _have_info; }
198 const std::string& info(void) const { return _info; }
199
201 MsgType type(void) const { return _type; }
202
203 void reset(void) {
204 _have_label = false;
205 _have_nogood = false;
206 _have_info = false;
207 _have_version = false;
208 }
209 };
210
211
213 private:
215 enum Field {
216 LABEL = 0,
217 NOGOOD = 1,
218 INFO = 2,
219 VERSION = 3
220 };
221
222 Message msg;
223
224 typedef char* iter;
225
226 static void serializeType(std::vector<char>& data, MsgType f) {
227 data.push_back(static_cast<char>(f));
228 }
229
230 static void serializeField(std::vector<char>& data, Field f) {
231 data.push_back(static_cast<char>(f));
232 }
233
234 static void serialize(std::vector<char>& data, int32_t i) {
235 data.push_back(static_cast<char>((i & 0xFF000000) >> 24));
236 data.push_back(static_cast<char>((i & 0xFF0000) >> 16));
237 data.push_back(static_cast<char>((i & 0xFF00) >> 8));
238 data.push_back(static_cast<char>((i & 0xFF)));
239 }
240
241 static void serialize(std::vector<char>& data, NodeStatus s) {
242 data.push_back(static_cast<char>(s));
243 }
244
245 static void serialize(std::vector<char>& data, const std::string& s) {
246 serialize(data, static_cast<int32_t>(s.size()));
247 for (char c : s) {
248 data.push_back(c);
249 }
250 }
251
252 static MsgType deserializeMsgType(iter& it) {
253 auto m = static_cast<MsgType>(*it);
254 ++it;
255 return m;
256 }
257
258 static Field deserializeField(iter& it) {
259 auto f = static_cast<Field>(*it);
260 ++it;
261 return f;
262 }
263
264 static int32_t deserializeInt(iter& it) {
265 auto b1 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
266 auto b2 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
267 auto b3 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
268 auto b4 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
269
270 return static_cast<int32_t>(b1 << 24 | b2 << 16 | b3 << 8 | b4);
271 }
272
273 static NodeStatus deserializeStatus(iter& it) {
274 auto f = static_cast<NodeStatus>(*it);
275 ++it;
276 return f;
277 }
278
279 static std::string deserializeString(iter& it) {
280 std::string result;
281 int32_t size = deserializeInt(it);
282 result.reserve(static_cast<size_t>(size));
283 for (int32_t i = 0; i < size; i++) {
284 result += *it;
285 ++it;
286 }
287 return result;
288 }
289
290 public:
292 int32_t alt, int32_t kids, NodeStatus status) {
293 msg.reset();
294 msg.set_type(MsgType::NODE);
295
296 msg.set_nodeUID(node);
297 msg.set_parentUID(parent);
298
299 msg.set_alt(alt);
300 msg.set_kids(kids);
301 msg.set_status(status);
302
303 return msg;
304 }
305
306 void makeStart(const std::string& info) {
307 msg.reset();
308 msg.set_type(MsgType::START);
309 msg.set_version(PROFILER_PROTOCOL_VERSION);
310 msg.set_info(info);
311 }
312
313 void makeRestart(const std::string& info) {
314 msg.reset();
315 msg.set_type(MsgType::RESTART);
316 msg.set_info(info);
317 }
318
319 void makeDone(void) {
320 msg.reset();
321 msg.set_type(MsgType::DONE);
322 }
323
324 const Message& get_msg(void) { return msg; }
325
326 std::vector<char> serialize(void) const {
327 std::vector<char> data;
328 size_t dataSize = 1 + (msg.isNode() ? 4 * 8 + 1 : 0) +
329 (msg.has_label() ? 1 + 4 + msg.label().size() : 0) +
330 (msg.has_nogood() ? 1 + 4 + msg.nogood().size() : 0) +
331 (msg.has_info() ? 1 + 4 + msg.info().size() : 0);
332 data.reserve(dataSize);
333
334 serializeType(data, msg.type());
335 if (msg.isNode()) {
336 // serialize NodeId node
337 auto n_uid = msg.nodeUID();
338 serialize(data, n_uid.nid);
339 serialize(data, n_uid.rid);
340 serialize(data, n_uid.tid);
341 // serialize NodeId parent
342 auto p_uid = msg.parentUID();
343 serialize(data, p_uid.nid);
344 serialize(data, p_uid.rid);
345 serialize(data, p_uid.tid);
346 // Other Data
347 serialize(data, msg.alt());
348 serialize(data, msg.kids());
349 serialize(data, msg.status());
350 }
351
352 if(msg.has_version()) {
353 serializeField(data, VERSION);
354 serialize(data, msg.version());
355 }
356 if (msg.has_label()) {
357 serializeField(data, LABEL);
358 serialize(data, msg.label());
359 }
360 if (msg.has_nogood()) {
361 serializeField(data, NOGOOD);
362 serialize(data, msg.nogood());
363 }
364 if (msg.has_info()) {
365 serializeField(data, INFO);
366 serialize(data, msg.info());
367 }
368 return data;
369 }
370
371 void deserialize(char* data, size_t size) {
372 char *end = data + size;
373 msg.set_type(deserializeMsgType(data));
374 if (msg.isNode()) {
375 int32_t nid = deserializeInt(data);
376 int32_t rid = deserializeInt(data);
377 int32_t tid = deserializeInt(data);
378
379 msg.set_nodeUID({nid, rid, tid});
380
381 nid = deserializeInt(data);
382 rid = deserializeInt(data);
383 tid = deserializeInt(data);
384
385 msg.set_parentUID({nid, rid, tid});
386
387 msg.set_alt(deserializeInt(data));
388 msg.set_kids(deserializeInt(data));
389 msg.set_status(deserializeStatus(data));
390 }
391
392 msg.reset();
393
394 while (data != end) {
395 MessageMarshalling::Field f = deserializeField(data);
396 switch (f) {
397 case VERSION:
398 msg.set_version(deserializeInt(data)); break;
399 case LABEL:
400 msg.set_label(deserializeString(data)); break;
401 case NOGOOD:
402 msg.set_nogood(deserializeString(data)); break;
403 case INFO:
404 msg.set_info(deserializeString(data)); break;
405 default:
406 break;
407 }
408 }
409 }
410 };
411
412}}
413
414// STATISTICS: search-trace
std::vector< char > serialize(void) const
Definition message.hpp:326
void deserialize(char *data, size_t size)
Definition message.hpp:371
Message & makeNode(NodeUID node, NodeUID parent, int32_t alt, int32_t kids, NodeStatus status)
Definition message.hpp:291
void makeStart(const std::string &info)
Definition message.hpp:306
void makeRestart(const std::string &info)
Definition message.hpp:313
Message for the CP Profiler.
Definition message.hpp:124
void set_alt(int32_t alt)
Definition message.hpp:159
bool has_info(void) const
Definition message.hpp:197
NodeUID nodeUID(void) const
Definition message.hpp:152
void set_label(const std::string &label)
Definition message.hpp:167
void set_status(NodeStatus status)
Definition message.hpp:165
NodeUID parentUID(void) const
Definition message.hpp:155
void set_nogood(const std::string &nogood)
Definition message.hpp:177
void set_nodeUID(const NodeUID &n)
Definition message.hpp:153
const std::string & label() const
Definition message.hpp:191
const std::string & nogood(void) const
Definition message.hpp:194
bool isNode(void) const
Definition message.hpp:147
void set_info(const std::string &info)
Definition message.hpp:172
bool isStart(void) const
Definition message.hpp:149
int32_t version(void) const
Definition message.hpp:188
int32_t alt(void) const
Definition message.hpp:158
NodeStatus status(void) const
Definition message.hpp:164
void set_version(int32_t v)
Definition message.hpp:182
bool isRestart(void) const
Definition message.hpp:150
bool has_nogood(void) const
Definition message.hpp:193
void set_type(MsgType type)
Definition message.hpp:200
MsgType type(void) const
Definition message.hpp:201
int32_t kids(void) const
Definition message.hpp:161
bool isDone(void) const
Definition message.hpp:148
void set_kids(int32_t kids)
Definition message.hpp:162
const std::string & info(void) const
Definition message.hpp:198
bool has_label(void) const
Definition message.hpp:190
bool has_version(void) const
Definition message.hpp:187
void set_parentUID(const NodeUID &p)
Definition message.hpp:156
Optional value class.
Definition message.hpp:68
bool valid(void) const
Check whether value is present.
Definition message.hpp:89
void set(const T &t)
Set value to t.
Definition message.hpp:94
bool present
Whether value is present.
Definition message.hpp:73
T value_
A value, potentially not initialized.
Definition message.hpp:71
void unset(void)
Disregard value.
Definition message.hpp:99
const T & value(void) const
Access value.
Definition message.hpp:104
Code that is specific to the CPProfiler.
Definition search.hh:406
NodeStatus
Types of nodes for CP Profiler.
Definition message.hpp:51
@ SOLVED
Node representing a solution.
Definition message.hpp:52
@ BRANCH
Node representing a branch.
Definition message.hpp:54
@ SKIPPED
Node skipped by backjumping.
Definition message.hpp:55
@ FAILED
Node representing failure.
Definition message.hpp:53
MsgType
Types of messages for CP Profiler.
Definition message.hpp:59
Gecode toplevel namespace
Unique identifier for a node.
Definition message.hpp:114
int32_t nid
Node number.
Definition message.hpp:116
int32_t rid
Restart id.
Definition message.hpp:118
int32_t tid
Thread id.
Definition message.hpp:120
#define forceinline
Definition config.hpp:194