Halide  17.0.2
Halide compiler and libraries
Pipeline.h
Go to the documentation of this file.
1 #ifndef HALIDE_PIPELINE_H
2 #define HALIDE_PIPELINE_H
3 
4 /** \file
5  *
6  * Defines the front-end class representing an entire Halide imaging
7  * pipeline.
8  */
9 
10 #include <initializer_list>
11 #include <map>
12 #include <memory>
13 #include <vector>
14 
15 #include "IROperator.h"
16 #include "IntrusivePtr.h"
17 #include "JITModule.h"
18 #include "Module.h"
19 #include "Realization.h"
20 #include "Target.h"
21 #include "Tuple.h"
22 
23 namespace Halide {
24 
25 struct Argument;
26 class Callable;
27 class Func;
28 struct PipelineContents;
29 
30 /** Special the Autoscheduler to be used (if any), along with arbitrary
31  * additional arguments specific to the given Autoscheduler.
32  *
33  * The 'name' field specifies the type of Autoscheduler
34  * to be used (e.g. Adams2019, Mullapudi2016). If this is an empty string,
35  * no autoscheduling will be done; if not, it mustbe the name of a known Autoscheduler.
36  *
37  * At this time, well-known autoschedulers include:
38  * "Mullapudi2016" -- heuristics-based; the first working autoscheduler; currently built in to libHalide
39  * see http://graphics.cs.cmu.edu/projects/halidesched/
40  * "Adams2019" -- aka "the ML autoscheduler"; currently located in apps/autoscheduler
41  * see https://halide-lang.org/papers/autoscheduler2019.html
42  * "Li2018" -- aka "the gradient autoscheduler"; currently located in apps/gradient_autoscheduler.
43  * see https://people.csail.mit.edu/tzumao/gradient_halide
44  *
45  * The key/value pairs in 'extra' are defined on a per-autoscheduler basis.
46  * An autoscheduler can have any number of required or optional keys.
47  */
49  std::string name;
50  std::map<std::string, std::string> extra;
51 
52  AutoschedulerParams() = default;
53  /*not-explicit*/ AutoschedulerParams(const std::string &name)
54  : name(name) {
55  }
56  AutoschedulerParams(const std::string &name, const std::map<std::string, std::string> &extra)
57  : name(name), extra(extra) {
58  }
59 
60  std::string to_string() const;
61 };
62 
63 namespace Internal {
64 class IRMutator;
65 struct JITCache;
66 struct JITCallArgs;
67 } // namespace Internal
68 
69 /**
70  * Used to determine if the output printed to file should be as a normal string
71  * or as an HTML file which can be opened in a browerser and manipulated via JS and CSS.*/
74  HTML
75 };
76 
77 namespace {
78 // Helper for deleting custom lowering passes. In the header so that
79 // it goes in user code on windows, where you can have multiple heaps.
80 template<typename T>
81 void delete_lowering_pass(T *pass) {
82  delete pass;
83 }
84 } // namespace
85 
86 /** A custom lowering pass. See Pipeline::add_custom_lowering_pass. */
89  std::function<void()> deleter;
90 };
91 
92 struct JITExtern;
93 
95  Target target; // Target specified to the autoscheduler
96  AutoschedulerParams autoscheduler_params; // The autoscheduler used, along with its params
97  std::string schedule_source; // The C++ source code of the generated schedule
98  std::vector<uint8_t> featurization; // The featurization of the pipeline (if any)
99 };
100 
101 class Pipeline;
102 
103 using AutoSchedulerFn = std::function<void(const Pipeline &, const Target &, const AutoschedulerParams &, AutoSchedulerResults *outputs)>;
104 
105 /** A class representing a Halide pipeline. Constructed from the Func
106  * or Funcs that it outputs. */
107 class Pipeline {
108 public:
109  struct RealizationArg {
110  // Only one of the following may be non-null
111  Realization *r{nullptr};
112  halide_buffer_t *buf{nullptr};
113  std::unique_ptr<std::vector<Buffer<>>> buffer_list;
114 
116  : r(&r) {
117  }
119  : r(&r) {
120  }
122  : buf(buf) {
123  }
124  template<typename T, int Dims>
126  : buf(dst.raw_buffer()) {
127  }
128  template<typename T, int Dims>
130  : buf(dst.raw_buffer()) {
131  }
132  template<typename T, int Dims, typename... Args,
133  typename = typename std::enable_if<Internal::all_are_convertible<Buffer<>, Args...>::value>::type>
134  RealizationArg(Buffer<T, Dims> &a, Args &&...args)
135  : buffer_list(std::make_unique<std::vector<Buffer<>>>(std::initializer_list<Buffer<>>{a, std::forward<Args>(args)...})) {
136  }
137  RealizationArg(RealizationArg &&from) = default;
138 
139  size_t size() const {
140  if (r != nullptr) {
141  return r->size();
142  } else if (buffer_list) {
143  return buffer_list->size();
144  }
145  return 1;
146  }
147  };
148 
149 private:
151 
152  // For the three method below, precisely one of the first two args should be non-null
153  void prepare_jit_call_arguments(RealizationArg &output, const Target &target,
154  JITUserContext **user_context, bool is_bounds_inference, Internal::JITCallArgs &args_result);
155 
156  static std::vector<Internal::JITModule> make_externs_jit_module(const Target &target,
157  std::map<std::string, JITExtern> &externs_in_out);
158 
159  static std::map<std::string, AutoSchedulerFn> &get_autoscheduler_map();
160 
161  static AutoSchedulerFn find_autoscheduler(const std::string &autoscheduler_name);
162 
163  int call_jit_code(const Target &target, const Internal::JITCallArgs &args);
164 
165  // Get the value of contents->jit_target, but reality-check that the contents
166  // sensibly match the value. Return Target() if not jitted.
167  Target get_compiled_jit_target() const;
168 
169  static Internal::JITCache compile_jit_cache(const Module &module,
170  std::vector<Argument> args,
171  const std::vector<Internal::Function> &outputs,
172  const std::map<std::string, JITExtern> &jit_externs,
173  const Target &target_arg);
174 
175 public:
176  /** Make an undefined Pipeline object. */
178 
179  /** Make a pipeline that computes the given Func. Schedules the
180  * Func compute_root(). */
181  Pipeline(const Func &output);
182 
183  /** Make a pipeline that computes the givens Funcs as
184  * outputs. Schedules the Funcs compute_root(). */
185  Pipeline(const std::vector<Func> &outputs);
186 
187  /** Make a pipeline from deserialization. */
188  Pipeline(const std::vector<Func> &outputs, const std::vector<Internal::Stmt> &requirements);
189 
190  std::vector<Argument> infer_arguments(const Internal::Stmt &body);
191 
192  /** Get the Funcs this pipeline outputs. */
193  std::vector<Func> outputs() const;
194 
195  /** Get the requirements of this pipeline. */
196  std::vector<Internal::Stmt> requirements() const;
197 
198  /** Generate a schedule for the pipeline using the specified autoscheduler. */
200  const AutoschedulerParams &autoscheduler_params) const;
201 
202  /** Add a new the autoscheduler method with the given name. Does not affect the current default autoscheduler.
203  * It is an error to call this with the same name multiple times. */
204  static void add_autoscheduler(const std::string &autoscheduler_name, const AutoSchedulerFn &autoscheduler);
205 
206  /** Return handle to the index-th Func within the pipeline based on the
207  * topological order. */
208  Func get_func(size_t index);
209 
210  /** Compile and generate multiple target files with single call.
211  * Deduces target files based on filenames specified in
212  * output_files map.
213  */
214  void compile_to(const std::map<OutputFileType, std::string> &output_files,
215  const std::vector<Argument> &args,
216  const std::string &fn_name,
217  const Target &target);
218 
219  /** Statically compile a pipeline to llvm bitcode, with the given
220  * filename (which should probably end in .bc), type signature,
221  * and C function name. If you're compiling a pipeline with a
222  * single output Func, see also Func::compile_to_bitcode. */
223  void compile_to_bitcode(const std::string &filename,
224  const std::vector<Argument> &args,
225  const std::string &fn_name,
226  const Target &target = get_target_from_environment());
227 
228  /** Statically compile a pipeline to llvm assembly, with the given
229  * filename (which should probably end in .ll), type signature,
230  * and C function name. If you're compiling a pipeline with a
231  * single output Func, see also Func::compile_to_llvm_assembly. */
232  void compile_to_llvm_assembly(const std::string &filename,
233  const std::vector<Argument> &args,
234  const std::string &fn_name,
235  const Target &target = get_target_from_environment());
236 
237  /** Statically compile a pipeline with multiple output functions to an
238  * object file, with the given filename (which should probably end in
239  * .o or .obj), type signature, and C function name (which defaults to
240  * the same name as this halide function. You probably don't want to
241  * use this directly; call compile_to_static_library or compile_to_file instead. */
242  void compile_to_object(const std::string &filename,
243  const std::vector<Argument> &,
244  const std::string &fn_name,
245  const Target &target = get_target_from_environment());
246 
247  /** Emit a header file with the given filename for a pipeline. The
248  * header will define a function with the type signature given by
249  * the second argument, and a name given by the third. You don't
250  * actually have to have defined any of these functions yet to
251  * call this. You probably don't want to use this directly; call
252  * compile_to_static_library or compile_to_file instead. */
253  void compile_to_header(const std::string &filename,
254  const std::vector<Argument> &,
255  const std::string &fn_name,
256  const Target &target = get_target_from_environment());
257 
258  /** Statically compile a pipeline to text assembly equivalent to
259  * the object file generated by compile_to_object. This is useful
260  * for checking what Halide is producing without having to
261  * disassemble anything, or if you need to feed the assembly into
262  * some custom toolchain to produce an object file. */
263  void compile_to_assembly(const std::string &filename,
264  const std::vector<Argument> &args,
265  const std::string &fn_name,
266  const Target &target = get_target_from_environment());
267 
268  /** Statically compile a pipeline to C source code. This is useful
269  * for providing fallback code paths that will compile on many
270  * platforms. Vectorization will fail, and parallelization will
271  * produce serial code. */
272  void compile_to_c(const std::string &filename,
273  const std::vector<Argument> &,
274  const std::string &fn_name,
275  const Target &target = get_target_from_environment());
276 
277  /** Write out an internal representation of lowered code. Useful
278  * for analyzing and debugging scheduling. Can emit html or plain
279  * text. */
280  void compile_to_lowered_stmt(const std::string &filename,
281  const std::vector<Argument> &args,
282  StmtOutputFormat fmt = Text,
283  const Target &target = get_target_from_environment());
284 
285  /** Write out the loop nests specified by the schedule for this
286  * Pipeline's Funcs. Helpful for understanding what a schedule is
287  * doing. */
289 
290  /** Compile to object file and header pair, with the given
291  * arguments. */
292  void compile_to_file(const std::string &filename_prefix,
293  const std::vector<Argument> &args,
294  const std::string &fn_name,
295  const Target &target = get_target_from_environment());
296 
297  /** Compile to static-library file and header pair, with the given
298  * arguments. */
299  void compile_to_static_library(const std::string &filename_prefix,
300  const std::vector<Argument> &args,
301  const std::string &fn_name,
302  const Target &target = get_target_from_environment());
303 
304  /** Compile to static-library file and header pair once for each target;
305  * each resulting function will be considered (in order) via halide_can_use_target_features()
306  * at runtime, with the first appropriate match being selected for subsequent use.
307  * This is typically useful for specializations that may vary unpredictably by machine
308  * (e.g., SSE4.1/AVX/AVX2 on x86 desktop machines).
309  * All targets must have identical arch-os-bits.
310  */
311  void compile_to_multitarget_static_library(const std::string &filename_prefix,
312  const std::vector<Argument> &args,
313  const std::vector<Target> &targets);
314 
315  /** Like compile_to_multitarget_static_library(), except that the object files
316  * are all output as object files (rather than bundled into a static library).
317  *
318  * `suffixes` is an optional list of strings to use for as the suffix for each object
319  * file. If nonempty, it must be the same length as `targets`. (If empty, Target::to_string()
320  * will be used for each suffix.)
321  *
322  * Note that if `targets.size()` > 1, the wrapper code (to select the subtarget)
323  * will be generated with the filename `${filename_prefix}_wrapper.o`
324  *
325  * Note that if `targets.size()` > 1 and `no_runtime` is not specified, the runtime
326  * will be generated with the filename `${filename_prefix}_runtime.o`
327  */
328  void compile_to_multitarget_object_files(const std::string &filename_prefix,
329  const std::vector<Argument> &args,
330  const std::vector<Target> &targets,
331  const std::vector<std::string> &suffixes);
332 
333  /** Create an internal representation of lowered code as a self
334  * contained Module suitable for further compilation. */
335  Module compile_to_module(const std::vector<Argument> &args,
336  const std::string &fn_name,
337  const Target &target = get_target_from_environment(),
339 
340  /** Eagerly jit compile the function to machine code. This
341  * normally happens on the first call to realize. If you're
342  * running your halide pipeline inside time-sensitive code and
343  * wish to avoid including the time taken to compile a pipeline,
344  * then you can call this ahead of time. Default is to use the Target
345  * returned from Halide::get_jit_target_from_environment()
346  */
348 
349  /** Eagerly jit compile the function to machine code and return a callable
350  * struct that behaves like a function pointer. The calling convention
351  * will exactly match that of an AOT-compiled version of this Func
352  * with the same Argument list.
353  */
354  Callable compile_to_callable(const std::vector<Argument> &args,
355  const Target &target = get_jit_target_from_environment());
356 
357  /** Install a set of external C functions or Funcs to satisfy
358  * dependencies introduced by HalideExtern and define_extern
359  * mechanisms. These will be used by calls to realize,
360  * infer_bounds, and compile_jit. */
361  void set_jit_externs(const std::map<std::string, JITExtern> &externs);
362 
363  /** Return the map of previously installed externs. Is an empty
364  * map unless set otherwise. */
365  const std::map<std::string, JITExtern> &get_jit_externs();
366 
367  /** Get a struct containing the currently set custom functions
368  * used by JIT. This can be mutated. Changes will take effect the
369  * next time this Pipeline is realized. */
371 
372  /** Add a custom pass to be used during lowering. It is run after
373  * all other lowering passes. Can be used to verify properties of
374  * the lowered Stmt, instrument it with extra code, or otherwise
375  * modify it. The Func takes ownership of the pass, and will call
376  * delete on it when the Func goes out of scope. So don't pass a
377  * stack object, or share pass instances between multiple
378  * Funcs. */
379  template<typename T>
380  void add_custom_lowering_pass(T *pass) {
381  // Template instantiate a custom deleter for this type, then
382  // wrap in a lambda. The custom deleter lives in user code, so
383  // that deletion is on the same heap as construction (I hate Windows).
384  add_custom_lowering_pass(pass, [pass]() { delete_lowering_pass<T>(pass); });
385  }
386 
387  /** Add a custom pass to be used during lowering, with the
388  * function that will be called to delete it also passed in. Set
389  * it to nullptr if you wish to retain ownership of the object. */
390  void add_custom_lowering_pass(Internal::IRMutator *pass, std::function<void()> deleter);
391 
392  /** Remove all previously-set custom lowering passes */
394 
395  /** Get the custom lowering passes. */
396  const std::vector<CustomLoweringPass> &custom_lowering_passes();
397 
398  /** See Func::realize */
399  Realization realize(std::vector<int32_t> sizes = {}, const Target &target = Target());
400 
401  /** Same as above, but takes a custom user-provided context to be
402  * passed to runtime functions. A nullptr context is legal, and is
403  * equivalent to calling the variant of realize that does not take
404  * a context. */
406  std::vector<int32_t> sizes = {},
407  const Target &target = Target());
408 
409  /** Evaluate this Pipeline into an existing allocated buffer or
410  * buffers. If the buffer is also one of the arguments to the
411  * function, strange things may happen, as the pipeline isn't
412  * necessarily safe to run in-place. The realization should
413  * contain one Buffer per tuple component per output Func. For
414  * each individual output Func, all Buffers must have the same
415  * shape, but the shape can vary across the different output
416  * Funcs. This form of realize does *not* automatically copy data
417  * back from the GPU. */
418  void realize(RealizationArg output, const Target &target = Target());
419 
420  /** Same as above, but takes a custom user-provided context to be
421  * passed to runtime functions. A nullptr context is legal, and
422  * is equivalent to calling the variant of realize that does not
423  * take a context. */
424  void realize(JITUserContext *context,
425  RealizationArg output,
426  const Target &target = Target());
427 
428  /** For a given size of output, or a given set of output buffers,
429  * determine the bounds required of all unbound ImageParams
430  * referenced. Communicates the result by allocating new buffers
431  * of the appropriate size and binding them to the unbound
432  * ImageParams. */
433  // @{
434  void infer_input_bounds(const std::vector<int32_t> &sizes,
435  const Target &target = get_jit_target_from_environment());
437  const Target &target = get_jit_target_from_environment());
438  // @}
439 
440  /** Variants of infer_inputs_bounds that take a custom user context */
441  // @{
443  const std::vector<int32_t> &sizes,
444  const Target &target = get_jit_target_from_environment());
446  RealizationArg output,
447  const Target &target = get_jit_target_from_environment());
448  // @}
449 
450  /** Infer the arguments to the Pipeline, sorted into a canonical order:
451  * all buffers (sorted alphabetically by name), followed by all non-buffers
452  * (sorted alphabetically by name).
453  This lets you write things like:
454  \code
455  pipeline.compile_to_assembly("/dev/stdout", pipeline.infer_arguments());
456  \endcode
457  */
458  std::vector<Argument> infer_arguments();
459 
460  /** Check if this pipeline object is defined. That is, does it
461  * have any outputs? */
462  bool defined() const;
463 
464  /** Invalidate any internal cached state, e.g. because Funcs have
465  * been rescheduled. */
467 
468  /** Add a top-level precondition to the generated pipeline,
469  * expressed as a boolean Expr. The Expr may depend on parameters
470  * only, and may not call any Func or use a Var. If the condition
471  * is not true at runtime, the pipeline will call halide_error
472  * with the remaining arguments, and return
473  * halide_error_code_requirement_failed. Requirements are checked
474  * in the order added. */
475  // @{
476  void add_requirement(const Expr &condition, const std::vector<Expr> &error_args);
477 
478  template<typename... Args,
479  typename = typename std::enable_if<Internal::all_are_printable_args<Args...>::value>::type>
480  inline HALIDE_NO_USER_CODE_INLINE void add_requirement(const Expr &condition, Args &&...error_args) {
481  std::vector<Expr> collected_args;
482  Internal::collect_print_args(collected_args, std::forward<Args>(error_args)...);
483  add_requirement(condition, collected_args);
484  }
485  // @}
486 
487  /** Generate begin_pipeline and end_pipeline tracing calls for this pipeline. */
489 
490 private:
491  std::string generate_function_name() const;
492 };
493 
495 private:
496  Type ret_type_; // Only meaningful if is_void_return is false; must be default value otherwise
497  bool is_void_return_{false};
498  std::vector<Type> arg_types_;
499 
500 public:
501  ExternSignature() = default;
502 
503  ExternSignature(const Type &ret_type, bool is_void_return, const std::vector<Type> &arg_types)
504  : ret_type_(ret_type),
505  is_void_return_(is_void_return),
506  arg_types_(arg_types) {
507  internal_assert(!(is_void_return && ret_type != Type()));
508  }
509 
510  template<typename RT, typename... Args>
511  explicit ExternSignature(RT (*f)(Args... args))
512  : ret_type_(type_of<RT>()),
513  is_void_return_(std::is_void<RT>::value),
514  arg_types_({type_of<Args>()...}) {
515  }
516 
517  const Type &ret_type() const {
518  internal_assert(!is_void_return());
519  return ret_type_;
520  }
521 
522  bool is_void_return() const {
523  return is_void_return_;
524  }
525 
526  const std::vector<Type> &arg_types() const {
527  return arg_types_;
528  }
529 
530  friend std::ostream &operator<<(std::ostream &stream, const ExternSignature &sig) {
531  if (sig.is_void_return_) {
532  stream << "void";
533  } else {
534  stream << sig.ret_type_;
535  }
536  stream << " (*)(";
537  bool comma = false;
538  for (const auto &t : sig.arg_types_) {
539  if (comma) {
540  stream << ", ";
541  }
542  stream << t;
543  comma = true;
544  }
545  stream << ")";
546  return stream;
547  }
548 };
549 
551 private:
552  void *address_{nullptr};
553  ExternSignature signature_;
554 
555 public:
556  ExternCFunction() = default;
557 
559  : address_(address), signature_(signature) {
560  }
561 
562  template<typename RT, typename... Args>
563  ExternCFunction(RT (*f)(Args... args))
564  : ExternCFunction((void *)f, ExternSignature(f)) {
565  }
566 
567  void *address() const {
568  return address_;
569  }
570  const ExternSignature &signature() const {
571  return signature_;
572  }
573 };
574 
575 struct JITExtern {
576 private:
577  // Note that exactly one of pipeline_ and extern_c_function_
578  // can be set in a given JITExtern instance.
579  Pipeline pipeline_;
580  ExternCFunction extern_c_function_;
581 
582 public:
584  explicit JITExtern(const Func &func);
586 
587  template<typename RT, typename... Args>
588  explicit JITExtern(RT (*f)(Args... args))
589  : JITExtern(ExternCFunction(f)) {
590  }
591 
592  const Pipeline &pipeline() const {
593  return pipeline_;
594  }
596  return extern_c_function_;
597  }
598 };
599 
600 } // namespace Halide
601 
602 #endif
#define internal_assert(c)
Definition: Errors.h:19
Defines various operator overloads and utility functions that make it more pleasant to work with Hali...
Support classes for reference-counting via intrusive shared pointers.
Defines the struct representing lifetime and dependencies of a JIT compiled halide pipeline.
Defines Module, an IR container that fully describes a Halide program.
Defines Realization - a vector of Buffer for use in pipelines with multiple outputs.
Defines the structure that describes a Halide target.
Defines Tuple - the front-end handle on small arrays of expressions.
#define HALIDE_NO_USER_CODE_INLINE
Definition: Util.h:46
A Halide::Buffer is a named shared reference to a Halide::Runtime::Buffer.
Definition: Buffer.h:122
A halide function.
Definition: Func.h:706
A base class for passes over the IR which modify it (e.g.
Definition: IRMutator.h:26
A halide module.
Definition: Module.h:142
A class representing a Halide pipeline.
Definition: Pipeline.h:107
void compile_to_bitcode(const std::string &filename, const std::vector< Argument > &args, const std::string &fn_name, const Target &target=get_target_from_environment())
Statically compile a pipeline to llvm bitcode, with the given filename (which should probably end in ...
std::vector< Argument > infer_arguments()
Infer the arguments to the Pipeline, sorted into a canonical order: all buffers (sorted alphabeticall...
void compile_to_c(const std::string &filename, const std::vector< Argument > &, const std::string &fn_name, const Target &target=get_target_from_environment())
Statically compile a pipeline to C source code.
void compile_jit(const Target &target=get_jit_target_from_environment())
Eagerly jit compile the function to machine code.
void trace_pipeline()
Generate begin_pipeline and end_pipeline tracing calls for this pipeline.
const std::map< std::string, JITExtern > & get_jit_externs()
Return the map of previously installed externs.
Realization realize(std::vector< int32_t > sizes={}, const Target &target=Target())
See Func::realize.
void compile_to_file(const std::string &filename_prefix, const std::vector< Argument > &args, const std::string &fn_name, const Target &target=get_target_from_environment())
Compile to object file and header pair, with the given arguments.
Realization realize(JITUserContext *context, std::vector< int32_t > sizes={}, const Target &target=Target())
Same as above, but takes a custom user-provided context to be passed to runtime functions.
void realize(JITUserContext *context, RealizationArg output, const Target &target=Target())
Same as above, but takes a custom user-provided context to be passed to runtime functions.
Func get_func(size_t index)
Return handle to the index-th Func within the pipeline based on the topological order.
void compile_to_header(const std::string &filename, const std::vector< Argument > &, const std::string &fn_name, const Target &target=get_target_from_environment())
Emit a header file with the given filename for a pipeline.
void infer_input_bounds(JITUserContext *context, const std::vector< int32_t > &sizes, const Target &target=get_jit_target_from_environment())
Variants of infer_inputs_bounds that take a custom user context.
std::vector< Internal::Stmt > requirements() const
Get the requirements of this pipeline.
void compile_to_lowered_stmt(const std::string &filename, const std::vector< Argument > &args, StmtOutputFormat fmt=Text, const Target &target=get_target_from_environment())
Write out an internal representation of lowered code.
static void add_autoscheduler(const std::string &autoscheduler_name, const AutoSchedulerFn &autoscheduler)
Add a new the autoscheduler method with the given name.
void set_jit_externs(const std::map< std::string, JITExtern > &externs)
Install a set of external C functions or Funcs to satisfy dependencies introduced by HalideExtern and...
void add_custom_lowering_pass(Internal::IRMutator *pass, std::function< void()> deleter)
Add a custom pass to be used during lowering, with the function that will be called to delete it also...
Pipeline()
Make an undefined Pipeline object.
void compile_to_llvm_assembly(const std::string &filename, const std::vector< Argument > &args, const std::string &fn_name, const Target &target=get_target_from_environment())
Statically compile a pipeline to llvm assembly, with the given filename (which should probably end in...
Pipeline(const std::vector< Func > &outputs)
Make a pipeline that computes the givens Funcs as outputs.
Callable compile_to_callable(const std::vector< Argument > &args, const Target &target=get_jit_target_from_environment())
Eagerly jit compile the function to machine code and return a callable struct that behaves like a fun...
std::vector< Argument > infer_arguments(const Internal::Stmt &body)
void infer_input_bounds(const std::vector< int32_t > &sizes, const Target &target=get_jit_target_from_environment())
For a given size of output, or a given set of output buffers, determine the bounds required of all un...
Pipeline(const std::vector< Func > &outputs, const std::vector< Internal::Stmt > &requirements)
Make a pipeline from deserialization.
void compile_to_multitarget_object_files(const std::string &filename_prefix, const std::vector< Argument > &args, const std::vector< Target > &targets, const std::vector< std::string > &suffixes)
Like compile_to_multitarget_static_library(), except that the object files are all output as object f...
void compile_to_multitarget_static_library(const std::string &filename_prefix, const std::vector< Argument > &args, const std::vector< Target > &targets)
Compile to static-library file and header pair once for each target; each resulting function will be ...
AutoSchedulerResults apply_autoscheduler(const Target &target, const AutoschedulerParams &autoscheduler_params) const
Generate a schedule for the pipeline using the specified autoscheduler.
JITHandlers & jit_handlers()
Get a struct containing the currently set custom functions used by JIT.
void compile_to_object(const std::string &filename, const std::vector< Argument > &, const std::string &fn_name, const Target &target=get_target_from_environment())
Statically compile a pipeline with multiple output functions to an object file, with the given filena...
void invalidate_cache()
Invalidate any internal cached state, e.g.
const std::vector< CustomLoweringPass > & custom_lowering_passes()
Get the custom lowering passes.
void add_requirement(const Expr &condition, const std::vector< Expr > &error_args)
Add a top-level precondition to the generated pipeline, expressed as a boolean Expr.
void infer_input_bounds(RealizationArg output, const Target &target=get_jit_target_from_environment())
void print_loop_nest()
Write out the loop nests specified by the schedule for this Pipeline's Funcs.
Module compile_to_module(const std::vector< Argument > &args, const std::string &fn_name, const Target &target=get_target_from_environment(), LinkageType linkage_type=LinkageType::ExternalPlusMetadata)
Create an internal representation of lowered code as a self contained Module suitable for further com...
HALIDE_NO_USER_CODE_INLINE void add_requirement(const Expr &condition, Args &&...error_args)
Definition: Pipeline.h:480
void infer_input_bounds(JITUserContext *context, RealizationArg output, const Target &target=get_jit_target_from_environment())
std::vector< Func > outputs() const
Get the Funcs this pipeline outputs.
void compile_to_assembly(const std::string &filename, const std::vector< Argument > &args, const std::string &fn_name, const Target &target=get_target_from_environment())
Statically compile a pipeline to text assembly equivalent to the object file generated by compile_to_...
void realize(RealizationArg output, const Target &target=Target())
Evaluate this Pipeline into an existing allocated buffer or buffers.
void clear_custom_lowering_passes()
Remove all previously-set custom lowering passes.
bool defined() const
Check if this pipeline object is defined.
void compile_to_static_library(const std::string &filename_prefix, const std::vector< Argument > &args, const std::string &fn_name, const Target &target=get_target_from_environment())
Compile to static-library file and header pair, with the given arguments.
Pipeline(const Func &output)
Make a pipeline that computes the given Func.
void add_custom_lowering_pass(T *pass)
Add a custom pass to be used during lowering.
Definition: Pipeline.h:380
void compile_to(const std::map< OutputFileType, std::string > &output_files, const std::vector< Argument > &args, const std::string &fn_name, const Target &target)
Compile and generate multiple target files with single call.
A Realization is a vector of references to existing Buffer objects.
Definition: Realization.h:19
size_t size() const
The number of images in the Realization.
A templated Buffer class that wraps halide_buffer_t and adds functionality.
Definition: HalideBuffer.h:216
HALIDE_NO_USER_CODE_INLINE void collect_print_args(std::vector< Expr > &args)
Definition: IROperator.h:335
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
LinkageType
Type of linkage a function in a lowered Halide module can have.
Definition: Module.h:52
@ ExternalPlusMetadata
Visible externally. Argument metadata and an argv wrapper are also generated.
@ Internal
Not visible externally, similar to 'static' linkage in C.
Type type_of()
Construct the halide equivalent of a C type.
Definition: Type.h:561
std::function< void(const Pipeline &, const Target &, const AutoschedulerParams &, AutoSchedulerResults *outputs)> AutoSchedulerFn
Definition: Pipeline.h:103
Target get_jit_target_from_environment()
Return the target that Halide will use for jit-compilation.
Target get_target_from_environment()
Return the target that Halide will use.
StmtOutputFormat
Used to determine if the output printed to file should be as a normal string or as an HTML file which...
Definition: Pipeline.h:72
@ HTML
Definition: Pipeline.h:74
@ Text
Definition: Pipeline.h:73
std::string schedule_source
Definition: Pipeline.h:97
std::vector< uint8_t > featurization
Definition: Pipeline.h:98
AutoschedulerParams autoscheduler_params
Definition: Pipeline.h:96
Special the Autoscheduler to be used (if any), along with arbitrary additional arguments specific to ...
Definition: Pipeline.h:48
AutoschedulerParams(const std::string &name, const std::map< std::string, std::string > &extra)
Definition: Pipeline.h:56
AutoschedulerParams(const std::string &name)
Definition: Pipeline.h:53
std::string to_string() const
std::map< std::string, std::string > extra
Definition: Pipeline.h:50
A custom lowering pass.
Definition: Pipeline.h:87
Internal::IRMutator * pass
Definition: Pipeline.h:88
std::function< void()> deleter
Definition: Pipeline.h:89
A fragment of Halide syntax.
Definition: Expr.h:258
ExternCFunction(void *address, const ExternSignature &signature)
Definition: Pipeline.h:558
const ExternSignature & signature() const
Definition: Pipeline.h:570
void * address() const
Definition: Pipeline.h:567
ExternCFunction(RT(*f)(Args... args))
Definition: Pipeline.h:563
const std::vector< Type > & arg_types() const
Definition: Pipeline.h:526
friend std::ostream & operator<<(std::ostream &stream, const ExternSignature &sig)
Definition: Pipeline.h:530
ExternSignature(const Type &ret_type, bool is_void_return, const std::vector< Type > &arg_types)
Definition: Pipeline.h:503
const Type & ret_type() const
Definition: Pipeline.h:517
ExternSignature(RT(*f)(Args... args))
Definition: Pipeline.h:511
bool is_void_return() const
Definition: Pipeline.h:522
A reference-counted handle to a statement node.
Definition: Expr.h:419
JITExtern(const Func &func)
JITExtern(Pipeline pipeline)
const Pipeline & pipeline() const
Definition: Pipeline.h:592
JITExtern(RT(*f)(Args... args))
Definition: Pipeline.h:588
const ExternCFunction & extern_c_function() const
Definition: Pipeline.h:595
JITExtern(const ExternCFunction &extern_c_function)
A set of custom overrides of runtime functions.
Definition: JITModule.h:35
A context to be passed to Pipeline::realize.
Definition: JITModule.h:136
RealizationArg(Buffer< T, Dims > &a, Args &&...args)
Definition: Pipeline.h:134
RealizationArg(halide_buffer_t *buf)
Definition: Pipeline.h:121
HALIDE_NO_USER_CODE_INLINE RealizationArg(Buffer< T, Dims > &dst)
Definition: Pipeline.h:129
RealizationArg(RealizationArg &&from)=default
RealizationArg(Runtime::Buffer< T, Dims > &dst)
Definition: Pipeline.h:125
RealizationArg(Realization &&r)
Definition: Pipeline.h:118
RealizationArg(Realization &r)
Definition: Pipeline.h:115
std::unique_ptr< std::vector< Buffer<> > > buffer_list
Definition: Pipeline.h:113
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
The raw representation of an image passed around by generated Halide code.