Halide 22.0.0 Halide compiler and libraries

Classes | Namespaces | Macros | Typedefs | Enumerations | Functions | Variables
Generator.h File Reference

Generator is a class used to encapsulate the building of Funcs in user pipelines. More...

`#include <algorithm>`
`#include <functional>`
`#include <iterator>`
`#include <limits>`
`#include <memory>`
`#include <mutex>`
`#include <set>`
`#include <sstream>`
`#include <string>`
`#include <type_traits>`
`#include <utility>`
`#include <vector>`
`#include "AbstractGenerator.h"`
`#include "Func.h"`
`#include "ImageParam.h"`
`#include "ObjectInstanceRegistry.h"`
`#include "Target.h"`

Go to the source code of this file.

## Classes
class | Halide::Internal::GeneratorFactoryProvider
| GeneratorFactoryProvider provides a way to customize the Generators that are visible to generate_filter_main (which otherwise would just look at the global registry of C++ Generators). More...
struct | Halide::Internal::cond< B, T >
struct | Halide::Internal::select_type< First, Rest >
struct | Halide::Internal::select_type< First >
class | Halide::Internal::GeneratorParamBase
struct | Halide::Internal::Convert< FROM, TO >
class | Halide::Internal::GeneratorParamImpl< T >
class | Halide::Internal::GeneratorParam_Target< T >
class | Halide::Internal::GeneratorParam_AutoSchedulerParams
class | Halide::Internal::GeneratorParam_LoopLevel
class | Halide::Internal::GeneratorParam_Arithmetic< T >
class | Halide::Internal::GeneratorParam_Bool< T >
class | Halide::Internal::GeneratorParam_Enum< T >
class | Halide::Internal::GeneratorParam_Type< T >
class | Halide::Internal::GeneratorParam_String< T >
class | Halide::GeneratorParam< T >
| GeneratorParam is a templated class that can be used to modify the behavior of the Generator at code-generation time. More...
class | Halide::Internal::StubInputBuffer< T, Dims >
| StubInputBuffer is the placeholder that a Stub uses when it requires a Buffer for an input (rather than merely a Func or Expr). More...
class | Halide::Internal::StubOutputBufferBase
class | Halide::Internal::StubOutputBuffer< T >
| StubOutputBuffer is the placeholder that a Stub uses when it requires a Buffer for an output (rather than merely a Func). More...
class | Halide::Internal::StubInput
class | Halide::Internal::GIOBase
| GIOBase is the base class for all GeneratorInput<> and GeneratorOutput<> instantiations; it is not part of the public API and should never be used directly by user code. More...
class | Halide::Internal::GeneratorInputBase
class | Halide::Internal::GeneratorInputImpl< T, ValueType >
class | Halide::Internal::GeneratorInput_Buffer< T >
class | Halide::Internal::GeneratorInput_Func< T >
class | Halide::Internal::GeneratorInput_DynamicScalar< T >
class | Halide::Internal::GeneratorInput_Scalar< T >
class | Halide::Internal::GeneratorInput_Arithmetic< T >
struct | Halide::Internal::has_static_halide_type_method< T2, typename >
struct | Halide::Internal::has_static_halide_type_method< T2, type_sink_t< decltype(T2::static_halide_type())> >
class | Halide::GeneratorInput< T >
class | Halide::Internal::GeneratorOutputBase
class | Halide::Internal::GeneratorOutputImpl< T >
class | Halide::Internal::GeneratorOutput_Buffer< T >
class | Halide::Internal::GeneratorOutput_Func< T >
class | Halide::Internal::GeneratorOutput_Arithmetic< T >
class | Halide::GeneratorOutput< T >
class | Halide::Internal::GeneratorParam_Synthetic< T >
class | Halide::GeneratorContext
| GeneratorContext is a class that is used when using Generators (or Stubs) directly; it is used to allow the outer context (typically, either a Generator or "top-level" code) to specify certain information to the inner context to ensure that inner and outer Generators are compiled in a compatible way. More...
class | Halide::NamesInterface
struct | Halide::Internal::NoRealizations<... >
struct | Halide::Internal::NoRealizations<>
struct | Halide::Internal::NoRealizations< T, Args... >
class | Halide::Internal::GeneratorParamInfo
class | Halide::Internal::GeneratorBase
class | Halide::Internal::GeneratorRegistry
class | Halide::Generator< T >
class | Halide::Internal::RegisterGenerator
struct | Halide::Internal::ExecuteGeneratorArgs
| ExecuteGeneratorArgs is the set of arguments to execute_generator(). More...

## Namespaces
namespace | Halide
| This file defines the class FunctionDAG, which is our representation of a Halide pipeline, and contains methods to using Halide's bounds tools to query properties of it.
namespace | Halide::Internal
namespace | Halide::Internal::GeneratorMinMax
namespace | halide_register_generator

## Macros
#define | HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE) virtual void set(const TYPE &new_value) = 0;
#define | HALIDE_GENERATOR_PARAM_TYPED_SETTER(TYPE)
#define | HALIDE_FORWARD_METHOD(Class, Method)
#define | HALIDE_FORWARD_METHOD_CONST(Class, Method)
#define | _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME)
#define | _HALIDE_REGISTER_GENERATOR2(GEN_CLASS_NAME, GEN_REGISTRY_NAME) _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, GEN_REGISTRY_NAME)
#define | _HALIDE_REGISTER_GENERATOR3(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME) _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME)
#define | __HALIDE_REGISTER_ARGCOUNT_IMPL(_1, _2, _3, COUNT, ...) COUNT
#define | _HALIDE_REGISTER_ARGCOUNT_IMPL(ARGS) __HALIDE_REGISTER_ARGCOUNT_IMPL ARGS
#define | _HALIDE_REGISTER_ARGCOUNT(...) _HALIDE_REGISTER_ARGCOUNT_IMPL((__VA_ARGS__, 3, 2, 1, 0))
#define | ___HALIDE_REGISTER_CHOOSER(COUNT) _HALIDE_REGISTER_GENERATOR##COUNT
#define | __HALIDE_REGISTER_CHOOSER(COUNT) ___HALIDE_REGISTER_CHOOSER(COUNT)
#define | _HALIDE_REGISTER_CHOOSER(COUNT) __HALIDE_REGISTER_CHOOSER(COUNT)
#define | _HALIDE_REGISTER_GENERATOR_PASTE(A, B) A B
#define | HALIDE_REGISTER_GENERATOR(...) _HALIDE_REGISTER_GENERATOR_PASTE(_HALIDE_REGISTER_CHOOSER(_HALIDE_REGISTER_ARGCOUNT(__VA_ARGS__)), (__VA_ARGS__))
#define | HALIDE_REGISTER_GENERATOR_ALIAS(GEN_REGISTRY_NAME, ORIGINAL_REGISTRY_NAME, ...)
#define | HALIDE_GENERATOR_PYSTUB(GEN_REGISTRY_NAME, MODULE_NAME)

## Typedefs
template<typename... Args>
using | Halide::Internal::select_type_t = typename select_type< Args... >::type
template<typename T >
using | Halide::Internal::GeneratorParamImplBase = select_type_t< cond< std::is_same_v< T, Target >, GeneratorParam_Target< T > >, cond< std::is_same_v< T, LoopLevel >, GeneratorParam_LoopLevel >, cond< std::is_same_v< T, std::string >, GeneratorParam_String< T > >, cond< std::is_same_v< T, Type >, GeneratorParam_Type< T > >, cond< std::is_same_v< T, bool >, GeneratorParam_Bool< T > >, cond< std::is_arithmetic_v< T >, GeneratorParam_Arithmetic< T > >, cond< std::is_enum_v< T >, GeneratorParam_Enum< T > > >
template<typename >
using | Halide::Internal::type_sink_t = void
template<typename T , typename TBase = std::remove_all_extents_t<T>>
using | Halide::Internal::GeneratorInputImplBase = select_type_t< cond< has_static_halide_type_method_v< TBase >, GeneratorInput_Buffer< T > >, cond< std::is_same_v< TBase, Func >, GeneratorInput_Func< T > >, cond< std::is_arithmetic_v< TBase >, GeneratorInput_Arithmetic< T > >, cond< std::is_scalar_v< TBase >, GeneratorInput_Scalar< T > >, cond< std::is_same_v< TBase, Expr >, GeneratorInput_DynamicScalar< T > > >
template<typename T , typename TBase = std::remove_all_extents_t<T>>
using | Halide::Internal::GeneratorOutputImplBase = select_type_t< cond< has_static_halide_type_method_v< TBase >, GeneratorOutput_Buffer< T > >, cond< std::is_same_v< TBase, Func >, GeneratorOutput_Func< T > >, cond< std::is_arithmetic_v< TBase >, GeneratorOutput_Arithmetic< T > > >
using | Halide::Internal::GeneratorFactory = std::function< AbstractGeneratorPtr(const GeneratorContext &context)>

## Enumerations
enum class | Halide::Internal::SyntheticParamType { Halide::Internal::Type , Halide::Internal::Dim , Halide::Internal::ArraySize }

## Functions
void | Halide::Internal::generator_test ()
std::vector< Expr > | Halide::Internal::parameter_constraints (const Parameter &p)
template<typename T >
HALIDE_NO_USER_CODE_INLINE std::string | Halide::Internal::enum_to_string (const std::map< std::string, T > &enum_map, const T &t)
template<typename T >
T | Halide::Internal::enum_from_string (const std::map< std::string, T > &enum_map, const std::string &s)
const std::map< std::string, Halide::Type > & | Halide::Internal::get_halide_type_enum_map ()
std::string | Halide::Internal::halide_type_to_enum_string (const Type &t)
std::string | Halide::Internal::halide_type_to_c_source (const Type &t)
std::string | Halide::Internal::halide_type_to_c_type (const Type &t)
const GeneratorFactoryProvider & | Halide::Internal::get_registered_generators ()
| Return a GeneratorFactoryProvider that knows about all the currently-registered C++ Generators. More...
int | Halide::Internal::generate_filter_main (int argc, char **argv)
| generate_filter_main() is a convenient wrapper for GeneratorRegistry::create() + compile_to_files(); it can be trivially wrapped by a "real" main() to produce a command-line utility for ahead-of-time filter compilation. More...
int | Halide::Internal::generate_filter_main (int argc, char **argv, const GeneratorFactoryProvider &generator_factory_provider)
| This overload of generate_filter_main lets you provide your own provider for how to enumerate and/or create the generators based on registration name; this is useful if you want to re-use the 'main' logic but avoid the global Generator registry (e.g. More...
template<typename Other , typename T >
auto | Halide::operator+ (const Other &a, const GeneratorParam< T > &b) -> decltype(a+(T) b)
| Addition between GeneratorParam<T> and any type that supports operator+ with T. More...
template<typename Other , typename T >
auto | Halide::operator+ (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a+b)
template<typename Other , typename T >
auto | Halide::operator- (const Other &a, const GeneratorParam< T > &b) -> decltype(a -(T) b)
| Subtraction between GeneratorParam<T> and any type that supports operator- with T. More...
template<typename Other , typename T >
auto | Halide::operator- (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a - b)
template<typename Other , typename T >
auto | Halide::operator* (const Other &a, const GeneratorParam< T > &b) -> decltype(a *(T) b)
| Multiplication between GeneratorParam<T> and any type that supports operator* with T. More...
template<typename Other , typename T >
auto | Halide::operator* (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a *b)
template<typename Other , typename T >
auto | Halide::operator/ (const Other &a, const GeneratorParam< T > &b) -> decltype(a/(T) b)
| Division between GeneratorParam<T> and any type that supports operator/ with T. More...
template<typename Other , typename T >
auto | Halide::operator/ (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a/b)
template<typename Other , typename T >
auto | Halide::operator% (const Other &a, const GeneratorParam< T > &b) -> decltype(a %(T) b)
| Modulo between GeneratorParam<T> and any type that supports operator% with T. More...
template<typename Other , typename T >
auto | Halide::operator% (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a % b)
template<typename Other , typename T >
auto | Halide::operator> (const Other &a, const GeneratorParam< T > &b) -> decltype(a >(T) b)
| Greater than comparison between GeneratorParam<T> and any type that supports operator> with T. More...
template<typename Other , typename T >
auto | Halide::operator> (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a > b)
template<typename Other , typename T >
auto | Halide::operator< (const Other &a, const GeneratorParam< T > &b) -> decltype(a<(T) b)
| Less than comparison between GeneratorParam<T> and any type that supports operator< with T. More...
template<typename Other , typename T >
auto | Halide::operator< (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a< b)
template<typename Other , typename T >
auto | Halide::operator>= (const Other &a, const GeneratorParam< T > &b) -> decltype(a >=(T) b)
| Greater than or equal comparison between GeneratorParam<T> and any type that supports operator>= with T. More...
template<typename Other , typename T >
auto | Halide::operator>= (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a >=b)
template<typename Other , typename T >
auto | Halide::operator<= (const Other &a, const GeneratorParam< T > &b) -> decltype(a<=(T) b)
| Less than or equal comparison between GeneratorParam<T> and any type that supports operator<= with T. More...
template<typename Other , typename T >
auto | Halide::operator<= (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a<=b)
template<typename Other , typename T >
auto | Halide::operator== (const Other &a, const GeneratorParam< T > &b) -> decltype(a==(T) b)
| Equality comparison between GeneratorParam<T> and any type that supports operator== with T. More...
template<typename Other , typename T >
auto | Halide::operator== (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a==b)
template<typename Other , typename T >
auto | Halide::operator!= (const Other &a, const GeneratorParam< T > &b) -> decltype(a !=(T) b)
| Inequality comparison between between GeneratorParam<T> and any type that supports operator!= with T. More...
template<typename Other , typename T >
auto | Halide::operator!= (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a !=b)
template<typename Other , typename T >
auto | Halide::operator&& (const Other &a, const GeneratorParam< T > &b) -> decltype(a &&(T) b)
| Logical and between between GeneratorParam<T> and any type that supports operator&& with T. More...
template<typename Other , typename T >
auto | Halide::operator&& (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a &&b)
template<typename T >
auto | Halide::operator&& (const GeneratorParam< T > &a, const GeneratorParam< T > &b) -> decltype((T) a &&(T) b)
template<typename Other , typename T >
auto | Halide::operator|| (const Other &a, const GeneratorParam< T > &b) -> decltype(a||(T) b)
| Logical or between between GeneratorParam<T> and any type that supports operator|| with T. More...
template<typename Other , typename T >
auto | Halide::operator|| (const GeneratorParam< T > &a, const Other &b) -> decltype((T) a||b)
template<typename T >
auto | Halide::operator|| (const GeneratorParam< T > &a, const GeneratorParam< T > &b) -> decltype((T) a||(T) b)
template<typename Other , typename T >
auto | Halide::Internal::GeneratorMinMax::min_forward (const Other &a, const GeneratorParam< T > &b) -> decltype(min(a,(T) b))
template<typename Other , typename T >
auto | Halide::Internal::GeneratorMinMax::min_forward (const GeneratorParam< T > &a, const Other &b) -> decltype(min((T) a, b))
template<typename Other , typename T >
auto | Halide::Internal::GeneratorMinMax::max_forward (const Other &a, const GeneratorParam< T > &b) -> decltype(max(a,(T) b))
template<typename Other , typename T >
auto | Halide::Internal::GeneratorMinMax::max_forward (const GeneratorParam< T > &a, const Other &b) -> decltype(max((T) a, b))
template<typename Other , typename T >
auto | Halide::min (const Other &a, const GeneratorParam< T > &b) -> decltype(Internal::GeneratorMinMax::min_forward(a, b))
| Compute minimum between GeneratorParam<T> and any type that supports min with T. More...
template<typename Other , typename T >
auto | Halide::min (const GeneratorParam< T > &a, const Other &b) -> decltype(Internal::GeneratorMinMax::min_forward(a, b))
template<typename Other , typename T >
auto | Halide::max (const Other &a, const GeneratorParam< T > &b) -> decltype(Internal::GeneratorMinMax::max_forward(a, b))
| Compute the maximum value between GeneratorParam<T> and any type that supports max with T. More...
template<typename Other , typename T >
auto | Halide::max (const GeneratorParam< T > &a, const Other &b) -> decltype(Internal::GeneratorMinMax::max_forward(a, b))
template<typename T >
auto | Halide::operator! (const GeneratorParam< T > &a) -> decltype(!(T) a)
| Not operator for GeneratorParam. More...
template<typename T >
T | Halide::Internal::parse_scalar (const std::string &value)
std::vector< Type > | Halide::Internal::parse_halide_type_list (const std::string &types)
void | Halide::Internal::execute_generator (const ExecuteGeneratorArgs &args)
| Execute a Generator for AOT compilation – this provides the implementation of the command-line Generator interface `generate_filter_main()`, but with a structured API that is more suitable for calling directly from code (vs command line). More...
Callable | Halide::create_callable_from_generator (const GeneratorContext &context, const std::string &name, const GeneratorParamsMap &generator_params={})
| Create a Generator from the currently-registered Generators, use it to create a Callable. More...
Callable | Halide::create_callable_from_generator (const Target &target, const std::string &name, const GeneratorParamsMap &generator_params={})

## Variables
template<typename... Args>
constexpr bool | Halide::Internal::has_static_halide_type_method_v = has_static_halide_type_method<Args...>::value
template<typename... Args>
constexpr bool | Halide::Internal::no_realizations_v = NoRealizations<Args...>::value

## Detailed Description

Generator is a class used to encapsulate the building of Funcs in user pipelines.

A Generator is agnostic to JIT vs AOT compilation; it can be used for either purpose, but is especially convenient to use for AOT compilation.

A Generator explicitly declares the Inputs and Outputs associated for a given pipeline, and (optionally) separates the code for constructing the outputs from the code from scheduling them. For instance:

class Blur : public Generator<Blur> {
public:
Input<Func> input{"input", UInt(16), 2};
Output<Func> output{"output", UInt(16), 2};
void generate() {
blur_x(x, y) = (input(x, y) + input(x+1, y) + input(x+2, y))/3;
blur_y(x, y) = (blur_x(x, y) + blur_x(x, y+1) + blur_x(x, y+2))/3;
output(x, y) = blur(x, y);
}
void schedule() {
blur_y.split(y, y, yi, 8).parallel(y).vectorize(x, 8);
blur_x.store_at(blur_y, y).compute_at(blur_y, yi).vectorize(x, 8);
}
private:
Var x, y, xi, yi;
Func blur_x, blur_y;
};
Halide::UInt
Type UInt(int bits, int lanes=1)
Constructing an unsigned integer type.
Definition: Type.h:544
Halide::OutputFileType::schedule
@ schedule

Halide can compile a Generator into the correct pipeline by introspecting these values and constructing an appropriate signature based on them.

A Generator provides implementations of two methods:

- generate(), which must fill in all Output Func(s); it may optionally also do scheduling if no schedule() method is present.
- schedule(), which (if present) should contain all scheduling code.

Inputs can be any C++ scalar type:

Input<float> radius{"radius"};
Input<int32_t> increment{"increment"};

An Input<Func> is (essentially) like an ImageParam, except that it may (or may not) not be backed by an actual buffer, and thus has no defined extents.

Input<Func> input{"input", Float(32), 2};
Halide::Float
Type Float(int bits, int lanes=1)
Construct a floating-point type.
Definition: Type.h:549

You can optionally make the type and/or dimensions of Input<Func> unspecified, in which case the value is simply inferred from the actual Funcs passed to them. Of course, if you specify an explicit Type or Dimension, we still require the input Func to match, or a compilation error results.

Input<Func> input{ "input", 3 }; // require 3-dimensional Func,
// but leave Type unspecified

A Generator must explicitly list the output(s) it produces:

Output<Func> output{"output", Float(32), 2};

You can specify an output that returns a Tuple by specifying a list of Types:

class Tupler : Generator<Tupler> {
Input<Func> input{"input", Int(32), 2};
Output<Func> output{"output", {Float(32), UInt(8)}, 2};
void generate() {
Var x, y;
Expr a = cast<float>(input(x, y));
Expr b = cast<uint8_t>(input(x, y));
output(x, y) = Tuple(a, b);
}
};
Halide::Int
Type Int(int bits, int lanes=1)
Constructing a signed integer type.
Definition: Type.h:539

You can also specify Output<X> for any scalar type (except for Handle types); this is merely syntactic sugar on top of a zero-dimensional Func, but can be quite handy, especially when used with multiple outputs:

Output<float> sum{"sum"}; // equivalent to Output<Func> {"sum", Float(32), 0}
Halide::sum
Expr sum(Expr, const std::string &s="sum")
An inline reduction.

As with Input<Func>, you can optionally make the type and/or dimensions of an Output<Func> unspecified; any unspecified types must be resolved via an implicit GeneratorParam in order to use top-level compilation.

You can also declare an array of Input or Output, by using an array type as the type parameter:

// Takes exactly 3 images and outputs exactly 3 sums.
class SumRowsAndColumns : Generator<SumRowsAndColumns> {
Input<Func[3]> inputs{"inputs", Float(32), 2};
Input<int32_t[2]> extents{"extents"};
Output<Func[3]> sums{"sums", Float(32), 1};
void generate() {
assert(inputs.size() == sums.size());
// assume all inputs are same extent
Expr width = extent[0];
Expr height = extent[1];
for (size_t i = 0; i < inputs.size(); ++i) {
RDom r(0, width, 0, height);
sums[i]() = 0.f;
sums[i]() += inputs[i](r.x, r.y);
}
}
};

You can also leave array size unspecified, with some caveats:

- For ahead-of-time compilation, Inputs must have a concrete size specified via a GeneratorParam at build time (e.g., pyramid.size=3)
- For JIT compilation via a Stub, Inputs array sizes will be inferred from the vector passed.
- For ahead-of-time compilation, Outputs may specify a concrete size via a GeneratorParam at build time (e.g., pyramid.size=3), or the size can be specified via a resize() method.

class Pyramid : public Generator<Pyramid> {
public:
GeneratorParam<int32_t> levels{"levels", 10};
Input<Func> input{ "input", Float(32), 2 };
Output<Func[]> pyramid{ "pyramid", Float(32), 2 };
void generate() {
pyramid.resize(levels);
pyramid[0](x, y) = input(x, y);
for (int i = 1; i < pyramid.size(); i++) {
pyramid[i](x, y) = (pyramid[i-1](2*x, 2*y) +
pyramid[i-1](2*x+1, 2*y) +
pyramid[i-1](2*x, 2*y+1) +
pyramid[i-1](2*x+1, 2*y+1))/4;
}
}
};

A Generator can also be customized via compile-time parameters (GeneratorParams), which affect code generation.

GeneratorParams, Inputs, and Outputs are (by convention) always public and always declared at the top of the Generator class, in the order

GeneratorParam(s)
Input<Func>(s)
Input<non-Func>(s)
Output<Func>(s)
Halide::Internal::ArgInfoDirection::Input
@ Input

Note that the Inputs and Outputs will appear in the C function call in the order they are declared. All Input<Func> and Output<Func> are represented as halide_buffer_t; all other Input<> are the appropriate C++ scalar type. (GeneratorParams are always referenced by name, not position, so their order is irrelevant.)

All Inputs and Outputs must have explicit names, and all such names must match the regex [A-Za-z][A-Za-z_0-9]* (i.e., essentially a C/C++ variable name, with some extra restrictions on underscore use). By convention, the name should match the member-variable name.

You can dynamically add Inputs and Outputs to your Generator via adding a configure() method; if present, it will be called before generate(). It can examine GeneratorParams but it may not examine predeclared Inputs or Outputs; the only thing it should do is call add_input<>() and/or add_output<>(), or call set_type()/set_dimensions()/set_array_size() on an Input or Output with an unspecified type. Added inputs will be appended (in order) after predeclared Inputs but before any Outputs; added outputs will be appended after predeclared Outputs.

Note that the pointers returned by add_input() and add_output() are owned by the Generator and will remain valid for the Generator's lifetime; user code should not attempt to delete or free them.

class MultiSum : public Generator<MultiSum> {
public:
GeneratorParam<int32_t> input_count{"input_count", 10};
Output<Func> output{ "output", Float(32), 2 };
void configure() {
for (int i = 0; i < input_count; ++i) {
extra_inputs.push_back(
add_input<Func>("input_" + std::to_string(i), Float(32), 2);
}
}
void generate() {
Expr sum = 0.f;
for (int i = 0; i < input_count; ++i) {
sum += (*extra_inputs)[i](x, y);
}
output(x, y) = sum;
}
private:
std::vector<Input<Func>* extra_inputs;
};

All Generators have two GeneratorParams that are implicitly provided by the base class:

    GeneratorParam<Target> target{"target", Target()};
    GeneratorParam<AutoschedulerParams> autoscheduler{"autoscheduler", {}}

- 'target' is the Halide::Target for which the Generator is producing code. It is read-only during the Generator's lifetime, and must not be modified; its value should always be filled in by the calling code: either the Halide build system (for ahead-of-time compilation), or ordinary C++ code (for JIT compilation).
- 'autoscheduler' is a string-to-string map that is used to indicates whether and how an auto-scheduler should be run for this Generator:
  - if empty, the Generator should schedule its Funcs as it sees fit; no autoscheduler will be run.
  - if the 'name' key is set, it should be one of the known autoschedulers provided with this release of Halide, which will be used to schedule the Funcs in the Generator. In this case, the Generator should only provide estimate()s for its Funcs, and not call any other scheduling methods.
  - Other keys may be specified in the params, on a per-autoscheduler basis, to optimize or enhance the automatically-generated schedule. See documentation for each autoscheduler for options.

Generators are added to a global registry to simplify AOT build mechanics; this is done by simply using the HALIDE_REGISTER_GENERATOR macro at global scope:

HALIDE_REGISTER_GENERATOR(ExampleGen, jit_example)
HALIDE_REGISTER_GENERATOR
#define HALIDE_REGISTER_GENERATOR(...)
Definition: Generator.h:4105

The registered name of the Generator is provided must match the same rules as Input names, above.

Note that the class name of the generated Stub class will match the registered name by default; if you want to vary it (typically, to include namespaces), you can add it as an optional third argument:

HALIDE_REGISTER_GENERATOR(ExampleGen, jit_example, SomeNamespace::JitExampleStub)

Note that a Generator is always executed with a specific Target assigned to it, that you can access via the get_target() method. (You should not use the global get_target_from_environment(), etc. methods provided in Target.h)

(Note that there are older variations of Generator that differ from what's documented above; these are still supported but not described here. See https://github.com/halide/Halide/wiki/Old-Generator-Documentation for more information.)

Definition in file Generator.h.

## Macro Definition Documentation

## ◆ HALIDE_GENERATOR_PARAM_TYPED_SETTER [1/2]

#define HALIDE_GENERATOR_PARAM_TYPED_SETTER | ( |  | TYPE | ) | virtual void set(const TYPE &new_value) = 0;

Definition at line 527 of file Generator.h.

## ◆ HALIDE_GENERATOR_PARAM_TYPED_SETTER [2/2]

#define HALIDE_GENERATOR_PARAM_TYPED_SETTER | ( |  | TYPE | ) |

Value:
void set(const TYPE &new_value) override { \
typed_setter_impl<TYPE>(new_value, #TYPE); \
}

Definition at line 527 of file Generator.h.

## ◆ HALIDE_FORWARD_METHOD

#define HALIDE_FORWARD_METHOD | ( |  | Class,
|  |  | Method
| ) |  |

Value:
template<typename... Args> \
inline auto Method(Args &&...args) -> std::remove_reference_t<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))> { \
return this->template as<Class>().Method(std::forward<Args>(args)...); \
}

Definition at line 1651 of file Generator.h.

## ◆ HALIDE_FORWARD_METHOD_CONST

#define HALIDE_FORWARD_METHOD_CONST | ( |  | Class,
|  |  | Method
| ) |  |

Value:
template<typename... Args> \
inline auto Method(Args &&...args) const -> std::remove_reference_t<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))> { \
this->check_gio_access(); \
return this->template as<Class>().Method(std::forward<Args>(args)...); \
}

Definition at line 1657 of file Generator.h.

## ◆ _HALIDE_REGISTER_GENERATOR_IMPL

#define _HALIDE_REGISTER_GENERATOR_IMPL | ( |  | GEN_CLASS_NAME,
|  |  | GEN_REGISTRY_NAME,
|  |  | FULLY_QUALIFIED_STUB_NAME
| ) |  |

Value:
namespace halide_register_generator { \
struct halide_global_ns; \
namespace GEN_REGISTRY_NAME##_ns { \
std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \
std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context) { \
using GenType = std::remove_pointer_t<decltype(new GEN_CLASS_NAME)>; /* NOLINT(bugprone-macro-parentheses) */ \
return GenType::create(context, #GEN_REGISTRY_NAME, #FULLY_QUALIFIED_STUB_NAME); \
} \
} \
namespace { \
auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \
} \
} \
static_assert(std::is_same_v<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>, \
"HALIDE_REGISTER_GENERATOR must be used at global scope");
Halide::GeneratorContext
GeneratorContext is a class that is used when using Generators (or Stubs) directly; it is used to all...
Definition: Generator.h:3013
Halide::Internal::RegisterGenerator
Definition: Generator.h:3950
halide_register_generator
Definition: Generator.h:4054

Definition at line 4058 of file Generator.h.

## ◆ _HALIDE_REGISTER_GENERATOR2

#define _HALIDE_REGISTER_GENERATOR2 | ( |  | GEN_CLASS_NAME,
|  |  | GEN_REGISTRY_NAME
| ) |  | _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, GEN_REGISTRY_NAME)

Definition at line 4075 of file Generator.h.

## ◆ _HALIDE_REGISTER_GENERATOR3

#define _HALIDE_REGISTER_GENERATOR3 | ( |  | GEN_CLASS_NAME,
|  |  | GEN_REGISTRY_NAME,
|  |  | FULLY_QUALIFIED_STUB_NAME
| ) |  | _HALIDE_REGISTER_GENERATOR_IMPL(GEN_CLASS_NAME, GEN_REGISTRY_NAME, FULLY_QUALIFIED_STUB_NAME)

Definition at line 4078 of file Generator.h.

## ◆ __HALIDE_REGISTER_ARGCOUNT_IMPL

#define __HALIDE_REGISTER_ARGCOUNT_IMPL | ( |  | _1,
|  |  | _2,
|  |  | _3,
|  |  | COUNT,
|  |  | ...
| ) |  | COUNT

Definition at line 4084 of file Generator.h.

## ◆ _HALIDE_REGISTER_ARGCOUNT_IMPL

#define _HALIDE_REGISTER_ARGCOUNT_IMPL | ( |  | ARGS | ) | __HALIDE_REGISTER_ARGCOUNT_IMPL ARGS

Definition at line 4087 of file Generator.h.

## ◆ _HALIDE_REGISTER_ARGCOUNT

#define _HALIDE_REGISTER_ARGCOUNT | ( |  | ... | ) | _HALIDE_REGISTER_ARGCOUNT_IMPL((__VA_ARGS__, 3, 2, 1, 0))

Definition at line 4090 of file Generator.h.

## ◆ ___HALIDE_REGISTER_CHOOSER

#define ___HALIDE_REGISTER_CHOOSER | ( |  | COUNT | ) | _HALIDE_REGISTER_GENERATOR##COUNT

Definition at line 4093 of file Generator.h.

## ◆ __HALIDE_REGISTER_CHOOSER

#define __HALIDE_REGISTER_CHOOSER | ( |  | COUNT | ) | ___HALIDE_REGISTER_CHOOSER(COUNT)

Definition at line 4096 of file Generator.h.

## ◆ _HALIDE_REGISTER_CHOOSER

#define _HALIDE_REGISTER_CHOOSER | ( |  | COUNT | ) | __HALIDE_REGISTER_CHOOSER(COUNT)

Definition at line 4099 of file Generator.h.

## ◆ _HALIDE_REGISTER_GENERATOR_PASTE

#define _HALIDE_REGISTER_GENERATOR_PASTE | ( |  | A,
|  |  | B
| ) |  | A B

Definition at line 4102 of file Generator.h.

## ◆ HALIDE_REGISTER_GENERATOR

#define HALIDE_REGISTER_GENERATOR | ( |  | ... | ) | _HALIDE_REGISTER_GENERATOR_PASTE(_HALIDE_REGISTER_CHOOSER(_HALIDE_REGISTER_ARGCOUNT(__VA_ARGS__)), (__VA_ARGS__))

Examples
  tutorial/lesson_15_generators.cpp.

Definition at line 4105 of file Generator.h.

## ◆ HALIDE_REGISTER_GENERATOR_ALIAS

#define HALIDE_REGISTER_GENERATOR_ALIAS | ( |  | GEN_REGISTRY_NAME,
|  |  | ORIGINAL_REGISTRY_NAME,
|  |  | ...
| ) |  |

Value:
namespace halide_register_generator { \
struct halide_global_ns; \
namespace ORIGINAL_REGISTRY_NAME##_ns { \
std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \
} \
namespace GEN_REGISTRY_NAME##_ns { \
std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context) { \
auto g = ORIGINAL_REGISTRY_NAME##_ns::factory(context); \
const Halide::GeneratorParamsMap m = __VA_ARGS__; \
g->set_generatorparam_values(m); \
return g; \
} \
} \
namespace { \
auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \
} \
} \
static_assert(std::is_same_v<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>, \
"HALIDE_REGISTER_GENERATOR_ALIAS must be used at global scope");
Halide::GeneratorParamsMap
std::map< std::string, std::string > GeneratorParamsMap
Definition: AbstractGenerator.h:22

Definition at line 4122 of file Generator.h.

## ◆ HALIDE_GENERATOR_PYSTUB

#define HALIDE_GENERATOR_PYSTUB | ( |  | GEN_REGISTRY_NAME,
|  |  | MODULE_NAME
| ) |  |

Value:
static_assert(PY_MAJOR_VERSION >= 3, "Python bindings for Halide require Python 3+"); \
extern "C" PyObject *_halide_pystub_impl(const char *module_name, const Halide::Internal::GeneratorFactory &factory); \
namespace halide_register_generator::GEN_REGISTRY_NAME##_ns { \
extern std::unique_ptr<Halide::Internal::AbstractGenerator> factory(const Halide::GeneratorContext &context); \
} \
extern "C" HALIDE_EXPORT_SYMBOL PyObject *PyInit_##MODULE_NAME() { \
const auto factory = halide_register_generator::GEN_REGISTRY_NAME##_ns::factory; \
return _halide_pystub_impl(#MODULE_NAME, factory); \
}
HALIDE_EXPORT_SYMBOL
#define HALIDE_EXPORT_SYMBOL
Definition: HalideRuntime.h:83
Halide::Internal::GeneratorFactory
std::function< AbstractGeneratorPtr(const GeneratorContext &context)> GeneratorFactory
Definition: Generator.h:3124

Definition at line 4146 of file Generator.h.