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