Halide
Generator.h File Reference
#include <algorithm>
#include <iterator>
#include <limits>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "ExternalCode.h"
#include "Func.h"
#include "ImageParam.h"
#include "Introspection.h"
#include "ObjectInstanceRegistry.h"
#include "Target.h"

Go to the source code of this file.

Classes

class  Halide::Buffer< T >
 A Halide::Buffer is a named shared reference to a Halide::Runtime::Buffer. More...
 
class  Halide::Internal::ValueTracker
 ValueTracker is an internal utility class that attempts to track and flag certain obvious Stub-related errors at Halide compile time: it tracks the constraints set on any Parameter-based argument (i.e., Input<Buffer> and Output<Buffer>) to ensure that incompatible values aren't set. 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_MachineParams< T >
 
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::GeneratorInput_Buffer< T >
 
class  Halide::Internal::StubInputBuffer< T >
 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_Scalar< T >
 
class  Halide::Internal::GeneratorInput_Arithmetic< T >
 
struct  Halide::Internal::type_sink< typename >
 
struct  Halide::Internal::has_static_halide_type_method< T2, typename >
 
struct  Halide::Internal::has_static_halide_type_method< T2, typename type_sink< decltype(T2::static_halide_type())>::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 base 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< Args >
 
struct  Halide::Internal::NoRealizations<>
 
struct  Halide::Internal::NoRealizations< T, Args... >
 
struct  Halide::Internal::StringOrLoopLevel
 
class  Halide::Internal::GeneratorParamInfo
 
class  Halide::Internal::GeneratorBase
 
class  Halide::Internal::GeneratorRegistry
 
class  Halide::Generator< T >
 
class  Halide::Internal::RegisterGenerator
 
class  Halide::Internal::GeneratorStub
 
struct  Halide::Internal::GeneratorStub::Names
 

Namespaces

 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.
 
 Halide::Internal
 
 Halide::Internal::GeneratorMinMax
 
 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, ...)
 

Typedefs

template<typename T >
using Halide::Internal::GeneratorParamImplBase = typename select_type< cond< std::is_same< T, Target >::value, GeneratorParam_Target< T > >, cond< std::is_same< T, MachineParams >::value, GeneratorParam_MachineParams< T > >, cond< std::is_same< T, LoopLevel >::value, GeneratorParam_LoopLevel >, cond< std::is_same< T, std::string >::value, GeneratorParam_String< T > >, cond< std::is_same< T, Type >::value, GeneratorParam_Type< T > >, cond< std::is_same< T, bool >::value, GeneratorParam_Bool< T > >, cond< std::is_arithmetic< T >::value, GeneratorParam_Arithmetic< T > >, cond< std::is_enum< T >::value, GeneratorParam_Enum< T > >>::type
 
template<typename T , typename TBase = typename std::remove_all_extents<T>::type>
using Halide::Internal::GeneratorInputImplBase = typename select_type< cond< has_static_halide_type_method< TBase >::value, GeneratorInput_Buffer< T > >, cond< std::is_same< TBase, Func >::value, GeneratorInput_Func< T > >, cond< std::is_arithmetic< TBase >::value, GeneratorInput_Arithmetic< T > >, cond< std::is_scalar< TBase >::value, GeneratorInput_Scalar< T > >>::type
 
template<typename T , typename TBase = typename std::remove_all_extents<T>::type>
using Halide::Internal::GeneratorOutputImplBase = typename select_type< cond< has_static_halide_type_method< TBase >::value, GeneratorOutput_Buffer< T > >, cond< std::is_same< TBase, Func >::value, GeneratorOutput_Func< T > >, cond< std::is_arithmetic< TBase >::value, GeneratorOutput_Arithmetic< T > >>::type
 
using Halide::Internal::GeneratorFactory = std::function< std::unique_ptr< GeneratorBase >(const GeneratorContext &)>
 
using Halide::Internal::GeneratorParamsMap = std::map< std::string, StringOrLoopLevel >
 

Enumerations

enum  Halide::Internal::IOKind { Halide::Internal::IOKind::Scalar, Halide::Internal::IOKind::Function, Halide::Internal::IOKind::Buffer }
 
enum  Halide::Internal::SyntheticParamType { Halide::Internal::SyntheticParamType::Type, Halide::Internal::SyntheticParamType::Dim, Halide::Internal::SyntheticParamType::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 >
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)
 
int Halide::Internal::generate_filter_main (int argc, char **argv, std::ostream &cerr)
 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...
 
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 >
Halide::Internal::parse_scalar (const std::string &value)
 
std::vector< Type > Halide::Internal::parse_halide_type_list (const std::string &types)
 

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 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};

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);
}
};

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}

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)

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<>(). 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 three GeneratorParams that are implicitly provided by the base class:

GeneratorParam<Target> target{"target", Target()};
GeneratorParam<bool> auto_schedule{"auto_schedule", false};
GeneratorParam<MachineParams> machine_params{"machine_params", MachineParams::generic()};
  • '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).
  • 'auto_schedule' indicates whether the auto-scheduler should be run for this Generator:
    • if 'false', the Generator should schedule its Funcs as it sees fit.
    • if 'true', the Generator should only provide estimate()s for its Funcs, and not call any other scheduling methods.
  • 'machine_params' is only used if auto_schedule is true; it is ignored if auto_schedule is false. It provides details about the machine architecture being targeted which may be used to enhance the automatically-generated schedule.

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)

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 519 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 519 of file Generator.h.

◆ HALIDE_FORWARD_METHOD

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

Definition at line 1631 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-> \
typename std::remove_reference<decltype(std::declval<Class>().Method(std::forward<Args>(args)...))>::type { \
this->check_gio_access(); \
return this->template as<Class>().Method(std::forward<Args>(args)...); \
}

Definition at line 1637 of file Generator.h.

◆ _HALIDE_REGISTER_GENERATOR_IMPL

#define _HALIDE_REGISTER_GENERATOR_IMPL (   GEN_CLASS_NAME,
  GEN_REGISTRY_NAME,
  FULLY_QUALIFIED_STUB_NAME 
)
Value:
struct halide_global_ns; \
namespace GEN_REGISTRY_NAME##_ns { \
std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context); \
std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context) { \
return GEN_CLASS_NAME::create(context, #GEN_REGISTRY_NAME, #FULLY_QUALIFIED_STUB_NAME); \
} \
} \
static auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \
} \
static_assert(std::is_same<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>::value, \
"HALIDE_REGISTER_GENERATOR must be used at global scope");

Definition at line 3773 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 3787 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 3790 of file Generator.h.

◆ __HALIDE_REGISTER_ARGCOUNT_IMPL

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

Definition at line 3796 of file Generator.h.

◆ _HALIDE_REGISTER_ARGCOUNT_IMPL

#define _HALIDE_REGISTER_ARGCOUNT_IMPL (   ARGS)    __HALIDE_REGISTER_ARGCOUNT_IMPL ARGS

Definition at line 3799 of file Generator.h.

◆ _HALIDE_REGISTER_ARGCOUNT

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

Definition at line 3802 of file Generator.h.

◆ ___HALIDE_REGISTER_CHOOSER

#define ___HALIDE_REGISTER_CHOOSER (   COUNT)    _HALIDE_REGISTER_GENERATOR##COUNT

Definition at line 3805 of file Generator.h.

◆ __HALIDE_REGISTER_CHOOSER

#define __HALIDE_REGISTER_CHOOSER (   COUNT)    ___HALIDE_REGISTER_CHOOSER(COUNT)

Definition at line 3808 of file Generator.h.

◆ _HALIDE_REGISTER_CHOOSER

#define _HALIDE_REGISTER_CHOOSER (   COUNT)    __HALIDE_REGISTER_CHOOSER(COUNT)

Definition at line 3811 of file Generator.h.

◆ _HALIDE_REGISTER_GENERATOR_PASTE

#define _HALIDE_REGISTER_GENERATOR_PASTE (   A,
 
)    A B

Definition at line 3814 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 3817 of file Generator.h.

◆ HALIDE_REGISTER_GENERATOR_ALIAS

#define HALIDE_REGISTER_GENERATOR_ALIAS (   GEN_REGISTRY_NAME,
  ORIGINAL_REGISTRY_NAME,
  ... 
)
Value:
struct halide_global_ns; \
namespace ORIGINAL_REGISTRY_NAME##_ns { \
std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context); \
} \
namespace GEN_REGISTRY_NAME##_ns { \
std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context); \
std::unique_ptr<Halide::Internal::GeneratorBase> factory(const Halide::GeneratorContext &context) { \
auto g = ORIGINAL_REGISTRY_NAME##_ns::factory(context); \
g->set_generator_param_values(__VA_ARGS__); \
return g; \
} \
} \
static auto reg_##GEN_REGISTRY_NAME = Halide::Internal::RegisterGenerator(#GEN_REGISTRY_NAME, GEN_REGISTRY_NAME##_ns::factory); \
} \
static_assert(std::is_same<::halide_register_generator::halide_global_ns, halide_register_generator::halide_global_ns>::value, \
"HALIDE_REGISTER_GENERATOR_ALIAS must be used at global scope");

Definition at line 3834 of file Generator.h.

Halide::sum
Expr sum(Expr, const std::string &s="sum")
An inline reduction.
Halide::Float
Type Float(int bits, int lanes=1)
Construct a floating-point type.
Definition: Type.h:482
Halide::UInt
Type UInt(int bits, int lanes=1)
Constructing an unsigned integer type.
Definition: Type.h:477
Halide::GeneratorContext
GeneratorContext is a base class that is used when using Generators (or Stubs) directly; it is used t...
Definition: Generator.h:2856
halide_register_generator
Definition: Generator.h:3769
Halide::Output::schedule
@ schedule
Halide::Internal::RegisterGenerator
Definition: Generator.h:3690
HALIDE_REGISTER_GENERATOR
#define HALIDE_REGISTER_GENERATOR(...)
Definition: Generator.h:3817
Halide::Int
Type Int(int bits, int lanes=1)
Constructing a signed integer type.
Definition: Type.h:472