688 lines
27 KiB
C++
688 lines
27 KiB
C++
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
/*!
|
|
* \file tvm/relax/transform.h
|
|
* \brief Relax specific transformation passes.
|
|
*/
|
|
#ifndef TVM_RELAX_TRANSFORM_H_
|
|
#define TVM_RELAX_TRANSFORM_H_
|
|
|
|
#include <tvm/ffi/reflection/registry.h>
|
|
#include <tvm/ir/transform.h>
|
|
#include <tvm/relax/dataflow_pattern.h>
|
|
#include <tvm/relax/expr.h>
|
|
#include <tvm/tirx/function.h>
|
|
#include <tvm/tirx/index_map.h>
|
|
|
|
namespace tvm {
|
|
namespace relax {
|
|
namespace transform {
|
|
|
|
using Pass = tvm::transform::Pass;
|
|
using PassInfo = tvm::transform::PassInfo;
|
|
using PassContext = tvm::transform::PassContext;
|
|
using Function = tvm::relax::Function;
|
|
using DataflowBlock = tvm::relax::DataflowBlock;
|
|
using tvm::transform::CreateModulePass;
|
|
using LayoutCb = ffi::TypedFunction<ffi::Map<ffi::String, ffi::Array<ffi::String>>(Call)>;
|
|
|
|
/*!
|
|
* \brief Create a function pass.
|
|
*
|
|
* \param pass_func The packed function that contains the optimization.
|
|
* \param opt_level The optimization level of the function pass.
|
|
* \param name The name of the function pass.
|
|
* \param required The list of the passes that the function pass is dependent on.
|
|
* \param traceable Boolean variable whether the dataflowblock pass is traceable.
|
|
*
|
|
* \return The created function pass.
|
|
*/
|
|
TVM_DLL Pass CreateFunctionPass(std::function<Function(Function, IRModule, PassContext)> pass_func,
|
|
int opt_level, ffi::String name,
|
|
tvm::ffi::Array<ffi::String> required, bool traceable = false);
|
|
|
|
/*!
|
|
* \brief Create a dataflowblock pass.
|
|
*
|
|
* \param pass_func The packed function that contains the optimization.
|
|
* \param opt_level The optimization level of the dataflowblock pass.
|
|
* \param name The name of the dataflowblock pass.
|
|
* \param required The list of the passes that the dataflowblock pass is dependent on.
|
|
* \param traceable Boolean variable whether the dataflowblock pass is traceable.
|
|
*
|
|
* \return The created dataflowblock pass.
|
|
*/
|
|
TVM_DLL Pass CreateDataflowBlockPass(
|
|
std::function<DataflowBlock(DataflowBlock, IRModule, PassContext)> pass_func, int opt_level,
|
|
ffi::String name, tvm::ffi::Array<ffi::String> required, bool traceable = false);
|
|
|
|
/*!
|
|
* \brief Perform lambda lifting to lift functions from nested into global.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass LambdaLift();
|
|
|
|
/*!
|
|
* \brief Transform all dataflow structure to non-dataflow version.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass ToNonDataflow();
|
|
|
|
/*!
|
|
* \brief Activate force_pure on all pure functions in the module
|
|
* and unwrap all pure override ops into the normal versions.
|
|
*
|
|
* This effectively means that there will be no more purity tracking,
|
|
* useful for low-level code generation.
|
|
*
|
|
* \return The Pass.
|
|
*
|
|
* \note Should be used after ToNonDataflow()
|
|
*/
|
|
TVM_DLL Pass RemovePurityChecking();
|
|
|
|
/*!
|
|
* \brief Perform explicit tensor allocation for call_tir and call_dps_packed.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass CallTIRRewrite();
|
|
|
|
/*!
|
|
* \brief Convert all reshape-like call_tir whose corresponding binding
|
|
* vars are DataflowVars to relax.reshape operator calls. The relax.reshape
|
|
* calls will be lowered an external builtin function call in a subsequent
|
|
* pass, where the external builtin function does a CreateView operation
|
|
* at runtime, instead of doing real data copy.
|
|
* Here "reshape-like" includes reshape, expand_dims, flatten, etc.
|
|
*
|
|
* \return The Pass.
|
|
* \note The pass is applied at the first stage of Relax VM build, before
|
|
* rewriting call_tir, as this pass requires dataflow information.
|
|
*/
|
|
TVM_DLL Pass RewriteDataflowReshape();
|
|
|
|
/*!
|
|
* \brief The static memory planning pass on BindingBlock level.
|
|
* The pass will reuse allocated memory to its best effort, in order to
|
|
* reduce the total amount of allocated memory size.
|
|
*
|
|
* The pass "supports" dynamic shape in the way of TIR variable bound
|
|
* annotations. We can optionally annotate the attributes "tir_var_upper_bound"
|
|
* and "tir_var_lower_bound" to Relax functions. The attribute values are dicts
|
|
* from strings to integers, denoting the name of TIR variables to the bound
|
|
* values of the TIR vars.
|
|
* Note: The annotated bound attributes only apply to TIR vars in the
|
|
* function signature for clarity.
|
|
*
|
|
* For example, we can annotate a Relax function with
|
|
* `R.func_attr({"tir_var_lower_bound": {"n": 1}, "tir_var_upper_bound": {"n": 1024}})`.
|
|
* It means the variable that names "n" in the function signature will have
|
|
* range [1, 1024]. And we will use these bounds during memory planning.
|
|
* If lower bound is not specified, it defaults to 0.
|
|
*
|
|
* \return The pass.
|
|
*/
|
|
TVM_DLL Pass StaticPlanBlockMemory();
|
|
|
|
/*!
|
|
* \brief Attach global_symbol to Relax functions and TIR Primfuncs for codegen.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass AttachGlobalSymbol();
|
|
|
|
/*!
|
|
* \brief Transform Relax IR to normal form: transform AST to A-normal form, and fill the
|
|
* ty of expressions.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass Normalize();
|
|
|
|
/*!
|
|
* \brief Possibly rename the GlobalVar in an IRModule to ensure these properties:
|
|
* 1. (Invariant) First ensure every public function has the same name as its "global_symbol"
|
|
* attribute;
|
|
* 2. To ensure 1., we may need to rename private functions with conflicting names;
|
|
* 3. Finally, the name of every GlobalVar is unique in the IRModule.
|
|
*/
|
|
TVM_DLL Pass NormalizeGlobalVar();
|
|
|
|
/*!
|
|
* \brief Simplify a Relax module by folding var bindings and match shape nodes,
|
|
* as well as tuple indices.
|
|
* Best used alongside constant folding and eliminating unused bindings.
|
|
*
|
|
* \note If a dataflow var is used only in a binding to the dataflow block
|
|
* output var (i.e., a non-dataflow var), this pass will also remove the dataflow var
|
|
* and replaces the output var's binding with the dataflow var's direct definition.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass CanonicalizeBindings();
|
|
|
|
/*!
|
|
* Eliminate common subexpressions within functions.
|
|
* \return The pass that eliminates common subexpressions.
|
|
*
|
|
* \note For nested functions, this pass performs CSE *within* those functions.
|
|
* \param call_only If true, enable eliminating only call nodes.
|
|
*/
|
|
TVM_DLL Pass EliminateCommonSubexpr(bool call_only = false);
|
|
|
|
/*!
|
|
* \brief Bind params of function of the module to constant tensors.
|
|
*
|
|
* \param func_name The name of the function to bind parameters.
|
|
* \param params The parameters to bind.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass BindParams(ffi::String func_name, ffi::Map<Any, ffi::ObjectRef> params);
|
|
|
|
/*!
|
|
* \brief Bind symbolic vars to constant shape values.
|
|
*
|
|
* \param binding_map The dictionary of symbolic variables and their
|
|
* constant shape values. Dictionary keys may be either a
|
|
* `tirx.Var` or a string name of the variable. If the variables
|
|
* are referred to by name, the name must uniquely identify a
|
|
* symbolic variable in each function where it is used.
|
|
*
|
|
* \param func_name The name of the function in which to bind shape
|
|
* values. If std::nullopt, all functions in the module will be
|
|
* updated.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass BindSymbolicVars(ffi::Map<ffi::Variant<tirx::Var, ffi::String>, PrimExpr> binding_map,
|
|
ffi::Optional<ffi::String> func_name = std::nullopt);
|
|
|
|
/*!
|
|
* \brief Fold constant expressions within dataflow blocks.
|
|
*
|
|
* \note ConvertToDataflow may need to be called first to provide dataflow blocks.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass FoldConstant();
|
|
|
|
/*!
|
|
* \brief Legalize high-level operator calls in Relax functions to call_tir
|
|
* with corresponding low-level TIR PrimFuncs.
|
|
*
|
|
* For each high-level operator, we register the way of legalizing it as a
|
|
* function, which takes a context BlockBuilder and the Call being legalized
|
|
* as input, and returns the legalized call. Here the input BlockBuilder is
|
|
* mainly used for adding the PrimFunc created by call_te into the context
|
|
* IRModule.
|
|
*
|
|
* The legalization function for each operator is registered as an attribute (with
|
|
* attribute key `FLegalize`) of the operator.
|
|
*
|
|
* For customizability, the user can pass their own legalization by an optional customized map,
|
|
* with the key to be the operator name and value to be the legalization function.
|
|
* The default legalization function will be overridden by the customized one.
|
|
*
|
|
* \param cmap The customized operator legalization function map. The customized function
|
|
* will override the default one.
|
|
* \param skip_ops The list operator names which need to be skipped from legalization
|
|
* \param enable_warning A boolean value indicating if to print warnings for TIR functions not
|
|
* showing up in the database.
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass LegalizeOps(ffi::Optional<ffi::Map<ffi::String, ffi::Function>> cmap,
|
|
ffi::Optional<ffi::Array<ffi::String>> skip_ops,
|
|
bool enable_warning = false);
|
|
|
|
/*!
|
|
* \brief Propagate virtual device information.
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass RealizeVDevice();
|
|
|
|
/*!
|
|
* \brief Attach layout free buffers to the tirx::PrimFunc.
|
|
*
|
|
* This pass is used to attach layout free buffers to the tirx::PrimFunc according to
|
|
* the function usage in the relax function. Currently, the layout free buffers are the model
|
|
* weights and relax constants.
|
|
*
|
|
* \note We recommend applying CanonicalizeBindings before this pass.
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass AttachAttrLayoutFreeBuffers();
|
|
|
|
/*!
|
|
* \brief Split the layout rewrite preproc block to a separate tirx::PrimFunc.
|
|
*
|
|
* This pass is used in the prepack weight after meta_schedule tuning.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass SplitLayoutRewritePreproc();
|
|
|
|
/*!
|
|
* \brief Lift transformation of the parameters of a function.
|
|
*
|
|
* When some inputs of the function is marked as 'parameters' (the model weights), this pass
|
|
* identifies the transformation of the parameters and lifts them to a separate function called
|
|
* `transform_params`. `transform_params` takes a tuple of the original parameters as input and
|
|
* returns a tuple of the transformed parameters. The original function will be rewritten to accept
|
|
* a tuple of transformed parameters as input.
|
|
*
|
|
* Users are expected to invoke the `transform_params` function in runtime and pass the transformed
|
|
* parameters to the original function as input.
|
|
*
|
|
* \param shared_transform Indicates how the parameter transformation function will be produced.
|
|
* - `False` (default): A separate parameter transformation function will be produced for each
|
|
* function with the `"num_input"` attribute.
|
|
*
|
|
* - `True`: A single parameter transformation function will be produced, containing the
|
|
* preprocessing steps common across all functions with the `"num_input"` attribute.
|
|
*
|
|
* - List[str]: A single parameter transformation function will be produced, containing the
|
|
* preprocessing steps common across each function whose name is in the list. Passing a list of
|
|
* all functions with the `"num_input"` attribute or an empty list is equivalent to passing
|
|
* `True`.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass
|
|
LiftTransformParams(ffi::Variant<bool, ffi::Array<ffi::String>> shared_transform = false);
|
|
|
|
/*!
|
|
* \brief Update virtual device.
|
|
* \param new_vdevice The new virtual device.
|
|
* \param index The device index indicates the device on which the update will be performed.
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass UpdateVDevice(VDevice new_vdevice, int64_t index);
|
|
|
|
/*! \brief Expand tuple arguments to internal functions
|
|
*
|
|
* \return The Pass
|
|
*/
|
|
TVM_DLL Pass ExpandTupleArguments();
|
|
|
|
/*! \brief Remove unused parameters to internal functions
|
|
*
|
|
* \return The Pass
|
|
*/
|
|
TVM_DLL Pass RemoveUnusedParameters();
|
|
|
|
/*! \brief Remove unused outputs from internal functions
|
|
*
|
|
* \return The Pass
|
|
*/
|
|
TVM_DLL Pass RemoveUnusedOutputs();
|
|
|
|
/*!
|
|
* \brief Annotate Op Pattern Kind for TIR functions, which is used in FuseOps.
|
|
* \note It is an auto-detect pass for "unscheduled prim_funcs", the op_pattern will be
|
|
* "opaque" of we can't detect it. Users can manually annotate the attr `op_pattern`
|
|
* to prim_func.
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass AnnotateTIROpPattern();
|
|
|
|
/*!
|
|
* \brief This pass groups bindings in a dataflow block of Relax functions and generates a new
|
|
* grouped Relax function for each group, according to the fusion algorithm described in the pass
|
|
* implementation. By grouping bindings into new Relax functions, we substitute the bindings in the
|
|
* function being manipulated into function calls to the new grouped function.
|
|
*
|
|
* A follow-up pass named "FuseTIR" will generate a TIR PrimFunc for each grouped function.
|
|
* \param fuse_opt_level The level of fuse optimization.
|
|
* -1 indicates that the level will be inferred from pass context.
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass FuseOps(int fuse_opt_level = -1);
|
|
|
|
/*!
|
|
* \brief The pattern object used as the input of FuseOpsByPattern. For bindings to be
|
|
* fused, it needs to be matched with `pattern` and the `check` function needs to return
|
|
* true.
|
|
*/
|
|
class FusionPatternNode : public ffi::Object {
|
|
public:
|
|
/*!
|
|
* \brief The name of pattern. It becomes the value of the kComposite attribute
|
|
* of a fused function after successful matching
|
|
*/
|
|
ffi::String name;
|
|
|
|
/*!
|
|
* \brief The dataflow pattern that will be used to match expression in the DataflowBlock.
|
|
* All the call nodes covered by the pattern will be extracted into the fused function.
|
|
*/
|
|
DFPattern pattern;
|
|
|
|
/*!
|
|
* \brief The map which is used to extract important expressions from the pattern match
|
|
* result. All DFPattern in this map should be part of the `pattern`.
|
|
*/
|
|
ffi::Map<ffi::String, DFPattern> annotation_patterns;
|
|
|
|
/*!
|
|
* \brief The function to determine whether the match result is accepted. This can be
|
|
* std::nullopt if check function is not necessary for this pattern.
|
|
*
|
|
* It should have signature
|
|
* bool(const PatternCheckContext& context)
|
|
*/
|
|
ffi::Optional<ffi::Function> check;
|
|
|
|
/*!
|
|
* \brief The function to get attributes for fused function
|
|
*
|
|
* It should have signature
|
|
* ffi::Map<ffi::String, Any>(const ffi::Map<ffi::String, Expr>& context)
|
|
*/
|
|
ffi::Optional<ffi::Function> attrs_getter;
|
|
|
|
static void RegisterReflection() {
|
|
namespace refl = tvm::ffi::reflection;
|
|
refl::ObjectDef<FusionPatternNode>()
|
|
.def_ro("name", &FusionPatternNode::name)
|
|
.def_ro("pattern", &FusionPatternNode::pattern)
|
|
.def_ro("annotation_patterns", &FusionPatternNode::annotation_patterns)
|
|
.def_ro("check", &FusionPatternNode::check)
|
|
.def_ro("attrs_getter", &FusionPatternNode::attrs_getter);
|
|
}
|
|
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.transform.FusionPattern", FusionPatternNode,
|
|
ffi::Object);
|
|
};
|
|
|
|
class FusionPattern : public ffi::ObjectRef {
|
|
public:
|
|
FusionPattern(ffi::String name, DFPattern pattern,
|
|
ffi::Map<ffi::String, DFPattern> annotation_patterns,
|
|
ffi::Optional<ffi::Function> check, ffi::Optional<ffi::Function> attrs_getter);
|
|
|
|
FusionPattern(ffi::String name, DFPattern pattern)
|
|
: FusionPattern(name, pattern, {}, std::nullopt, std::nullopt) {}
|
|
|
|
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(FusionPattern, ffi::ObjectRef, FusionPatternNode);
|
|
};
|
|
|
|
/*!
|
|
* \brief The input of FusionPattern::check.
|
|
*/
|
|
class PatternCheckContextNode : public ffi::Object {
|
|
public:
|
|
/*!
|
|
* \brief The expression that's matched with the FusionPattern::pattern.
|
|
*/
|
|
Expr matched_expr;
|
|
|
|
/*!
|
|
* \brief A map which contains all expressions matched by the sub patterns in
|
|
* FusionPattern::annotation_patterns.
|
|
*/
|
|
ffi::Map<ffi::String, Expr> annotated_expr;
|
|
|
|
/*!
|
|
* \brief Map from variable to its value. It contains variables from bindings that
|
|
* is being fused by FuseOpsByPattern.
|
|
*/
|
|
ffi::Map<Var, Expr> matched_bindings;
|
|
|
|
/*!
|
|
* \brief A map mapping variable definitions to a set of uses. It has all variables
|
|
* used in the function.
|
|
*/
|
|
ffi::Map<Var, ffi::Array<Var>> var_usages;
|
|
|
|
/*!
|
|
* \brief Map from value to its bound variable. It doesn't have variables after the
|
|
* matched expression.
|
|
*/
|
|
ffi::Map<Expr, Var> value_to_bound_var;
|
|
|
|
static void RegisterReflection() {
|
|
namespace refl = tvm::ffi::reflection;
|
|
refl::ObjectDef<PatternCheckContextNode>()
|
|
.def_ro("matched_expr", &PatternCheckContextNode::matched_expr)
|
|
.def_ro("annotated_expr", &PatternCheckContextNode::annotated_expr)
|
|
.def_ro("matched_bindings", &PatternCheckContextNode::matched_bindings)
|
|
.def_ro("var_usages", &PatternCheckContextNode::var_usages)
|
|
.def_ro("value_to_bound_var", &PatternCheckContextNode::value_to_bound_var);
|
|
}
|
|
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("relax.transform.PatternCheckContext", PatternCheckContextNode,
|
|
ffi::Object);
|
|
};
|
|
|
|
class PatternCheckContext : public ffi::ObjectRef {
|
|
public:
|
|
PatternCheckContext(Expr matched_expr, ffi::Map<ffi::String, Expr> annotated_expr,
|
|
ffi::Map<Var, Expr> matched_bindings,
|
|
ffi::Map<Var, ffi::Array<Var>> var_usages,
|
|
ffi::Map<Expr, Var> value_to_bound_var);
|
|
|
|
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(PatternCheckContext, ffi::ObjectRef,
|
|
PatternCheckContextNode);
|
|
};
|
|
|
|
/*!
|
|
* \brief Reverse-mode automatic differentiation.
|
|
*
|
|
* This pass will differentiate one function in the IRModule. Now the input function must have only
|
|
* one dataflow block.
|
|
*
|
|
* For a given function specified by `func_name`, it generates a new function with the name
|
|
* `func_name + "_adjoint"`. The new function computes the gradient of the **differentiation
|
|
* target** with respect to the arguments specified by `require_grads` of the original function.
|
|
*
|
|
* If the function has only one return value, the return value will be specified as target. If the
|
|
* function has more than one return values, the target will be specified as the target_index-th
|
|
* return value. The target must be a scalar (0-dim tensor).
|
|
*
|
|
* \param func_name The name of the specified function.
|
|
* \param require_grads The relax variables whose adjoints is needed. Must be parameters of the
|
|
* given function and should not be duplicate. If it is not specified, adjoints of all parameters
|
|
* would be computed.
|
|
* \param target_index If the specified function has more than one return values, specify the index
|
|
* of the return value as the target. If it is not specified, the first return value will be the
|
|
* target.
|
|
* \return The Pass.
|
|
*
|
|
* \note ConvertToDataflow may need to be called first to provide dataflow blocks.
|
|
*/
|
|
TVM_DLL Pass Gradient(ffi::String func_name,
|
|
ffi::Optional<ffi::Array<Var>> require_grads = std::nullopt,
|
|
int target_index = 0);
|
|
|
|
/*!
|
|
* \brief Apply pattern matching to each function in the given module, and group matched
|
|
* expressions into a new function. The end result is similar to FuseOps, but fusion is driven
|
|
* completely by the provided patterns.
|
|
*
|
|
* \param patterns The patterns to detect. The order of the patterns determines the order
|
|
* of priority in which they are matched. Higher-priority patterns should come earlier in the list.
|
|
* \param bind_constants Whether or not to keep bound constants of the grouped function.
|
|
* \param annotate_codegen If true, wrap each created composite function with another function,
|
|
* whose body consists only of a call to the composite function, and annotate the outer function
|
|
* with kCodegen and kGlobalSymbol attributes. The kCodegen attribute is set as the prefix of the
|
|
* corresponding pattern name. For example, "dnnl" if the pattern name is "dnnl.conv2d_relu".
|
|
* This must be True if the created composite functions are intended to be offloaded to
|
|
* an external backend without using the MergeCompositeFunctions pass.
|
|
* \param entry_function_names The names of functions that should be considered as entry points. If
|
|
* not specified, all externally exposed functions will be considered as entry points.
|
|
* \return The Pass.
|
|
*
|
|
* \note Only operates within dataflow blocks. ConvertToDataflow may need to be called first.
|
|
*/
|
|
TVM_DLL Pass FuseOpsByPattern(const tvm::ffi::Array<FusionPattern>& patterns,
|
|
bool bind_constants = true, bool annotate_codegen = false,
|
|
const tvm::ffi::Array<ffi::String>& entry_function_names = {});
|
|
|
|
/*!
|
|
* \brief Group one or multiple composite functions created by FuseOpsByPattern into a new
|
|
* function. The new function will be annotated with kCodegen and GlobalSymbol attributes,
|
|
* and it is intented to be offloaded to an external backend.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass MergeCompositeFunctions();
|
|
|
|
/*!
|
|
* \brief Fuse relax sub-function into a larger TIR function if possible.
|
|
this pass works together with FuseOps to perform operator fusion.
|
|
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass FuseTIR();
|
|
|
|
/*!
|
|
* \brief Run codegen.
|
|
* \param target_options pairs of target name and compilation options
|
|
* \param entry_functions list of entry functions
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass
|
|
RunCodegen(ffi::Optional<ffi::Map<ffi::String, ffi::Map<ffi::String, ffi::Any>>> target_options,
|
|
ffi::Array<ffi::String> entry_functions);
|
|
|
|
/*!
|
|
* \brief Decompose composite operators during inference. For example, The result of batch norm (a
|
|
* triple) will be simplified. Operators like Attention, Erf, etc. can be also simplified into
|
|
* several operators as well.
|
|
*
|
|
* \param func_name The name of the specified function. If not specified, the pass will run in
|
|
* all functions.
|
|
*/
|
|
TVM_DLL Pass DecomposeOpsForInference(ffi::Optional<ffi::String> func_name);
|
|
|
|
/*!
|
|
* \brief Decompose composite operators during training. For example, The result of batch norm (a
|
|
* triple) will be simplified. Operators like Attention, Erf, etc. can be also simplified into
|
|
* several operators as well.
|
|
*
|
|
* \param func_name The name of the specified function. If not specified, the pass will run in
|
|
* all functions.
|
|
*/
|
|
TVM_DLL Pass DecomposeOpsForTraining(ffi::Optional<ffi::String> func_name);
|
|
|
|
/*!
|
|
* \brief Returns a pass which replaces PrimFuncs which have matching kOperatorName attribute in \p
|
|
* op_impl_map, with replacement PrimFunc that could possibly have different layouts on i/o
|
|
* buffers. The layout transformations on i/o buffers is present in the \p op_buffer_transforms. The
|
|
* pass inserts the layout transformations in the call sites of PrimFuncs being replaced to
|
|
* transform i/o buffers into expected layout.
|
|
*
|
|
* \param op_impl_map Map from kOperatorName attr (e.g., relax.conv2d) to replacement PrimFunc
|
|
* \param op_buffer_transforms Map from kOperatorName attr to layout transformations on each of the
|
|
* PrimFunc i/o buffers.
|
|
* \param axis_separators Map from kOperatorName attr to axis_separators of each buffer_transforms
|
|
* \param input_axis_separators Map from kOperatorName attr to axis_separator for input buffer
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass AlterOpImpl(
|
|
const ffi::Map<ffi::String, tirx::PrimFunc>& op_impl_map,
|
|
const ffi::Map<ffi::String, ffi::Array<tirx::IndexMap>>& op_buffer_transforms,
|
|
const ffi::Map<ffi::String, ffi::Optional<ffi::Array<ffi::Array<IntImm>>>>& axis_separators,
|
|
const ffi::Map<ffi::String, ffi::Optional<ffi::Array<ffi::Array<IntImm>>>>&
|
|
input_axis_separators);
|
|
|
|
/*!
|
|
* \brief Layout conversion pass.
|
|
* \param desired_layouts The desired layouts for some operators.
|
|
* \param layout_cb custom call back to define layouts dynamically.
|
|
* \return The Pass.
|
|
* \note Operates only on dataflow blocks. ConvertToDataflow may need to be called first.
|
|
*/
|
|
TVM_DLL Pass ConvertLayout(ffi::Map<ffi::String, ffi::Array<ffi::String>> desired_layouts,
|
|
LayoutCb layout_cb);
|
|
|
|
/*!
|
|
* \brief A pass that converts consecutive dataflow operations
|
|
* inside binding blocks into dataflow blocks.
|
|
* \param min_size The minimum number of consecutive dataflow bindings
|
|
* required for the pass to create a new dataflow block
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass ConvertToDataflow(int min_size = 2);
|
|
|
|
/*!
|
|
* \brief Dead code elimination.
|
|
* \sa RemoveAllUnused
|
|
* Currently it removes:
|
|
* 1. Unused local VarBindings
|
|
* (those where the bound var is unused and no impure operation is used).
|
|
* 2. Unused Relax functions in the module.
|
|
* We detect the call chain from the entry function, and remove all unused functions.
|
|
*
|
|
* Any binding blocks that are left empty will be removed by the normalizer.
|
|
*
|
|
* \param entry_functions Names of functions that should be considered
|
|
* as entry points, in addition to any externally exposed functions.
|
|
*
|
|
* \return The Pass.
|
|
*/
|
|
TVM_DLL Pass DeadCodeElimination(ffi::Array<ffi::String> entry_functions = {});
|
|
|
|
/*!
|
|
* \brief Pass that changes calls to operators that can be done in-place
|
|
* (generally, these are elementwise operations) in dataflow blocks into in-place implementations.
|
|
* Supported operators will be replaced by calls to `call_tir_inplace` that invoke in-place
|
|
* PrimFunc implementations of those operators (which are based on the legalizations of those
|
|
* operators).
|
|
* \note ConvertToDataflow may need to be called first to provide dataflow blocks.
|
|
* \return The pass.
|
|
*/
|
|
TVM_DLL Pass DataflowUseInplaceCalls();
|
|
|
|
/*!
|
|
* \brief Automatic mixed precision pass. Currently the pass assumes the input module to be fp32
|
|
* only, and will automatically cast fp32 to fp16 for certain ops.
|
|
* \param out_dtype The output data type of gemm/conv, which is the data type of the accumulator.
|
|
* \param fp16_input_names The names of function parameters whose dtype should become fp16. The
|
|
* function signature would change accordingly.
|
|
* \return The Pass.
|
|
*
|
|
* \note Mainly operates within dataflow blocks. ConvertToDataflow may need to be called first.
|
|
*/
|
|
TVM_DLL Pass ToMixedPrecision(
|
|
DLDataType out_dtype, ffi::Optional<ffi::Array<ffi::String>> fp16_input_names = std::nullopt);
|
|
|
|
/*!
|
|
* \brief Rewrite a Relax module for executing with CUDA graph. This pass identifies
|
|
* the regions that can be executed with CUDA graph and lifts them into new functions for runtime
|
|
* graph capturing.
|
|
*/
|
|
TVM_DLL Pass RewriteCUDAGraph();
|
|
|
|
/*!
|
|
* \brief This pass updates the var_buffer mapping of PrimFunctions from the call_tir info.
|
|
* Primarily used to update the VDevice information if any changes occurred from the caller.
|
|
* This pass recreates the buffers and updates the map.
|
|
*/
|
|
TVM_DLL Pass SpecializePrimFuncBasedOnCallSite();
|
|
|
|
} // namespace transform
|
|
} // namespace relax
|
|
} // namespace tvm
|
|
|
|
#endif // TVM_RELAX_TRANSFORM_H_
|