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