#ifndef HALIDE_IMAGE_PARAM_H
#define HALIDE_IMAGE_PARAM_H
/** \file
*
* Classes for declaring image parameters to halide pipelines
*/
#include "Var.h"
#include "OutputImageParam.h"
#include "Func.h"
namespace Halide {
/** An Image parameter to a halide pipeline. E.g., the input image. */
class ImageParam : public OutputImageParam {
/** Func representation of the ImageParam.
* All call to ImageParam is equivalent to call to its intrinsic Func
* representation. */
Func func;
/** Helper function to initialize the Func representation of this ImageParam. */
EXPORT void init_func();
public:
/** Construct a nullptr image parameter handle. */
ImageParam() : OutputImageParam() {}
/** Construct an image parameter of the given type and
* dimensionality, with an auto-generated unique name. */
EXPORT ImageParam(Type t, int d);
/** Construct an image parameter of the given type and
* dimensionality, with the given name */
EXPORT ImageParam(Type t, int d, const std::string &n);
/** Bind an Image to this ImageParam. Only relevant for jitting */
// @{
EXPORT void set(Buffer<> im);
// @}
/** Get a reference to the Buffer bound to this ImageParam. Only relevant for jitting. */
// @{
EXPORT Buffer<> get() const;
// @}
/** Unbind any bound Buffer */
EXPORT void reset();
/** Construct an expression which loads from this image
* parameter. The location is extended with enough implicit
* variables to match the dimensionality of the image
* (see \ref Var::implicit)
*/
// @{
template <typename... Args>
NO_INLINE Expr operator()(Args&&... args) const {
return func(std::forward<Args>(args)...);
}
EXPORT Expr operator()(std::vector<Expr>) const;
EXPORT Expr operator()(std::vector<Var>) const;
// @}
/** Return the intrinsic Func representation of this ImageParam. This allows
* an ImageParam to be implicitly converted to a Func.
*
* Note that we use implicit vars to name the dimensions of Funcs associated
* with the ImageParam: both its internal Func representation and wrappers
* (See \ref ImageParam::in). For example, to unroll the first and second
* dimensions of the associated Func by a factor of 2, we would do the following:
\code
func.unroll(_0, 2).unroll(_1, 2);
\endcode
* '_0' represents the first dimension of the Func, while _1 represents the
* second dimension of the Func.
*/
EXPORT operator Func() const;
/** Creates and returns a new Func that wraps this ImageParam. During
* compilation, Halide will replace calls to this ImageParam with calls
* to the wrapper as appropriate. If this ImageParam is already wrapped
* for use in some Func, it will return the existing wrapper.
*
* For example, img.in(g) would rewrite a pipeline like this:
\code
ImageParam img(Int(32), 2);
Func g;
g(x, y) = ... img(x, y) ...
\endcode
* into a pipeline like this:
\code
ImageParam img(Int(32), 2);
Func img_wrap, g;
img_wrap(x, y) = img(x, y);
g(x, y) = ... img_wrap(x, y) ...
\endcode
*
* This has a variety of uses. One use case is to stage loads from an
* ImageParam via some intermediate buffer (e.g. on the stack or in shared
* GPU memory).
*
* The following example illustrates how you would use the 'in()' directive
* to stage loads from an ImageParam into the GPU shared memory:
\code
ImageParam img(Int(32), 2);
output(x, y) = img(y, x);
Var tx, ty;
output.compute_root().gpu_tile(x, y, tx, ty, 8, 8);
img.in().compute_at(output, x).unroll(_0, 2).unroll(_1, 2).gpu_threads(x, y);
\endcode
*
* Note that we use implicit vars to name the dimensions of the wrapper Func
* (See \ref ImageParam::in for more details). See \ref Func::in for more
* possible use cases of the 'in()' directive.
*/
// @{
EXPORT Func in(const Func &f);
EXPORT Func in(const std::vector<Func> &fs);
EXPORT Func in();
// @}
};
}
#endif