From 3edb2e9d64baf0f8442e86233eda46c993329191 Mon Sep 17 00:00:00 2001 From: Junru Shao Date: Mon, 26 Jul 2021 22:57:57 +0000 Subject: [PATCH] [RFC] Meta Schedule (AutoTIR) Co-authored-by: Siyuan Feng Co-authored-by: Bohan Hou <32121147+spectrometerHBH@users.noreply.github.com> Co-authored-by: Ruihang Lai Co-authored-by: Hongyi Jin <3231950289@qq.com> Co-authored-by: Wuwei Lin Co-authored-by: Cody Yu Co-authored-by: Tristan Konolige Co-authored-by: Andrew Reusch --- resources/meta-schedule-workflow.png | Bin 0 -> 42034 bytes rfcs/0001-meta-schedule-autotensorir.md | 604 ++++++++++++++++++++++++ 2 files changed, 604 insertions(+) create mode 100644 resources/meta-schedule-workflow.png create mode 100644 rfcs/0001-meta-schedule-autotensorir.md diff --git a/resources/meta-schedule-workflow.png b/resources/meta-schedule-workflow.png new file mode 100644 index 0000000000000000000000000000000000000000..300b9eb8c94164a47db91e1a353bddee6086551e GIT binary patch literal 42034 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 literal 0 HcmV?d00001 diff --git a/rfcs/0001-meta-schedule-autotensorir.md b/rfcs/0001-meta-schedule-autotensorir.md new file mode 100644 index 00000000..79c192d8 --- /dev/null +++ b/rfcs/0001-meta-schedule-autotensorir.md @@ -0,0 +1,604 @@ + + + + + + + + + + + + + + + + + +* Feature Name: Meta Schedule (Formerly AutoTIR) +* Start Date: 2021-05-28 +* RFC PR: https://github.com/apache/tvm-rfcs/pull/5/ +* GitHub Issue: https://github.com/apache/tvm/issues/8473 + +## 1. Summary + +This proposal introduces Meta Schedule: a scheduling DSL on TIR that unifies the +approaches of AutoTVM [1] and AutoScheduler [2]. Meta schedule provides a pragmatic way to define +the space of automatic tuning, extensibility in terms of all possible TIR schedule primitives like +tensorization and loop partitioning, and customizability on every layer of the automation system. + +Meta Schedule is the 3rd generation automatic scheduling system. + +## 2. Motivation + +**Scheduling.** In TVM, +both TensorIR and TE allow direct or indirect IR transformation guided by a +developer-provided program, for example, +specifying a particular reordering of loops for better locality, +or tensorizing a compute region with specific hardware intrinsics. +The process of invoking such a set of pre-defined transformations is called "**scheduling**", +and each of such transformations is called a "**schedule primitive**". +These primitives form a domain-specific language (DSL). + +**Design space.** The set of all possible schedulings of a TE/TensorIR is called its design space. +Optimization in TVM is essentially exploring such space to find out a scheduling that transforms the +IR to generate the kernel with optimal performance. + +### Problems with the current scheduling system + +Currently there are 3 sets of scheduling APIs in TVM: +* **Manual schedule**: Developers optimize their programs by manually invoking schedule primitives, + i.e. explore points in the design space with humans in the loop. This can be a tedious and + error-prone approach, hence the creation of AutoTVM and AutoScheduler. +* **AutoTVM**: The automation system requires users to define the design space through + per-operator "schedule templates." Therefore, programmer time is a bottleneck in scaling + to hundreds of operators across many hardware platforms. + hardware platforms. +* **AutoScheduler**: It automatically generates schedule templates as the design space, + according to a set of predefined "search rules". However, it is non-trivial to extend + AutoScheduler to new schedule primitives (tensorize, loop partition, software pipelining, etc). +* The three systems above have isolated sets of APIs with several layers of their own abstraction, + which are not only hard to learn, but also engineering-intensive to customize. + +### Benefits of Meta Schedule + +The existing three scheduling systems are mutually incompatible with each other in terms of API +design and divergence: besides manual TE scheduling, AutoTVM requires users to learn a new set of +APIs, and AutoScheduler brings in another set of C++-based search rules. It adds the users' mental +overhead to understand and extend the existing systems. Further, the inability to switch between +template-based and template-free auto-tuning could lead to inferior customizability and hence +make it needlessly difficult to achieve optimal performance. + +Meta schedule provides: +* Succinct syntax, consistent APIs to TensorIR schedule with no other layer of abstraction. +* Unified APIs for implementing manual schedules, AutoTVM-style schedules, and AutoScheduler-style + schedules. +* Extensibility of all the schedule primitives, including tensorization and loop partitioning. + Almost no extra effort is needed to use a new primitive in auto-tuning. +* The automation infrastructure is extensible on every of its components. Every component of the + system can be customized easily in pure python or C++ or both. For example, one can develop a new + design space generator in python, a new ProgramRunner in python, etc. + + +## 3. Guide-level explanation + +Meta Schedule DSL is a language that provides TVM backend developers +a flexible way to define or auto-generate the operator design space. + +This section introduces the syntax of Meta Schedule DSL by describing the 5 common usage patterns +envisioned by this RFC. These patterns are: +1) Manually constructing a schedule using existing schedule primitives (Section 3.1); +2) Defining composite schedule to simplify the ap sequence of schedule primitives (Section 3.2); +3) Describing a design space of possible schedules, +a.k.a. AutoTVM-style schedule templates (Section 3.3); +4) Automatically generating the design space, a.k.a. AutoScheduler-style search rules (Section 3.4); +5) Mixing the usage of manual schedule, AutoTVM and AutoScheduler-style design space specification +in Meta Schedule (Section 3.5). + +### 3.1. Manual Schedule + +Meta schedule APIs are almost the same as TE or TensorIR scheduling. Here is an example of a manual +schedule for matrix multiplication: + +```python +# Designate a set of tile sizes +i_tiles = [16, 8, 8, 8] +j_tiles = [16, 8, 8, 8] +k_tiles = [256, 8] + +# Tile the loops according to the tile sizes +i_0, i_1, i_2, i_3 = sch.split(loop=i, factors=i_tiles) +j_0, j_1, j_2, j_3 = sch.split(loop=j, factors=j_tiles) +k_0, k_1 = sch.split(loop=k, factors=k_tiles) + +# Organize the loops into "SSRSRS" 6-level tiles +sch.reorder( + i_0, j_0, # S: the 1st spatial tile + i_1, j_1, # S: the 2nd spatial tile + k_0, # R: the 1st reduction tile + i_2, j_2, # S: the 3rd spatial tile + k_1, # R: the 2nd reduction tile + i_3, j_3, # S: the 4th spatial tile +) +``` + +In this manual scheduling example, the developers tweak the tile sizes and measure the performance of the +generated kernels to explore the opportunities of potential optimization. + +Generally speaking, while writing a schedule, there are often some parameters that are hard to +determine ahead of time, for example, tile sizes, unroll steps, or which tensor intrinsics to use. +Developers may manually enumerate possible combinations of these unknown factors, and then pick the +best schedule according to measurement results on their device. + +### 3.2. Composite Schedule Rules + +As introduced in the previous section, in TensorIR, each schedule primitive handles only a very +basic transformation of the IR. For example, `split` only splits a loop into two new loops. In the +real world, the over-fine granularity of those primitives usually leads to repetitive and verbose +scheduling code. Take the code snippet in the previous section as an example: a sequence of `split`s +are invoked, followed by a `reorder`. Taken together these 4 primitives are colloquially known as +"SSRSRS" tiling. + +To make it more convenient and modular, users are allowed to register **composite schedules** that apply +a sequence of schedule primitives according to certain analysis of the IR. +The word **composite** here means the schedule transformation is *composed* of those **primitives**. + +For example, suppose there is a composite schedule called `Inline-Elementwise-Operation`, which +inlines elementwise computation into their consumers if possible. Applying it to the +following TensorIR: + +```python +@tvm.script.tir +def example_func(...): + for i, j in ...: + with tir.Block("B") ...: + B[i, j] = A[i, j] + 1 + for i, j in ...: + with tir.Block("C") ...: + C[i, j] = B[i, j] + 1 + for i, j in ...: + with tir.Block("D") ...: + D[i, j] = C[i, j] + 1 + +sch = tir.Schedule(example_func) +# `InlineElementwiseOperation` is a composite schedule rule that analyzes a given block. +# If the block contains only elementwise computation, and can be inlined into its consumer, +# then `sch.compute_inline` is called on that block. +inliner = InlineElementwiseOperation() +inliner.apply(schedule=sch, block=sch.get_block("B")) +inliner.apply(schedule=sch, block=sch.get_block("C")) +inliner.apply(schedule=sch, block=sch.get_block("D")) +``` + +Below is the result after applying this composite schedule, and its corresponding trace: + +```python + +>>> print(tvm.script.asscript(sch.mod)) +@tvm.script.tir +def example_func(...): + for i, j in ...: + with tir.Block("D") ...: + D[i, j] = A[i, j] + 1 + 1 + 1 + +>>> print(sch.trace) +# Block "B" is elementwise and inlinable, then `sch.compute_inline(B)` is called +B = sch.get_block("B") +sch.compute_inline(B) +# Block "C" is elementwise and inlinable, then `sch.compute_inline(C)` is called +C = sch.get_block("C") +sch.compute_inline(C) +# Block "D" is elementwise but does not have a consumer, +# so the rule does not call `compute_inline` because it is not inlinable +D = sch.get_block("D") +``` + +### 3.3. AutoTVM-style Design Space Description + +Meta schedule extends the schedule DSL with a set of new schedule primitives +called **sampling instructions**. These primitives do not transform the TensorIR, +but instead introduce random statistical variables which can be referenced later in scheduling +to parameterize the schedule. Incorporating **sampling instructions** into a operator's schedule +allows the backend developers to succinctly describe a design space in terms of +tiling strategies, fusion levels, unroll lengths, etc. + +The matmul example above is extended to cover all possible tilings using these sampling +instructions: + +```python +# Sample tile sizes +i_tiles = sch.sample_perfect_tile(i, n=4) # was: i_tiles = [16, 8, 8, 8] +j_tiles = sch.sample_perfect_tile(j, n=4) # was: j_tiles = [16, 8, 8, 8] +k_tiles = sch.sample_perfect_tile(k, n=2) # was: k_tiles = [256, 8] +# Tile the loops according to the random variables +i_0, i_1, i_2, i_3 = sch.split(loop=i, factors=i_tiles) +j_0, j_1, j_2, j_3 = sch.split(loop=j, factors=j_tiles) +k_0, k_1 = sch.split(loop=k, factors=k_tiles) +# Organize the loops into "SSRSRS" 6-level tiles +sch.reorder( + i_0, j_0, # S: the 1st spatial tile + i_1, j_1, # S: the 2nd spatial tile + k_0, # R: the 1st reduction tile + i_2, j_2, # S: the 3rd spatial tile + k_1, # R: the 2nd reduction tile + i_3, j_3, # S: the 4th spatial tile +) +``` + +### 3.4. AutoScheduler-style Design Space Generation + +To generate design space, AutoScheduler applies a set of rules to each +[TE stage](https://tvm.apache.org/docs/api/python/te.html#tvm.te.Stage) that corresponds to a +[TE operation](https://tvm.apache.org/docs/api/doxygen/classtvm_1_1te_1_1Operation.html), +defined by [`te.compute(...)`](https://tvm.apache.org/docs/api/python/te.html#tvm.te.compute). +The rules analyze the TE operations and apply an [internal DSL]() to manipulating its internal IR, +which is in the end mapped to TE schedule primitives. This process is called *sketch generation*. + +Composite schedule rules work in a similar way scheduling TensorIR, as introduced in Section 3.2. +It analyzes the TensorIR and apply schedule primitives directly to TensorIR accordingly. +When applying such rules to each TensorIR block in certain order (Post-DFS is provided as the +builtin order, but customization is allowed), +it generates a sequence of schedule primitives. +This process corresponds to the *sketch generation* phase in AutoScheduler. +If sampling instructions are present in this sequence, +then a design space is defined by those instructions for the meta schedule to explore. +This process is similar to the *random annotation* phase in AutoScheduler. + +Several built-in composite schedule rules are shipped with meta schedule to align with the design +space generated by AutoScheduler: + +* Multi-level tiling +* Inline pure spatial blocks +* Parallelize & vectorize & unroll +* Auto tensorize + +Developers may implement their own rules in either Python or C++. They may specify which rules to +use with the following syntax: + +```python +from tvm import meta_schedule as ms + +design_space_generator = ms.PostOrderApply(rules=[ + ms.MultiLevelTiling(...), + CustomRule(...), + ms.OtherBuiltinRules(...), +]) + +``` + +### 3.5. Unifying manual schedule / AutoTVM / AutoScheduler + +This subsection shows that the design space induced by TE manual schedule, AutoTVM and AutoScheduler +are all subsets of meta schedule, and meta schedule further allows mixing those three styles to +search jointly. + +- **Manual schedule**. The TE schedule is a special case of a meta schedule program, where there is no +randomness introduced by sampling instructions. It is a single point in terms of design space. +- **AutoTVM (Template-based tuning)**. It is more natural representation of AutoTVM’s schedule +templates (knobs) by writing one or more schedule functions in meta schedule with sampling +instructions. The probability space supported by the sampling instructions is the design space to +be explored. +- **AutoScheduler (Template-free tuning)**. As mentioned in the previous section, application + of composite schedule rules generates the design space, which is equivalent to AutoScheduler’s + sketch generation. +- **Mixing styles in design space definition**. By taking union of the spaces induced by the three + special cases, meta schedule allows developers to combine generic rules that AutoScheduler + provides and operator-specific scheduling. + +## 4. Reference-level explanation + +This section introduces the underlying techniques for the automation system to extract and +explore the design space. The figure below briefly illustrates the workflow of the system: + +![meta-schedule-workflow](../resources/meta-schedule-workflow.png) + +### 4.1. Execution trace as the design space + +**Trace**. To represent the design space defined by the meta schedule DSL, the underlying system +records all the instructions users applied to the schedule class, including sampling and schedule +primitives. This list of scheduling instructions being invoked, along with the random decisions made +on sampling instructions, is called a trace. + +For instance, executing the example above results in the following trace: + +``` +Instruction 0. Sample-Perfect-Tile +Instruction 1. Sample-Perfect-Tile +Instruction 2. Sample-Perfect-Tile +Instruction 3. Split +Instruction 4. Split +Instruction 5. Split +Instruction 6. Reorder +``` + +**Trace forms design space.** A trace may contain zero or more sampling instructions, which +introduces the uncertainty in scheduling - one instance of sampling results in one point in the +design space. Therefore, the trace itself forms a design space to explore, e.g. which set of tile +sizes works best on a specific hardware. + +**Union of design space**. Meta schedule works on a set of traces, representing the union of the design +spaces represented by every single trace. + +**Fork a trace**. When two different decisions in the scheduling process are equally important to +generate high-performance schedules, it is allowed to fork the trace into two, and the design space is +the union of the forked traces. + +The trace is not strictly user-facing, but can be accessed and printed with the following syntax: + +```python +# requires to trace the execution +sch = tir.Schedule(..., traced=True) +# do a lot of scheduling +... +# print the trace +print(sch.trace) +``` + +And below is an example of the printed trace, which honestly reflects the schedule as a snippet of +python scheduling function: + +```python +b0 = sch.get_block(name="matmul", func_name="main") +l1, l2, l3 = sch.get_loops(block=b0) +v4, v5, v6, v7 = sch.sample_perfect_tile(loop=l1, n=4, max_innermost_factor=16, decision=[32, 1, 16, 2]) +v8, v9, v10, v11 = sch.sample_perfect_tile(loop=l2, n=4, max_innermost_factor=16, decision=[64, 4, 2, 2]) +v12, v13 = sch.sample_perfect_tile(loop=l3, n=2, max_innermost_factor=16, decision=[64, 16]) +l14, l15, l16, l17 = sch.split(loop=l1, factors=[v4, v5, v6, v7]) +l18, l19, l20, l21 = sch.split(loop=l2, factors=[v8, v9, v10, v11]) +l22, l23 = sch.split(loop=l3, factors=[v12, v13]) +sch.reorder(l14, l18, l15, l19, l22, l16, l20, l23, l17, l21) +``` + +**Implementation.** A trace is defined as: + +```python +class Trace: + instructions: List[Instruction] + decisions: Dict[Instruction, Any] +``` + +For each sampling instruction in the trace, if it has a corresponding entry in the decisions dict, +then the output is uniquely determined by the decision, hence reproducibility is guaranteed +(Example 1); If a corresponding entry is not presented, then randomness will be introduced by +interpreting the trace (Example 2). + +```python +# Example 1. Trace with deterministic result +l1, l2 = sch.sample_perfect_tile(loop, n=2, decisions=[4, 32]) # Deterministic l1 = 4, l2 = 32 +# Example 2. Trace with randomized result +l1, l2 = sch.sample_perfect_tile(loop, n=2) # l1 and l2 are random +``` + +### 4.2. Exploring the Design Space + +Meta Schedule provides several built-in exploration strategies to exhaustively or efficiently search +for efficient schedules. Those strategies are mostly supported by re-execute either a function or a +trace with a builtin interpreter in meta schedule, and this process is called **replay**. + +#### Random search by replaying schedule functions + +With a user-provided schedule function +as a black-box design space generator, meta schedule repetitively invokes such an opaque TVM +packed function without doing any extra analysis. +If sampling instructions are present in the trace, then scheduling is non-deterministic +(random decisions may not be repeated across runs) +Effectively, it is equivalent to random exploration without trace, +allowing the flexibility for users to define arbitrary functions +that trace may not well support (e.g. control flow divergence based on the value of intermediate +random variables), but it forbids future opportunity of any trace-based analysis. + +#### Random search by replaying traces + +A builtin interpreter directly replays the traces obtained +from manual schedule, template-based or template-free design space generation. +If sampling instructions are present in the traces, +then their random decisions are mutated during each replay, i.e. jumps to a new point in the +design space. Therefore, repetitive replay of those traces are equivalent to exploration of the +design space. + +The search speed of meta schedule could be improved by allowing traces to be analyzed before they +are run. For example, trace analysis could reject obviously-invalid schedules (e.g. using too many +CUDA resource), remove dead-code before they are run. The cost model could benefit from the traces +as well by extracting trace-level features. + +#### Cost-model-guided evolutionary search + +A more efficient exploration strategy introduced by AutoScheduler. +For more details, please refer to Section 5.1 of its paper [2]. + +The evolutionary search strategy requires two sets of rule-specific logic to execute to +either validate or tweak the produced schedule: + +* Mutator: defines how to jump to a point’s "neighbor" in the design space +* Postprocessor: after the trace is executed, there are some extra rules to execute, for + example: + * Check CUDA resource limits: There is a hard requirement in CUDA that the maximum number of + threads should not exceed 1024, but it is a random variable that cannot be determined before + actually executing the trace. In this case, a postprocessor is implemented to error out when + such conditions are not satisfied. + * Fuse outer loops until the extent of the fused loops is large enough: The number of outer loops + to be fused together depends on their extents, which are random variables. In this case, the + composite schedule rule annotates the maximum extent allowed on the block, and a corresponding + postprocessor detects the annotation and does the actual fusion. + +The evolutionary search algorithm uses mutators to find possible schedules in the design space, then +applies postprocessors and asks the cost model to predict its performance. After a few +iterations, the new schedules with the highest scores are finally compiled and measured on device. +Epsilon-greedy is used in this process to balance exploitation and exploration. + +### 4.3. Database + +All the measure records are serialized and stored in a database. The schema of the database has the +following information: + +- The workload, a serialized TensorIR; +- The hardware target where the measure is conducted; +- Argument type: the shapes and dtypes of the input tensors fed to the measured PrimFunc. +This field can be useful for future dynamic-shape workloads; +- The trace, including the schedule primitives used and their corresponding decisions (if any); +- The measured running time; +- The version of the log. + +### 4.4. Python-first for flexibility & customizability + +The system is implemented in a way that all levels are decoupled and open to customization, aiming +at providing a playground for developers to try out new ideas and potentially deliver performance +quickly. + +While all the important APIs are implemented in C++ for efficiency, every part of the system can be +easily switched to customized python implementation. For example, + +#### Customize design space in python + +The design space can be defined as a python function + +```python +def schedule_matmul(sch) -> sch: + i, j, k = sch.get_loops(sch.get_block("matmul")) + i_tiles = sch.sample_perfect_tile(i, n=4) + j_tiles = sch.sample_perfect_tile(j, n=4) + k_tiles = sch.sample_perfect_tile(k, n=2) + # Tile the loops according to the random variables + i_0, i_1, i_2, i_3 = sch.split(loop=i, factors=i_tiles) + j_0, j_1, j_2, j_3 = sch.split(loop=j, factors=j_tiles) + k_0, k_1 = sch.split(loop=k, factors=k_tiles) + # Organize the loops into "SSRSRS" 6-level tiles + sch.reorder( + i_0, j_0, # S + i_1, j_1, # S + k_0, # R + i_2, j_2, # S + k_1, # R + i_3, j_3, # S + ) + return sch +``` + +#### Customize composite schedule in python + +The system provides two interfaces to define a composite schedule in python, one is more succinct, +and the other is more comprehensive: + +Method 1. Derive from `PyCompositeSchedule`, and implement two methods `initialize` and `apply`: + +```python +class MultiLevelTiling(PyCompositeSchedule): + def initialize(...): + # initialize the class, usually this method is empty + ... + + def apply(sch: Schedule, block: BlockRV) -> Union[Schedule, List[Schedule]]: + # write any python code, including: + # - analyze `block` + # - invoke schedule primitives in `sch` + # - do debug printing + ... +``` + +Method 2. A decorator as the syntactic sugar if the `initialize` method is empty, which converts the +function to the `apply` method. + +```python +@tir.as_composite_schedule(name="multi-level-tiling") +def multi_level_tiling(sch: Schedule, block: BlockRV) -> Union[Schedule, List[Schedule]]: + # write any python code, including: + # - analyze `block` + # - invoke schedule primitives in `sch` + # - do debug printing + ... +``` + +#### Customize exploration strategies in python + +Developers can implement any search algorithm in python as well by deriving from `PySearchPolicy`, +and the syntax is identical to customizing with `PyCompositeSchedule`. + +#### Other customizable components + +This list includes: + +* Cost model +* Database +* Measure callbacks +* Feature extractor +* Program builder & runner +* Analysis methods +* ... + +In a short summary, almost every component of the system is decoupled with each other and extensions +could be easily plugged in. + +## 5. Drawbacks + +Meta schedule requires integration with Relay operator strategy and compile engine (TECompiler) to +properly lower a Relay subgraph for task extraction. Further, TE schedules in TOPI will need to be +migrated to TensorIR schedules. + +## 6. Rationale and alternatives + +The system is designed with the principle of minimalism: Assuming users already know TensorIR +scheduling APIs, there is no more extra API set to learn; The previous programs that schedules +TensorIR still work out of box with the meta schedule DSL. It could potentially lower the bar of +adopting this system. + +Unifying manual scheduling, AutoTVM's semi automatic templates and AutoScheduler's fully automatic +sketch generation provides flexible way to balance injection new domain knowledge and automation. + +Flexibility in customization allows quick try-out on new tasks, new strategies and new hardware +targets without deep knowledge of the system. + +## 7. Prior art + +**Tensor Expression (TE)** in TVM is a DSL that decouples compute and schedule, which provides +convenient ways to handcraft optimized kernels for different hardware targets. + +**TensorIR** is the low-level IR in TVM. Its capability of eagerly applying schedule primitives +opens the door for meta schedule, the proposed next-generation auto scheduling system. + +**AutoTVM** is the 1st generation automation framework in TVM, which requires developers to +implement per-operator scheduling templates, and the system could handle the tuning process. + +**AutoScheduler** is the 2nd generation automation framework in TVM, whose built-in rules +could automatically generate schedule templates for almost all the operators on CPU, GPU, etc. + +## 8. Unresolved questions + +**Control Flow** + +The meta schedule DSL does not support control flow yet. Although there is no report of +real-world use case at the time of writing, it is possible that it could appear in some future +workloads. The best syntax of the control flow is not determined yet, but a working example could be +TensorFlow's `tf.cond`. + +**Assertion** + +Sampling instructions may lead to wrong schedules on CUDA, e.g. the resulting program uses too much +shared memory, too many threads, etc. It is detected by a postprocessor. To accelerate the process, +it is possible to introduce an assertion statement that exits early if the GPU code is not valid, +and its syntax can be, for example: + +```python +sch.assert(j_2 * j_2 <= 1024) +``` + +## 9. Future possibilities + +**Unifying Manual Scheduling, AutoTVM and AutoScheduler in TOPI** + +As described in Section 3.5, meta schedule provides an idiomatic approach to unify the three +existing scheduling APIs in TVM: + +* Manual schedules are meta schedules without sampling instructions; +* AutoTVM templates are meta schedules where knobs are replaced by sampling instructions; +* Each of AutoScheduler’s search rules generates a snippet of a meta schedule; +* Mixture of the above three approaches to cover larger design space. + +At the time of writing, TOPI contains a number of schedule functions implemented either in manual TE +or AutoTVM-style. It is our future work to unify these existing scheduling APIs on TOPI operators, +and enable different styles to be auto-tuned jointly. + +[1] Zheng, Lianmin, et al. "Ansor: Generating high-performance tensor programs for deep learning." +14th {USENIX} Symposium on Operating Systems Design and Implementation ({OSDI} 20). 2020. + +[2] Chen, Tianqi, et al. "Learning to Optimize Tensor Programs." Advances in Neural Information +Processing Systems 31 (2018): 3389-3400.