Halide 22.0.0 Halide compiler and libraries

AbstractGenerator.h
Go to the documentation of this file.
1#ifndef HALIDE_ABSTRACT_GENERATOR_H_
2#define HALIDE_ABSTRACT_GENERATOR_H_
3
4#include <functional>
5#include <map>
6#include <string>
7#include <vector>
8
9#include "Callable.h"
10#include "Expr.h"
11#include "Func.h"
12#include "Module.h"
13#include "Parameter.h"
14#include "Pipeline.h"
15#include "Schedule.h"
16#include "Target.h"
17#include "Type.h"
18
19 namespace Halide {
20
21class GeneratorContext;
22 using GeneratorParamsMap = std::map<std::string, std::string>;
23
24 namespace Internal {
25
26 enum class ArgInfoKind { Scalar,
27 Function,
28 Buffer };
29
30 enum class ArgInfoDirection { Input,
31 Output };
32
33/**
34 * AbstractGenerator is an ABC that defines the API a Generator must provide
35 * to work with the existing Generator infrastructure (GenGen, RunGen, execute_generator(),
36 * Generator Stubs). The existing Generator<>-based instances all implement
37 * this API, but any other code that implements this (and uses RegisterGenerator
38 * to register itself) should be indistinguishable from a user perspective.
39 *
40 * An AbstractGenerator is meant to be "single-use"; typically lifetimes will be
41 * something like:
42 * - create an instance (with a specific Target)
43 * - optionally set GeneratorParam values
44 * - optionally re-bind inputs (if using in JIT or Stub modes)
45 * - call build_pipeline()
46 * - optionally call output_func() to get the output(s) (if using in JIT or Stub modes)
47 * - discard the instance
48 *
49 * AbstractGenerators should be fairly cheap to instantiate! Don't try to re-use
50 * one by re-setting inputs and calling build_pipeline() multiple times.
51 *
52 * Note that an AbstractGenerator instance is (generally) stateful in terms of the order
53 * that methods should be called; calling the methods out of order may cause
54 * assert-fails or other undesirable behavior. Read the method notes carefully!
55 */
56 class AbstractGenerator {
57public:
58 virtual ~AbstractGenerator() = default;
59
60 /** ArgInfo is a struct to contain name-and-type information for the inputs and outputs to
61 * the Pipeline that build_pipeline() will return.
62 *
63 * Note that this looks rather similar to Halide::Argument, but unfortunately
64 * that is not a good fit here, as it cannot represent Func inputs (only
65 * Buffer and Scalar), nor can it really handle Outputs.
66 */
67 struct ArgInfo {
68 std::string name;
69 ArgInfoDirection dir = ArgInfoDirection::Input;
70 ArgInfoKind kind = ArgInfoKind::Scalar;
71 // Note that this can have multiple entries for Tuple-valued Inputs or Outputs
72 std::vector<Type> types;
73 int dimensions = 0;
74 };
75
76 /** Return the name of this Generator. (This should always be the name
77 * used to register it.) */
78 virtual std::string name() = 0;
79
80 /** Return the Target and autoscheduler info that this Generator
81 * was created with. Always legal to call on any AbstractGenerator instance,
82 * regardless of what other methods have been called. (All AbstractGenerator instances
83 * are expected to be created with immutable values for these, which can't be
84 * changed for a given instance after creation. Note that Generator<> based subclasses
85 * can customize Target somewhat via init_from_context(); see Generator.h for more info.)
86 *
87 * CALL-AFTER: any
88 * CALL-BEFORE: any
89 */
90 virtual GeneratorContext context() const = 0;
91
92 /** Return a list of all the ArgInfos for this generator. The list will be in the order
93 * that the input and outputs are declared (possibly interleaved).
94 * Any inputs or outputs added by a configure() method will be in the list,
95 * at the end, in the order added.
96 * All input and output names will be unique within a given Generator instance.
97 *
98 * CALL-AFTER: configure()
99 * CALL-BEFORE: any
100 */
101 virtual std::vector<ArgInfo> arginfos() = 0;
102
103 /** Set the value for a specific GeneratorParam for an AbstractGenerator instance.
104 *
105 * Names that aren't known generator names should assert-fail.
106 *
107 * Values that can't be parsed for the specific GeneratorParam (e.g. passing "foo" where
108 * an integer is expected) should assert-fail at some point (either immediately, or when
109 * build_pipeline() is called)
110 *
111 * This can be called multiple times, but only prior to build_pipeline().
112 *
113 * CALL-AFTER: none
114 * CALL-BEFORE: build_pipeline
115 */
116 // @{
117 virtual void set_generatorparam_value(const std::string &name, const std::string &value) = 0;
118 virtual void set_generatorparam_value(const std::string &name, const LoopLevel &loop_level) = 0;
119 // @}
120
121 /** Build and return the Pipeline for this AbstractGenerator. This method should be called
122 * only once per instance.
123 *
124 * CALL-AFTER: set_generatorparam_value, bind_input
125 * CALL-BEFORE: input_parameter, output_func, external_code_map
126 */
127 virtual Pipeline build_pipeline() = 0;
128
129 /** Given the name of an input, return the Parameter(s) for that input.
130 * (Most inputs will have exactly one, but inputs that are declared as arrays
131 * will have multiple.)
132 *
133 * CALL-AFTER: build_pipeline
134 * CALL-BEFORE: none
135 */
136 virtual std::vector<Parameter> input_parameter(const std::string &name) = 0;
137
138 /** Given the name of an output, return the Func(s) for that output.
139 *
140 * Most outputs will have exactly one, but outputs that are declared as arrays will have multiple.
141 *
142 * Note that outputs with Tuple values are still just a single Func, though they do get realized
143 * as multiple Buffers.
144 *
145 * Must be called after build_pipeline(), since the output Funcs will be undefined prior to that.
146 *
147 * CALL-AFTER: build_pipeline()
148 * CALL-BEFORE: none
149 */
150 virtual std::vector<Func> output_func(const std::string &name) = 0;
151
152 /** Rebind a specified Input to refer to the given piece of IR, replacing the
153 * default ImageParam / Param in place for that Input. Basic type-checking is
154 * done to ensure that inputs are still sane (e.g. types, dimensions, etc must match expectations).
155 *
156 * CALL-AFTER: set_generatorparam_value
157 * CALL-BEFORE: build_pipeline
158 */
159 // @{
160 virtual void bind_input(const std::string &name, const std::vector<Parameter> &v) = 0;
161 virtual void bind_input(const std::string &name, const std::vector<Func> &v) = 0;
162 virtual void bind_input(const std::string &name, const std::vector<Expr> &v) = 0;
163 // @}
164
165 /** Emit a Generator Stub (.stub.h) file to the given path. Not all Generators support this.
166 *
167 * If you call this method, you should not call any other AbstractGenerator methods
168 * on this instance, before or after this call.
169 *
170 * If the Generator is capable of emitting a Stub, do so and return true. (Errors
171 * during stub emission should assert-fail rather than returning false.)
172 *
173 * If the Generator is not capable of emitting a Stub, do nothing and return false.
174 *
175 * CALL-AFTER: none
176 * CALL-BEFORE: none
177 */
178 virtual bool emit_cpp_stub(const std::string &stub_file_path) = 0;
179
180 /** Emit a Serialized Halide Pipeline (.hlpipe) file to the given path. Not all Generators support this.
181 *
182 * If you call this method, you should not call any other AbstractGenerator methods
183 * on this instance, before or after this call.
184 *
185 * If the Generator is capable of emitting an hlpipe, do so and return true. (Errors
186 * during hlpipe emission should assert-fail rather than returning false.)
187 *
188 * If the Generator is not capable of emitting an hlpipe, do nothing and return false.
189 *
190 * CALL-AFTER: none
191 * CALL-BEFORE: none
192 */
193 virtual bool emit_hlpipe(const std::string &hlpipe_file_path) = 0;
194
195 /** By default, a Generator must declare all Inputs before all Outputs.
196 * In some unusual situations (e.g. metaprogramming situations), it's
197 * desirable to allow them to be declared out-of-order and put the onus
198 * of a non-obvious call order on the coder; a Generator may override this
199 * to return 'true' to allow this behavior.
200 */
201 virtual bool allow_out_of_order_inputs_and_outputs() const = 0;
202
203 // Below are some concrete methods that build on top of the rest of the AbstractGenerator API.
204 // Note that they are nonvirtual. TODO: would these be better as freestanding methods that
205 // just take AbstractGeneratorPtr as arguments?
206
207 /** Call generate() and produce a Module for the result.
208 *If function_name is empty, generator_name() will be used for the function. */
209 Module build_module(const std::string &function_name = "");
210
211 /**
212 * Build a module that is suitable for using for gradient descent calculation in TensorFlow or PyTorch.
213 *
214 * Essentially:
215 * - A new Pipeline is synthesized from the current Generator (according to the rules below)
216 * - The new Pipeline is autoscheduled (if autoscheduling is requested, but it would be odd not to do so)
217 * - The Pipeline is compiled to a Module and returned
218 *
219 * The new Pipeline is adjoint to the original; it has:
220 * - All the same inputs as the original, in the same order
221 * - Followed by one grad-input for each original output
222 * - Followed by one output for each unique pairing of original-output + original-input.
223 * (For the common case of just one original-output, this amounts to being one output for each original-input.)
224 */
225 Module build_gradient_module(const std::string &function_name);
226
227 /**
228 * JIT the AbstractGenerator into a Callable (using the currently-set
229 * Target) and return it.
230 *
231 * If jit_handlers is not null, set the jitted func's jit_handlers to use a copy of it.
232 *
233 * If jit_externs is not null, use it to set the jitted func's external dependencies.
234 */
235 Callable compile_to_callable(const JITHandlers *jit_handlers = nullptr,
236 const std::map<std::string, JITExtern> *jit_externs = nullptr);
237
238 /*
239 * Set all the GeneratorParams in the map. This is equivalent to simply calling the
240 * `set_generatorparam_value()` method in a loop over the map, but is quite convenient. */
241 void set_generatorparam_values(const GeneratorParamsMap &m);
242};
243
244 using AbstractGeneratorPtr = std::unique_ptr<AbstractGenerator>;
245
246} // namespace Internal
247} // namespace Halide
248
249#endif
Callable.h
Defines the front-end class representing a jitted, callable Halide pipeline.
Expr.h
Base classes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
Func.h
Defines Func - the front-end handle on a halide function, and related classes.
Module.h
Defines Module, an IR container that fully describes a Halide program.
Parameter.h
Defines the internal representation of parameters to halide piplines.
Pipeline.h
Defines the front-end class representing an entire Halide imaging pipeline.
Schedule.h
Defines the internal representation of the schedule for a function.
Target.h
Defines the structure that describes a Halide target.
Type.h
Defines halide types.
Halide::Buffer
A Halide::Buffer is a named shared reference to a Halide::Runtime::Buffer.
Definition: Buffer.h:122
Halide::Callable
Definition: Callable.h:82
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::AbstractGenerator
AbstractGenerator is an ABC that defines the API a Generator must provide to work with the existing G...
Definition: AbstractGenerator.h:56
Halide::Internal::AbstractGenerator::arginfos
virtual std::vector< ArgInfo > arginfos()=0
Return a list of all the ArgInfos for this generator.
Halide::Internal::AbstractGenerator::emit_cpp_stub
virtual bool emit_cpp_stub(const std::string &stub_file_path)=0
Emit a Generator Stub (.stub.h) file to the given path.
Halide::Internal::AbstractGenerator::set_generatorparam_values
void set_generatorparam_values(const GeneratorParamsMap &m)
Halide::Internal::AbstractGenerator::set_generatorparam_value
virtual void set_generatorparam_value(const std::string &name, const std::string &value)=0
Set the value for a specific GeneratorParam for an AbstractGenerator instance.
Halide::Internal::AbstractGenerator::emit_hlpipe
virtual bool emit_hlpipe(const std::string &hlpipe_file_path)=0
Emit a Serialized Halide Pipeline (.hlpipe) file to the given path.
Halide::Internal::AbstractGenerator::bind_input
virtual void bind_input(const std::string &name, const std::vector< Func > &v)=0
Halide::Internal::AbstractGenerator::allow_out_of_order_inputs_and_outputs
virtual bool allow_out_of_order_inputs_and_outputs() const =0
By default, a Generator must declare all Inputs before all Outputs.
Halide::Internal::AbstractGenerator::bind_input
virtual void bind_input(const std::string &name, const std::vector< Parameter > &v)=0
Rebind a specified Input to refer to the given piece of IR, replacing the default ImageParam / Param ...
Halide::Internal::AbstractGenerator::compile_to_callable
Callable compile_to_callable(const JITHandlers *jit_handlers=nullptr, const std::map< std::string, JITExtern > *jit_externs=nullptr)
JIT the AbstractGenerator into a Callable (using the currently-set Target) and return it.
Halide::Internal::AbstractGenerator::output_func
virtual std::vector< Func > output_func(const std::string &name)=0
Given the name of an output, return the Func(s) for that output.
Halide::Internal::AbstractGenerator::~AbstractGenerator
virtual ~AbstractGenerator()=default
Halide::Internal::AbstractGenerator::set_generatorparam_value
virtual void set_generatorparam_value(const std::string &name, const LoopLevel &loop_level)=0
Halide::Internal::AbstractGenerator::bind_input
virtual void bind_input(const std::string &name, const std::vector< Expr > &v)=0
Halide::Internal::AbstractGenerator::build_pipeline
virtual Pipeline build_pipeline()=0
Build and return the Pipeline for this AbstractGenerator.
Halide::Internal::AbstractGenerator::build_gradient_module
Module build_gradient_module(const std::string &function_name)
Build a module that is suitable for using for gradient descent calculation in TensorFlow or PyTorch.
Halide::Internal::AbstractGenerator::name
virtual std::string name()=0
Return the name of this Generator.
Halide::Internal::AbstractGenerator::context
virtual GeneratorContext context() const =0
Return the Target and autoscheduler info that this Generator was created with.
Halide::Internal::AbstractGenerator::build_module
Module build_module(const std::string &function_name="")
Call generate() and produce a Module for the result.
Halide::Internal::AbstractGenerator::input_parameter
virtual std::vector< Parameter > input_parameter(const std::string &name)=0
Given the name of an input, return the Parameter(s) for that input.
Halide::Internal::Function
A reference-counted handle to Halide's internal representation of a function.
Definition: Function.h:39
Halide::LoopLevel
A reference to a site in a Halide statement at the top of the body of a particular for loop.
Definition: Schedule.h:203
Halide::Module
A halide module.
Definition: Module.h:142
Halide::Pipeline
A class representing a Halide pipeline.
Definition: Pipeline.h:107
Halide::Internal::ArgInfoKind
ArgInfoKind
Definition: AbstractGenerator.h:26
Halide::Internal::ArgInfoKind::Scalar
@ Scalar
Halide::Internal::AbstractGeneratorPtr
std::unique_ptr< AbstractGenerator > AbstractGeneratorPtr
Definition: AbstractGenerator.h:244
Halide::Internal::ArgInfoDirection
ArgInfoDirection
Definition: AbstractGenerator.h:30
Halide::Internal::ArgInfoDirection::Output
@ Output
Halide::Internal::ArgInfoDirection::Input
@ Input
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::GeneratorParamsMap
std::map< std::string, std::string > GeneratorParamsMap
Definition: AbstractGenerator.h:22
Halide::Internal::AbstractGenerator::ArgInfo
ArgInfo is a struct to contain name-and-type information for the inputs and outputs to the Pipeline t...
Definition: AbstractGenerator.h:67
Halide::Internal::AbstractGenerator::ArgInfo::dir
ArgInfoDirection dir
Definition: AbstractGenerator.h:69
Halide::Internal::AbstractGenerator::ArgInfo::types
std::vector< Type > types
Definition: AbstractGenerator.h:72
Halide::Internal::AbstractGenerator::ArgInfo::name
std::string name
Definition: AbstractGenerator.h:68
Halide::Internal::AbstractGenerator::ArgInfo::dimensions
int dimensions
Definition: AbstractGenerator.h:73
Halide::Internal::AbstractGenerator::ArgInfo::kind
ArgInfoKind kind
Definition: AbstractGenerator.h:70
Halide::JITHandlers
A set of custom overrides of runtime functions.
Definition: JITModule.h:35