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
28#ifndef TVM_IR_TRANSFORM_H_
29#define TVM_IR_TRANSFORM_H_
30
31#include <tvm/ffi/container/array.h>
32#include <tvm/ffi/function.h>
33#include <tvm/ffi/reflection/creator.h>
34#include <tvm/ffi/reflection/registry.h>
35#include <tvm/ffi/string.h>
36#include <tvm/ir/module.h>
37#include <tvm/ir/with_context.h>
38
39#include <string>
40#include <type_traits>
41#include <utility>
42
43namespace tvm {
44namespace transform {
45
46class PassInfo;
47class PassContextObj;
48
62class PassContext : public ffi::ObjectRef {
63 public:
64 static constexpr bool _type_is_nullable = false;
68 explicit PassContext(ffi::UnsafeInit tag) : ffi::ObjectRef(tag) {}
72 explicit PassContext(ffi::UnsafeInit tag, ffi::ObjectPtr<PassContextObj> n);
77 const PassContextObj* operator->() const;
83
94
99 TVM_TIRX_DLL static ffi::Map<ffi::String, ffi::Map<ffi::String, ffi::String>> ListConfigs();
100
107
114
125 TVM_TIRX_DLL bool InstrumentBeforePass(const IRModule& mod, const PassInfo& info) const;
126
135 TVM_TIRX_DLL void InstrumentAfterPass(const IRModule& mod, const PassInfo& info) const;
136
142 TVM_TIRX_DLL bool PassEnabled(const PassInfo& info) const;
143
150 template <typename ValueType>
151 static void RegisterConfigOption(const char* key) {
152 if constexpr (std::is_base_of_v<ffi::ObjectRef, ValueType>) {
153 // Static-init blocks may run before the cached runtime type index is initialized.
154 int32_t tindex = ValueType::ContainerType::_GetOrAllocRuntimeTypeIndex();
155 auto type_key = ffi::TypeIndexToTypeKey(tindex);
156 auto legalization = [=](ffi::Any value) -> ffi::Any {
157 if (auto opt_map = value.try_cast<ffi::Map<ffi::String, ffi::Any>>()) {
158 return ffi::reflection::ObjectCreator(type_key)(opt_map.value());
159 } else {
160 auto opt_val = value.try_cast<ValueType>();
161 if (!opt_val.has_value()) {
162 TVM_FFI_THROW(AttributeError)
163 << "Expect config " << key << " to have type " << type_key << ", but instead get "
164 << ffi::details::AnyUnsafe::GetMismatchTypeInfo<ValueType>(value);
165 }
166 return *opt_val;
167 }
168 };
169 RegisterConfigOption(key, type_key, legalization);
170 } else {
171 // non-object type, do not support implicit conversion from map
172 std::string type_str = ffi::TypeTraits<ValueType>::TypeStr();
173 auto legalization = [=](ffi::Any value) -> ffi::Any {
174 auto opt_val = value.try_cast<ValueType>();
175 if (!opt_val.has_value()) {
176 TVM_FFI_THROW(AttributeError)
177 << "Expect config " << key << " to have type " << type_str << ", but instead get "
178 << ffi::details::AnyUnsafe::GetMismatchTypeInfo<ValueType>(value);
179 } else {
180 return *opt_val;
181 }
182 };
183 RegisterConfigOption(key, type_str, legalization);
184 }
185 }
186
187 // accessor.
189 class Internal;
190
191 private:
192 // The entry of a pass context scope.
193 TVM_TIRX_DLL void EnterWithScope();
194 // The exit of a pass context scope.
195 TVM_TIRX_DLL void ExitWithScope();
196 // Register configuration key value type.
197 TVM_TIRX_DLL static void RegisterConfigOption(const char* key, ffi::String value_type_str,
198 std::function<ffi::Any(ffi::Any)> legalization);
199
200 // Classes to get the Python `with` like syntax.
201 friend class Internal;
202 friend class With<PassContext>;
203};
204
211template <typename TConfig>
212inline TConfig PassConfigWithDefaults() {
213 static_assert(std::is_base_of_v<ffi::ObjectRef, TConfig>,
214 "Can only create ObjectRef-derived types");
215 using ContainerType = typename TConfig::ContainerType;
216 static auto finit_object = ffi::Function::GetGlobalRequired("ffi.MakeObjectFromPackedArgs");
217 ffi::AnyView packed_args[1];
218 packed_args[0] = ContainerType::RuntimeTypeIndex();
219 ffi::Any rv;
220 finit_object.CallPacked(ffi::PackedArgs(packed_args, 1), &rv);
221 return rv.cast<TConfig>();
222}
223
228class PassInfoObj : public ffi::Object {
229 public:
232
234 ffi::String name;
235
236 PassInfoObj() = default;
237
238 static void RegisterReflection() {
239 namespace refl = tvm::ffi::reflection;
240 refl::ObjectDef<PassInfoObj>()
241 .def_ro("opt_level", &PassInfoObj::opt_level)
242 .def_ro("name", &PassInfoObj::name);
243 }
244 TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassInfo", PassInfoObj, ffi::Object);
245};
246
251class PassInfo : public ffi::ObjectRef {
252 public:
258 TVM_TIRX_DLL PassInfo(int opt_level, ffi::String name);
259
261};
262
268class PassObj : public ffi::Object {
269 public:
270 virtual ~PassObj() {}
273 virtual PassInfo Info() const = 0;
274
283 return this->operator()(std::move(mod), PassContext::Current());
284 }
285
294 virtual IRModule operator()(IRModule mod, const PassContext& pass_ctx) const = 0;
295 TVM_FFI_DECLARE_OBJECT_INFO("transform.Pass", PassObj, ffi::Object);
296};
297
298class Pass : public ffi::ObjectRef {
299 public:
316
325 IRModule operator()(IRModule mod, const PassContext& pass_ctx) const;
326
328
329 private:
330 IRModule static AssertImmutableModule(const IRModule& mod, const PassObj* node,
331 const PassContext& pass_ctx);
332};
333
342class SequentialObj : public PassObj {
343 public:
345 explicit SequentialObj(ffi::UnsafeInit tag) : pass_info(tag) {}
346 /* \brief The pass meta data.*/
348
350 tvm::ffi::Array<Pass> passes;
351
352 static void RegisterReflection() {
353 namespace refl = tvm::ffi::reflection;
354 refl::ObjectDef<SequentialObj>()
355 .def_ro("pass_info", &SequentialObj::pass_info)
356 .def_ro("passes", &SequentialObj::passes);
357 }
358
362 PassInfo Info() const override { return pass_info; }
363
375 IRModule operator()(IRModule mod, const PassContext& pass_ctx) const final;
377};
378
379class Sequential : public Pass {
380 public:
387 TVM_TIRX_DLL Sequential(ffi::Array<Pass> passes, PassInfo pass_info);
388
397 TVM_TIRX_DLL Sequential(ffi::Array<Pass> passes, ffi::String name = "sequential");
398
399 explicit Sequential(ffi::UnsafeInit tag) : Pass(tag) {}
400
401 const SequentialObj* operator->() const;
403};
404
405/*
406 * \brief Create a module pass.
407 *
408 * \param pass_func The packed function that contains the optimization.
409 * \param opt_level The optimization level of the module pass.
410 * \param name The name of the module pass.
411 *
412 * \return The created module pass.
413 */
415 int opt_level, ffi::String name);
416
422TVM_TIRX_DLL Pass PrintIR(ffi::String header = "");
423
446 const ffi::Error& err, const IRModule& mod, ffi::String pass_name,
447 ffi::Optional<GlobalVar> func = ffi::Optional<GlobalVar>(std::nullopt));
448
505class PassInstrumentObj : public ffi::Object {
506 public:
508 ffi::String name;
509
511
513 virtual void EnterPassContext() const = 0;
514
516 virtual void ExitPassContext() const = 0;
517
526 virtual bool ShouldRun(const IRModule& mod, const transform::PassInfo& info) const = 0;
527
533 virtual void RunBeforePass(const IRModule& mod, const transform::PassInfo& info) const = 0;
534
540 virtual void RunAfterPass(const IRModule& mod, const transform::PassInfo& info) const = 0;
541
542 static void RegisterReflection() {
543 namespace refl = tvm::ffi::reflection;
544 refl::ObjectDef<PassInstrumentObj>().def_ro("name", &PassInstrumentObj::name);
545 }
546 TVM_FFI_DECLARE_OBJECT_INFO("transform.PassInstrument", PassInstrumentObj, ffi::Object);
547};
548
553class PassInstrument : public ffi::ObjectRef {
554 public:
556};
557
563class PassContextObj : public ffi::Object {
564 public:
566 int opt_level{2};
567
569 ffi::Array<ffi::String> required_pass;
571 ffi::Array<ffi::String> disabled_pass;
573 ffi::Map<ffi::String, Any> config;
574
576 ffi::Array<PassInstrument> instruments;
577
578 PassContextObj() = default;
579
586 template <typename T>
587 ffi::Optional<T> GetConfig(const std::string& key) const {
588 if (config.defined()) {
589 auto it = config.find(key);
590 if (it != config.end()) {
591 return (*it).second.as_or_throw<ffi::Optional<T>>();
592 }
593 }
594 return std::nullopt;
595 }
596
603 template <typename TConfig>
604 TConfig GetConfigOrDefault(const std::string& key) const {
605 auto config = GetConfig<TConfig>(key);
606 if (config.has_value()) {
607 return config.value();
608 }
609 return PassConfigWithDefaults<TConfig>();
610 }
611
612 static void RegisterReflection() {
613 namespace refl = tvm::ffi::reflection;
614 refl::ObjectDef<PassContextObj>()
615 .def_ro("opt_level", &PassContextObj::opt_level)
616 .def_ro("required_pass", &PassContextObj::required_pass)
617 .def_ro("disabled_pass", &PassContextObj::disabled_pass)
618 .def_ro("instruments", &PassContextObj::instruments)
619 .def_ro("config", &PassContextObj::config);
620 }
621 TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassContext", PassContextObj, ffi::Object);
622};
623
624inline PassContext::PassContext(ffi::UnsafeInit tag, ffi::ObjectPtr<PassContextObj> n)
625 : ffi::ObjectRef(tag) {
626 data_ = std::move(n);
627}
628
630 TVM_FFI_ICHECK(get() != nullptr);
631 return static_cast<const PassContextObj*>(get());
632}
633
635 TVM_FFI_ICHECK(get() != nullptr);
636 return static_cast<PassContextObj*>(get_mutable());
637}
638
639} // namespace transform
640} // namespace tvm
641
642#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
PassContextObj contains the information that a pass can rely on, such as analysis results.
Definition transform.h:563
TConfig GetConfigOrDefault(const std::string &key) const
Get a config object, constructing reflection defaults only when absent.
Definition transform.h:604
ffi::Array< PassInstrument > instruments
A list of pass instrument implementations.
Definition transform.h:576
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassContext", PassContextObj, ffi::Object)
ffi::Map< ffi::String, Any > config
Pass specific configurations.
Definition transform.h:573
ffi::Array< ffi::String > required_pass
The list of required passes.
Definition transform.h:569
int opt_level
The default optimization level.
Definition transform.h:566
static void RegisterReflection()
Definition transform.h:612
ffi::Array< ffi::String > disabled_pass
The list of disabled passes.
Definition transform.h:571
ffi::Optional< T > GetConfig(const std::string &key) const
Get a config value, returning an empty optional when the key is absent.
Definition transform.h:587
PassContext that is used to configure the pass behavior.
Definition transform.h:62
static TVM_TIRX_DLL ffi::Map< ffi::String, ffi::Map< ffi::String, ffi::String > > ListConfigs()
Get all supported configuration names and metadata, registered within the PassContext.
static constexpr bool _type_is_nullable
Definition transform.h:64
TVM_TIRX_DLL void InstrumentEnterPassContext()
Call instrument implementations' callbacks when entering PassContext. The callbacks are called in ord...
static TVM_TIRX_DLL PassContext Current()
Get the default pass context in the current scope.
static void RegisterConfigOption(const char *key)
Register a valid configuration option and its ValueType for validation.
Definition transform.h:151
TVM_TIRX_DLL void InstrumentExitPassContext()
Call instrument implementations' callbacks when exiting PassContext. The callbacks are called in orde...
friend class Internal
Definition transform.h:201
const PassContextObj * operator->() const
const accessor.
Definition transform.h:629
TVM_TIRX_DLL bool InstrumentBeforePass(const IRModule &mod, const PassInfo &info) const
Call instrument implementations' callbacks before a pass run. The callbacks are called in order,...
TVM_TIRX_DLL void InstrumentAfterPass(const IRModule &mod, const PassInfo &info) const
Call instrument implementations callbacks after a pass run. The callbacks are called in order,...
static TVM_TIRX_DLL PassContext Create()
Construct a PassContext containing the default configurations.
PassContext(ffi::UnsafeInit tag)
constructor with UnsafeInit
Definition transform.h:68
TVM_TIRX_DLL bool PassEnabled(const PassInfo &info) const
Check whether a pass is enabled.
Meta data that will be used to help optimization and analysis.
Definition transform.h:228
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassInfo", PassInfoObj, ffi::Object)
int opt_level
The minimal optimization level that this pass will be enabled.
Definition transform.h:231
static void RegisterReflection()
Definition transform.h:238
ffi::String name
The name of an optimization/analysis pass.
Definition transform.h:234
Managed reference class for PassInfoObj.
Definition transform.h:251
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(PassInfo, ffi::ObjectRef, PassInfoObj)
TVM_TIRX_DLL PassInfo(int opt_level, ffi::String name)
Constructor.
PassInstrumentObj forms an instrument implementation. It provides API for users to register callbacks...
Definition transform.h:505
ffi::String name
Name of this pass instrument object.
Definition transform.h:508
TVM_FFI_DECLARE_OBJECT_INFO("transform.PassInstrument", PassInstrumentObj, ffi::Object)
virtual void RunBeforePass(const IRModule &mod, const transform::PassInfo &info) const =0
Instrument before pass run. Called multiple times depend on number of passes.
virtual ~PassInstrumentObj()
Definition transform.h:510
virtual void EnterPassContext() const =0
Instrument when entering PassContext. Called once within a PassContext.
virtual void RunAfterPass(const IRModule &mod, const transform::PassInfo &info) const =0
Instrument after pass run. Called multiple time depend on number of passes.
virtual void ExitPassContext() const =0
Instrument when exiting PassContext. Called once within a PassContext.
virtual bool ShouldRun(const IRModule &mod, const transform::PassInfo &info) const =0
Determine whether to run the pass or not. Called multiple times depend on number of passes.
static void RegisterReflection()
Definition transform.h:542
Managed reference class for PassInstrumentObj.
Definition transform.h:553
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(PassInstrument, ffi::ObjectRef, PassInstrumentObj)
PassObj is the base type of differnt types of optimization passes. It is designed as a pure class and...
Definition transform.h:268
IRModule operator()(IRModule mod) const
Transform mod using the default PassContext in the current scope.
Definition transform.h:282
virtual IRModule operator()(IRModule mod, const PassContext &pass_ctx) const =0
Transform mod using a functor under a given pass context.
virtual ~PassObj()
Definition transform.h:270
virtual PassInfo Info() const =0
Get the pass information/meta data.
TVM_FFI_DECLARE_OBJECT_INFO("transform.Pass", PassObj, ffi::Object)
Definition transform.h:298
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Pass, ffi::ObjectRef, PassObj)
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 SequentialObj contains a set of passes that transform Relax programs from one AST to another sema...
Definition transform.h:342
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...
PassInfo Info() const override
Get the pass information/meta data.
Definition transform.h:362
PassInfo pass_info
Definition transform.h:347
SequentialObj(PassInfo pass_info)
Definition transform.h:344
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.Sequential", SequentialObj, PassObj)
static void RegisterReflection()
Definition transform.h:352
tvm::ffi::Array< Pass > passes
A list of passes that used to compose a sequential pass.
Definition transform.h:350
SequentialObj(ffi::UnsafeInit tag)
Definition transform.h:345
Definition transform.h:379
const SequentialObj * operator->() const
TVM_TIRX_DLL Sequential(ffi::Array< Pass > passes, PassInfo pass_info)
The constructor of Sequential.
TVM_TIRX_DLL Sequential(ffi::Array< Pass > passes, ffi::String name="sequential")
The constructor of Sequential.
Sequential(ffi::UnsafeInit tag)
Definition transform.h:399
IRModule that holds the functions and type definitions.
TVM_TIRX_DLL 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...
TVM_TIRX_DLL Pass CreateModulePass(std::function< IRModule(IRModule, PassContext)> pass_func, int opt_level, ffi::String name)
TVM_TIRX_DLL Pass PrintIR(ffi::String header="")
A special trace pass that prints the header and IR to LOG(INFO).
TConfig PassConfigWithDefaults()
Create a pass-config object with all default values, using the reflection defaults.
Definition transform.h:212
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition attr.h:23
#define TVM_TIRX_DLL
Definition base.h:83
RAII wrapper function to enter and exit a context object similar to python's with syntax.