Halide  13.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 "ExternalCode.h"
16 #include "IROperator.h"
17 #include "IntrusivePtr.h"
18 #include "JITModule.h"
19 #include "Module.h"
20 #include "ParamMap.h"
21 #include "Realization.h"
22 #include "Target.h"
23 #include "Tuple.h"
24 
25 namespace Halide {
26 
27 struct Argument;
28 class Func;
29 struct PipelineContents;
30 
31 /** A struct representing the machine parameters to generate the auto-scheduled
32  * code for. */
33 struct MachineParams {
34  /** Maximum level of parallelism avalaible. */
36  /** Size of the last-level cache (in bytes). */
38  /** Indicates how much more expensive is the cost of a load compared to
39  * the cost of an arithmetic operation at last level cache. */
40  float balance;
41 
42  explicit MachineParams(int parallelism, uint64_t llc, float balance)
44  }
45 
46  /** Default machine parameters for generic CPU architecture. */
47  static MachineParams generic();
48 
49  /** Convert the MachineParams into canonical string form. */
50  std::string to_string() const;
51 
52  /** Reconstruct a MachineParams from canonical string form. */
53  explicit MachineParams(const std::string &s);
54 };
55 
56 namespace Internal {
57 class IRMutator;
58 } // namespace Internal
59 
60 /**
61  * Used to determine if the output printed to file should be as a normal string
62  * or as an HTML file which can be opened in a browerser and manipulated via JS and CSS.*/
65  HTML
66 };
67 
68 namespace {
69 // Helper for deleting custom lowering passes. In the header so that
70 // it goes in user code on windows, where you can have multiple heaps.
71 template<typename T>
72 void delete_lowering_pass(T *pass) {
73  delete pass;
74 }
75 } // namespace
76 
77 /** A custom lowering pass. See Pipeline::add_custom_lowering_pass. */
80  std::function<void()> deleter;
81 };
82 
83 struct JITExtern;
84 
86  std::string scheduler_name; // name of the autoscheduler used
87  Target target; // Target specified to the autoscheduler
88  std::string machine_params_string; // MachineParams specified to the autoscheduler (in string form)
89  std::string schedule_source; // The C++ source code of the generated schedule
90  std::vector<uint8_t> featurization; // The featurization of the pipeline (if any)
91 };
92 
93 class Pipeline;
94 
95 using AutoSchedulerFn = std::function<void(const Pipeline &, const Target &, const MachineParams &, AutoSchedulerResults *outputs)>;
96 
97 /** A class representing a Halide pipeline. Constructed from the Func
98  * or Funcs that it outputs. */
99 class Pipeline {
100 public:
101  struct RealizationArg {
102  // Only one of the following may be non-null
103  Realization *r{nullptr};
104  halide_buffer_t *buf{nullptr};
105  std::unique_ptr<std::vector<Buffer<>>> buffer_list;
106 
108  : r(&r) {
109  }
111  : r(&r) {
112  }
114  : buf(buf) {
115  }
116  template<typename T, int D>
118  : buf(dst.raw_buffer()) {
119  }
120  template<typename T>
122  : buf(dst.raw_buffer()) {
123  }
124  template<typename T, typename... Args,
125  typename = typename std::enable_if<Internal::all_are_convertible<Buffer<>, Args...>::value>::type>
126  RealizationArg(Buffer<T> &a, Args &&...args)
127  : buffer_list(std::make_unique<std::vector<Buffer<>>>(std::initializer_list<Buffer<>>{a, std::forward<Args>(args)...})) {
128  }
129  RealizationArg(RealizationArg &&from) = default;
130 
131  size_t size() const {
132  if (r != nullptr) {
133  return r->size();
134  } else if (buffer_list) {
135  return buffer_list->size();
136  }
137  return 1;
138  }
139  };
140 
141 private:
143 
144  struct JITCallArgs; // Opaque structure to optimize away dynamic allocation in this path.
145 
146  // For the three method below, precisely one of the first two args should be non-null
147  void prepare_jit_call_arguments(RealizationArg &output, const Target &target, const ParamMap &param_map,
148  void *user_context, bool is_bounds_inference, JITCallArgs &args_result);
149 
150  static std::vector<Internal::JITModule> make_externs_jit_module(const Target &target,
151  std::map<std::string, JITExtern> &externs_in_out);
152 
153  static std::map<std::string, AutoSchedulerFn> &get_autoscheduler_map();
154 
155  static std::string &get_default_autoscheduler_name();
156 
157  static AutoSchedulerFn find_autoscheduler(const std::string &autoscheduler_name);
158 
159  int call_jit_code(const Target &target, const JITCallArgs &args);
160 
161  // Get the value of contents->jit_target, but reality-check that the contents
162  // sensibly match the value. Return Target() if not jitted.
163  Target get_compiled_jit_target() const;
164 
165 public:
166  /** Make an undefined Pipeline object. */
168 
169  /** Make a pipeline that computes the given Func. Schedules the
170  * Func compute_root(). */
171  Pipeline(const Func &output);
172 
173  /** Make a pipeline that computes the givens Funcs as
174  * outputs. Schedules the Funcs compute_root(). */
175  Pipeline(const std::vector<Func> &outputs);
176 
177  std::vector<Argument> infer_arguments(const Internal::Stmt &body);
178 
179  /** Get the Funcs this pipeline outputs. */
180  std::vector<Func> outputs() const;
181 
182  /** Generate a schedule for the pipeline using the currently-default autoscheduler. */
184  const MachineParams &arch_params = MachineParams::generic());
185 
186  /** Generate a schedule for the pipeline using the specified autoscheduler. */
187  AutoSchedulerResults auto_schedule(const std::string &autoscheduler_name,
188  const Target &target,
189  const MachineParams &arch_params = MachineParams::generic());
190 
191  /** Add a new the autoscheduler method with the given name. Does not affect the current default autoscheduler.
192  * It is an error to call this with the same name multiple times. */
193  static void add_autoscheduler(const std::string &autoscheduler_name, const AutoSchedulerFn &autoscheduler);
194 
195  /** Globally set the default autoscheduler method to use whenever
196  * autoscheduling any Pipeline when no name is specified. If the autoscheduler_name isn't in the
197  * current table of known autoschedulers, assert-fail.
198  *
199  * At this time, well-known autoschedulers include:
200  * "Mullapudi2016" -- heuristics-based; the first working autoscheduler; currently built in to libHalide
201  * see http://graphics.cs.cmu.edu/projects/halidesched/
202  * "Adams2019" -- aka "the ML autoscheduler"; currently located in apps/autoscheduler
203  * see https://halide-lang.org/papers/autoscheduler2019.html
204  * "Li2018" -- aka "the gradient autoscheduler"; currently located in apps/gradient_autoscheduler.
205  * see https://people.csail.mit.edu/tzumao/gradient_halide
206  */
207  static void set_default_autoscheduler_name(const std::string &autoscheduler_name);
208 
209  /** Return handle to the index-th Func within the pipeline based on the
210  * topological order. */
211  Func get_func(size_t index);
212 
213  /** Compile and generate multiple target files with single call.
214  * Deduces target files based on filenames specified in
215  * output_files map.
216  */
217  void compile_to(const std::map<Output, std::string> &output_files,
218  const std::vector<Argument> &args,
219  const std::string &fn_name,
220  const Target &target);
221 
222  /** Statically compile a pipeline to llvm bitcode, with the given
223  * filename (which should probably end in .bc), type signature,
224  * and C function name. If you're compiling a pipeline with a
225  * single output Func, see also Func::compile_to_bitcode. */
226  void compile_to_bitcode(const std::string &filename,
227  const std::vector<Argument> &args,
228  const std::string &fn_name,
229  const Target &target = get_target_from_environment());
230 
231  /** Statically compile a pipeline to llvm assembly, with the given
232  * filename (which should probably end in .ll), type signature,
233  * and C function name. If you're compiling a pipeline with a
234  * single output Func, see also Func::compile_to_llvm_assembly. */
235  void compile_to_llvm_assembly(const std::string &filename,
236  const std::vector<Argument> &args,
237  const std::string &fn_name,
238  const Target &target = get_target_from_environment());
239 
240  /** Statically compile a pipeline with multiple output functions to an
241  * object file, with the given filename (which should probably end in
242  * .o or .obj), type signature, and C function name (which defaults to
243  * the same name as this halide function. You probably don't want to
244  * use this directly; call compile_to_static_library or compile_to_file instead. */
245  void compile_to_object(const std::string &filename,
246  const std::vector<Argument> &,
247  const std::string &fn_name,
248  const Target &target = get_target_from_environment());
249 
250  /** Emit a header file with the given filename for a pipeline. The
251  * header will define a function with the type signature given by
252  * the second argument, and a name given by the third. You don't
253  * actually have to have defined any of these functions yet to
254  * call this. You probably don't want to use this directly; call
255  * compile_to_static_library or compile_to_file instead. */
256  void compile_to_header(const std::string &filename,
257  const std::vector<Argument> &,
258  const std::string &fn_name,
259  const Target &target = get_target_from_environment());
260 
261  /** Statically compile a pipeline to text assembly equivalent to
262  * the object file generated by compile_to_object. This is useful
263  * for checking what Halide is producing without having to
264  * disassemble anything, or if you need to feed the assembly into
265  * some custom toolchain to produce an object file. */
266  void compile_to_assembly(const std::string &filename,
267  const std::vector<Argument> &args,
268  const std::string &fn_name,
269  const Target &target = get_target_from_environment());
270 
271  /** Statically compile a pipeline to C source code. This is useful
272  * for providing fallback code paths that will compile on many
273  * platforms. Vectorization will fail, and parallelization will
274  * produce serial code. */
275  void compile_to_c(const std::string &filename,
276  const std::vector<Argument> &,
277  const std::string &fn_name,
278  const Target &target = get_target_from_environment());
279 
280  /** Write out an internal representation of lowered code. Useful
281  * for analyzing and debugging scheduling. Can emit html or plain
282  * text. */
283  void compile_to_lowered_stmt(const std::string &filename,
284  const std::vector<Argument> &args,
285  StmtOutputFormat fmt = Text,
286  const Target &target = get_target_from_environment());
287 
288  /** Write out the loop nests specified by the schedule for this
289  * Pipeline's Funcs. Helpful for understanding what a schedule is
290  * doing. */
292 
293  /** Compile to object file and header pair, with the given
294  * arguments. */
295  void compile_to_file(const std::string &filename_prefix,
296  const std::vector<Argument> &args,
297  const std::string &fn_name,
298  const Target &target = get_target_from_environment());
299 
300  /** Compile to static-library file and header pair, with the given
301  * arguments. */
302  void compile_to_static_library(const std::string &filename_prefix,
303  const std::vector<Argument> &args,
304  const std::string &fn_name,
305  const Target &target = get_target_from_environment());
306 
307  /** Compile to static-library file and header pair once for each target;
308  * each resulting function will be considered (in order) via halide_can_use_target_features()
309  * at runtime, with the first appropriate match being selected for subsequent use.
310  * This is typically useful for specializations that may vary unpredictably by machine
311  * (e.g., SSE4.1/AVX/AVX2 on x86 desktop machines).
312  * All targets must have identical arch-os-bits.
313  */
314  void compile_to_multitarget_static_library(const std::string &filename_prefix,
315  const std::vector<Argument> &args,
316  const std::vector<Target> &targets);
317 
318  /** Like compile_to_multitarget_static_library(), except that the object files
319  * are all output as object files (rather than bundled into a static library).
320  *
321  * `suffixes` is an optional list of strings to use for as the suffix for each object
322  * file. If nonempty, it must be the same length as `targets`. (If empty, Target::to_string()
323  * will be used for each suffix.)
324  *
325  * Note that if `targets.size()` > 1, the wrapper code (to select the subtarget)
326  * will be generated with the filename `${filename_prefix}_wrapper.o`
327  *
328  * Note that if `targets.size()` > 1 and `no_runtime` is not specified, the runtime
329  * will be generated with the filename `${filename_prefix}_runtime.o`
330  */
331  void compile_to_multitarget_object_files(const std::string &filename_prefix,
332  const std::vector<Argument> &args,
333  const std::vector<Target> &targets,
334  const std::vector<std::string> &suffixes);
335 
336  /** Create an internal representation of lowered code as a self
337  * contained Module suitable for further compilation. */
338  Module compile_to_module(const std::vector<Argument> &args,
339  const std::string &fn_name,
340  const Target &target = get_target_from_environment(),
342 
343  /** Eagerly jit compile the function to machine code. This
344  * normally happens on the first call to realize. If you're
345  * running your halide pipeline inside time-sensitive code and
346  * wish to avoid including the time taken to compile a pipeline,
347  * then you can call this ahead of time. Default is to use the Target
348  * returned from Halide::get_jit_target_from_environment()
349  */
351 
352  /** Set the error handler function that be called in the case of
353  * runtime errors during halide pipelines. If you are compiling
354  * statically, you can also just define your own function with
355  * signature
356  \code
357  extern "C" void halide_error(void *user_context, const char *);
358  \endcode
359  * This will clobber Halide's version.
360  */
361  void set_error_handler(void (*handler)(void *, const char *));
362 
363  /** Set a custom malloc and free for halide to use. Malloc should
364  * return 32-byte aligned chunks of memory, and it should be safe
365  * for Halide to read slightly out of bounds (up to 8 bytes before
366  * the start or beyond the end). If compiling statically, routines
367  * with appropriate signatures can be provided directly
368  \code
369  extern "C" void *halide_malloc(void *, size_t)
370  extern "C" void halide_free(void *, void *)
371  \endcode
372  * These will clobber Halide's versions. See HalideRuntime.h
373  * for declarations.
374  */
375  void set_custom_allocator(void *(*malloc)(void *, size_t),
376  void (*free)(void *, void *));
377 
378  /** Set a custom task handler to be called by the parallel for
379  * loop. It is useful to set this if you want to do some
380  * additional bookkeeping at the granularity of parallel
381  * tasks. The default implementation does this:
382  \code
383  extern "C" int halide_do_task(void *user_context,
384  int (*f)(void *, int, uint8_t *),
385  int idx, uint8_t *state) {
386  return f(user_context, idx, state);
387  }
388  \endcode
389  * If you are statically compiling, you can also just define your
390  * own version of the above function, and it will clobber Halide's
391  * version.
392  *
393  * If you're trying to use a custom parallel runtime, you probably
394  * don't want to call this. See instead \ref Func::set_custom_do_par_for .
395  */
397  int (*custom_do_task)(void *, int (*)(void *, int, uint8_t *),
398  int, uint8_t *));
399 
400  /** Set a custom parallel for loop launcher. Useful if your app
401  * already manages a thread pool. The default implementation is
402  * equivalent to this:
403  \code
404  extern "C" int halide_do_par_for(void *user_context,
405  int (*f)(void *, int, uint8_t *),
406  int min, int extent, uint8_t *state) {
407  int exit_status = 0;
408  parallel for (int idx = min; idx < min+extent; idx++) {
409  int job_status = halide_do_task(user_context, f, idx, state);
410  if (job_status) exit_status = job_status;
411  }
412  return exit_status;
413  }
414  \endcode
415  *
416  * However, notwithstanding the above example code, if one task
417  * fails, we may skip over other tasks, and if two tasks return
418  * different error codes, we may select one arbitrarily to return.
419  *
420  * If you are statically compiling, you can also just define your
421  * own version of the above function, and it will clobber Halide's
422  * version.
423  */
425  int (*custom_do_par_for)(void *, int (*)(void *, int, uint8_t *), int,
426  int, uint8_t *));
427 
428  /** Set custom routines to call when tracing is enabled. Call this
429  * on the output Func of your pipeline. This then sets custom
430  * routines for the entire pipeline, not just calls to this
431  * Func.
432  *
433  * If you are statically compiling, you can also just define your
434  * own versions of the tracing functions (see HalideRuntime.h),
435  * and they will clobber Halide's versions. */
436  void set_custom_trace(int (*trace_fn)(void *, const halide_trace_event_t *));
437 
438  /** Set the function called to print messages from the runtime.
439  * If you are compiling statically, you can also just define your
440  * own function with signature
441  \code
442  extern "C" void halide_print(void *user_context, const char *);
443  \endcode
444  * This will clobber Halide's version.
445  */
446  void set_custom_print(void (*handler)(void *, const char *));
447 
448  /** Install a set of external C functions or Funcs to satisfy
449  * dependencies introduced by HalideExtern and define_extern
450  * mechanisms. These will be used by calls to realize,
451  * infer_bounds, and compile_jit. */
452  void set_jit_externs(const std::map<std::string, JITExtern> &externs);
453 
454  /** Return the map of previously installed externs. Is an empty
455  * map unless set otherwise. */
456  const std::map<std::string, JITExtern> &get_jit_externs();
457 
458  /** Get a struct containing the currently set custom functions
459  * used by JIT. */
461 
462  /** Add a custom pass to be used during lowering. It is run after
463  * all other lowering passes. Can be used to verify properties of
464  * the lowered Stmt, instrument it with extra code, or otherwise
465  * modify it. The Func takes ownership of the pass, and will call
466  * delete on it when the Func goes out of scope. So don't pass a
467  * stack object, or share pass instances between multiple
468  * Funcs. */
469  template<typename T>
470  void add_custom_lowering_pass(T *pass) {
471  // Template instantiate a custom deleter for this type, then
472  // wrap in a lambda. The custom deleter lives in user code, so
473  // that deletion is on the same heap as construction (I hate Windows).
474  add_custom_lowering_pass(pass, [pass]() { delete_lowering_pass<T>(pass); });
475  }
476 
477  /** Add a custom pass to be used during lowering, with the
478  * function that will be called to delete it also passed in. Set
479  * it to nullptr if you wish to retain ownership of the object. */
480  void add_custom_lowering_pass(Internal::IRMutator *pass, std::function<void()> deleter);
481 
482  /** Remove all previously-set custom lowering passes */
484 
485  /** Get the custom lowering passes. */
486  const std::vector<CustomLoweringPass> &custom_lowering_passes();
487 
488  /** See Func::realize */
489  Realization realize(std::vector<int32_t> sizes = {}, const Target &target = Target(),
490  const ParamMap &param_map = ParamMap::empty_map());
491 
492  /** Evaluate this Pipeline into an existing allocated buffer or
493  * buffers. If the buffer is also one of the arguments to the
494  * function, strange things may happen, as the pipeline isn't
495  * necessarily safe to run in-place. The realization should
496  * contain one Buffer per tuple component per output Func. For
497  * each individual output Func, all Buffers must have the same
498  * shape, but the shape can vary across the different output
499  * Funcs. This form of realize does *not* automatically copy data
500  * back from the GPU. */
501  void realize(RealizationArg output, const Target &target = Target(),
502  const ParamMap &param_map = ParamMap::empty_map());
503 
504  /** For a given size of output, or a given set of output buffers,
505  * determine the bounds required of all unbound ImageParams
506  * referenced. Communicates the result by allocating new buffers
507  * of the appropriate size and binding them to the unbound
508  * ImageParams. */
509  // @{
510  void infer_input_bounds(const std::vector<int32_t> &sizes,
511  const Target &target = get_jit_target_from_environment(),
512  const ParamMap &param_map = ParamMap::empty_map());
514  const Target &target = get_jit_target_from_environment(),
515  const ParamMap &param_map = ParamMap::empty_map());
516  // @}
517 
518  /** Infer the arguments to the Pipeline, sorted into a canonical order:
519  * all buffers (sorted alphabetically by name), followed by all non-buffers
520  * (sorted alphabetically by name).
521  This lets you write things like:
522  \code
523  pipeline.compile_to_assembly("/dev/stdout", pipeline.infer_arguments());
524  \endcode
525  */
526  std::vector<Argument> infer_arguments();
527 
528  /** Check if this pipeline object is defined. That is, does it
529  * have any outputs? */
530  bool defined() const;
531 
532  /** Invalidate any internal cached state, e.g. because Funcs have
533  * been rescheduled. */
535 
536  /** Add a top-level precondition to the generated pipeline,
537  * expressed as a boolean Expr. The Expr may depend on parameters
538  * only, and may not call any Func or use a Var. If the condition
539  * is not true at runtime, the pipeline will call halide_error
540  * with the remaining arguments, and return
541  * halide_error_code_requirement_failed. Requirements are checked
542  * in the order added. */
543  void add_requirement(const Expr &condition, std::vector<Expr> &error);
544 
545  /** Generate begin_pipeline and end_pipeline tracing calls for this pipeline. */
547 
548  template<typename... Args>
549  inline HALIDE_NO_USER_CODE_INLINE void add_requirement(const Expr &condition, Args &&...args) {
550  std::vector<Expr> collected_args;
551  Internal::collect_print_args(collected_args, std::forward<Args>(args)...);
552  add_requirement(condition, collected_args);
553  }
554 
555 private:
556  std::string generate_function_name() const;
557 };
558 
560 private:
561  Type ret_type_; // Only meaningful if is_void_return is false; must be default value otherwise
562  bool is_void_return_{false};
563  std::vector<Type> arg_types_;
564 
565 public:
566  ExternSignature() = default;
567 
568  ExternSignature(const Type &ret_type, bool is_void_return, const std::vector<Type> &arg_types)
569  : ret_type_(ret_type),
570  is_void_return_(is_void_return),
571  arg_types_(arg_types) {
573  }
574 
575  template<typename RT, typename... Args>
576  explicit ExternSignature(RT (*f)(Args... args))
577  : ret_type_(type_of<RT>()),
578  is_void_return_(std::is_void<RT>::value),
579  arg_types_({type_of<Args>()...}) {
580  }
581 
582  const Type &ret_type() const {
584  return ret_type_;
585  }
586 
587  bool is_void_return() const {
588  return is_void_return_;
589  }
590 
591  const std::vector<Type> &arg_types() const {
592  return arg_types_;
593  }
594 
595  friend std::ostream &operator<<(std::ostream &stream, const ExternSignature &sig) {
596  if (sig.is_void_return_) {
597  stream << "void";
598  } else {
599  stream << sig.ret_type_;
600  }
601  stream << " (*)(";
602  bool comma = false;
603  for (const auto &t : sig.arg_types_) {
604  if (comma) {
605  stream << ", ";
606  }
607  stream << t;
608  comma = true;
609  }
610  stream << ")";
611  return stream;
612  }
613 };
614 
616 private:
617  void *address_{nullptr};
618  ExternSignature signature_;
619 
620 public:
621  ExternCFunction() = default;
622 
624  : address_(address), signature_(signature) {
625  }
626 
627  template<typename RT, typename... Args>
628  ExternCFunction(RT (*f)(Args... args))
629  : ExternCFunction((void *)f, ExternSignature(f)) {
630  }
631 
632  void *address() const {
633  return address_;
634  }
635  const ExternSignature &signature() const {
636  return signature_;
637  }
638 };
639 
640 struct JITExtern {
641 private:
642  // Note that exactly one of pipeline_ and extern_c_function_
643  // can be set in a given JITExtern instance.
644  Pipeline pipeline_;
645  ExternCFunction extern_c_function_;
646 
647 public:
649  explicit JITExtern(const Func &func);
651 
652  template<typename RT, typename... Args>
653  explicit JITExtern(RT (*f)(Args... args))
654  : JITExtern(ExternCFunction(f)) {
655  }
656 
657  const Pipeline &pipeline() const {
658  return pipeline_;
659  }
661  return extern_c_function_;
662  }
663 };
664 
665 } // namespace Halide
666 
667 #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 a collection of parameters to be passed as formal arguments to a JIT invocation.
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:45
A Halide::Buffer is a named shared reference to a Halide::Runtime::Buffer.
Definition: Buffer.h:115
A halide function.
Definition: Func.h:698
A base class for passes over the IR which modify it (e.g.
Definition: IRMutator.h:26
A halide module.
Definition: Module.h:135
static const ParamMap & empty_map()
A const ref to an empty ParamMap.
Definition: ParamMap.h:104
A class representing a Halide pipeline.
Definition: Pipeline.h:99
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 ...
void add_requirement(const Expr &condition, std::vector< Expr > &error)
Add a top-level precondition to the generated pipeline, expressed as a boolean Expr.
std::vector< Argument > infer_arguments()
Infer the arguments to the Pipeline, sorted into a canonical order: all buffers (sorted alphabeticall...
void set_error_handler(void(*handler)(void *, const char *))
Set the error handler function that be called in the case of runtime errors during halide pipelines.
const Internal::JITHandlers & jit_handlers()
Get a struct containing the currently set custom functions used by JIT.
AutoSchedulerResults auto_schedule(const std::string &autoscheduler_name, const Target &target, const MachineParams &arch_params=MachineParams::generic())
Generate a schedule for the pipeline using the specified autoscheduler.
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 set_custom_do_task(int(*custom_do_task)(void *, int(*)(void *, int, uint8_t *), int, uint8_t *))
Set a custom task handler to be called by the parallel for loop.
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.
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(std::vector< int32_t > sizes={}, const Target &target=Target(), const ParamMap &param_map=ParamMap::empty_map())
See Func::realize.
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 set_custom_print(void(*handler)(void *, const char *))
Set the function called to print messages from the runtime.
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 realize(RealizationArg output, const Target &target=Target(), const ParamMap &param_map=ParamMap::empty_map())
Evaluate this Pipeline into an existing allocated buffer or buffers.
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...
AutoSchedulerResults auto_schedule(const Target &target, const MachineParams &arch_params=MachineParams::generic())
Generate a schedule for the pipeline using the currently-default autoscheduler.
Pipeline(const std::vector< Func > &outputs)
Make a pipeline that computes the givens Funcs as outputs.
void infer_input_bounds(const std::vector< int32_t > &sizes, const Target &target=get_jit_target_from_environment(), const ParamMap &param_map=ParamMap::empty_map())
For a given size of output, or a given set of output buffers, determine the bounds required of all un...
std::vector< Argument > infer_arguments(const Internal::Stmt &body)
void compile_to(const std::map< Output, 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.
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 ...
static void set_default_autoscheduler_name(const std::string &autoscheduler_name)
Globally set the default autoscheduler method to use whenever autoscheduling any Pipeline when no nam...
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 infer_input_bounds(RealizationArg output, const Target &target=get_jit_target_from_environment(), const ParamMap &param_map=ParamMap::empty_map())
void set_custom_allocator(void *(*malloc)(void *, size_t), void(*free)(void *, void *))
Set a custom malloc and free for halide to use.
void print_loop_nest()
Write out the loop nests specified by the schedule for this Pipeline's Funcs.
void set_custom_do_par_for(int(*custom_do_par_for)(void *, int(*)(void *, int, uint8_t *), int, int, uint8_t *))
Set a custom parallel for loop launcher.
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...
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 set_custom_trace(int(*trace_fn)(void *, const halide_trace_event_t *))
Set custom routines to call when tracing is enabled.
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:470
HALIDE_NO_USER_CODE_INLINE void add_requirement(const Expr &condition, Args &&...args)
Definition: Pipeline.h:549
A Realization is a vector of references to existing Buffer objects.
Definition: Realization.h:21
size_t size() const
The number of images in the Realization.
HALIDE_NO_USER_CODE_INLINE void collect_print_args(std::vector< Expr > &args)
Definition: IROperator.h:326
WEAK halide_do_task_t custom_do_task
WEAK halide_do_par_for_t custom_do_par_for
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
std::function< void(const Pipeline &, const Target &, const MachineParams &, AutoSchedulerResults *outputs)> AutoSchedulerFn
Definition: Pipeline.h:95
LinkageType
Type of linkage a function in a lowered Halide module can have.
Definition: Module.h:48
@ 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:525
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:63
@ HTML
Definition: Pipeline.h:65
@ Text
Definition: Pipeline.h:64
char * dst
Definition: printer.h:32
void * user_context
Definition: printer.h:33
unsigned __INT64_TYPE__ uint64_t
void * malloc(size_t)
unsigned __INT8_TYPE__ uint8_t
void free(void *)
std::string schedule_source
Definition: Pipeline.h:89
std::string machine_params_string
Definition: Pipeline.h:88
std::vector< uint8_t > featurization
Definition: Pipeline.h:90
std::string scheduler_name
Definition: Pipeline.h:86
A custom lowering pass.
Definition: Pipeline.h:78
Internal::IRMutator * pass
Definition: Pipeline.h:79
std::function< void()> deleter
Definition: Pipeline.h:80
A fragment of Halide syntax.
Definition: Expr.h:256
ExternCFunction(void *address, const ExternSignature &signature)
Definition: Pipeline.h:623
const ExternSignature & signature() const
Definition: Pipeline.h:635
void * address() const
Definition: Pipeline.h:632
ExternCFunction(RT(*f)(Args... args))
Definition: Pipeline.h:628
const std::vector< Type > & arg_types() const
Definition: Pipeline.h:591
friend std::ostream & operator<<(std::ostream &stream, const ExternSignature &sig)
Definition: Pipeline.h:595
ExternSignature(const Type &ret_type, bool is_void_return, const std::vector< Type > &arg_types)
Definition: Pipeline.h:568
const Type & ret_type() const
Definition: Pipeline.h:582
ExternSignature(RT(*f)(Args... args))
Definition: Pipeline.h:576
bool is_void_return() const
Definition: Pipeline.h:587
A reference-counted handle to a statement node.
Definition: Expr.h:413
JITExtern(const Func &func)
JITExtern(Pipeline pipeline)
const Pipeline & pipeline() const
Definition: Pipeline.h:657
JITExtern(RT(*f)(Args... args))
Definition: Pipeline.h:653
const ExternCFunction & extern_c_function() const
Definition: Pipeline.h:660
JITExtern(const ExternCFunction &extern_c_function)
A struct representing the machine parameters to generate the auto-scheduled code for.
Definition: Pipeline.h:33
int parallelism
Maximum level of parallelism avalaible.
Definition: Pipeline.h:35
float balance
Indicates how much more expensive is the cost of a load compared to the cost of an arithmetic operati...
Definition: Pipeline.h:40
std::string to_string() const
Convert the MachineParams into canonical string form.
MachineParams(int parallelism, uint64_t llc, float balance)
Definition: Pipeline.h:42
MachineParams(const std::string &s)
Reconstruct a MachineParams from canonical string form.
static MachineParams generic()
Default machine parameters for generic CPU architecture.
uint64_t last_level_cache_size
Size of the last-level cache (in bytes).
Definition: Pipeline.h:37
RealizationArg(Runtime::Buffer< T, D > &dst)
Definition: Pipeline.h:117
HALIDE_NO_USER_CODE_INLINE RealizationArg(Buffer< T > &dst)
Definition: Pipeline.h:121
RealizationArg(halide_buffer_t *buf)
Definition: Pipeline.h:113
RealizationArg(RealizationArg &&from)=default
RealizationArg(Buffer< T > &a, Args &&...args)
Definition: Pipeline.h:126
RealizationArg(Realization &&r)
Definition: Pipeline.h:110
RealizationArg(Realization &r)
Definition: Pipeline.h:107
std::unique_ptr< std::vector< Buffer<> > > buffer_list
Definition: Pipeline.h:105
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:265
The raw representation of an image passed around by generated Halide code.