tvm
Loading...
Searching...
No Matches
op.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
24#ifndef TVM_IR_OP_H_
25#define TVM_IR_OP_H_
26
27#include <tvm/ffi/container/list.h>
28#include <tvm/ffi/expected.h>
29#include <tvm/ffi/optional.h>
30#include <tvm/ffi/reflection/native_function.h>
31#include <tvm/ffi/reflection/registry.h>
32#include <tvm/ir/attrs.h>
33#include <tvm/ir/env_func.h>
34#include <tvm/ir/expr.h>
35#include <tvm/ir/type.h>
36
37#include <string>
38#include <type_traits>
39#include <utility>
40
41namespace tvm {
42
43template <typename>
44class OpAttrMap;
45
51
53using FInferType = ffi::reflection::NativeFunctionView<Type(const CallNode* call)>;
54
56class ArgumentInfoObj : public ffi::Object {
57 public:
59 ffi::String name;
61 ffi::String doc;
62
63 static void RegisterReflection() {
64 namespace refl = ffi::reflection;
65 refl::ObjectDef<ArgumentInfoObj>()
66 .def_ro("name", &ArgumentInfoObj::name)
67 .def_ro("doc", &ArgumentInfoObj::doc);
68 }
69
70 static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindTreeNode;
71 TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.ArgumentInfo", ArgumentInfoObj, ffi::Object);
72};
73
75class ArgumentInfo : public ffi::ObjectRef {
76 public:
77 explicit ArgumentInfo(ffi::UnsafeInit tag, ffi::ObjectPtr<ArgumentInfoObj> n)
78 : ffi::ObjectRef(tag) {
79 data_ = std::move(n);
80 }
81
83};
84
86class OpNode : public ExprNode {
87 private:
88 // Dense process-local index into attribute columns; never serialized.
89 uint32_t index_{0};
90
91 public:
93 ffi::String name;
95 ffi::String doc;
97 ffi::Array<ArgumentInfo> args_info;
99 ffi::Array<ArgumentInfo> ty_args_info;
101 ffi::Optional<ArgumentInfo> var_args_info;
103 ffi::Optional<ArgumentInfo> var_ty_args_info;
105 ffi::String attrs_type_key;
107 uint32_t attrs_type_index{0};
109 ffi::Any validator;
112
114
115 static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindUniqueInstance;
117
118 private:
119 friend class OpRegistry;
120 friend class OpDef;
121 friend class Op;
122 template <typename>
123 friend class OpAttrMap;
124};
125
147class Op : public Expr {
148 public:
150 explicit Op(ffi::ObjectPtr<OpNode> n) : Expr(std::move(n)) {
151 TVM_FFI_CHECK(defined(), ValueError) << "Op expects a defined OpNode";
152 }
153
161 template <typename ValueType>
162 static OpAttrMap<ValueType> GetAttrMap(const ffi::String& attr_name);
168 TVM_TIRX_DLL static bool HasAttrMap(const ffi::String& attr_name);
175 TVM_TIRX_DLL static Op Get(const ffi::String& op_name);
177 TVM_TIRX_DLL static ffi::Array<ffi::String> ListNames();
178
180 TVM_FFI_INLINE void Validate(const CallNode* call) const {
181 const auto& validator = get()->validator;
182 if (validator != nullptr) {
183 if (TVM_FFI_PREDICT_FALSE(!call)) {
184 ThrowInvalidCall(get());
185 }
186 using View = ffi::reflection::NativeFunctionView<void(const CallNode*)>;
187 // set_validator stores only an owning NativeFunction with this signature.
188 ffi::details::AnyUnsafe::CopyFromAnyViewAfterCheck<View>(validator)
189 .CallExpected(call)
190 .value();
191 }
192 }
194
195 private:
196 TVM_TIRX_DLL static void ThrowInvalidCall(const OpNode* op);
197 TVM_TIRX_DLL static ffi::List<ffi::Any> GetAttrColumn(const ffi::String& attr_name);
198};
199
200namespace sig {
201
203struct SignatureTrait {
205 static constexpr size_t kArgsCount = 0;
207 static constexpr size_t kTyArgsCount = 0;
209 static constexpr size_t kVarArgsCount = 0;
211 static constexpr size_t kVarTyArgsCount = 0;
213 static constexpr size_t kCallAttrsCount = 0;
214};
215
217struct ValidateState {
219 const CallNode* call;
221 const OpNode* op;
223 size_t args_index = 0;
225 size_t ty_args_index = 0;
226};
227
228namespace details {
229
230template <typename T>
231inline bool ReportTypeMismatch(ffi::Expected<void>* out, const ValidateState* state, bool type_arg,
232 size_t index, ffi::AnyView actual) {
233 const auto& fixed = type_arg ? state->op->ty_args_info : state->op->args_info;
234 const auto& tail = type_arg ? state->op->var_ty_args_info : state->op->var_args_info;
235 std::string name;
236 if (index < fixed.size()) {
237 name = fixed[index]->name;
238 } else if (tail.has_value()) {
239 name = tail.value()->name;
240 }
241 std::string name_clause = name.empty() ? "" : " (`" + name + "`)";
242 TVMFFIAny raw = actual.CopyToTVMFFIAny();
243 *out = TVM_FFI_UNEXPECTED(TypeError)
244 << "Op `" << state->op->name << "`: `" << (type_arg ? "Call.ty_args[" : "Call.args[")
245 << index << "]`" << name_clause << " expected `" << ffi::TypeTraits<T>::TypeStr()
246 << "`, got `" << ffi::TypeTraits<T>::GetMismatchTypeInfo(&raw) << "`.";
247 return false;
248}
249
250} // namespace details
251
254template <typename T = Expr>
255struct arg : SignatureTrait {
256 static_assert(std::is_base_of_v<Expr, T>, "arg<T> expects an expression view");
258 static constexpr size_t kArgsCount = 1;
260 ffi::String name;
262 ffi::String doc;
263
264 explicit arg(ffi::String name, ffi::String doc = "")
265 : name(std::move(name)), doc(std::move(doc)) {}
266
267 void CollectMetadata(OpNode* op) const {
268 auto info = ffi::make_object<ArgumentInfoObj>();
269 info->name = name;
270 info->doc = doc;
271 op->args_info.push_back(ArgumentInfo(ffi::UnsafeInit{}, std::move(info)));
272 }
273
274 static bool Validate(ValidateState* state, ffi::Expected<void>* out) {
275 if constexpr (!std::is_same_v<T, Expr>) {
276 ffi::AnyView value(state->call->args.GetArrayObj()->begin()[state->args_index]);
277 if (TVM_FFI_PREDICT_FALSE(value == nullptr ||
278 !ffi::details::AnyUnsafe::CheckAnyViewStrict<T>(value))) {
279 return details::ReportTypeMismatch<T>(out, state, false, state->args_index, value);
280 }
281 }
282 ++state->args_index;
283 return true;
284 }
285};
286
289template <typename T = Expr>
290struct var_args : SignatureTrait {
291 static_assert(std::is_base_of_v<Expr, T>, "var_args<T> expects an expression view");
293 static constexpr size_t kVarArgsCount = 1;
295 ffi::String name;
297 ffi::String doc;
298
299 explicit var_args(ffi::String name, ffi::String doc = "")
300 : name(std::move(name)), doc(std::move(doc)) {}
301
302 void CollectMetadata(OpNode* op) const {
303 auto info = ffi::make_object<ArgumentInfoObj>();
304 info->name = name;
305 info->doc = doc;
306 op->var_args_info = ArgumentInfo(ffi::UnsafeInit{}, std::move(info));
307 }
308
309 static bool Validate(ValidateState* state, ffi::Expected<void>* out) {
310 if constexpr (!std::is_same_v<T, Expr>) {
311 const ffi::Any* values = state->call->args.GetArrayObj()->begin();
312 for (; state->args_index != state->call->args.size(); ++state->args_index) {
313 ffi::AnyView value(values[state->args_index]);
314 if (TVM_FFI_PREDICT_FALSE(value == nullptr ||
315 !ffi::details::AnyUnsafe::CheckAnyViewStrict<T>(value))) {
316 return details::ReportTypeMismatch<T>(out, state, false, state->args_index, value);
317 }
318 }
319 } else {
320 state->args_index = state->call->args.size();
321 }
322 return true;
323 }
324};
325
328template <typename T = Type>
329struct ty_arg : SignatureTrait {
330 static_assert(std::is_base_of_v<Type, T>, "ty_arg<T> expects a type view");
332 static constexpr size_t kTyArgsCount = 1;
334 ffi::String name;
336 ffi::String doc;
337
338 explicit ty_arg(ffi::String name, ffi::String doc = "")
339 : name(std::move(name)), doc(std::move(doc)) {}
340
341 void CollectMetadata(OpNode* op) const {
342 auto info = ffi::make_object<ArgumentInfoObj>();
343 info->name = name;
344 info->doc = doc;
345 op->ty_args_info.push_back(ArgumentInfo(ffi::UnsafeInit{}, std::move(info)));
346 }
347
348 static bool Validate(ValidateState* state, ffi::Expected<void>* out) {
349 if constexpr (!std::is_same_v<T, Type>) {
350 ffi::AnyView value(state->call->ty_args.GetArrayObj()->begin()[state->ty_args_index]);
351 if (TVM_FFI_PREDICT_FALSE(value == nullptr ||
352 !ffi::details::AnyUnsafe::CheckAnyViewStrict<T>(value))) {
353 return details::ReportTypeMismatch<T>(out, state, true, state->ty_args_index, value);
354 }
355 }
356 ++state->ty_args_index;
357 return true;
358 }
359};
360
363template <typename T = Type>
364struct var_ty_args : SignatureTrait {
365 static_assert(std::is_base_of_v<Type, T>, "var_ty_args<T> expects a type view");
367 static constexpr size_t kVarTyArgsCount = 1;
369 ffi::String name;
371 ffi::String doc;
372
373 explicit var_ty_args(ffi::String name, ffi::String doc = "")
374 : name(std::move(name)), doc(std::move(doc)) {}
375
376 void CollectMetadata(OpNode* op) const {
377 auto info = ffi::make_object<ArgumentInfoObj>();
378 info->name = name;
379 info->doc = doc;
380 op->var_ty_args_info = ArgumentInfo(ffi::UnsafeInit{}, std::move(info));
381 }
382
383 static bool Validate(ValidateState* state, ffi::Expected<void>* out) {
384 if constexpr (!std::is_same_v<T, Type>) {
385 const ffi::Any* values = state->call->ty_args.GetArrayObj()->begin();
386 for (; state->ty_args_index != state->call->ty_args.size(); ++state->ty_args_index) {
387 ffi::AnyView value(values[state->ty_args_index]);
388 if (TVM_FFI_PREDICT_FALSE(value == nullptr ||
389 !ffi::details::AnyUnsafe::CheckAnyViewStrict<T>(value))) {
390 return details::ReportTypeMismatch<T>(out, state, true, state->ty_args_index, value);
391 }
392 }
393 } else {
394 state->ty_args_index = state->call->ty_args.size();
395 }
396 return true;
397 }
398};
399
408template <typename T>
409struct call_attrs : SignatureTrait {
410 static_assert(std::is_base_of_v<AttrsNode, T>, "call_attrs<T> expects an attribute node type");
412 static constexpr size_t kCallAttrsCount = 1;
413
414 void CollectMetadata(OpNode* op) const {
415 uint32_t index = T::RuntimeTypeIndex();
416 op->attrs_type_key = T::_type_key;
417 op->attrs_type_index = index;
418 }
419
420 static bool Validate(ValidateState* state, ffi::Expected<void>* out) {
421 ffi::AnyView attrs(state->call->attrs);
422 if (TVM_FFI_PREDICT_FALSE(!state->call->attrs.has_value() ||
423 !ffi::details::AnyUnsafe::CheckAnyViewStrict<const T*>(attrs))) {
424 TVMFFIAny raw = attrs.CopyToTVMFFIAny();
425 std::string actual = state->call->attrs.has_value()
426 ? "`" + ffi::TypeTraits<const T*>::GetMismatchTypeInfo(&raw) + "`"
427 : "None";
428 *out = TVM_FFI_UNEXPECTED(TypeError)
429 << "Op `" << state->op->name << "`: Call.attrs expected `"
430 << ffi::TypeTraits<const T*>::TypeStr() << "`, got " << actual;
431 return false;
432 }
433 return true;
434 }
435};
436
437} // namespace sig
438
440class OpDef {
441 public:
446 TVM_TIRX_DLL explicit OpDef(const ffi::String& name);
452 TVM_TIRX_DLL OpDef(const ffi::String& name, const ffi::String& doc);
453 OpDef(const OpDef&) = delete;
454 OpDef& operator=(const OpDef&) = delete;
455 OpDef(OpDef&&) = delete;
456 OpDef& operator=(OpDef&&) = delete;
458 Op op() const { return op_; }
465 TVM_TIRX_DLL OpDef& add_arg(const ffi::String& name, const ffi::String& doc);
471 template <typename AttrsType>
473 uint32_t index = AttrsType::RuntimeTypeIndex();
474 get()->attrs_type_key = AttrsType::_type_key;
475 get()->attrs_type_index = index;
476 return *this;
477 }
483 TVM_TIRX_DLL OpDef& set_attrs_type_key(const ffi::String& key);
490 TVM_TIRX_DLL OpDef& add_ty_arg(const ffi::String& name, const ffi::String& doc);
513 template <typename... Specs>
514 OpDef& signature(const Specs&... specs) {
515 auto updated = ffi::make_object<OpNode>();
516 (ApplySignatureTrait(updated.get(), specs), ...);
517 if (op_->validator == nullptr) {
518 using View = ffi::reflection::NativeFunctionView<void(const CallNode*)>;
519 set_validator(View::FromNative<&ValidateSignature<Specs...>>());
520 get()->validator_is_custom = false;
521 }
522 OpNode* target = get();
523 target->args_info = std::move(updated->args_info);
524 target->ty_args_info = std::move(updated->ty_args_info);
525 target->var_args_info = std::move(updated->var_args_info);
526 target->var_ty_args_info = std::move(updated->var_ty_args_info);
527 target->attrs_type_key = std::move(updated->attrs_type_key);
528 target->attrs_type_index = updated->attrs_type_index;
529 return *this;
530 }
539 template <typename ValueType>
540 OpDef& set_attr(const ffi::String& attr_name, const ValueType& value, bool override = false) {
541 UpdateAttr(attr_name, ffi::Any(value), override);
542 return *this;
543 }
563 OpDef& set_validator(ffi::reflection::NativeFunctionView<void(const CallNode*)> validator,
564 bool override = false) {
565 TVM_FFI_CHECK(override || op_->validator == nullptr, ValueError)
566 << "Validator of " << op_->name << " is already registered";
567 get()->validator = ffi::reflection::NativeFunction<void(const CallNode*)>::From(validator);
568 get()->validator_is_custom = true;
569 return *this;
570 }
576 TVM_TIRX_DLL OpDef& reset_attr(const ffi::String& attr_name);
577
578 private:
579 template <typename Spec>
580 static void ApplySignatureTrait(OpNode* op, const Spec& spec) {
581 static_assert(std::is_base_of_v<sig::SignatureTrait, Spec>, "Unknown signature descriptor");
582 spec.CollectMetadata(op);
583 }
584
585 template <typename... Specs>
586 TVM_FFI_INLINE static ffi::Expected<void> ValidateSignature(const CallNode* call) noexcept {
587 static_assert((std::is_base_of_v<sig::SignatureTrait, Specs> && ...),
588 "Unknown signature descriptor");
589 constexpr size_t n_args = (size_t{0} + ... + Specs::kArgsCount);
590 constexpr size_t n_ty_args = (size_t{0} + ... + Specs::kTyArgsCount);
591 constexpr size_t n_var_args = (size_t{0} + ... + Specs::kVarArgsCount);
592 constexpr size_t n_var_ty_args = (size_t{0} + ... + Specs::kVarTyArgsCount);
593 constexpr size_t n_attrs = (size_t{0} + ... + Specs::kCallAttrsCount);
594 static_assert(n_var_args <= 1 && n_var_ty_args <= 1 && n_attrs <= 1,
595 "Duplicate signature tail or call_attrs");
596 const OpNode* op = call ? call->op.as<OpNode>() : nullptr;
597 if (TVM_FFI_PREDICT_FALSE(!op)) {
598 return TVM_FFI_UNEXPECTED(TypeError) << "Invalid Op Call";
599 }
600 if (TVM_FFI_PREDICT_FALSE(!call->args.defined() || !call->ty_args.defined())) {
601 return TVM_FFI_UNEXPECTED(TypeError) << "Op `" << op->name << "`: invalid Call";
602 }
603 ffi::Expected<void> result;
604 auto* out = &result;
605 if (TVM_FFI_PREDICT_FALSE(n_var_args ? call->args.size() < n_args
606 : call->args.size() != n_args)) {
607 *out = TVM_FFI_UNEXPECTED(TypeError)
608 << "Op `" << op->name << "`: Call.args expected " << (n_var_args ? "at least " : "")
609 << n_args << (n_args == 1 ? " argument" : " arguments") << ", got "
610 << call->args.size();
611 return result;
612 }
613 if (TVM_FFI_PREDICT_FALSE(n_var_ty_args ? call->ty_args.size() < n_ty_args
614 : call->ty_args.size() != n_ty_args)) {
615 *out = TVM_FFI_UNEXPECTED(TypeError)
616 << "Op `" << op->name << "`: Call.ty_args expected "
617 << (n_var_ty_args ? "at least " : "") << n_ty_args
618 << (n_ty_args == 1 ? " type argument" : " type arguments") << ", got "
619 << call->ty_args.size();
620 return result;
621 }
622 if constexpr (sizeof...(Specs) != 0) {
623 sig::ValidateState state{call, op};
624 if (TVM_FFI_PREDICT_FALSE(!(Specs::Validate(&state, out) && ...))) {
625 return result;
626 }
627 }
628 return result;
629 }
630
631 OpNode* get() { return const_cast<OpNode*>(op_.operator->()); }
632 TVM_TIRX_DLL void UpdateAttr(const ffi::String& attr_name, ffi::Any value, bool override);
633 Op op_;
634};
635
644template <typename ValueType>
646 public:
652 int count(const Op& op) const {
653 return op->index_ < column_.size() && column_[op->index_] != nullptr;
654 }
660 ValueType operator[](const Op& op) const {
661 TVM_FFI_ICHECK(count(op)) << "Attribute " << attr_name_ << " has not been registered for "
662 << op->name;
663 if constexpr (std::is_same_v<ValueType, ffi::Any>) {
664 return column_[op->index_];
665 } else {
666 return column_[op->index_].template cast<ValueType>();
667 }
668 }
675 ValueType get(const Op& op, ValueType def_value) const {
676 return count(op) ? (*this)[op] : def_value;
677 }
684 ValueType get(const Expr& expr, ValueType def_value) const {
685 TVM_FFI_ICHECK(expr.defined());
686 if (const auto* op = expr.as<OpNode>()) {
687 return get(ffi::GetRef<Op>(op), def_value);
688 }
689 return def_value;
690 }
691
692 private:
693 friend class Op;
694 OpAttrMap(ffi::List<ffi::Any> column, ffi::String attr_name)
695 : column_(std::move(column)), attr_name_(std::move(attr_name)) {}
696 ffi::List<ffi::Any> column_;
697 ffi::String attr_name_;
698};
699
700template <typename ValueType>
701OpAttrMap<ValueType> Op::GetAttrMap(const ffi::String& attr_name) {
702 return OpAttrMap<ValueType>(GetAttrColumn(attr_name), attr_name);
703}
704
705namespace op_attr {
706inline constexpr const char* kInferType = "FInferType";
707inline constexpr const char* kFixedReturnType = "TFixedReturnType";
708} // namespace op_attr
709
710} // namespace tvm
711#endif // TVM_IR_OP_H_
Helpers for attribute objects.
An operator argument's name and documentation.
Definition op.h:56
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.ArgumentInfo", ArgumentInfoObj, ffi::Object)
ffi::String doc
Argument documentation.
Definition op.h:61
static void RegisterReflection()
Definition op.h:63
ffi::String name
Argument name.
Definition op.h:59
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition op.h:70
Managed reference to an argument descriptor.
Definition op.h:75
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ArgumentInfo, ffi::ObjectRef, ArgumentInfoObj)
ArgumentInfo(ffi::UnsafeInit tag, ffi::ObjectPtr< ArgumentInfoObj > n)
Definition op.h:77
Call corresponds to callable invocation.
Definition expr.h:935
Base type of all the expressions.
Definition base_expr.h:324
Managed reference to ExprNode.
Definition base_expr.h:359
Typed live view of an Op attribute column.
Definition op.h:645
int count(const Op &op) const
Check whether an operator has a value in this column.
Definition op.h:652
ValueType operator[](const Op &op) const
Look up an operator's attribute, raising InternalError if absent.
Definition op.h:660
ValueType get(const Expr &expr, ValueType def_value) const
Look up an expression's attribute with a fallback.
Definition op.h:684
ValueType get(const Op &op, ValueType def_value) const
Look up an operator's attribute with a fallback.
Definition op.h:675
Noncopyable temporary builder for a canonical Op; see Op for the example.
Definition op.h:440
TVM_TIRX_DLL OpDef(const ffi::String &name, const ffi::String &doc)
Get or create the named Op and set its documentation.
TVM_TIRX_DLL OpDef & reset_attr(const ffi::String &attr_name)
Remove the current attribute value, with no priority fallback.
OpDef & operator=(const OpDef &)=delete
TVM_TIRX_DLL OpDef(const ffi::String &name)
Get or create the named Op without changing its documentation.
OpDef & attrs_type()
Set the attribute object type key and runtime index together.
Definition op.h:472
OpDef(const OpDef &)=delete
TVM_TIRX_DLL OpDef & add_arg(const ffi::String &name, const ffi::String &doc)
Append a required value-argument descriptor.
TVM_TIRX_DLL OpDef & set_attrs_type_key(const ffi::String &key)
Resolve and set the attribute object type key and runtime index together.
OpDef(OpDef &&)=delete
TVM_TIRX_DLL OpDef & add_ty_arg(const ffi::String &name, const ffi::String &doc)
Append a descriptor for a type argument in Call.ty_args.
OpDef & set_validator(ffi::reflection::NativeFunctionView< void(const CallNode *)> validator, bool override=false)
Register a validator that checks a Call with this operator.
Definition op.h:563
OpDef & set_attr(const ffi::String &attr_name, const ValueType &value, bool override=false)
Register an extensible attribute, rejecting duplicates unless overridden.
Definition op.h:540
OpDef & operator=(OpDef &&)=delete
Op op() const
Get the canonical operator.
Definition op.h:458
OpDef & signature(const Specs &... specs)
Register a complete typed Call signature and its validator.
Definition op.h:514
Metadata for a canonical primitive operator invoked through Call.
Definition op.h:86
bool validator_is_custom
Whether the validator was explicitly registered rather than generated.
Definition op.h:111
ffi::String attrs_type_key
Attribute object type key, or empty when no attrs type is declared.
Definition op.h:105
ffi::Array< ArgumentInfo > args_info
Descriptors for the ordered required value-argument prefix.
Definition op.h:97
ffi::Optional< ArgumentInfo > var_args_info
Named variadic value tail, excluded from the required args_info prefix.
Definition op.h:101
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.Op", OpNode, ExprNode)
uint32_t attrs_type_index
Runtime index corresponding to attrs_type_key; not serialized.
Definition op.h:107
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition op.h:115
ffi::String doc
Operator documentation.
Definition op.h:95
ffi::Array< ArgumentInfo > ty_args_info
Descriptors for the ordered required type-argument prefix.
Definition op.h:99
ffi::String name
Canonical operator name.
Definition op.h:93
static TVM_TIRX_DLL void RegisterReflection()
ffi::Optional< ArgumentInfo > var_ty_args_info
Named variadic type-argument tail, excluded from ty_args_info.
Definition op.h:103
friend class OpRegistry
Definition op.h:119
ffi::Any validator
Process-local validation callback, omitted from reflection.
Definition op.h:109
Reference-counted handle to a canonical named operator.
Definition op.h:147
static TVM_TIRX_DLL bool HasAttrMap(const ffi::String &attr_name)
Check whether an attribute column exists, even if some Ops lack a value.
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Op, Expr, OpNode)
static TVM_TIRX_DLL Op Get(const ffi::String &op_name)
Look up a registered operator by name.
TVM_FFI_INLINE void Validate(const CallNode *call) const
Validate a Call with this Op's callback, when one is registered.
Definition op.h:180
static TVM_TIRX_DLL ffi::Array< ffi::String > ListNames()
List registered operator names.
static OpAttrMap< ValueType > GetAttrMap(const ffi::String &attr_name)
Get a typed live view of a registered attribute column.
Definition op.h:701
Op(ffi::ObjectPtr< OpNode > n)
Construct a handle from a defined node.
Definition op.h:150
Managed reference to TypeNode.
Definition base_expr.h:80
Serializable global function used in IR.
Base expr nodes in TVM.
IR/AST nodes for TVM types shared across IR variants.
bool ReportTypeMismatch(ffi::Expected< void > *out, const ValidateState *state, bool type_arg, size_t index, ffi::AnyView actual)
Definition op.h:231
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition attr.h:23
ffi::reflection::NativeFunctionView< Type(const CallNode *call)> FInferType
Infer a Call's result type from its explicit inputs without builder state.
Definition op.h:53
#define TVM_TIRX_DLL
Definition base.h:83