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