1 #ifndef HALIDE_IMAGE_PARAM_H
2 #define HALIDE_IMAGE_PARAM_H
3 
4 /** \file
5  *
6  * Classes for declaring image parameters to halide pipelines
7  */
8 
9 #include <utility>
10 
11 #include "Func.h"
12 #include "OutputImageParam.h"
13 #include "Var.h"
14 
15 namespace Halide {
16 
17 namespace Internal {
18 template<typename T2>
19 class GeneratorInput_Buffer;
20 }
21 
22 /** An Image parameter to a halide pipeline. E.g., the input image. */
23 class ImageParam : public OutputImageParam {
24     template<typename T2>
25     friend class ::Halide::Internal::GeneratorInput_Buffer;
26 
27     // Only for use of Generator
ImageParam(const Internal::Parameter & p,Func f)28     ImageParam(const Internal::Parameter &p, Func f)
29         : OutputImageParam(p, Argument::InputBuffer, std::move(f)) {
30     }
31 
32     /** Helper function to initialize the Func representation of this ImageParam. */
33     Func create_func() const;
34 
35 public:
36     /** Construct a nullptr image parameter handle. */
37     ImageParam() = default;
38 
39     /** Construct an image parameter of the given type and
40      * dimensionality, with an auto-generated unique name. */
41     ImageParam(Type t, int d);
42 
43     /** Construct an image parameter of the given type and
44      * dimensionality, with the given name */
45     ImageParam(Type t, int d, const std::string &n);
46 
47     /** Bind an Image to this ImageParam. Only relevant for jitting */
48     // @{
49     void set(const Buffer<> &im);
50     // @}
51 
52     /** Get a reference to the Buffer bound to this ImageParam. Only relevant for jitting. */
53     // @{
54     Buffer<> get() const;
55     // @}
56 
57     /** Unbind any bound Buffer */
58     void reset();
59 
60     /** Construct an expression which loads from this image
61      * parameter. The location is extended with enough implicit
62      * variables to match the dimensionality of the image
63      * (see \ref Var::implicit)
64      */
65     // @{
66     template<typename... Args>
operator()67     HALIDE_NO_USER_CODE_INLINE Expr operator()(Args &&... args) const {
68         return func(std::forward<Args>(args)...);
69     }
70     Expr operator()(std::vector<Expr>) const;
71     Expr operator()(std::vector<Var>) const;
72     // @}
73 
74     /** Return the intrinsic Func representation of this ImageParam. This allows
75      * an ImageParam to be implicitly converted to a Func.
76      *
77      * Note that we use implicit vars to name the dimensions of Funcs associated
78      * with the ImageParam: both its internal Func representation and wrappers
79      * (See \ref ImageParam::in). For example, to unroll the first and second
80      * dimensions of the associated Func by a factor of 2, we would do the following:
81      \code
82      func.unroll(_0, 2).unroll(_1, 2);
83      \endcode
84      * '_0' represents the first dimension of the Func, while _1 represents the
85      * second dimension of the Func.
86      */
87     operator Func() const;
88 
89     /** Creates and returns a new Func that wraps this ImageParam. During
90      * compilation, Halide will replace calls to this ImageParam with calls
91      * to the wrapper as appropriate. If this ImageParam is already wrapped
92      * for use in some Func, it will return the existing wrapper.
93      *
94      * For example, img.in(g) would rewrite a pipeline like this:
95      \code
96      ImageParam img(Int(32), 2);
97      Func g;
98      g(x, y) = ... img(x, y) ...
99      \endcode
100      * into a pipeline like this:
101      \code
102      ImageParam img(Int(32), 2);
103      Func img_wrap, g;
104      img_wrap(x, y) = img(x, y);
105      g(x, y) = ... img_wrap(x, y) ...
106      \endcode
107      *
108      * This has a variety of uses. One use case is to stage loads from an
109      * ImageParam via some intermediate buffer (e.g. on the stack or in shared
110      * GPU memory).
111      *
112      * The following example illustrates how you would use the 'in()' directive
113      * to stage loads from an ImageParam into the GPU shared memory:
114      \code
115      ImageParam img(Int(32), 2);
116      output(x, y) = img(y, x);
117      Var tx, ty;
118      output.compute_root().gpu_tile(x, y, tx, ty, 8, 8);
119      img.in().compute_at(output, x).unroll(_0, 2).unroll(_1, 2).gpu_threads(_0, _1);
120      \endcode
121      *
122      * Note that we use implicit vars to name the dimensions of the wrapper Func.
123      * See \ref Func::in for more possible use cases of the 'in()' directive.
124      */
125     // @{
126     Func in(const Func &f);
127     Func in(const std::vector<Func> &fs);
128     Func in();
129     // @}
130 
131     /** Trace all loads from this ImageParam by emitting calls to halide_trace. */
132     void trace_loads();
133 
134     /** Add a trace tag to this ImageParam's Func. */
135     ImageParam &add_trace_tag(const std::string &trace_tag);
136 };
137 
138 }  // namespace Halide
139 
140 #endif
141