Halide 14.0.0
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
25namespace Halide {
26
27struct Argument;
28class Func;
29struct PipelineContents;
30
31/** A struct representing the machine parameters to generate the auto-scheduled
32 * code for. */
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
56namespace Internal {
57class 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
68namespace {
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.
71template<typename T>
72void 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
83struct 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
93class Pipeline;
94
95using 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. */
99class Pipeline {
100public:
102 // Only one of the following may be non-null
103 Realization *r{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 Dims>
118 : buf(dst.raw_buffer()) {
119 }
120 template<typename T, int Dims>
122 : buf(dst.raw_buffer()) {
123 }
124 template<typename T, int Dims, typename... Args,
125 typename = typename std::enable_if<Internal::all_are_convertible<Buffer<>, Args...>::value>::type>
126 RealizationArg(Buffer<T, Dims> &a, Args &&...args)
127 : buffer_list(std::make_unique<std::vector<Buffer<>>>(std::initializer_list<Buffer<>>{a, std::forward<Args>(args)...})) {
128 }
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
141private:
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 JITUserContext **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
165public:
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<OutputFileType, 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,
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 /** Deprecated variants of the above that use a void pointer
353 * instead of a JITUserContext pointer. */
354 // @{
355 HALIDE_ATTRIBUTE_DEPRECATED("Custom handlers should by set by modifying the struct returned by jit_handlers()")
356 void set_error_handler(void (*handler)(void *, const char *));
357 HALIDE_ATTRIBUTE_DEPRECATED("Custom handlers should by set by modifying the struct returned by jit_handlers()")
358 void set_custom_allocator(void *(*malloc)(void *, size_t),
359 void (*free)(void *, void *));
360 HALIDE_ATTRIBUTE_DEPRECATED("Custom handlers should by set by modifying the struct returned by jit_handlers()")
362 int (*custom_do_task)(void *, int (*)(void *, int, uint8_t *),
363 int, uint8_t *));
364 HALIDE_ATTRIBUTE_DEPRECATED("Custom handlers should by set by modifying the struct returned by jit_handlers()")
366 int (*custom_do_par_for)(void *, int (*)(void *, int, uint8_t *), int,
367 int, uint8_t *));
368 HALIDE_ATTRIBUTE_DEPRECATED("Custom handlers should by set by modifying the struct returned by jit_handlers()")
369 void set_custom_trace(int (*trace_fn)(void *, const halide_trace_event_t *));
370 HALIDE_ATTRIBUTE_DEPRECATED("Custom handlers should by set by modifying the struct returned by jit_handlers()")
371 void set_custom_print(void (*handler)(void *, const char *));
372 // @}
373
374 /** Install a set of external C functions or Funcs to satisfy
375 * dependencies introduced by HalideExtern and define_extern
376 * mechanisms. These will be used by calls to realize,
377 * infer_bounds, and compile_jit. */
378 void set_jit_externs(const std::map<std::string, JITExtern> &externs);
379
380 /** Return the map of previously installed externs. Is an empty
381 * map unless set otherwise. */
382 const std::map<std::string, JITExtern> &get_jit_externs();
383
384 /** Get a struct containing the currently set custom functions
385 * used by JIT. This can be mutated. Changes will take effect the
386 * next time this Pipeline is realized. */
388
389 /** Add a custom pass to be used during lowering. It is run after
390 * all other lowering passes. Can be used to verify properties of
391 * the lowered Stmt, instrument it with extra code, or otherwise
392 * modify it. The Func takes ownership of the pass, and will call
393 * delete on it when the Func goes out of scope. So don't pass a
394 * stack object, or share pass instances between multiple
395 * Funcs. */
396 template<typename T>
398 // Template instantiate a custom deleter for this type, then
399 // wrap in a lambda. The custom deleter lives in user code, so
400 // that deletion is on the same heap as construction (I hate Windows).
401 add_custom_lowering_pass(pass, [pass]() { delete_lowering_pass<T>(pass); });
402 }
403
404 /** Add a custom pass to be used during lowering, with the
405 * function that will be called to delete it also passed in. Set
406 * it to nullptr if you wish to retain ownership of the object. */
407 void add_custom_lowering_pass(Internal::IRMutator *pass, std::function<void()> deleter);
408
409 /** Remove all previously-set custom lowering passes */
411
412 /** Get the custom lowering passes. */
413 const std::vector<CustomLoweringPass> &custom_lowering_passes();
414
415 /** See Func::realize */
416 Realization realize(std::vector<int32_t> sizes = {}, const Target &target = Target(),
417 const ParamMap &param_map = ParamMap::empty_map());
418
419 /** Same as above, but takes a custom user-provided context to be
420 * passed to runtime functions. A nullptr context is legal, and is
421 * equivalent to calling the variant of realize that does not take
422 * a context. */
424 std::vector<int32_t> sizes = {},
425 const Target &target = Target(),
426 const ParamMap &param_map = ParamMap::empty_map());
427
428 /** Evaluate this Pipeline into an existing allocated buffer or
429 * buffers. If the buffer is also one of the arguments to the
430 * function, strange things may happen, as the pipeline isn't
431 * necessarily safe to run in-place. The realization should
432 * contain one Buffer per tuple component per output Func. For
433 * each individual output Func, all Buffers must have the same
434 * shape, but the shape can vary across the different output
435 * Funcs. This form of realize does *not* automatically copy data
436 * back from the GPU. */
438 const Target &target = Target(),
439 const ParamMap &param_map = ParamMap::empty_map());
440
441 /** Same as above, but takes a custom user-provided context to be
442 * passed to runtime functions. A nullptr context is legal, and
443 * is equivalent to calling the variant of realize that does not
444 * take a context. */
445 void realize(JITUserContext *context,
446 RealizationArg output,
447 const Target &target = Target(),
448 const ParamMap &param_map = ParamMap::empty_map());
449
450 /** For a given size of output, or a given set of output buffers,
451 * determine the bounds required of all unbound ImageParams
452 * referenced. Communicates the result by allocating new buffers
453 * of the appropriate size and binding them to the unbound
454 * ImageParams. */
455 // @{
456 void infer_input_bounds(const std::vector<int32_t> &sizes,
457 const Target &target = get_jit_target_from_environment(),
458 const ParamMap &param_map = ParamMap::empty_map());
460 const Target &target = get_jit_target_from_environment(),
461 const ParamMap &param_map = ParamMap::empty_map());
462 // @}
463
464 /** Variants of infer_inputs_bounds that take a custom user context */
465 // @{
467 const std::vector<int32_t> &sizes,
468 const Target &target = get_jit_target_from_environment(),
469 const ParamMap &param_map = ParamMap::empty_map());
471 RealizationArg output,
472 const Target &target = get_jit_target_from_environment(),
473 const ParamMap &param_map = ParamMap::empty_map());
474 // @}
475
476 /** Infer the arguments to the Pipeline, sorted into a canonical order:
477 * all buffers (sorted alphabetically by name), followed by all non-buffers
478 * (sorted alphabetically by name).
479 This lets you write things like:
480 \code
481 pipeline.compile_to_assembly("/dev/stdout", pipeline.infer_arguments());
482 \endcode
483 */
484 std::vector<Argument> infer_arguments();
485
486 /** Check if this pipeline object is defined. That is, does it
487 * have any outputs? */
488 bool defined() const;
489
490 /** Invalidate any internal cached state, e.g. because Funcs have
491 * been rescheduled. */
493
494 /** Add a top-level precondition to the generated pipeline,
495 * expressed as a boolean Expr. The Expr may depend on parameters
496 * only, and may not call any Func or use a Var. If the condition
497 * is not true at runtime, the pipeline will call halide_error
498 * with the remaining arguments, and return
499 * halide_error_code_requirement_failed. Requirements are checked
500 * in the order added. */
501 void add_requirement(const Expr &condition, std::vector<Expr> &error);
502
503 /** Generate begin_pipeline and end_pipeline tracing calls for this pipeline. */
505
506 template<typename... Args>
507 inline HALIDE_NO_USER_CODE_INLINE void add_requirement(const Expr &condition, Args &&...args) {
508 std::vector<Expr> collected_args;
509 Internal::collect_print_args(collected_args, std::forward<Args>(args)...);
510 add_requirement(condition, collected_args);
511 }
512
513private:
514 std::string generate_function_name() const;
515};
516
518private:
519 Type ret_type_; // Only meaningful if is_void_return is false; must be default value otherwise
520 bool is_void_return_{false};
521 std::vector<Type> arg_types_;
522
523public:
524 ExternSignature() = default;
525
526 ExternSignature(const Type &ret_type, bool is_void_return, const std::vector<Type> &arg_types)
527 : ret_type_(ret_type),
528 is_void_return_(is_void_return),
529 arg_types_(arg_types) {
531 }
532
533 template<typename RT, typename... Args>
534 explicit ExternSignature(RT (*f)(Args... args))
535 : ret_type_(type_of<RT>()),
536 is_void_return_(std::is_void<RT>::value),
537 arg_types_({type_of<Args>()...}) {
538 }
539
540 const Type &ret_type() const {
542 return ret_type_;
543 }
544
545 bool is_void_return() const {
546 return is_void_return_;
547 }
548
549 const std::vector<Type> &arg_types() const {
550 return arg_types_;
551 }
552
553 friend std::ostream &operator<<(std::ostream &stream, const ExternSignature &sig) {
554 if (sig.is_void_return_) {
555 stream << "void";
556 } else {
557 stream << sig.ret_type_;
558 }
559 stream << " (*)(";
560 bool comma = false;
561 for (const auto &t : sig.arg_types_) {
562 if (comma) {
563 stream << ", ";
564 }
565 stream << t;
566 comma = true;
567 }
568 stream << ")";
569 return stream;
570 }
571};
572
574private:
575 void *address_{nullptr};
576 ExternSignature signature_;
577
578public:
579 ExternCFunction() = default;
580
582 : address_(address), signature_(signature) {
583 }
584
585 template<typename RT, typename... Args>
586 ExternCFunction(RT (*f)(Args... args))
587 : ExternCFunction((void *)f, ExternSignature(f)) {
588 }
589
590 void *address() const {
591 return address_;
592 }
593 const ExternSignature &signature() const {
594 return signature_;
595 }
596};
597
598struct JITExtern {
599private:
600 // Note that exactly one of pipeline_ and extern_c_function_
601 // can be set in a given JITExtern instance.
602 Pipeline pipeline_;
603 ExternCFunction extern_c_function_;
604
605public:
607 explicit JITExtern(const Func &func);
609
610 template<typename RT, typename... Args>
611 explicit JITExtern(RT (*f)(Args... args))
613 }
614
615 const Pipeline &pipeline() const {
616 return pipeline_;
617 }
619 return extern_c_function_;
620 }
621};
622
623} // namespace Halide
624
625#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:120
A halide function.
Definition: Func.h:703
A base class for passes over the IR which modify it (e.g.
Definition: IRMutator.h:26
A halide module.
Definition: Module.h:172
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.
void set_error_handler(void(*handler)(void *, const char *))
Deprecated variants of the above that use a void pointer instead of a JITUserContext pointer.
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 *))
void trace_pipeline()
Generate begin_pipeline and end_pipeline tracing calls for this pipeline.
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.
void realize(JITUserContext *context, RealizationArg output, const Target &target=Target(), const ParamMap &param_map=ParamMap::empty_map())
Same as above, but takes a custom user-provided context to be passed to runtime functions.
Realization realize(JITUserContext *context, std::vector< int32_t > sizes={}, const Target &target=Target(), const ParamMap &param_map=ParamMap::empty_map())
Same as above, but takes a custom user-provided context to be passed to runtime functions.
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.
std::vector< Argument > infer_arguments()
Infer the arguments to the Pipeline, sorted into a canonical order: all buffers (sorted alphabeticall...
void set_custom_print(void(*handler)(void *, const char *))
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.
const std::map< std::string, JITExtern > & get_jit_externs()
Return the map of previously installed externs.
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...
const std::vector< CustomLoweringPass > & custom_lowering_passes()
Get the custom lowering passes.
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...
std::vector< Argument > infer_arguments(const Internal::Stmt &body)
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...
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.
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 *))
void infer_input_bounds(JITUserContext *context, const std::vector< int32_t > &sizes, const Target &target=get_jit_target_from_environment(), const ParamMap &param_map=ParamMap::empty_map())
Variants of infer_inputs_bounds that take a custom user context.
std::vector< Func > outputs() const
Get the Funcs this pipeline outputs.
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 *))
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...
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_...
JITHandlers & jit_handlers()
Get a struct containing the currently set custom functions used by JIT.
void set_custom_trace(int(*trace_fn)(void *, const halide_trace_event_t *))
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.
void infer_input_bounds(JITUserContext *context, RealizationArg output, const Target &target=get_jit_target_from_environment(), const ParamMap &param_map=ParamMap::empty_map())
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:397
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.
HALIDE_NO_USER_CODE_INLINE void add_requirement(const Expr &condition, Args &&...args)
Definition: Pipeline.h:507
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:142
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:84
@ ExternalPlusMetadata
Visible externally. Argument metadata and an argv wrapper are also generated.
@ Internal
Not visible externally, similar to 'static' linkage in C.
class HALIDE_ATTRIBUTE_DEPRECATED("Use OutputFileType instead of Output") Output
Definition: Module.h:46
Type type_of()
Construct the halide equivalent of a C type.
Definition: Type.h:547
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
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
void * address() const
Definition: Pipeline.h:590
ExternCFunction(void *address, const ExternSignature &signature)
Definition: Pipeline.h:581
const ExternSignature & signature() const
Definition: Pipeline.h:593
ExternCFunction(RT(*f)(Args... args))
Definition: Pipeline.h:586
ExternSignature(const Type &ret_type, bool is_void_return, const std::vector< Type > &arg_types)
Definition: Pipeline.h:526
friend std::ostream & operator<<(std::ostream &stream, const ExternSignature &sig)
Definition: Pipeline.h:553
const Type & ret_type() const
Definition: Pipeline.h:540
const std::vector< Type > & arg_types() const
Definition: Pipeline.h:549
ExternSignature(RT(*f)(Args... args))
Definition: Pipeline.h:534
bool is_void_return() const
Definition: Pipeline.h:545
A reference-counted handle to a statement node.
Definition: Expr.h:417
JITExtern(const Func &func)
const Pipeline & pipeline() const
Definition: Pipeline.h:615
const ExternCFunction & extern_c_function() const
Definition: Pipeline.h:618
JITExtern(Pipeline pipeline)
JITExtern(RT(*f)(Args... args))
Definition: Pipeline.h:611
JITExtern(const ExternCFunction &extern_c_function)
A set of custom overrides of runtime functions.
Definition: JITModule.h:33
A context to be passed to Pipeline::realize.
Definition: JITModule.h:134
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(Buffer< T, Dims > &a, Args &&...args)
Definition: Pipeline.h:126
RealizationArg(halide_buffer_t *buf)
Definition: Pipeline.h:113
HALIDE_NO_USER_CODE_INLINE RealizationArg(Buffer< T, Dims > &dst)
Definition: Pipeline.h:121
RealizationArg(RealizationArg &&from)=default
RealizationArg(Runtime::Buffer< T, Dims > &dst)
Definition: Pipeline.h:117
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:266
The raw representation of an image passed around by generated Halide code.