tvm
Loading...
Searching...
No Matches
transform.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
56#ifndef TVM_IR_TRANSFORM_H_
57#define TVM_IR_TRANSFORM_H_
58
59#include <tvm/ffi/container/array.h>
60#include <tvm/ffi/function.h>
61#include <tvm/ffi/reflection/creator.h>
62#include <tvm/ffi/reflection/registry.h>
63#include <tvm/ffi/string.h>
64#include <tvm/ir/instrument.h>
65#include <tvm/ir/module.h>
66#include <tvm/ir/with_context.h>
67
68#include <string>
69#include <type_traits>
70#include <utility>
71
72namespace tvm {
73namespace transform {
74
80class PassContextNode : public ffi::Object {
81 public:
83 int opt_level{2};
84
86 ffi::Array<ffi::String> required_pass;
88 ffi::Array<ffi::String> disabled_pass;
90 ffi::Map<ffi::String, Any> config;
91
93 ffi::Array<instrument::PassInstrument> instruments;
94
95 PassContextNode() = default;
96
108 template <typename TObjectRef>
109 ffi::Optional<TObjectRef> GetConfig(
110 const std::string& key,
111 ffi::Optional<TObjectRef> default_value = ffi::Optional<TObjectRef>(std::nullopt)) const {
112 if (!config.defined()) return default_value;
113 auto it = config.find(key);
114 if (it != config.end()) {
115 return (*it).second.as_or_throw<ffi::Optional<TObjectRef>>();
116 } else {
117 return default_value;
118 }
119 }
120 // variant that uses TObjectRef to enable implicit conversion to default value.
121 template <typename TObjectRef>
122 ffi::Optional<TObjectRef> GetConfig(const std::string& key, TObjectRef default_value) const {
123 return GetConfig<TObjectRef>(key, ffi::Optional<TObjectRef>(default_value));
124 }
125
126 static void RegisterReflection() {
127 namespace refl = tvm::ffi::reflection;
128 refl::ObjectDef<PassContextNode>()
129 .def_ro("opt_level", &PassContextNode::opt_level)
130 .def_ro("required_pass", &PassContextNode::required_pass)
131 .def_ro("disabled_pass", &PassContextNode::disabled_pass)
132 .def_ro("instruments", &PassContextNode::instruments)
133 .def_ro("config", &PassContextNode::config);
134 }
135 TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassContext", PassContextNode, ffi::Object);
136};
137
151class PassContext : public ffi::ObjectRef {
152 public:
157 explicit PassContext(ffi::UnsafeInit tag) : ffi::ObjectRef(tag) {}
161 explicit PassContext(ffi::ObjectPtr<PassContextNode> n) : ffi::ObjectRef(n) {}
167 TVM_FFI_ICHECK(get() != nullptr);
168 return static_cast<const PassContextNode*>(get());
169 }
175 TVM_FFI_ICHECK(get() != nullptr);
176 return static_cast<PassContextNode*>(get_mutable());
177 }
178
189
194 TVM_DLL static ffi::Map<ffi::String, ffi::Map<ffi::String, ffi::String>> ListConfigs();
195
202
209
220 TVM_DLL bool InstrumentBeforePass(const IRModule& mod, const PassInfo& info) const;
221
230 TVM_DLL void InstrumentAfterPass(const IRModule& mod, const PassInfo& info) const;
231
237 TVM_DLL bool PassEnabled(const PassInfo& info) const;
238
245 template <typename ValueType>
246 static int32_t RegisterConfigOption(const char* key) {
247 // NOTE: we could further update the function later.
248 if constexpr (std::is_base_of_v<ffi::ObjectRef, ValueType>) {
249 int32_t tindex = ffi::TypeToRuntimeTypeIndex<ValueType>::v();
250 auto type_key = ffi::TypeIndexToTypeKey(tindex);
251 auto legalization = [=](ffi::Any value) -> ffi::Any {
252 if (auto opt_map = value.try_cast<ffi::Map<ffi::String, ffi::Any>>()) {
253 return ffi::reflection::ObjectCreator(type_key)(opt_map.value());
254 } else {
255 auto opt_val = value.try_cast<ValueType>();
256 if (!opt_val.has_value()) {
258 << "Expect config " << key << " to have type " << type_key << ", but instead get "
259 << ffi::details::AnyUnsafe::GetMismatchTypeInfo<ValueType>(value);
260 }
261 return *opt_val;
262 }
263 };
265 } else {
266 // non-object type, do not support implicit conversion from map
267 std::string type_str = ffi::TypeTraits<ValueType>::TypeStr();
268 auto legalization = [=](ffi::Any value) -> ffi::Any {
269 auto opt_val = value.try_cast<ValueType>();
270 if (!opt_val.has_value()) {
272 << "Expect config " << key << " to have type " << type_str << ", but instead get "
273 << ffi::details::AnyUnsafe::GetMismatchTypeInfo<ValueType>(value);
274 } else {
275 return *opt_val;
276 }
277 };
278 RegisterConfigOption(key, type_str, legalization);
279 }
280 return 0;
281 }
282
283 // accessor.
285 class Internal;
286
287 private:
288 // The entry of a pass context scope.
289 TVM_DLL void EnterWithScope();
290 // The exit of a pass context scope.
291 TVM_DLL void ExitWithScope();
292 // Register configuration key value type.
293 TVM_DLL static void RegisterConfigOption(const char* key, ffi::String value_type_str,
294 std::function<ffi::Any(ffi::Any)> legalization);
295
296 // Classes to get the Python `with` like syntax.
297 friend class Internal;
298 friend class With<PassContext>;
299};
300
307template <typename TConfig>
309 static_assert(std::is_base_of_v<ffi::ObjectRef, TConfig>,
310 "Can only create ObjectRef-derived types");
311 using ContainerType = typename TConfig::ContainerType;
312 static auto finit_object = ffi::Function::GetGlobalRequired("ffi.MakeObjectFromPackedArgs");
313 ffi::AnyView packed_args[1];
314 packed_args[0] = ContainerType::RuntimeTypeIndex();
315 ffi::Any rv;
316 finit_object.CallPacked(ffi::PackedArgs(packed_args, 1), &rv);
317 return rv.cast<TConfig>();
318}
319
320#define TVM_PASS_CTX_CONFIG_VAR_DEF [[maybe_unused]] static uint32_t __make_PassContext_tid
321
328#define TVM_REGISTER_PASS_CONFIG_OPTION(Key, ValueType) \
329 TVM_FFI_STR_CONCAT(TVM_PASS_CTX_CONFIG_VAR_DEF, __COUNTER__) = \
330 ::tvm::transform::PassContext::RegisterConfigOption<ValueType>(Key)
331
336class PassInfoNode : public ffi::Object {
337 public:
340
342 ffi::String name;
343
346
348 ffi::Array<ffi::String> required;
349
350 PassInfoNode() = default;
351
352 static void RegisterReflection() {
353 namespace refl = tvm::ffi::reflection;
354 refl::ObjectDef<PassInfoNode>()
355 .def_ro("opt_level", &PassInfoNode::opt_level)
356 .def_ro("name", &PassInfoNode::name)
357 .def_ro("required", &PassInfoNode::required)
358 .def_ro("traceable", &PassInfoNode::traceable);
359 }
360 TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassInfo", PassInfoNode, ffi::Object);
361};
362
367class PassInfo : public ffi::ObjectRef {
368 public:
376 TVM_DLL PassInfo(int opt_level, ffi::String name, ffi::Array<ffi::String> required,
377 bool traceable);
378
380};
381
387class PassNode : public ffi::Object {
388 public:
389 virtual ~PassNode() {}
392 virtual PassInfo Info() const = 0;
393
402 return this->operator()(std::move(mod), PassContext::Current());
403 }
404
413 virtual IRModule operator()(IRModule mod, const PassContext& pass_ctx) const = 0;
414 TVM_FFI_DECLARE_OBJECT_INFO("transform.Pass", PassNode, ffi::Object);
415};
416
417class Pass : public ffi::ObjectRef {
418 public:
435
445
447
448 private:
449 IRModule static AssertImmutableModule(const IRModule& mod, const PassNode* node,
450 const PassContext& pass_ctx);
451};
452
461class SequentialNode : public PassNode {
462 public:
463 /* \brief The pass meta data.*/
465
467 tvm::ffi::Array<Pass> passes;
468
469 static void RegisterReflection() {
470 namespace refl = tvm::ffi::reflection;
471 refl::ObjectDef<SequentialNode>()
472 .def_ro("pass_info", &SequentialNode::pass_info)
473 .def_ro("passes", &SequentialNode::passes);
474 }
475
479 PassInfo Info() const override { return pass_info; }
480
491 void ResolveDependency(const IRModule& mod);
492
506};
507
508class Sequential : public Pass {
509 public:
516 TVM_DLL Sequential(ffi::Array<Pass> passes, PassInfo pass_info);
517
526 TVM_DLL Sequential(ffi::Array<Pass> passes, ffi::String name = "sequential");
527
528 Sequential() = default;
529 explicit Sequential(ffi::ObjectPtr<SequentialNode> n) : Pass(n) {}
530
533};
534
535/*
536 * \brief Create a module pass.
537 *
538 * \param pass_func The packed function that contains the optimization.
539 * \param opt_level The optimization level of the module pass.
540 * \param name The name of the module pass.
541 * \param required The list of the passes that the module pass is dependent on.
542 *
543 * \return The created module pass.
544 */
546 int opt_level, ffi::String name, ffi::Array<ffi::String> required,
547 bool traceable = false);
548
554TVM_DLL Pass PrintIR(ffi::String header = "");
555
578 const ffi::Error& err, const IRModule& mod, ffi::String pass_name,
579 ffi::Optional<GlobalVar> func = ffi::Optional<GlobalVar>(std::nullopt));
580
581} // namespace transform
582} // namespace tvm
583
584#endif // TVM_IR_TRANSFORM_H_
Managed reference class to IRModuleNode.
Definition module.h:255
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
PassContextNode contains the information that a pass can rely on, such as analysis results.
Definition transform.h:80
ffi::Map< ffi::String, Any > config
Pass specific configurations.
Definition transform.h:90
ffi::Optional< TObjectRef > GetConfig(const std::string &key, TObjectRef default_value) const
Definition transform.h:122
ffi::Array< ffi::String > disabled_pass
The list of disabled passes.
Definition transform.h:88
ffi::Array< instrument::PassInstrument > instruments
A list of pass instrument implementations.
Definition transform.h:93
ffi::Optional< TObjectRef > GetConfig(const std::string &key, ffi::Optional< TObjectRef > default_value=ffi::Optional< TObjectRef >(std::nullopt)) const
Get a config value from the pass context.
Definition transform.h:109
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassContext", PassContextNode, ffi::Object)
static void RegisterReflection()
Definition transform.h:126
int opt_level
The default optimization level.
Definition transform.h:83
ffi::Array< ffi::String > required_pass
The list of required passes.
Definition transform.h:86
PassContext that is used to configure the pass behavior.
Definition transform.h:151
static PassContext Current()
Get the default pass context in the current scope.
bool PassEnabled(const PassInfo &info) const
Check whether a pass is enabled.
friend class Internal
Definition transform.h:297
PassContextNode * operator->()
mutable accessor.
Definition transform.h:174
PassContext()
Definition transform.h:153
static int32_t RegisterConfigOption(const char *key)
Register a valid configuration option and its ValueType for validation.
Definition transform.h:246
const PassContextNode * operator->() const
const accessor.
Definition transform.h:166
static PassContext Create()
Construct a PassContext containing the default configurations.
void InstrumentEnterPassContext()
Call instrument implementations' callbacks when entering PassContext. The callbacks are called in ord...
void InstrumentExitPassContext()
Call instrument implementations' callbacks when exiting PassContext. The callbacks are called in orde...
static ffi::Map< ffi::String, ffi::Map< ffi::String, ffi::String > > ListConfigs()
Get all supported configuration names and metadata, registered within the PassContext.
PassContext(ffi::ObjectPtr< PassContextNode > n)
constructor with ffi::ObjectPtr
Definition transform.h:161
PassContext(ffi::UnsafeInit tag)
constructor with UnsafeInit
Definition transform.h:157
bool InstrumentBeforePass(const IRModule &mod, const PassInfo &info) const
Call instrument implementations' callbacks before a pass run. The callbacks are called in order,...
void InstrumentAfterPass(const IRModule &mod, const PassInfo &info) const
Call instrument implementations callbacks after a pass run. The callbacks are called in order,...
Meta data that will be used to help optimization and analysis.
Definition transform.h:336
ffi::String name
The name of an optimization/analysis pass.
Definition transform.h:342
bool traceable
Boolean that tells whether this pass will be traced or not.
Definition transform.h:345
static void RegisterReflection()
Definition transform.h:352
int opt_level
The minimal optimization level that this pass will be enabled.
Definition transform.h:339
ffi::Array< ffi::String > required
The passes that are required to perform the current pass.
Definition transform.h:348
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassInfo", PassInfoNode, ffi::Object)
Managed reference class for PassInfoNode.
Definition transform.h:367
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(PassInfo, ffi::ObjectRef, PassInfoNode)
PassInfo(int opt_level, ffi::String name, ffi::Array< ffi::String > required, bool traceable)
Constructor.
PassNode is the base type of differnt types of optimization passes. It is designed as a pure class an...
Definition transform.h:387
virtual IRModule operator()(IRModule mod, const PassContext &pass_ctx) const =0
Transform mod using a functor under a given pass context.
TVM_FFI_DECLARE_OBJECT_INFO("transform.Pass", PassNode, ffi::Object)
IRModule operator()(IRModule mod) const
Transform mod using the default PassContext in the current scope.
Definition transform.h:401
virtual PassInfo Info() const =0
Get the pass information/meta data.
virtual ~PassNode()
Definition transform.h:389
Definition transform.h:417
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(Pass, ffi::ObjectRef, PassNode)
IRModule operator()(IRModule mod, const PassContext &pass_ctx) const
Transform mod using a functor under a given pass context.
IRModule operator()(IRModule mod) const
Transform mod using the default PassContext in the current scope.
The SequentialNode contains a set of passes that transform Relax programs from one AST to another sem...
Definition transform.h:461
static void RegisterReflection()
Definition transform.h:469
PassInfo Info() const override
Get the pass information/meta data.
Definition transform.h:479
void ResolveDependency(const IRModule &mod)
Resolve the pass dependency. It globs all required passes by a given pass and executes them.
IRModule operator()(IRModule mod, const PassContext &pass_ctx) const final
Perform optimizations on a series of passes. The aforementioned typical pass manager jobs could be do...
tvm::ffi::Array< Pass > passes
A list of passes that used to compose a sequential pass.
Definition transform.h:467
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.Sequential", SequentialNode, PassNode)
PassInfo pass_info
Definition transform.h:464
Definition transform.h:508
Sequential(ffi::Array< Pass > passes, ffi::String name="sequential")
The constructor of Sequential.
Sequential(ffi::ObjectPtr< SequentialNode > n)
Definition transform.h:529
const SequentialNode * operator->() const
Sequential(ffi::Array< Pass > passes, PassInfo pass_info)
The constructor of Sequential.
IRModule that holds the functions and type definitions.
Pass PrintIR(ffi::String header="")
A special trace pass that prints the header and IR to LOG(INFO).
ffi::Error EnrichPassErrorWithContext(const ffi::Error &err, const IRModule &mod, ffi::String pass_name, ffi::Optional< GlobalVar > func=ffi::Optional< GlobalVar >(std::nullopt))
Enrich a pass-time error with a TVMScript-rendered, underlined source location derived from the error...
Pass CreateModulePass(std::function< IRModule(IRModule, PassContext)> pass_func, int opt_level, ffi::String name, ffi::Array< ffi::String > required, bool traceable=false)
TConfig PassConfigWithDefaults()
Create a pass-config object with all default values, using the reflection defaults.
Definition transform.h:308
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
RAII wrapper function to enter and exit a context object similar to python's with syntax.