Halide
printer.h
Go to the documentation of this file.
1 #ifndef HALIDE_RUNTIME_PRINTER_H
2 #define HALIDE_RUNTIME_PRINTER_H
3 namespace Halide { namespace Runtime { namespace Internal {
4 
8 
9 // A class for constructing debug messages from the runtime. Dumps
10 // items into a stack array, then prints them when the object leaves
11 // scope using halide_print. Think of it as a stringstream that prints
12 // when it dies. Use it like this:
13 
14 // debug(user_context) << "A" << b << c << "\n";
15 
16 // If you use it like this:
17 
18 // debug d(user_context);
19 // d << "A";
20 // d << b;
21 // d << c << "\n";
22 
23 // Then remember the print only happens when the debug object leaves
24 // scope, which may print at a confusing time.
25 
26 namespace {
27 template<int type, uint64_t length = 1024>
28 class Printer {
29 public:
30  char *buf, *dst, *end;
31  void *user_context;
32  bool own_mem;
33 
34  Printer(void *ctx, char *mem = NULL) : user_context(ctx), own_mem(mem == NULL) {
35  buf = mem ? mem : (char *)halide_malloc(user_context, length);
36  dst = buf;
37  if (dst) {
38  end = buf + (length-1);
39  *end = 0;
40  } else {
41  // Pointers equal ensures no writes to buffer via formatting code
42  end = dst;
43  }
44  }
45 
46  Printer &operator<<(const char *arg) {
47  dst = halide_string_to_string(dst, end, arg);
48  return *this;
49  }
50 
51  Printer &operator<<(int64_t arg) {
52  dst = halide_int64_to_string(dst, end, arg, 1);
53  return *this;
54  }
55 
56  Printer &operator<<(int32_t arg) {
57  dst = halide_int64_to_string(dst, end, arg, 1);
58  return *this;
59  }
60 
61  Printer &operator<<(uint64_t arg) {
62  dst = halide_uint64_to_string(dst, end, arg, 1);
63  return *this;
64  }
65 
66  Printer &operator<<(uint32_t arg) {
67  dst = halide_uint64_to_string(dst, end, arg, 1);
68  return *this;
69  }
70 
71  Printer &operator<<(double arg) {
72  dst = halide_double_to_string(dst, end, arg, 1);
73  return *this;
74  }
75 
76  Printer &operator<<(float arg) {
77  dst = halide_double_to_string(dst, end, arg, 0);
78  return *this;
79  }
80 
81  Printer &operator<<(const void *arg) {
82  dst = halide_pointer_to_string(dst, end, arg);
83  return *this;
84  }
85 
86  Printer & write_float16_from_bits(const uint16_t arg) {
87  double value = halide_float16_bits_to_double(arg);
88  dst = halide_double_to_string(dst, end, value, 1);
89  return *this;
90  }
91 
92  Printer &operator<<(const halide_type_t &t) {
93  dst = halide_type_to_string(dst, end, &t);
94  return *this;
95  }
96 
97  Printer &operator<<(const halide_buffer_t &buf) {
98  dst = halide_buffer_to_string(dst, end, &buf);
99  return *this;
100  }
101 
102  // Use it like a stringstream.
103  const char *str() {
104  if (buf) {
105  return buf;
106  } else {
107  return allocation_error();
108  }
109  }
110 
111  // Clear it. Useful for reusing a stringstream.
112  void clear() {
113  dst = buf;
114  if (dst) {
115  dst[0] = 0;
116  }
117  }
118 
119  // Returns the number of characters in the buffer
120  uint64_t size() const {
121  return (uint64_t)(dst - buf);
122  }
123 
124  // Delete the last N characters
125  void erase(int n) {
126  if (dst) {
127  dst -= n;
128  if (dst < buf) {
129  dst = buf;
130  }
131  dst[0] = 0;
132  }
133  }
134 
135  const char *allocation_error() {
136  return "Printer buffer allocation failed.\n";
137  }
138 
139  void msan_annotate_is_initialized() {
140  halide_msan_annotate_memory_is_initialized(user_context, buf, dst - buf + 1);
141  }
142 
143  ~Printer() {
144  if (!buf) {
145  halide_error(user_context, allocation_error());
146  } else {
147  msan_annotate_is_initialized();
148  if (type == ErrorPrinter) {
149  halide_error(user_context, buf);
150  } else if (type == BasicPrinter) {
151  halide_print(user_context, buf);
152  } else {
153  // It's a stringstream. Do nothing.
154  }
155  }
156 
157  if (own_mem) {
158  halide_free(user_context, buf);
159  }
160  }
161 };
162 
163 // A class that supports << with all the same types as Printer, but
164 // does nothing and should compile to a no-op.
165 class SinkPrinter {
166 public:
167  SinkPrinter(void *user_context) {}
168 };
169 template<typename T>
170 SinkPrinter operator<<(const SinkPrinter &s, T) {
171  return s;
172 }
173 
174 typedef Printer<BasicPrinter> print;
175 typedef Printer<ErrorPrinter> error;
176 typedef Printer<StringStreamPrinter> stringstream;
177 
178 #ifdef DEBUG_RUNTIME
179 typedef Printer<BasicPrinter> debug;
180 #else
181 typedef SinkPrinter debug;
182 #endif
183 }
184 
185 
186 }}}
187 #endif
void halide_error(void *user_context, const char *)
Halide calls this function on runtime errors (for example bounds checking failures).
void * user_context
Definition: printer.h:31
WEAK char * halide_uint64_to_string(char *dst, char *end, uint64_t arg, int digits)
void halide_print(void *user_context, const char *)
Print a message to stderr.
WEAK char * halide_buffer_to_string(char *dst, char *end, const halide_buffer_t *arg)
void * halide_malloc(void *user_context, size_t x)
Halide calls these functions to allocate and free memory.
EXPORT Expr print(const std::vector< Expr > &values)
Create an Expr that prints out its value whenever it is evaluated.
WEAK char * halide_int64_to_string(char *dst, char *end, int64_t arg, int digits)
Defines methods for manipulating and analyzing boolean expressions.
void halide_msan_annotate_memory_is_initialized(void *user_context, const void *ptr, uint64_t len)
Annotate that a given range of memory has been initialized; only used when Target::MSAN is enabled...
#define NULL
WEAK char * halide_pointer_to_string(char *dst, char *end, const void *arg)
WEAK char * halide_double_to_string(char *dst, char *end, double arg, int scientific)
bool own_mem
Definition: printer.h:32
void halide_free(void *user_context, void *ptr)
Halide calls these functions to allocate and free memory.
double halide_float16_bits_to_double(uint16_t)
Read bits representing a half precision floating point number and return the double that represents t...
WEAK char * halide_type_to_string(char *dst, char *end, const halide_type_t *arg)
char * end
Definition: printer.h:30
unsigned __INT32_TYPE__ uint32_t
char * dst
Definition: printer.h:30
signed __INT64_TYPE__ int64_t
A runtime tag for a type in the halide type system.
unsigned __INT16_TYPE__ uint16_t
char * buf
Definition: printer.h:30
WEAK char * halide_string_to_string(char *dst, char *end, const char *arg)
The raw representation of an image passed around by generated Halide code.
unsigned __INT64_TYPE__ uint64_t
EXPORT std::ostream & operator<<(std::ostream &stream, const Expr &)
Emit an expression on an output stream (such as std::cout) in a human-readable form.
signed __INT32_TYPE__ int32_t