Halide 16.0.0
Halide compiler and libraries
Function.h
Go to the documentation of this file.
1#ifndef HALIDE_FUNCTION_H
2#define HALIDE_FUNCTION_H
3
4/** \file
5 * Defines the internal representation of a halide function and related classes
6 */
7#include <map>
8#include <string>
9#include <utility>
10#include <vector>
11
12#include "Definition.h"
13#include "Expr.h"
14#include "FunctionPtr.h"
15#include "Schedule.h"
16
17namespace Halide {
18
19struct ExternFuncArgument;
20class Tuple;
21
22class Var;
23
24/** An enum to specify calling convention for extern stages. */
25enum class NameMangling {
26 Default, ///< Match whatever is specified in the Target
27 C, ///< No name mangling
28 CPlusPlus, ///< C++ name mangling
29};
30
31namespace Internal {
32
33struct Call;
34class Parameter;
35
36/** A reference-counted handle to Halide's internal representation of
37 * a function. Similar to a front-end Func object, but with no
38 * syntactic sugar to help with definitions. */
39class Function {
40 FunctionPtr contents;
41
42public:
43 /** This lets you use a Function as a key in a map of the form
44 * map<Function, Foo, Function::Compare> */
45 struct Compare {
46 bool operator()(const Function &a, const Function &b) const {
47 internal_assert(a.contents.defined() && b.contents.defined());
48 return a.contents < b.contents;
49 }
50 };
51
52 /** Construct a new function with no definitions and no name. This
53 * constructor only exists so that you can make vectors of
54 * functions, etc.
55 */
56 Function() = default;
57
58 /** Construct a new function with the given name */
59 explicit Function(const std::string &n);
60
61 /** Construct a new function with the given name,
62 * with a requirement that it can only represent Expr(s) of the given type(s),
63 * and must have exactly the give nnumber of dimensions.
64 * required_types.empty() means there are no constraints on the type(s).
65 * required_dims == AnyDims means there are no constraints on the dimensions. */
66 explicit Function(const std::vector<Type> &required_types, int required_dims, const std::string &n);
67
68 /** Construct a Function from an existing FunctionContents pointer. Must be non-null */
69 explicit Function(const FunctionPtr &);
70
71 /** Get a handle on the halide function contents that this Function
72 * represents. */
74 return contents;
75 }
76
77 /** Deep copy this Function into 'copy'. It recursively deep copies all called
78 * functions, schedules, update definitions, extern func arguments, specializations,
79 * and reduction domains. This method does not deep-copy the Parameter objects.
80 * This method also takes a map of <old Function, deep-copied version> as input
81 * and would use the deep-copied Function from the map if exists instead of
82 * creating a new deep-copy to avoid creating deep-copies of the same Function
83 * multiple times. If 'name' is specified, copy's name will be set to that.
84 */
85 // @{
86 void deep_copy(const FunctionPtr &copy, std::map<FunctionPtr, FunctionPtr> &copied_map) const;
87 void deep_copy(std::string name, const FunctionPtr &copy,
88 std::map<FunctionPtr, FunctionPtr> &copied_map) const;
89 // @}
90
91 /** Add a pure definition to this function. It may not already
92 * have a definition. All the free variables in 'value' must
93 * appear in the args list. 'value' must not depend on any
94 * reduction domain */
95 void define(const std::vector<std::string> &args, std::vector<Expr> values);
96
97 /** Add an update definition to this function. It must already
98 * have a pure definition but not an update definition, and the
99 * length of args must match the length of args used in the pure
100 * definition. 'value' must depend on some reduction domain, and
101 * may contain variables from that domain as well as pure
102 * variables. Any pure variables must also appear as Variables in
103 * the args array, and they must have the same name as the pure
104 * definition's argument in the same index. */
105 void define_update(const std::vector<Expr> &args, std::vector<Expr> values);
106
107 /** Accept a visitor to visit all of the definitions and arguments
108 * of this function. */
109 void accept(IRVisitor *visitor) const;
110
111 /** Accept a mutator to mutator all of the definitions and
112 * arguments of this function. */
113 void mutate(IRMutator *mutator);
114
115 /** Get the name of the function. */
116 const std::string &name() const;
117
118 /** If this is a wrapper of another func, created by a chain of in
119 * or clone_in calls, returns the name of the original
120 * Func. Otherwise returns the name. */
121 const std::string &origin_name() const;
122
123 /** Get a mutable handle to the init definition. */
125
126 /** Get the init definition. */
127 const Definition &definition() const;
128
129 /** Get the pure arguments. */
130 const std::vector<std::string> &args() const;
131
132 /** Get the dimensionality. */
133 int dimensions() const;
134
135 /** Get the number of outputs. */
136 int outputs() const;
137
138 /** Get the types of the outputs. */
139 const std::vector<Type> &output_types() const;
140
141 /** Get the type constaints on the outputs (if any). */
142 const std::vector<Type> &required_types() const;
143
144 /** Get the dimensionality constaints on the outputs (if any). */
146
147 /** Get the right-hand-side of the pure definition. Returns an
148 * empty vector if there is no pure definition. */
149 const std::vector<Expr> &values() const;
150
151 /** Does this function have a pure definition? */
153
154 /** Does this function *only* have a pure definition? */
155 bool is_pure() const {
156 return (has_pure_definition() &&
159 }
160
161 /** Is it legal to inline this function? */
162 bool can_be_inlined() const;
163
164 /** Get a handle to the function-specific schedule for the purpose
165 * of modifying it. */
167
168 /** Get a const handle to the function-specific schedule for inspecting it. */
169 const FuncSchedule &schedule() const;
170
171 /** Get a handle on the output buffer used for setting constraints
172 * on it. */
173 const std::vector<Parameter> &output_buffers() const;
174
175 /** Get a mutable handle to the stage-specfic schedule for the update
176 * stage. */
178
179 /** Get a mutable handle to this function's update definition at
180 * index 'idx'. */
181 Definition &update(int idx = 0);
182
183 /** Get a const reference to this function's update definition at
184 * index 'idx'. */
185 const Definition &update(int idx = 0) const;
186
187 /** Get a const reference to this function's update definitions. */
188 const std::vector<Definition> &updates() const;
189
190 /** Does this function have an update definition? */
192
193 /** Check if the function has an extern definition. */
195
196 /** Get the name mangling specified for the extern definition. */
198
199 /** Make a call node to the extern definition. An error if the
200 * function has no extern definition. */
201 Expr make_call_to_extern_definition(const std::vector<Expr> &args,
202 const Target &t) const;
203
204 /** Get the proxy Expr for the extern stage. This is an expression
205 * known to have the same data access pattern as the extern
206 * stage. It must touch at least all of the memory that the extern
207 * stage does, though it is permissible for it to be conservative
208 * and touch a superset. For most Functions, including those with
209 * extern definitions, this will be an undefined Expr. */
210 // @{
213 // @}
214
215 /** Add an external definition of this Func. */
216 void define_extern(const std::string &function_name,
217 const std::vector<ExternFuncArgument> &args,
218 const std::vector<Type> &types,
219 const std::vector<Var> &dims,
220 NameMangling mangling, DeviceAPI device_api);
221
222 /** Retrive the arguments of the extern definition. */
223 // @{
224 const std::vector<ExternFuncArgument> &extern_arguments() const;
225 std::vector<ExternFuncArgument> &extern_arguments();
226 // @}
227
228 /** Get the name of the extern function called for an extern
229 * definition. */
230 const std::string &extern_function_name() const;
231
232 /** Get the DeviceAPI declared for an extern function. */
234
235 /** Test for equality of identity. */
236 bool same_as(const Function &other) const {
237 return contents.same_as(other.contents);
238 }
239
240 /** Get a const handle to the debug filename. */
241 const std::string &debug_file() const;
242
243 /** Get a handle to the debug filename. */
244 std::string &debug_file();
245
246 /** Use an an extern argument to another function. */
247 operator ExternFuncArgument() const;
248
249 /** Tracing calls and accessors, passed down from the Func
250 * equivalents. */
251 // @{
255 void add_trace_tag(const std::string &trace_tag);
256 bool is_tracing_loads() const;
257 bool is_tracing_stores() const;
259 const std::vector<std::string> &get_trace_tags() const;
260 // @}
261
262 /** Replace this Function's LoopLevels with locked copies that
263 * cannot be mutated further. */
265
266 /** Mark function as frozen, which means it cannot accept new
267 * definitions. */
268 void freeze();
269
270 /** Check if a function has been frozen. If so, it is an error to
271 * add new definitions. */
272 bool frozen() const;
273
274 /** Make a new Function with the same lifetime as this one, and
275 * return a strong reference to it. Useful to create Functions which
276 * have circular references to this one - e.g. the wrappers
277 * produced by Func::in. */
279
280 /** Mark calls of this function by 'f' to be replaced with its wrapper
281 * during the lowering stage. If the string 'f' is empty, it means replace
282 * all calls to this function by all other functions (excluding itself) in
283 * the pipeline with the wrapper. This will also freeze 'wrapper' to prevent
284 * user from updating the values of the Function it wraps via the wrapper.
285 * See \ref Func::in for more details. */
286 // @{
287 void add_wrapper(const std::string &f, Function &wrapper);
288 const std::map<std::string, FunctionPtr> &wrappers() const;
289 // @}
290
291 /** Check if a Function is a trivial wrapper around another
292 * Function, Buffer, or Parameter. Returns the Call node if it
293 * is. Otherwise returns null.
294 */
295 const Call *is_wrapper() const;
296
297 /** Replace every call to Functions in 'substitutions' keys by all Exprs
298 * referenced in this Function to call to their substitute Functions (i.e.
299 * the corresponding values in 'substitutions' map). */
300 // @{
301 Function &substitute_calls(const std::map<FunctionPtr, FunctionPtr> &substitutions);
303 // @}
304
305 /** Return true iff the name matches one of the Function's pure args. */
306 bool is_pure_arg(const std::string &name) const;
307
308 /** If the Function has type requirements, check that the given argument
309 * is compatible with them. If not, assert-fail. (If there are no type requirements, do nothing.) */
310 void check_types(const Expr &e) const;
311 void check_types(const Tuple &t) const;
312 void check_types(const Type &t) const;
313 void check_types(const std::vector<Expr> &exprs) const;
314 void check_types(const std::vector<Type> &types) const;
315
316 /** If the Function has dimension requirements, check that the given argument
317 * is compatible with them. If not, assert-fail. (If there are no dimension requirements, do nothing.) */
318 void check_dims(int dims) const;
319
320 /** Define the output buffers. If the Function has types specified, this can be called at
321 * any time. If not, it can only be called for a Function with a pure definition. */
322 void create_output_buffers(const std::vector<Type> &types, int dims) const;
323};
324
325/** Deep copy an entire Function DAG. */
326std::pair<std::vector<Function>, std::map<std::string, Function>> deep_copy(
327 const std::vector<Function> &outputs,
328 const std::map<std::string, Function> &env);
329
330} // namespace Internal
331} // namespace Halide
332
333#endif
Defines the internal representation of a halide function's definition and related classes.
#define internal_assert(c)
Definition: Errors.h:19
Base classes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
Defines the internal representation of the schedule for a function.
A Function definition which can either represent a init or an update definition.
Definition: Definition.h:38
A schedule for a Function of a Halide pipeline.
Definition: Schedule.h:543
A reference-counted handle to Halide's internal representation of a function.
Definition: Function.h:39
const std::vector< ExternFuncArgument > & extern_arguments() const
Retrive the arguments of the extern definition.
const std::string & extern_function_name() const
Get the name of the extern function called for an extern definition.
FunctionPtr get_contents() const
Get a handle on the halide function contents that this Function represents.
Definition: Function.h:73
void define(const std::vector< std::string > &args, std::vector< Expr > values)
Add a pure definition to this function.
void deep_copy(const FunctionPtr &copy, std::map< FunctionPtr, FunctionPtr > &copied_map) const
Deep copy this Function into 'copy'.
bool frozen() const
Check if a function has been frozen.
DeviceAPI extern_function_device_api() const
Get the DeviceAPI declared for an extern function.
Function(const std::string &n)
Construct a new function with the given name.
int dimensions() const
Get the dimensionality.
void check_types(const Type &t) const
bool is_tracing_realizations() const
bool has_extern_definition() const
Check if the function has an extern definition.
int outputs() const
Get the number of outputs.
int required_dimensions() const
Get the dimensionality constaints on the outputs (if any).
Function & substitute_calls(const std::map< FunctionPtr, FunctionPtr > &substitutions)
Replace every call to Functions in 'substitutions' keys by all Exprs referenced in this Function to c...
const std::map< std::string, FunctionPtr > & wrappers() const
const Definition & update(int idx=0) const
Get a const reference to this function's update definition at index 'idx'.
const std::vector< Type > & required_types() const
Get the type constaints on the outputs (if any).
void lock_loop_levels()
Replace this Function's LoopLevels with locked copies that cannot be mutated further.
bool can_be_inlined() const
Is it legal to inline this function?
StageSchedule & update_schedule(int idx=0)
Get a mutable handle to the stage-specfic schedule for the update stage.
bool is_tracing_stores() const
std::string & debug_file()
Get a handle to the debug filename.
const Call * is_wrapper() const
Check if a Function is a trivial wrapper around another Function, Buffer, or Parameter.
bool has_pure_definition() const
Does this function have a pure definition?
FuncSchedule & schedule()
Get a handle to the function-specific schedule for the purpose of modifying it.
const std::vector< Parameter > & output_buffers() const
Get a handle on the output buffer used for setting constraints on it.
const Definition & definition() const
Get the init definition.
void check_dims(int dims) const
If the Function has dimension requirements, check that the given argument is compatible with them.
Function()=default
Construct a new function with no definitions and no name.
bool is_pure() const
Does this function only have a pure definition?
Definition: Function.h:155
bool has_update_definition() const
Does this function have an update definition?
void trace_loads()
Tracing calls and accessors, passed down from the Func equivalents.
std::vector< ExternFuncArgument > & extern_arguments()
const FuncSchedule & schedule() const
Get a const handle to the function-specific schedule for inspecting it.
Function new_function_in_same_group(const std::string &)
Make a new Function with the same lifetime as this one, and return a strong reference to it.
const std::vector< Definition > & updates() const
Get a const reference to this function's update definitions.
Definition & definition()
Get a mutable handle to the init definition.
void check_types(const std::vector< Expr > &exprs) const
void create_output_buffers(const std::vector< Type > &types, int dims) const
Define the output buffers.
const std::vector< std::string > & args() const
Get the pure arguments.
void mutate(IRMutator *mutator)
Accept a mutator to mutator all of the definitions and arguments of this function.
void define_extern(const std::string &function_name, const std::vector< ExternFuncArgument > &args, const std::vector< Type > &types, const std::vector< Var > &dims, NameMangling mangling, DeviceAPI device_api)
Add an external definition of this Func.
void check_types(const Expr &e) const
If the Function has type requirements, check that the given argument is compatible with them.
void deep_copy(std::string name, const FunctionPtr &copy, std::map< FunctionPtr, FunctionPtr > &copied_map) const
Definition & update(int idx=0)
Get a mutable handle to this function's update definition at index 'idx'.
NameMangling extern_definition_name_mangling() const
Get the name mangling specified for the extern definition.
void define_update(const std::vector< Expr > &args, std::vector< Expr > values)
Add an update definition to this function.
void accept(IRVisitor *visitor) const
Accept a visitor to visit all of the definitions and arguments of this function.
bool same_as(const Function &other) const
Test for equality of identity.
Definition: Function.h:236
const std::vector< Type > & output_types() const
Get the types of the outputs.
bool is_pure_arg(const std::string &name) const
Return true iff the name matches one of the Function's pure args.
const std::vector< std::string > & get_trace_tags() const
void check_types(const Tuple &t) const
void freeze()
Mark function as frozen, which means it cannot accept new definitions.
const std::vector< Expr > & values() const
Get the right-hand-side of the pure definition.
Function & substitute_calls(const Function &orig, const Function &substitute)
const std::string & debug_file() const
Get a const handle to the debug filename.
void add_wrapper(const std::string &f, Function &wrapper)
Mark calls of this function by 'f' to be replaced with its wrapper during the lowering stage.
void check_types(const std::vector< Type > &types) const
Expr make_call_to_extern_definition(const std::vector< Expr > &args, const Target &t) const
Make a call node to the extern definition.
Function(const FunctionPtr &)
Construct a Function from an existing FunctionContents pointer.
const std::string & origin_name() const
If this is a wrapper of another func, created by a chain of in or clone_in calls, returns the name of...
const std::string & name() const
Get the name of the function.
void add_trace_tag(const std::string &trace_tag)
Expr extern_definition_proxy_expr() const
Get the proxy Expr for the extern stage.
Function(const std::vector< Type > &required_types, int required_dims, const std::string &n)
Construct a new function with the given name, with a requirement that it can only represent Expr(s) o...
A base class for passes over the IR which modify it (e.g.
Definition: IRMutator.h:26
A base class for algorithms that need to recursively walk over the IR.
Definition: IRVisitor.h:19
A schedule for a single stage of a Halide pipeline.
Definition: Schedule.h:646
Create a small array of Exprs for defining and calling functions with multiple outputs.
Definition: Tuple.h:18
std::pair< std::vector< Function >, std::map< std::string, Function > > deep_copy(const std::vector< Function > &outputs, const std::map< std::string, Function > &env)
Deep copy an entire Function DAG.
Expr substitute(const std::string &name, const Expr &replacement, const Expr &expr)
Substitute variables with the given name with the replacement expression within expr.
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
NameMangling
An enum to specify calling convention for extern stages.
Definition: Function.h:25
@ C
No name mangling.
@ CPlusPlus
C++ name mangling.
@ Default
Match whatever is specified in the Target.
DeviceAPI
An enum describing a type of device API.
Definition: DeviceAPI.h:15
A fragment of Halide syntax.
Definition: Expr.h:257
An argument to an extern-defined Func.
A function call.
Definition: IR.h:482
This lets you use a Function as a key in a map of the form map<Function, Foo, Function::Compare>
Definition: Function.h:45
bool operator()(const Function &a, const Function &b) const
Definition: Function.h:46
A possibly-weak pointer to a Halide function.
Definition: FunctionPtr.h:27
bool defined() const
Check if the reference is defined.
Definition: FunctionPtr.h:74
bool same_as(const FunctionPtr &other) const
Check if two FunctionPtrs refer to the same Function.
Definition: FunctionPtr.h:79
A struct representing a target machine and os to generate code for.
Definition: Target.h:19
Types in the halide type system.
Definition: Type.h:276