Halide
Buffer.h
Go to the documentation of this file.
1 #ifndef HALIDE_BUFFER_H
2 #define HALIDE_BUFFER_H
3 
4 #include "DeviceInterface.h"
5 #include "Expr.h"
6 #include "IntrusivePtr.h"
7 #include "runtime/HalideBuffer.h"
8 
9 namespace Halide {
10 
11 template<typename T = void>
12 class Buffer;
13 
14 namespace Internal {
15 
18  std::string name;
20 };
21 
22 Expr buffer_accessor(const Buffer<> &buf, const std::vector<Expr> &args);
23 
24 template<typename... Args>
25 struct all_ints_and_optional_name : std::false_type {};
26 
27 template<typename First, typename... Rest>
28 struct all_ints_and_optional_name<First, Rest...> : meta_and<std::is_convertible<First, int>,
29  all_ints_and_optional_name<Rest...>> {};
30 
31 template<typename T>
32 struct all_ints_and_optional_name<T> : meta_or<std::is_convertible<T, std::string>,
33  std::is_convertible<T, int>> {};
34 
35 template<>
36 struct all_ints_and_optional_name<> : std::true_type {};
37 
38 template<typename T,
39  typename = typename std::enable_if<!std::is_convertible<T, std::string>::value>::type>
41  return "";
42 }
43 
44 inline std::string get_name_from_end_of_parameter_pack(const std::string &n) {
45  return n;
46 }
47 
49  return "";
50 }
51 
52 template<typename First,
53  typename Second,
54  typename... Args>
55 std::string get_name_from_end_of_parameter_pack(First first, Second second, Args &&... rest) {
56  return get_name_from_end_of_parameter_pack(second, std::forward<Args>(rest)...);
57 }
58 
59 inline void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &, const std::string &) {
60 }
61 
62 inline void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &) {
63 }
64 
65 template<typename... Args>
66 void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &result, int x, Args &&... rest) {
67  result.push_back(x);
68  get_shape_from_start_of_parameter_pack_helper(result, std::forward<Args>(rest)...);
69 }
70 
71 template<typename... Args>
72 std::vector<int> get_shape_from_start_of_parameter_pack(Args &&... args) {
73  std::vector<int> result;
74  get_shape_from_start_of_parameter_pack_helper(result, std::forward<Args>(args)...);
75  return result;
76 }
77 
78 template<typename T, typename T2>
79 using add_const_if_T_is_const = typename std::conditional<std::is_const<T>::value, const T2, T2>::type;
80 
81 // Helpers to produce the name of a Buffer element type (a Halide
82 // scalar type, or void, possibly with const). Useful for an error
83 // messages.
84 template<typename T>
85 void buffer_type_name_non_const(std::ostream &s) {
86  s << type_to_c_type(type_of<T>(), false);
87 }
88 
89 template<>
90 inline void buffer_type_name_non_const<void>(std::ostream &s) {
91  s << "void";
92 }
93 
94 template<typename T>
95 std::string buffer_type_name() {
96  std::ostringstream oss;
97  if (std::is_const<T>::value) {
98  oss << "const ";
99  }
100  buffer_type_name_non_const<typename std::remove_const<T>::type>(oss);
101  return oss.str();
102 }
103 
104 } // namespace Internal
105 
106 /** A Halide::Buffer is a named shared reference to a
107  * Halide::Runtime::Buffer.
108  *
109  * A Buffer<T1> can refer to a Buffer<T2> if T1 is const whenever T2
110  * is const, and either T1 = T2 or T1 is void. A Buffer<void> can
111  * refer to any Buffer of any non-const type, and the default
112  * template parameter is T = void.
113  */
114 template<typename T>
115 class Buffer {
116  Internal::IntrusivePtr<Internal::BufferContents> contents;
117 
118  template<typename T2>
119  friend class Buffer;
120 
121  template<typename T2>
122  static void assert_can_convert_from(const Buffer<T2> &other) {
123  if (!other.defined()) {
124  // Avoid UB of deferencing offset of a null contents ptr
125  static_assert((!std::is_const<T2>::value || std::is_const<T>::value),
126  "Can't convert from a Buffer<const T> to a Buffer<T>");
127  static_assert(std::is_same<typename std::remove_const<T>::type,
128  typename std::remove_const<T2>::type>::value ||
129  std::is_void<T>::value ||
130  std::is_void<T2>::value,
131  "type mismatch constructing Buffer");
132  } else {
133  // Don't delegate to
134  // Runtime::Buffer<T>::assert_can_convert_from. It might
135  // not assert is NDEBUG is defined. user_assert is
136  // friendlier anyway because it reports line numbers when
137  // debugging symbols are found, it throws an exception
138  // when exceptions are enabled, and we can print the
139  // actual types in question.
141  << "Type mismatch constructing Buffer. Can't construct Buffer<"
142  << Internal::buffer_type_name<T>() << "> from Buffer<"
143  << type_to_c_type(other.type(), false) << ">\n";
144  }
145  }
146 
147 public:
148  typedef T ElemType;
149 
150  // This class isn't final (and is subclassed from the Python binding
151  // code, at least) so it needs a virtual dtor.
152  virtual ~Buffer() = default;
153 
154  /** Make a null Buffer, which points to no Runtime::Buffer */
155  Buffer() = default;
156 
157  /** Trivial copy constructor. */
158  Buffer(const Buffer &that) = default;
159 
160  /** Trivial copy assignment operator. */
161  Buffer &operator=(const Buffer &that) = default;
162 
163  /** Trivial move assignment operator. */
164  Buffer &operator=(Buffer &&) noexcept = default;
165 
166  /** Make a Buffer from a Buffer of a different type */
167  template<typename T2>
168  Buffer(const Buffer<T2> &other)
169  : contents(other.contents) {
170  assert_can_convert_from(other);
171  }
172 
173  /** Move construct from a Buffer of a different type */
174  template<typename T2>
175  Buffer(Buffer<T2> &&other) noexcept {
176  assert_can_convert_from(other);
177  contents = std::move(other.contents);
178  }
179 
180  /** Construct a Buffer that captures and owns an rvalue Runtime::Buffer */
181  template<int D>
182  Buffer(Runtime::Buffer<T, D> &&buf, const std::string &name = "")
183  : contents(new Internal::BufferContents) {
184  contents->buf = std::move(buf);
185  if (name.empty()) {
186  contents->name = Internal::make_entity_name(this, "Halide:.*:Buffer<.*>", 'b');
187  } else {
188  contents->name = name;
189  }
190  }
191 
192  /** Constructors that match Runtime::Buffer with two differences:
193  * 1) They take a Type instead of a halide_type_t
194  * 2) There is an optional last string argument that gives the buffer a specific name
195  */
196  // @{
197  template<typename... Args,
198  typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
199  explicit Buffer(Type t,
200  int first, Args... rest)
201  : Buffer(Runtime::Buffer<T>(t, Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
203  }
204 
205  explicit Buffer(const halide_buffer_t &buf,
206  const std::string &name = "")
207  : Buffer(Runtime::Buffer<T>(buf), name) {
208  }
209 
210  template<typename... Args,
211  typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
212  explicit Buffer(int first, Args... rest)
213  : Buffer(Runtime::Buffer<T>(Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
215  }
216 
217  explicit Buffer(Type t,
218  const std::vector<int> &sizes,
219  const std::string &name = "")
220  : Buffer(Runtime::Buffer<T>(t, sizes), name) {
221  }
222 
223  explicit Buffer(Type t,
224  const std::vector<int> &sizes,
225  const std::vector<int> &storage_order,
226  const std::string &name = "")
227  : Buffer(Runtime::Buffer<T>(t, sizes, storage_order), name) {
228  }
229 
230  explicit Buffer(const std::vector<int> &sizes,
231  const std::string &name = "")
232  : Buffer(Runtime::Buffer<T>(sizes), name) {
233  }
234 
235  explicit Buffer(const std::vector<int> &sizes,
236  const std::vector<int> &storage_order,
237  const std::string &name = "")
238  : Buffer(Runtime::Buffer<T>(sizes, storage_order), name) {
239  }
240 
241  template<typename Array, size_t N>
242  explicit Buffer(Array (&vals)[N],
243  const std::string &name = "")
244  : Buffer(Runtime::Buffer<T>(vals), name) {
245  }
246 
247  template<typename... Args,
248  typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
249  explicit Buffer(Type t,
251  int first, Args &&... rest)
252  : Buffer(Runtime::Buffer<T>(t, data, Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
254  }
255 
256  template<typename... Args,
257  typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
258  explicit Buffer(Type t,
260  const std::vector<int> &sizes,
261  const std::string &name = "")
262  : Buffer(Runtime::Buffer<T>(t, data, sizes, name)) {
263  }
264 
265  template<typename... Args,
266  typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
267  explicit Buffer(T *data,
268  int first, Args &&... rest)
269  : Buffer(Runtime::Buffer<T>(data, Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
271  }
272 
273  explicit Buffer(T *data,
274  const std::vector<int> &sizes,
275  const std::string &name = "")
276  : Buffer(Runtime::Buffer<T>(data, sizes), name) {
277  }
278 
279  explicit Buffer(Type t,
281  const std::vector<int> &sizes,
282  const std::string &name = "")
283  : Buffer(Runtime::Buffer<T>(t, data, sizes), name) {
284  }
285 
286  explicit Buffer(Type t,
288  int d,
289  const halide_dimension_t *shape,
290  const std::string &name = "")
291  : Buffer(Runtime::Buffer<T>(t, data, d, shape), name) {
292  }
293 
294  explicit Buffer(T *data,
295  int d,
296  const halide_dimension_t *shape,
297  const std::string &name = "")
298  : Buffer(Runtime::Buffer<T>(data, d, shape), name) {
299  }
300 
301  static Buffer<T> make_scalar(const std::string &name = "") {
303  }
304 
305  static Buffer<> make_scalar(Type t, const std::string &name = "") {
307  }
308 
309  static Buffer<T> make_scalar(T *data, const std::string &name = "") {
311  }
312 
313  static Buffer<T> make_interleaved(int width, int height, int channels, const std::string &name = "") {
314  return Buffer<T>(Runtime::Buffer<T>::make_interleaved(width, height, channels),
315  name);
316  }
317 
318  static Buffer<> make_interleaved(Type t, int width, int height, int channels, const std::string &name = "") {
319  return Buffer<>(Runtime::Buffer<>::make_interleaved(t, width, height, channels),
320  name);
321  }
322 
323  static Buffer<T> make_interleaved(T *data, int width, int height, int channels, const std::string &name = "") {
324  return Buffer<T>(Runtime::Buffer<T>::make_interleaved(data, width, height, channels),
325  name);
326  }
327 
329  make_interleaved(Type t, T *data, int width, int height, int channels, const std::string &name = "") {
331  return Buffer<T2>(Runtime::Buffer<T2>::make_interleaved(t, data, width, height, channels),
332  name);
333  }
334 
335  template<typename T2>
337  void *(*allocate_fn)(size_t) = nullptr,
338  void (*deallocate_fn)(void *) = nullptr,
339  const std::string &name = "") {
340  return Buffer<T>(Runtime::Buffer<T>::make_with_shape_of(*src.get(), allocate_fn, deallocate_fn),
341  name);
342  }
343 
344  template<typename T2>
346  void *(*allocate_fn)(size_t) = nullptr,
347  void (*deallocate_fn)(void *) = nullptr,
348  const std::string &name = "") {
349  return Buffer<T>(Runtime::Buffer<T>::make_with_shape_of(src, allocate_fn, deallocate_fn),
350  name);
351  }
352  // @}
353 
354  /** Buffers are optionally named. */
355  // @{
356  void set_name(const std::string &n) {
357  contents->name = n;
358  }
359 
360  const std::string &name() const {
361  return contents->name;
362  }
363  // @}
364 
365  /** Check if two Buffer objects point to the same underlying Buffer */
366  template<typename T2>
367  bool same_as(const Buffer<T2> &other) const {
368  return (const void *)(contents.get()) == (const void *)(other.contents.get());
369  }
370 
371  /** Check if this Buffer refers to an existing
372  * Buffer. Default-constructed Buffer objects do not refer to any
373  * existing Buffer. */
374  bool defined() const {
375  return contents.defined();
376  }
377 
378  /** Get a pointer to the underlying Runtime::Buffer */
379  // @{
381  // It's already type-checked, so no need to use as<T>.
382  return (Runtime::Buffer<T> *)(&contents->buf);
383  }
384  const Runtime::Buffer<T> *get() const {
385  return (const Runtime::Buffer<T> *)(&contents->buf);
386  }
387  // @}
388 
389 public:
390  // We forward numerous methods from the underlying Buffer
391 #define HALIDE_BUFFER_FORWARD_CONST(method) \
392  template<typename... Args> \
393  auto method(Args &&... args) const->decltype(std::declval<const Runtime::Buffer<T>>().method(std::forward<Args>(args)...)) { \
394  user_assert(defined()) << "Undefined buffer calling const method " #method "\n"; \
395  return get()->method(std::forward<Args>(args)...); \
396  }
397 
398 #define HALIDE_BUFFER_FORWARD(method) \
399  template<typename... Args> \
400  auto method(Args &&... args)->decltype(std::declval<Runtime::Buffer<T>>().method(std::forward<Args>(args)...)) { \
401  user_assert(defined()) << "Undefined buffer calling method " #method "\n"; \
402  return get()->method(std::forward<Args>(args)...); \
403  }
404 
405 // This is a weird-looking but effective workaround for a deficiency in "perfect forwarding":
406 // namely, it can't really handle initializer-lists. The idea here is that we declare
407 // the expected type to be passed on, and that allows the compiler to handle it.
408 // The weirdness comes in with the variadic macro: the problem is that the type
409 // we want to forward might be something like `std::vector<std::pair<int, int>>`,
410 // which contains a comma, which throws a big wrench in C++ macro system.
411 // However... since all we really need to do is capture the remainder of the macro,
412 // and forward it as is, we can just use ... to allow an arbitrary number of commas,
413 // then use __VA_ARGS__ to forward the mess as-is, and while it looks horrible, it
414 // works.
415 #define HALIDE_BUFFER_FORWARD_INITIALIZER_LIST(method, ...) \
416  inline auto method(const __VA_ARGS__ &a)->decltype(std::declval<Runtime::Buffer<T>>().method(a)) { \
417  user_assert(defined()) << "Undefined buffer calling method " #method "\n"; \
418  return get()->method(a); \
419  }
420 
421  /** Does the same thing as the equivalent Halide::Runtime::Buffer method */
422  // @{
423  HALIDE_BUFFER_FORWARD(raw_buffer)
424  HALIDE_BUFFER_FORWARD_CONST(raw_buffer)
425  HALIDE_BUFFER_FORWARD_CONST(dimensions)
437  HALIDE_BUFFER_FORWARD_CONST(number_of_elements)
438  HALIDE_BUFFER_FORWARD_CONST(size_in_bytes)
445  HALIDE_BUFFER_FORWARD_INITIALIZER_LIST(crop, std::vector<std::pair<int, int>>)
446  HALIDE_BUFFER_FORWARD(slice)
448  HALIDE_BUFFER_FORWARD(embed)
450  HALIDE_BUFFER_FORWARD(set_min)
451  HALIDE_BUFFER_FORWARD(translate)
452  HALIDE_BUFFER_FORWARD_INITIALIZER_LIST(translate, std::vector<int>)
453  HALIDE_BUFFER_FORWARD(transpose)
454  HALIDE_BUFFER_FORWARD_CONST(transposed)
455  HALIDE_BUFFER_FORWARD(add_dimension)
456  HALIDE_BUFFER_FORWARD(copy_to_host)
458  HALIDE_BUFFER_FORWARD_CONST(has_device_allocation)
459  HALIDE_BUFFER_FORWARD_CONST(host_dirty)
460  HALIDE_BUFFER_FORWARD_CONST(device_dirty)
461  HALIDE_BUFFER_FORWARD(set_host_dirty)
462  HALIDE_BUFFER_FORWARD(set_device_dirty)
463  HALIDE_BUFFER_FORWARD(device_sync)
466  HALIDE_BUFFER_FORWARD(device_detach_native)
467  HALIDE_BUFFER_FORWARD(allocate)
468  HALIDE_BUFFER_FORWARD(deallocate)
469  HALIDE_BUFFER_FORWARD(device_deallocate)
470  HALIDE_BUFFER_FORWARD(device_free)
471  HALIDE_BUFFER_FORWARD_CONST(all_equal)
472 
473 #undef HALIDE_BUFFER_FORWARD
474 #undef HALIDE_BUFFER_FORWARD_CONST
475 
476  template<typename Fn, typename... Args>
477  Buffer<T> &for_each_value(Fn &&f, Args... other_buffers) {
478  get()->for_each_value(std::forward<Fn>(f), (*std::forward<Args>(other_buffers).get())...);
479  return *this;
480  }
481 
482  template<typename Fn, typename... Args>
483  const Buffer<T> &for_each_value(Fn &&f, Args... other_buffers) const {
484  get()->for_each_value(std::forward<Fn>(f), (*std::forward<Args>(other_buffers).get())...);
485  return *this;
486  }
487 
488  template<typename Fn>
490  get()->for_each_element(std::forward<Fn>(f));
491  return *this;
492  }
493 
494  template<typename Fn>
495  const Buffer<T> &for_each_element(Fn &&f) const {
496  get()->for_each_element(std::forward<Fn>(f));
497  return *this;
498  }
499 
500  template<typename FnOrValue>
501  Buffer<T> &fill(FnOrValue &&f) {
502  get()->fill(std::forward<FnOrValue>(f));
503  return *this;
504  }
505 
507 
510  }
511 
512  template<typename T2>
513  static bool can_convert_from(const Buffer<T2> &other) {
515  }
516 
517  // Note that since Runtime::Buffer stores halide_type_t rather than Halide::Type,
518  // there is no handle-specific type information, so all handle types are
519  // considered equivalent to void* here. (This only matters if you are making
520  // a Buffer-of-handles, which is not really a real use case...)
521  Type type() const {
522  return contents->buf.type();
523  }
524 
525  template<typename T2>
526  Buffer<T2> as() const {
527  return Buffer<T2>(*this);
528  }
529 
530  Buffer<T> copy() const {
531  return Buffer<T>(std::move(contents->buf.as<T>().copy()));
532  }
533 
534  template<typename T2>
535  void copy_from(const Buffer<T2> &other) {
536  contents->buf.copy_from(*other.get());
537  }
538 
539  template<typename... Args>
540  auto operator()(int first, Args &&... args) -> decltype(std::declval<Runtime::Buffer<T>>()(first, std::forward<Args>(args)...)) {
541  return (*get())(first, std::forward<Args>(args)...);
542  }
543 
544  template<typename... Args>
545  auto operator()(int first, Args &&... args) const -> decltype(std::declval<const Runtime::Buffer<T>>()(first, std::forward<Args>(args)...)) {
546  return (*get())(first, std::forward<Args>(args)...);
547  }
548 
549  auto operator()(const int *pos) -> decltype(std::declval<Runtime::Buffer<T>>()(pos)) {
550  return (*get())(pos);
551  }
552 
553  auto operator()(const int *pos) const -> decltype(std::declval<const Runtime::Buffer<T>>()(pos)) {
554  return (*get())(pos);
555  }
556 
557  auto operator()() -> decltype(std::declval<Runtime::Buffer<T>>()()) {
558  return (*get())();
559  }
560 
561  auto operator()() const -> decltype(std::declval<const Runtime::Buffer<T>>()()) {
562  return (*get())();
563  }
564  // @}
565 
566  /** Make an Expr that loads from this concrete buffer at a computed coordinate. */
567  // @{
568  template<typename... Args>
569  Expr operator()(const Expr &first, Args... rest) const {
570  std::vector<Expr> args = {first, rest...};
571  return (*this)(args);
572  };
573 
574  template<typename... Args>
575  Expr operator()(const std::vector<Expr> &args) const {
576  return buffer_accessor(Buffer<>(*this), args);
577  };
578  // @}
579 
580  /** Copy to the GPU, using the device API that is the default for the given Target. */
583  }
584 
585  /** Copy to the GPU, using the given device API */
587  return contents->buf.copy_to_device(get_device_interface_for_device_api(d, t, "Buffer::copy_to_device"));
588  }
589 
590  /** Allocate on the GPU, using the device API that is the default for the given Target. */
593  }
594 
595  /** Allocate storage on the GPU, using the given device API */
597  return contents->buf.device_malloc(get_device_interface_for_device_api(d, t, "Buffer::device_malloc"));
598  }
599 
600  /** Wrap a native handle, using the given device API.
601  * It is a bad idea to pass DeviceAPI::Default_GPU to this routine
602  * as the handle argument must match the API that the default
603  * resolves to and it is clearer and more reliable to pass the
604  * resolved DeviceAPI explicitly. */
606  return contents->buf.device_wrap_native(get_device_interface_for_device_api(d, t, "Buffer::device_wrap_native"), handle);
607  }
608 };
609 
610 } // namespace Halide
611 
612 #endif
Halide::Buffer::operator()
auto operator()(const int *pos) -> decltype(std::declval< Runtime::Buffer< T >>()(pos))
Definition: Buffer.h:549
Halide::Buffer::operator=
Buffer & operator=(const Buffer &that)=default
Trivial copy assignment operator.
Halide::Buffer::Buffer
Buffer(Runtime::Buffer< T, D > &&buf, const std::string &name="")
Construct a Buffer that captures and owns an rvalue Runtime::Buffer.
Definition: Buffer.h:182
Halide::Internal::IOKind::Buffer
@ Buffer
Halide::Buffer::Buffer
Buffer(Type t, const std::vector< int > &sizes, const std::string &name="")
Definition: Buffer.h:217
Halide::Buffer::has_static_halide_type
static constexpr bool has_static_halide_type
Definition: Buffer.h:506
halide_dimension_t
Definition: HalideRuntime.h:1365
Halide::Buffer::static_halide_type
static halide_type_t static_halide_type()
Definition: Buffer.h:508
Halide::Buffer::Buffer
Buffer(Array(&vals)[N], const std::string &name="")
Definition: Buffer.h:242
Halide::Buffer::operator()
Expr operator()(const std::vector< Expr > &args) const
Definition: Buffer.h:575
Halide::Buffer::Buffer
Buffer(Type t, Internal::add_const_if_T_is_const< T, void > *data, const std::vector< int > &sizes, const std::string &name="")
Definition: Buffer.h:258
Halide::DeviceAPI::Default_GPU
@ Default_GPU
Halide::Buffer::make_interleaved
static Buffer< T > make_interleaved(T *data, int width, int height, int channels, const std::string &name="")
Definition: Buffer.h:323
Halide::Internal::all_ints_and_optional_name
Definition: Buffer.h:25
Halide::Buffer::Buffer
Buffer(Type t, Internal::add_const_if_T_is_const< T, void > *data, int d, const halide_dimension_t *shape, const std::string &name="")
Definition: Buffer.h:286
HALIDE_BUFFER_FORWARD
#define HALIDE_BUFFER_FORWARD(method)
Definition: Buffer.h:398
Halide::min
Expr min(const FuncRef &a, const FuncRef &b)
Explicit overloads of min and max for FuncRef.
Definition: Func.h:577
HalideBuffer.h
Halide::Internal::make_entity_name
std::string make_entity_name(void *stack_ptr, const std::string &type, char prefix)
Make a unique name for an object based on the name of the stack variable passed in.
Halide::Buffer::get
const Runtime::Buffer< T > * get() const
Definition: Buffer.h:384
HALIDE_BUFFER_FORWARD_CONST
#define HALIDE_BUFFER_FORWARD_CONST(method)
Definition: Buffer.h:391
Halide::Buffer::make_with_shape_of
static Buffer< T > make_with_shape_of(const Runtime::Buffer< T2 > &src, void *(*allocate_fn)(size_t)=nullptr, void(*deallocate_fn)(void *)=nullptr, const std::string &name="")
Definition: Buffer.h:345
Halide::Internal::meta_and
Definition: Util.h:198
Halide::Internal::get_name_from_end_of_parameter_pack
std::string get_name_from_end_of_parameter_pack(First first, Second second, Args &&... rest)
Definition: Buffer.h:55
halide_type_t
A runtime tag for a type in the halide type system.
Definition: HalideRuntime.h:426
user_assert
#define user_assert(c)
Definition: Errors.h:15
Halide::Buffer::Buffer
Buffer(Type t, Internal::add_const_if_T_is_const< T, void > *data, int first, Args &&... rest)
Definition: Buffer.h:249
Halide::Buffer::Buffer
Buffer(const halide_buffer_t &buf, const std::string &name="")
Definition: Buffer.h:205
Halide::Internal::buffer_type_name
std::string buffer_type_name()
Definition: Buffer.h:95
Halide::Internal::add_const_if_T_is_const
typename std::conditional< std::is_const< T >::value, const T2, T2 >::type add_const_if_T_is_const
Definition: Buffer.h:79
Halide::Buffer::Buffer
Buffer(Type t, int first, Args... rest)
Constructors that match Runtime::Buffer with two differences: 1) They take a Type instead of a halide...
Definition: Buffer.h:199
Halide::Buffer::Buffer
Buffer(const std::vector< int > &sizes, const std::string &name="")
Definition: Buffer.h:230
Halide::Buffer::copy_to_device
int copy_to_device(const Target &t=get_jit_target_from_environment())
Copy to the GPU, using the device API that is the default for the given Target.
Definition: Buffer.h:581
uint64_t
unsigned __INT64_TYPE__ uint64_t
Definition: runtime_internal.h:19
Halide::Buffer::for_each_value
Buffer< T > & for_each_value(Fn &&f, Args... other_buffers)
Does the same thing as the equivalent Halide::Runtime::Buffer method.
Definition: Buffer.h:477
Halide::Type
Types in the halide type system.
Definition: Type.h:269
Halide::Buffer::for_each_element
const Buffer< T > & for_each_element(Fn &&f) const
Definition: Buffer.h:495
Halide::get_device_interface_for_device_api
const halide_device_interface_t * get_device_interface_for_device_api(DeviceAPI d, const Target &t=get_jit_target_from_environment(), const char *error_site=nullptr)
Gets the appropriate halide_device_interface_t * for a DeviceAPI.
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AddAtomicMutex.h:21
Halide::Buffer::copy_from
void copy_from(const Buffer< T2 > &other)
Definition: Buffer.h:535
Halide::Buffer::make_interleaved
static Buffer< Internal::add_const_if_T_is_const< T, void > > make_interleaved(Type t, T *data, int width, int height, int channels, const std::string &name="")
Definition: Buffer.h:329
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::Buffer::~Buffer
virtual ~Buffer()=default
Halide::Buffer::device_malloc
int device_malloc(const Target &t=get_jit_target_from_environment())
Allocate on the GPU, using the device API that is the default for the given Target.
Definition: Buffer.h:591
Halide::Buffer::make_scalar
static Buffer make_scalar(Type t, const std::string &name="")
Definition: Buffer.h:305
Halide::Buffer::same_as
bool same_as(const Buffer< T2 > &other) const
Check if two Buffer objects point to the same underlying Buffer.
Definition: Buffer.h:367
Halide::Buffer<>
Halide::Buffer::operator()
auto operator()(const int *pos) const -> decltype(std::declval< const Runtime::Buffer< T >>()(pos))
Definition: Buffer.h:553
Halide::Buffer::make_scalar
static Buffer< T > make_scalar(T *data, const std::string &name="")
Definition: Buffer.h:309
Halide::Runtime::Buffer::static_halide_type
static halide_type_t static_halide_type()
Get the Halide type of T.
Definition: HalideBuffer.h:172
Halide::Buffer::ElemType
T ElemType
Definition: Buffer.h:148
Halide::Buffer::Buffer
Buffer(T *data, int d, const halide_dimension_t *shape, const std::string &name="")
Definition: Buffer.h:294
Halide::Runtime::Buffer
A templated Buffer class that wraps halide_buffer_t and adds functionality.
Definition: HalideBuffer.h:43
HALIDE_BUFFER_FORWARD_INITIALIZER_LIST
#define HALIDE_BUFFER_FORWARD_INITIALIZER_LIST(method,...)
Definition: Buffer.h:415
Halide::Buffer::defined
bool defined() const
Check if this Buffer refers to an existing Buffer.
Definition: Buffer.h:374
Halide::Internal::get_shape_from_start_of_parameter_pack_helper
void get_shape_from_start_of_parameter_pack_helper(std::vector< int > &, const std::string &)
Definition: Buffer.h:59
DeviceInterface.h
Halide::Buffer::Buffer
Buffer(Type t, const std::vector< int > &sizes, const std::vector< int > &storage_order, const std::string &name="")
Definition: Buffer.h:223
Halide::Internal::BufferContents
Definition: Buffer.h:16
Halide::Internal::BufferContents::buf
Runtime::Buffer buf
Definition: Buffer.h:19
Halide::Buffer::Buffer
Buffer(T *data, const std::vector< int > &sizes, const std::string &name="")
Definition: Buffer.h:273
Halide::Buffer::make_with_shape_of
static Buffer< T > make_with_shape_of(Buffer< T2 > src, void *(*allocate_fn)(size_t)=nullptr, void(*deallocate_fn)(void *)=nullptr, const std::string &name="")
Definition: Buffer.h:336
Expr.h
Halide::Internal::BufferContents::name
std::string name
Definition: Buffer.h:18
Halide::Buffer::can_convert_from
static bool can_convert_from(const Buffer< T2 > &other)
Definition: Buffer.h:513
Halide::Buffer::Buffer
Buffer(T *data, int first, Args &&... rest)
Definition: Buffer.h:267
end
char * end
Definition: printer.h:32
Halide::Buffer::name
const std::string & name() const
Definition: Buffer.h:360
Halide::Internal::get_shape_from_start_of_parameter_pack
std::vector< int > get_shape_from_start_of_parameter_pack(Args &&... args)
Definition: Buffer.h:72
Halide::Buffer::type
Type type() const
Definition: Buffer.h:521
Halide::Buffer::make_interleaved
static Buffer< T > make_interleaved(int width, int height, int channels, const std::string &name="")
Definition: Buffer.h:313
Halide::Runtime::Buffer::can_convert_from
static bool can_convert_from(const Buffer< T2, D2 > &other)
Determine if if an Buffer<T, D> can be constructed from some other Buffer type.
Definition: HalideBuffer.h:619
Halide::Buffer::device_wrap_native
int device_wrap_native(const DeviceAPI &d, uint64_t handle, const Target &t=get_jit_target_from_environment())
Wrap a native handle, using the given device API.
Definition: Buffer.h:605
Halide::Buffer::Buffer
friend class Buffer
Definition: Buffer.h:119
Halide::Buffer::operator()
auto operator()(int first, Args &&... args) -> decltype(std::declval< Runtime::Buffer< T >>()(first, std::forward< Args >(args)...))
Definition: Buffer.h:540
Halide::Buffer::Buffer
Buffer(Type t, Internal::add_const_if_T_is_const< T, void > *data, const std::vector< int > &sizes, const std::string &name="")
Definition: Buffer.h:279
halide_buffer_t
The raw representation of an image passed around by generated Halide code.
Definition: HalideRuntime.h:1404
Halide::get_jit_target_from_environment
Target get_jit_target_from_environment()
Return the target that Halide will use for jit-compilation.
Halide::Buffer::for_each_value
const Buffer< T > & for_each_value(Fn &&f, Args... other_buffers) const
Definition: Buffer.h:483
Halide::Buffer::set_name
void set_name(const std::string &n)
Buffers are optionally named.
Definition: Buffer.h:356
Halide::Buffer::Buffer
Buffer(Buffer< T2 > &&other) noexcept
Move construct from a Buffer of a different type.
Definition: Buffer.h:175
buf
char * buf
Definition: printer.h:32
Halide::Internal::RefCount
A class representing a reference count to be used with IntrusivePtr.
Definition: IntrusivePtr.h:19
Halide::Internal::buffer_accessor
Expr buffer_accessor(const Buffer<> &buf, const std::vector< Expr > &args)
Halide::Buffer::as
Buffer< T2 > as() const
Definition: Buffer.h:526
Halide::Buffer::fill
Buffer< T > & fill(FnOrValue &&f)
Definition: Buffer.h:501
Halide::Buffer::for_each_element
Buffer< T > & for_each_element(Fn &&f)
Definition: Buffer.h:489
Halide::Expr
A fragment of Halide syntax.
Definition: Expr.h:256
Halide::Buffer::make_scalar
static Buffer< T > make_scalar(const std::string &name="")
Definition: Buffer.h:301
Halide::Internal::BufferContents::ref_count
RefCount ref_count
Definition: Buffer.h:17
Halide::Buffer::get
Runtime::Buffer< T > * get()
Get a pointer to the underlying Runtime::Buffer.
Definition: Buffer.h:380
Halide::Internal::meta_or
Definition: Util.h:204
Halide::Buffer::device_malloc
int device_malloc(const DeviceAPI &d, const Target &t=get_jit_target_from_environment())
Allocate storage on the GPU, using the given device API.
Definition: Buffer.h:596
Halide::Buffer::operator()
auto operator()() const -> decltype(std::declval< const Runtime::Buffer< T >>()())
Definition: Buffer.h:561
Halide::Internal::get_name_from_end_of_parameter_pack
std::string get_name_from_end_of_parameter_pack(T &&)
Definition: Buffer.h:40
Halide::Buffer::operator()
auto operator()(int first, Args &&... args) const -> decltype(std::declval< const Runtime::Buffer< T >>()(first, std::forward< Args >(args)...))
Definition: Buffer.h:545
Halide::Buffer::Buffer
Buffer(const std::vector< int > &sizes, const std::vector< int > &storage_order, const std::string &name="")
Definition: Buffer.h:235
Halide::Buffer::copy
Buffer< T > copy() const
Definition: Buffer.h:530
Halide::Buffer::operator()
Expr operator()(const Expr &first, Args... rest) const
Make an Expr that loads from this concrete buffer at a computed coordinate.
Definition: Buffer.h:569
Halide::Buffer::operator()
auto operator()() -> decltype(std::declval< Runtime::Buffer< T >>()())
Definition: Buffer.h:557
IntrusivePtr.h
Halide::type_to_c_type
std::string type_to_c_type(Type type, bool include_space, bool c_plus_plus=true)
Halide type to a C++ type.
Halide::Target
A struct representing a target machine and os to generate code for.
Definition: Target.h:19
Halide::Buffer::Buffer
Buffer(int first, Args... rest)
Definition: Buffer.h:212
Halide::Internal::buffer_type_name_non_const< void >
void buffer_type_name_non_const< void >(std::ostream &s)
Definition: Buffer.h:90
Halide::Buffer::copy_to_device
int copy_to_device(const DeviceAPI &d, const Target &t=get_jit_target_from_environment())
Copy to the GPU, using the given device API.
Definition: Buffer.h:586
Halide::DeviceAPI
DeviceAPI
An enum describing a type of device API.
Definition: DeviceAPI.h:15
Halide::Internal::buffer_type_name_non_const
void buffer_type_name_non_const(std::ostream &s)
Definition: Buffer.h:85
Halide::Buffer::make_interleaved
static Buffer make_interleaved(Type t, int width, int height, int channels, const std::string &name="")
Definition: Buffer.h:318