tvm
Loading...
Searching...
No Matches
ir_docsifier_functor.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#ifndef TVM_SCRIPT_PRINTER_IR_DOCSIFIER_FUNCTOR_H_
20#define TVM_SCRIPT_PRINTER_IR_DOCSIFIER_FUNCTOR_H_
21
22#include <tvm/ffi/function.h>
23#include <tvm/runtime/logging.h>
24
25#include <optional>
26#include <string>
27#include <type_traits>
28#include <unordered_map>
29#include <utility>
30#include <vector>
31
32namespace tvm {
33namespace script {
34namespace printer {
35
41template <typename R, typename... Args>
43 private:
44 using TSelf = IRDocsifierFunctor<R, Args...>;
45
46 template <class TObjectRef, class TCallable>
47 using IsDispatchFunction =
48 typename std::is_convertible<TCallable, std::function<R(TObjectRef, Args...)>>;
49
50 public:
62 template <class TObjectRef>
63 R operator()(const ffi::String& token, TObjectRef obj, Args... args) const {
64 uint32_t type_index = obj.defined() ? obj->type_index() : 0;
65 const ffi::Function* pf = nullptr;
66 if ((pf = LookupDispatchTable(token, type_index)) != nullptr) {
67 return (*pf)(obj, args...).template cast<R>();
68 }
69 if ((pf = LookupDispatchTable("", type_index)) != nullptr) {
70 return (*pf)(obj, args...).template cast<R>();
71 }
72 if ((pf = LookupFallback()) != nullptr) {
73 return (*pf)(obj, args...).template cast<R>();
74 }
75
76 LOG(WARNING) << "ObjectFunctor calls un-registered function on type: "
77 << ffi::Object::TypeIndex2Key(type_index) << " (token: " << token << ")"
78 << ". ObjectType: " << obj->GetTypeKey() << ". Object: " << obj;
79 TVM_FFI_ICHECK(false) << "ObjectFunctor calls un-registered function on type: "
80 << ffi::Object::TypeIndex2Key(type_index) << " (token: " << token << ")"
81 << ". ObjectType: " << obj->GetTypeKey() << ". Object: " << obj;
83 }
84
94 TSelf& set_dispatch(ffi::String token, uint32_t type_index, ffi::Function f) {
95 std::vector<ffi::Function>* table = &dispatch_table_[token];
96 if (table->size() <= type_index) {
97 table->resize(type_index + 1, nullptr);
98 }
99 ffi::Function& slot = (*table)[type_index];
100 if (slot != nullptr) {
101 TVM_FFI_ICHECK(false) << "Dispatch for type is already registered: "
102 << ffi::Object::TypeIndex2Key(type_index);
103 }
104 slot = f;
105 return *this;
106 }
107
108 TSelf& set_fallback(ffi::Function f) {
109 TVM_FFI_ICHECK(!dispatch_fallback_.has_value()) << "Fallback is already defined";
110 dispatch_fallback_ = f;
111 return *this;
112 }
113
114 void remove_fallback() { dispatch_fallback_ = std::nullopt; }
115
121 template <typename TObjectRef, typename TCallable,
122 typename = std::enable_if_t<IsDispatchFunction<TObjectRef, TCallable>::value>>
124 return set_dispatch(token, TObjectRef::ContainerType::RuntimeTypeIndex(),
125 ffi::TypedFunction<R(TObjectRef, Args...)>(f));
126 }
127
128 template <typename TCallable,
129 typename = std::enable_if_t<IsDispatchFunction<ffi::ObjectRef, TCallable>::value>>
131 ffi::Function func = ffi::TypedFunction<R(ffi::ObjectRef, Args...)>(f);
132 return set_fallback(func);
133 }
134
144 std::vector<ffi::Function>* table = &dispatch_table_[token];
145 if (table->size() <= type_index) {
146 return;
147 }
148 (*table)[type_index] = nullptr;
149 }
150
151 private:
158 const ffi::Function* LookupDispatchTable(const ffi::String& token, uint32_t type_index) const {
159 auto it = dispatch_table_.find(token);
160 if (it == dispatch_table_.end()) {
161 return nullptr;
162 }
163 const std::vector<ffi::Function>& tab = it->second;
164 if (type_index >= tab.size()) {
165 return nullptr;
166 }
167 const ffi::Function* f = &tab[type_index];
168 if (f->defined()) {
169 return f;
170 } else {
171 return nullptr;
172 }
173 }
174
178 const ffi::Function* LookupFallback() const {
179 if (dispatch_fallback_.has_value()) {
180 return &*dispatch_fallback_;
181 } else {
182 return nullptr;
183 }
184 }
185
186 /*
187 * This type alias and the following free functions are created to reduce the binary bloat
188 * from template and also hide implementation details from this header
189 */
190 using DispatchTable = std::unordered_map<std::string, std::vector<ffi::Function>>;
192 DispatchTable dispatch_table_;
193 std::optional<ffi::Function> dispatch_fallback_;
194};
195
196} // namespace printer
197} // namespace script
198} // namespace tvm
199#endif // TVM_SCRIPT_PRINTER_IR_DOCSIFIER_FUNCTOR_H_
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Dynamic dispatch functor based on AccessPath.
Definition ir_docsifier_functor.h:42
void remove_dispatch(ffi::String token, uint32_t type_index)
Remove dispatch function.
Definition ir_docsifier_functor.h:143
R operator()(const ffi::String &token, TObjectRef obj, Args... args) const
Call the dispatch function.
Definition ir_docsifier_functor.h:63
TSelf & set_dispatch(ffi::String token, uint32_t type_index, ffi::Function f)
Set the dispatch function.
Definition ir_docsifier_functor.h:94
TSelf & set_fallback(TCallable f)
Definition ir_docsifier_functor.h:130
void remove_fallback()
Definition ir_docsifier_functor.h:114
TSelf & set_dispatch(ffi::String token, TCallable f)
Set the dispatch function.
Definition ir_docsifier_functor.h:123
TSelf & set_fallback(ffi::Function f)
Definition ir_docsifier_functor.h:108
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40