Generated on Sat Oct 20 2018 12:43:45 for Gecode by doxygen 1.8.13
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 
45 namespace Gecode { namespace CPProfiler {
46 
48  static const int32_t PROFILER_PROTOCOL_VERSION = 3;
49 
51  enum NodeStatus {
52  SOLVED = 0,
53  FAILED = 1,
54  BRANCH = 2,
55  SKIPPED = 3
56  };
57 
59  enum class MsgType {
60  NODE = 0,
61  DONE = 1,
62  START = 2,
63  RESTART = 3
64  };
65 
67  template <class T>
68  class Option {
69  protected:
71  T value_;
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; }
165  void set_status(NodeStatus status) { _status = 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 
200  void set_type(MsgType type) { _type = type; }
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();
309  msg.set_version(PROFILER_PROTOCOL_VERSION);
310  msg.set_info(info);
311  }
312 
313  void makeRestart(const std::string& info) {
314  msg.reset();
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
void set_kids(int32_t kids)
Definition: message.hpp:162
const std::string & label() const
Definition: message.hpp:191
NodeType t
Type of node.
Definition: bool-expr.cpp:230
Message for the CP Profiler.
Definition: message.hpp:124
std::vector< char > serialize(void) const
Definition: message.hpp:326
void unset(void)
Disregard value.
Definition: message.hpp:99
bool valid(const FloatVal &n)
Return whether float n is a valid number.
Definition: limits.hpp:39
int32_t kids(void) const
Definition: message.hpp:161
void set_status(NodeStatus status)
Definition: message.hpp:165
Node representing failure.
Definition: message.hpp:53
void set_version(int32_t v)
Definition: message.hpp:182
int32_t tid
Thread id.
Definition: message.hpp:120
NodeStatus status(void) const
Definition: message.hpp:164
Node representing a solution.
Definition: message.hpp:52
#define forceinline
Definition: config.hpp:185
void set_parentUID(const NodeUID &p)
Definition: message.hpp:156
Node skipped by backjumping.
Definition: message.hpp:55
bool isStart(void) const
Definition: message.hpp:149
MsgType
Types of messages for CP Profiler.
Definition: message.hpp:59
Gecode::FloatVal c(-8, 8)
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:232
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:234
Gecode::IntArgs i({1, 2, 3, 4})
void makeStart(const std::string &info)
Definition: message.hpp:306
int32_t alt(void) const
Definition: message.hpp:158
void set(const T &t)
Set value to t.
Definition: message.hpp:94
bool isRestart(void) const
Definition: message.hpp:150
unsigned int size(I &i)
Size of all ranges of range iterator i.
Node representing a branch.
Definition: message.hpp:54
int32_t version(void) const
Definition: message.hpp:188
void set_nogood(const std::string &nogood)
Definition: message.hpp:177
T value_
A value, potentially not initialized.
Definition: message.hpp:71
bool valid(void) const
Check whether value is present.
Definition: message.hpp:89
bool isDone(void) const
Definition: message.hpp:148
const int v[7]
Definition: distinct.cpp:259
Post propagator for f(x \diamond_{\mathit{op}} y) \sim_r z \f$ void rel(Home home
void set_type(MsgType type)
Definition: message.hpp:200
const std::string & nogood(void) const
Definition: message.hpp:194
void set_info(const std::string &info)
Definition: message.hpp:172
Message & makeNode(NodeUID node, NodeUID parent, int32_t alt, int32_t kids, NodeStatus status)
Definition: message.hpp:291
bool has_nogood(void) const
Definition: message.hpp:193
void makeRestart(const std::string &info)
Definition: message.hpp:313
int32_t rid
Restart id.
Definition: message.hpp:118
Optional value class.
Definition: message.hpp:68
bool has_label(void) const
Definition: message.hpp:190
MsgType type(void) const
Definition: message.hpp:201
void set_nodeUID(const NodeUID &n)
Definition: message.hpp:153
const std::string & info(void) const
Definition: message.hpp:198
bool has_info(void) const
Definition: message.hpp:197
NodeUID parentUID(void) const
Definition: message.hpp:155
void set_label(const std::string &label)
Definition: message.hpp:167
NodeUID nodeUID(void) const
Definition: message.hpp:152
Gecode toplevel namespace
bool isNode(void) const
Definition: message.hpp:147
NodeStatus
Types of nodes for CP Profiler.
Definition: message.hpp:51
void set_alt(int32_t alt)
Definition: message.hpp:159
const T & value(void) const
Access value.
Definition: message.hpp:104
int32_t nid
Node number.
Definition: message.hpp:116
Unique identifier for a node.
Definition: message.hpp:114
void deserialize(char *data, size_t size)
Definition: message.hpp:371
bool has_version(void) const
Definition: message.hpp:187