This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new 4d98064b4f [REFACTOR][IR] Colocate typed attribute contracts (#20795)
4d98064b4f is described below
commit 4d98064b4f5b5d6595451f1dc40abbcb0d0c6e4d
Author: Tianqi Chen <[email protected]>
AuthorDate: Mon Oct 19 12:40:44 2026 -0400
[REFACTOR][IR] Colocate typed attribute contracts (#20795)
Place expression, tensor access, region, and operator attributes beside
their
owning APIs. Share the typed subscript contract across dialects, use
native
tensor-store validation, and remove redundant aliases and Evaluate's
type hook.
Keep primitive operators in prim/op.h and organize expression traits by
type,
with foundational conversion contracts available from base_expr.h.
---
src/relax/ir/dependent_type.cc | 29 +-
src/relax/utils.cc | 2 +-
src/s_tir/analysis/is_pure_function.cc | 2 +-
.../feature_extractor/per_store_feature.cc | 3 +-
src/s_tir/stmt.cc | 4 +-
src/s_tir/transform/rewrite_unsafe_select.cc | 5 +-
src/s_tir/transform/storage_access.cc | 2 +-
src/te/tensor.cc | 2 +-
tirx/include/tvm/ir/base_expr.h | 61 +++
tirx/include/tvm/ir/expr.h | 443 ++++-----------------
tirx/include/tvm/ir/op.h | 32 +-
tirx/include/tvm/ir/prim/op.h | 242 ++++++++++-
tirx/include/tvm/ir/stmt.h | 60 +--
tirx/include/tvm/script/printer/doc_translator.h | 6 +-
tirx/include/tvm/target/target.h | 12 +-
tirx/src/backend/cuda/codegen/intrin_rule_cuda.cc | 10 +-
tirx/src/backend/cuda/codegen/target_kind.cc | 2 +-
tirx/src/backend/cuda/op/iket.cc | 14 +-
tirx/src/backend/cuda/op/legacy.cc | 8 +-
tirx/src/backend/cuda/op/target_builtin.cc | 16 +-
tirx/src/backend/cuda/op/tcgen05.cc | 6 +-
tirx/src/backend/cuda/op/tensormap.cc | 2 +-
tirx/src/backend/cuda/tile/exec_context.cc | 1 +
.../src/backend/metal/codegen/intrin_rule_metal.cc | 6 +-
tirx/src/backend/metal/op/cooperative_tensor.cc | 8 +-
tirx/src/backend/metal/op/target_builtin.cc | 8 +-
.../backend/opencl/codegen/intrin_rule_opencl.cc | 1 +
tirx/src/backend/opencl/op/memory.cc | 6 +-
tirx/src/backend/trn/op/target_builtin.cc | 2 +-
.../backend/webgpu/codegen/intrin_rule_webgpu.cc | 6 +-
tirx/src/ir/expr.cc | 43 +-
tirx/src/ir/prim/builtin.cc | 13 +-
tirx/src/ir/prim/math.cc | 76 ++--
tirx/src/ir/side_effect.cc | 3 +-
tirx/src/ir/stmt.cc | 18 +-
tirx/src/ir/subscript_expr.cc | 22 +-
tirx/src/script/printer/ir/call.cc | 5 +-
tirx/src/tirx/ir/stmt.cc | 13 +-
tirx/src/tirx/ir/tensor.cc | 20 +-
tirx/src/tirx/ir/tensor_load.cc | 5 +-
tirx/src/tirx/op/abi.cc | 36 +-
tirx/src/tirx/op/annotation.cc | 4 +-
tirx/src/tirx/op/cpu.cc | 2 +-
tirx/src/tirx/op/gpu.cc | 32 +-
tirx/src/tirx/op/memory.cc | 31 +-
tirx/src/tirx/op/vector.cc | 8 +-
tirx/tests/cpp/ir/tensor_load_test.cc | 4 +-
tirx/tests/cpp/target/target_test.cc | 4 +-
.../python/tirx/script/test_error_handling.py | 9 +-
49 files changed, 680 insertions(+), 669 deletions(-)
diff --git a/src/relax/ir/dependent_type.cc b/src/relax/ir/dependent_type.cc
index 4430f7e527..2134064bc3 100644
--- a/src/relax/ir/dependent_type.cc
+++ b/src/relax/ir/dependent_type.cc
@@ -272,23 +272,18 @@ TVM_FFI_STATIC_INIT_BLOCK() {
ffi::FStructuralMutate::FromNative<&TensorTypeMutate>())
.attr(ffi::type_attr::kStructuralMaybeInplaceMutate,
ffi::FStructuralMutate::FromNative<&TensorTypeMaybeInplaceMutate>())
- .def(tvm::type_attr::kSubscriptExprRealize.name,
- [](Expr value,
- ffi::Array<ffi::Variant<ffi::Tuple<ffi::Optional<PrimExpr>,
ffi::Optional<PrimExpr>,
- ffi::Optional<PrimExpr>>,
- PrimExpr>>
- slice,
- Location loc) -> ffi::ObjectRef {
- TVM_FFI_CHECK_EQ(slice.size(), 1, IndexError)
- << "A Relax expression requires exactly one index";
- auto index = slice[0].as<PrimExpr>();
- TVM_FFI_CHECK(index.has_value(), TypeError)
- << "A Relax expression requires a point index";
- const auto* imm = index.value().as<IntImmNode>();
- TVM_FFI_CHECK(imm != nullptr, TypeError)
- << "A Relax expression requires a constant integer index";
- return TupleGetItem(value, imm->value.as<int>().value(), loc);
- });
+ .attr(tvm::type_attr::kExprSubscriptRealizeByTy,
+ [](Expr value, SubscriptSlice slice, Location loc) ->
ffi::ObjectRef {
+ TVM_FFI_CHECK_EQ(slice.size(), 1, IndexError)
+ << "A Relax expression requires exactly one index";
+ auto index = slice[0].as<PrimExpr>();
+ TVM_FFI_CHECK(index.has_value(), TypeError)
+ << "A Relax expression requires a point index";
+ const auto* imm = index.value().as<IntImmNode>();
+ TVM_FFI_CHECK(imm != nullptr, TypeError)
+ << "A Relax expression requires a constant integer index";
+ return TupleGetItem(value, imm->value.as<int>().value(), loc);
+ });
}
TVM_FFI_STATIC_INIT_BLOCK() {
diff --git a/src/relax/utils.cc b/src/relax/utils.cc
index 4e1c6bbe6d..e0cf657da4 100644
--- a/src/relax/utils.cc
+++ b/src/relax/utils.cc
@@ -247,7 +247,7 @@ bool IsImpureCall(const Call& call) {
static auto effect_map = Op::GetAttrMap(tvm::op_attr::kCallEffectKind);
TVM_FFI_ICHECK(effect_map.count(op))
<< "Cannot find the registered purity or call effect of this op: " <<
op->name;
- auto effect = static_cast<CallEffectKind>(effect_map[op]);
+ auto effect = effect_map[op];
return effect > CallEffectKind::kPure;
}
TVM_FFI_CHECK(!call->op->ty.as<tvm::FuncTypeNode>(), TypeError)
diff --git a/src/s_tir/analysis/is_pure_function.cc
b/src/s_tir/analysis/is_pure_function.cc
index a4084d69f5..873a7a224c 100644
--- a/src/s_tir/analysis/is_pure_function.cc
+++ b/src/s_tir/analysis/is_pure_function.cc
@@ -105,7 +105,7 @@ class PurityChecker : public StmtExprVisitor {
static auto op_call_effect = Op::GetAttrMap(tvm::op_attr::kCallEffectKind);
CallEffectKind effect = [&]() {
if (auto opt = call->op.as<Op>()) {
- return static_cast<CallEffectKind>(op_call_effect[opt.value()]);
+ return op_call_effect[opt.value()];
} else {
return CallEffectKind::kOpaque;
}
diff --git a/src/s_tir/meta_schedule/feature_extractor/per_store_feature.cc
b/src/s_tir/meta_schedule/feature_extractor/per_store_feature.cc
index 07b4990769..e42aaa826d 100644
--- a/src/s_tir/meta_schedule/feature_extractor/per_store_feature.cc
+++ b/src/s_tir/meta_schedule/feature_extractor/per_store_feature.cc
@@ -694,8 +694,7 @@ Feature::ArithOps::ArithOps(const TensorStoreNode* store,
int64_t prod_loop_exte
return StmtExprVisitor::Visit_(op);
}
static auto op_call_effect_ =
Op::GetAttrMap(tvm::op_attr::kCallEffectKind);
- CallEffectKind effect_kind =
-
static_cast<CallEffectKind>(op_call_effect_[op->op.as_or_throw<Op>()]);
+ CallEffectKind effect_kind = op_call_effect_[op->op.as_or_throw<Op>()];
bool is_pure =
effect_kind == CallEffectKind::kPure || effect_kind ==
CallEffectKind::kExprAnnotation;
if (is_pure) {
diff --git a/src/s_tir/stmt.cc b/src/s_tir/stmt.cc
index 0b196a9c0f..979adb4456 100644
--- a/src/s_tir/stmt.cc
+++ b/src/s_tir/stmt.cc
@@ -69,11 +69,11 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("s_tir.async_commit", "Commit asynchronous copies to a queue.")
.signature(sig::arg<IntImm>("queue_id"))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kUpdateState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kUpdateState);
OpDef("s_tir.async_wait", "Wait for committed asynchronous copies.")
.signature(sig::arg<IntImm>("queue_id"),
sig::arg<PrimExpr>("inflight_count"))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kUpdateState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kUpdateState);
}
namespace {
diff --git a/src/s_tir/transform/rewrite_unsafe_select.cc
b/src/s_tir/transform/rewrite_unsafe_select.cc
index ff2e90f4f5..0ee073315a 100644
--- a/src/s_tir/transform/rewrite_unsafe_select.cc
+++ b/src/s_tir/transform/rewrite_unsafe_select.cc
@@ -56,7 +56,7 @@ class UnsafeExprDetector : public tvm::ExprFunctor<bool(const
Expr& n)> {
}
return Dispatch(op->args[0]);
} else if (auto opt = op->op.as<Op>()) {
- auto effect_kind =
static_cast<CallEffectKind>(op_call_effect_[opt.value()]);
+ auto effect_kind = op_call_effect_[opt.value()];
if (effect_kind == CallEffectKind::kPure || effect_kind ==
CallEffectKind::kExprAnnotation) {
for (const Expr& arg : op->args) {
if (Dispatch(arg)) return true;
@@ -122,8 +122,7 @@ class UnsafeExprDetector : public
tvm::ExprFunctor<bool(const Expr& n)> {
return Dispatch(op->a) || Dispatch(op->b);
}
- decltype(Op::GetAttrMap(tvm::op_attr::kCallEffectKind)) op_call_effect_ =
- Op::GetAttrMap(tvm::op_attr::kCallEffectKind);
+ OpAttrMap<CallEffectKind> op_call_effect_ =
Op::GetAttrMap(tvm::op_attr::kCallEffectKind);
};
class UnsafeSelectRewriter : public StmtExprMutator {
diff --git a/src/s_tir/transform/storage_access.cc
b/src/s_tir/transform/storage_access.cc
index 5ecc9878f1..e47bd8a5fa 100644
--- a/src/s_tir/transform/storage_access.cc
+++ b/src/s_tir/transform/storage_access.cc
@@ -396,7 +396,7 @@ ffi::Optional<VisitInterrupt>
StorageAccessVisitor::Visit_(const CallNode* op) {
auto effect_map = Op::GetAttrMap(tvm::op_attr::kCallEffectKind);
auto callee = op->op.as<Op>();
if (!callee.has_value() || !effect_map.count(callee.value()) ||
- effect_map[callee.value()] > static_cast<int>(CallEffectKind::kPure)) {
+ effect_map[callee.value()] > CallEffectKind::kPure) {
in_opaque_call_ = true;
}
auto result = StmtExprVisitor::Visit_(op);
diff --git a/src/te/tensor.cc b/src/te/tensor.cc
index d1a41975ed..01168cf97b 100644
--- a/src/te/tensor.cc
+++ b/src/te/tensor.cc
@@ -104,7 +104,7 @@ PrimVar var(std::string name_hint, PrimType t) { return
PrimVar(name_hint, t); }
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("te.tensor_load")
.signature(sig::arg("tensor", "The input tensor."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kReadState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kReadState);
}
// Tensor
diff --git a/tirx/include/tvm/ir/base_expr.h b/tirx/include/tvm/ir/base_expr.h
index 380a10c0ae..e7a15bc421 100644
--- a/tirx/include/tvm/ir/base_expr.h
+++ b/tirx/include/tvm/ir/base_expr.h
@@ -25,9 +25,14 @@
#define TVM_IR_BASE_EXPR_H_
#include <tvm/ffi/cast.h>
+#include <tvm/ffi/container/array.h>
+#include <tvm/ffi/container/tuple.h>
+#include <tvm/ffi/container/variant.h>
#include <tvm/ffi/dtype.h>
#include <tvm/ffi/extra/structural_mutate.h>
#include <tvm/ffi/extra/structural_visit.h>
+#include <tvm/ffi/function.h>
+#include <tvm/ffi/optional.h>
#include <tvm/ffi/reflection/registry.h>
#include <tvm/ffi/string.h>
#include <tvm/ir/location.h>
@@ -528,8 +533,64 @@ struct TypeTraits<TypedExpr<ExpectedType>>
}
};
+// Declare these traits before containers such as Array<Expr> and
SubscriptSlice instantiate them.
+// Conversion bodies that require literal or tuple nodes are defined in
expr.cc.
+// Generic expression arguments accept primitive/string literals and arrays of
expressions.
+template <>
+inline constexpr bool use_default_type_traits_v<Expr> = false;
+
+template <>
+struct TypeTraits<Expr> : public ObjectRefWithFallbackTraitsBase<Expr,
PrimExpr, ffi::String> {
+ TVM_FFI_INLINE static Expr ConvertFallbackValue(PrimExpr value) { return
value; }
+ TVM_TIRX_DLL static Expr ConvertFallbackValue(ffi::String value);
+ TVM_TIRX_DLL static std::optional<Expr> TryCastFromAnyView(const TVMFFIAny*
src);
+};
+
+// Primitive expression arguments also accept bool, integer, and
floating-point literals.
+template <>
+inline constexpr bool use_default_type_traits_v<PrimExpr> = false;
+
+template <>
+struct TypeTraits<PrimExpr>
+ : public ObjectRefWithFallbackTraitsBase<PrimExpr, StrictBool, int64_t,
double> {
+ using Base = ObjectRefWithFallbackTraitsBase<PrimExpr, StrictBool, int64_t,
double>;
+ TVM_FFI_INLINE static bool CheckAnyStrict(const TVMFFIAny* src) {
+ if (src->type_index == TypeIndex::kTVMFFINone) return
PrimExpr::_type_is_nullable;
+ return TypeTraits<TypedExpr<PrimType>>::CheckAnyStrict(src);
+ }
+
+ TVM_TIRX_DLL static std::optional<PrimExpr> TryCastFromAnyView(const
TVMFFIAny* src);
+
+ TVM_FFI_INLINE static std::string TypeStr() { return "ir.PrimExpr"; }
+
+ TVM_FFI_INLINE static std::string GetMismatchTypeInfo(const TVMFFIAny* src) {
+ return TypeTraits<TypedExpr<PrimType>>::GetMismatchTypeInfo(src);
+ }
+
+ TVM_TIRX_DLL static PrimExpr ConvertFallbackValue(StrictBool value);
+ TVM_TIRX_DLL static PrimExpr ConvertFallbackValue(int64_t value);
+ TVM_TIRX_DLL static PrimExpr ConvertFallbackValue(double value);
+};
+
} // namespace ffi
+/*! \brief Expression subscripts: point indices or (start, stop, step) slices.
*/
+using SubscriptSlice = ffi::Array<ffi::Variant<
+ ffi::Tuple<ffi::Optional<PrimExpr>, ffi::Optional<PrimExpr>,
ffi::Optional<PrimExpr>>,
+ PrimExpr>>;
+
+namespace type_attr {
+/*!
+ * \brief Realize a subscript of an expression, dispatched on the type of the
expression.
+ *
+ * The callback receives the expression, its point indices or slices, and the
source location.
+ * It returns a defined object representing the realized subscription.
+ */
+inline constexpr ffi::reflection::AttrKey<
+ ffi::TypedFunction<ffi::ObjectRef(Expr, SubscriptSlice, Location)>>
+ kExprSubscriptRealizeByTy{"__tvm_expr_subscript_realize__"};
+} // namespace type_attr
+
} // namespace tvm
#endif // TVM_IR_BASE_EXPR_H_
diff --git a/tirx/include/tvm/ir/expr.h b/tirx/include/tvm/ir/expr.h
index add9df21c8..c19b5621a3 100644
--- a/tirx/include/tvm/ir/expr.h
+++ b/tirx/include/tvm/ir/expr.h
@@ -249,119 +249,6 @@ class FloatImm : public PrimExpr {
TVM_DEFINE_OBJECT_REF_COW_METHOD(FloatImmNode);
};
-namespace ffi {
-// Type traits to enable automatic conversion into IntImm, Integer, and Bool
-// when called through the FFI
-template <>
-inline constexpr bool use_default_type_traits_v<IntImm> = false;
-
-// specialize to enable implicit conversion from const char*
-template <>
-struct TypeTraits<IntImm> : public ObjectRefWithFallbackTraitsBase<IntImm,
int64_t> {
- TVM_FFI_INLINE static IntImm ConvertFallbackValue(int64_t value) {
- auto value_ty =
- (value > std::numeric_limits<int>::max() || value <
std::numeric_limits<int>::min())
- ? PrimType::Int(64)
- : PrimType::Int(32);
- return IntImm(value_ty, value);
- }
-};
-
-template <>
-inline constexpr bool use_default_type_traits_v<FloatImm> = false;
-
-template <>
-struct TypeTraits<FloatImm> : public ObjectRefWithFallbackTraitsBase<FloatImm,
double> {
- TVM_FFI_INLINE static FloatImm ConvertFallbackValue(double value) {
- return FloatImm(PrimType::Float(32), value);
- }
-};
-template <>
-inline constexpr bool use_default_type_traits_v<tvm::StringImm> = false;
-
-template <>
-struct TypeTraits<tvm::StringImm>
- : public ObjectRefWithFallbackTraitsBase<tvm::StringImm, ffi::String> {
- TVM_FFI_INLINE static tvm::StringImm ConvertFallbackValue(ffi::String value)
{
- return tvm::StringImm(value);
- }
-};
-
-// define automatic conversion from bool, int64_t, double to PrimExpr
-template <>
-inline constexpr bool use_default_type_traits_v<PrimExpr> = false;
-
-template <>
-struct TypeTraits<PrimExpr>
- : public ObjectRefWithFallbackTraitsBase<PrimExpr, StrictBool, int64_t,
double> {
- using Base = ObjectRefWithFallbackTraitsBase<PrimExpr, StrictBool, int64_t,
double>;
- TVM_FFI_INLINE static bool CheckAnyStrict(const TVMFFIAny* src) {
- if (src->type_index == TypeIndex::kTVMFFINone) return
PrimExpr::_type_is_nullable;
- return TypeTraits<TypedExpr<PrimType>>::CheckAnyStrict(src);
- }
-
- TVM_FFI_INLINE static std::optional<PrimExpr> TryCastFromAnyView(const
TVMFFIAny* src) {
- // A required expression cannot accept None.
- if (src->type_index == TypeIndex::kTVMFFINone) return std::nullopt;
- return Base::TryCastFromAnyView(src);
- }
-
- TVM_FFI_INLINE static std::string TypeStr() { return "ir.PrimExpr"; }
-
- TVM_FFI_INLINE static std::string GetMismatchTypeInfo(const TVMFFIAny* src) {
- return TypeTraits<TypedExpr<PrimType>>::GetMismatchTypeInfo(src);
- }
-
- TVM_FFI_INLINE static PrimExpr ConvertFallbackValue(StrictBool value) {
- return IntImm::Bool(value);
- }
- TVM_FFI_INLINE static PrimExpr ConvertFallbackValue(int64_t value) {
- return TypeTraits<IntImm>::ConvertFallbackValue(value);
- }
- TVM_FFI_INLINE static PrimExpr ConvertFallbackValue(double value) {
- return TypeTraits<FloatImm>::ConvertFallbackValue(value);
- }
-};
-
-template <>
-inline constexpr bool use_default_type_traits_v<IntExpr> = false;
-
-template <>
-struct TypeTraits<IntExpr> : public ObjectRefWithFallbackTraitsBase<IntExpr,
int64_t> {
- using Base = ObjectRefWithFallbackTraitsBase<IntExpr, int64_t>;
-
- TVM_FFI_INLINE static bool CheckAnyStrict(const TVMFFIAny* src) {
- if (!Base::CheckAnyStrict(src)) return false;
- if (src->type_index == TypeIndex::kTVMFFINone) return true;
- const auto* expr =
details::ObjectUnsafe::RawObjectPtrFromUnowned<ExprNode>(src->v_obj);
- const auto* ty = expr->ty.as<PrimTypeNode>();
- return ty != nullptr && ty->dtype.lanes == 1 &&
- (ty->dtype.code == kDLInt || ty->dtype.code == kDLUInt);
- }
-
- TVM_FFI_INLINE static IntExpr ConvertFallbackValue(int64_t value) {
- return
TypeTraits<PrimExpr>::ConvertFallbackValue(value).as_or_throw<IntExpr>();
- }
-
- TVM_FFI_INLINE static std::string TypeStr() { return "ir.IntExpr"; }
-
- TVM_FFI_INLINE static std::string GetMismatchTypeInfo(const TVMFFIAny* src) {
- return TypeTraits<TypedExpr<PrimType>>::GetMismatchTypeInfo(src);
- }
-};
-
-// Generic Expr arguments accept primitive/string literals and arrays of
expressions.
-template <>
-inline constexpr bool use_default_type_traits_v<Expr> = false;
-
-template <>
-struct TypeTraits<Expr> : public ObjectRefWithFallbackTraitsBase<Expr,
PrimExpr, ffi::String> {
- TVM_FFI_INLINE static Expr ConvertFallbackValue(PrimExpr value) { return
value; }
- TVM_FFI_INLINE static Expr ConvertFallbackValue(ffi::String value) { return
StringImm(value); }
- static std::optional<Expr> TryCastFromAnyView(const TVMFFIAny* src);
-};
-} // namespace ffi
-
/*! \brief Tuple container */
class TupleNode : public ExprNode {
public:
@@ -392,18 +279,6 @@ class Tuple : public Expr {
TVM_DEFINE_OBJECT_REF_COW_METHOD(TupleNode);
};
-// Use ordinary inline: array elements recursively invoke this conversion.
-inline std::optional<Expr> ffi::TypeTraits<Expr>::TryCastFromAnyView(const
TVMFFIAny* src) {
- if (auto value =
- ObjectRefWithFallbackTraitsBase<Expr, PrimExpr,
ffi::String>::TryCastFromAnyView(src)) {
- return value;
- }
- if (auto fields =
ffi::TypeTraits<ffi::Array<Expr>>::TryCastFromAnyView(src)) {
- return tvm::Tuple(std::move(*fields));
- }
- return std::nullopt;
-}
-
/*! \brief Get the index-th field out of a tuple. */
class TupleGetItemNode : public ExprNode {
public:
@@ -463,11 +338,15 @@ class TensorLoadNode : public ExprNode {
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.TensorLoad", TensorLoadNode, ExprNode);
};
+namespace type_attr {
/*!
* \brief Infer a load's primitive result type from its populated source,
indices and location.
* \note The callback must derive the result from those inputs, not the
unpublished result type.
*/
-using FTensorLoadInferType =
ffi::reflection::NativeFunctionView<PrimType(const TensorLoadNode*)>;
+inline constexpr ffi::reflection::AttrKey<
+ ffi::reflection::NativeFunctionView<PrimType(const TensorLoadNode*)>>
+ kTensorLoadInferType{"__tvm_tensor_load_infer_type__"};
+} // namespace type_attr
/*! \brief Managed reference to TensorLoadNode. */
class TensorLoad : public PrimExpr {
@@ -487,220 +366,6 @@ class TensorLoad : public PrimExpr {
TVM_DEFINE_OBJECT_REF_COW_METHOD(TensorLoadNode);
};
-/*!
- * \brief add operator
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator+(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief subtraction operator
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator-(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief negation.
- *
- * \param a input.
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator-(PrimExpr a);
-
-/*!
- * \brief multiplication operator
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator*(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief division operator
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator/(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief left shift operator
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator<<(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief right shift operator
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator>>(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief greater
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator>(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief greater_equal
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator>=(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief less
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator<(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief less_equal
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator<=(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief equal
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator==(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief not_equal
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator!=(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief and
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note This operator does eager constant folding.
- */
-TVM_TIRX_DLL PrimExpr operator&&(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief or
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note This operator does eager constant folding.
- */
-TVM_TIRX_DLL PrimExpr operator||(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief not
- *
- * \param a left operand
- * \return The result expression.
- * \note This operator does eager constant folding.
- */
-TVM_TIRX_DLL PrimExpr operator!(PrimExpr a);
-
-/*!
- * \brief take bitwise and of two values
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator&(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief take bitwise or of two values
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator|(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief take bitwise xor of two values
- *
- * \param a left operand
- * \param b right operand
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator^(PrimExpr a, PrimExpr b);
-
-/*!
- * \brief take bitwise negation of two values
- *
- * \param a the input expression.
- * \return The result expression.
- * \note this function does eager constant folding for
- * index types(int32, int64) when possible.
- */
-TVM_TIRX_DLL PrimExpr operator~(PrimExpr a);
-
/*!
* \brief A local variable in the IR.
*
@@ -1008,6 +673,11 @@ class Call : public Expr {
TVM_DEFINE_OBJECT_REF_COW_METHOD(CallNode);
};
+namespace op_attr {
+/*! \brief The runtime effect of an operator call. */
+inline constexpr ffi::reflection::AttrKey<CallEffectKind>
kCallEffectKind{"TCallEffectKind"};
+} // namespace op_attr
+
/*! \brief range over one dimension */
class RangeNode : public ffi::Object {
public:
@@ -1134,13 +804,76 @@ TVM_TIRX_DLL CallEffectKind SideEffect(const Expr& expr);
namespace ffi {
template <>
-inline constexpr bool use_default_type_traits_v<TensorRegion> = false;
+inline constexpr bool use_default_type_traits_v<IntExpr> = false;
template <>
-struct TypeTraits<TensorRegion> : public
ObjectRefWithFallbackTraitsBase<TensorRegion, TensorLoad> {
- TVM_TIRX_DLL static TensorRegion ConvertFallbackValue(TensorLoad value);
+struct TypeTraits<IntExpr> : public ObjectRefWithFallbackTraitsBase<IntExpr,
int64_t> {
+ using Base = ObjectRefWithFallbackTraitsBase<IntExpr, int64_t>;
+
+ TVM_FFI_INLINE static bool CheckAnyStrict(const TVMFFIAny* src) {
+ if (!Base::CheckAnyStrict(src)) return false;
+ if (src->type_index == TypeIndex::kTVMFFINone) return true;
+ const auto* expr =
details::ObjectUnsafe::RawObjectPtrFromUnowned<ExprNode>(src->v_obj);
+ const auto* ty = expr->ty.as<PrimTypeNode>();
+ return ty != nullptr && ty->dtype.lanes == 1 &&
+ (ty->dtype.code == kDLInt || ty->dtype.code == kDLUInt);
+ }
+
+ TVM_FFI_INLINE static IntExpr ConvertFallbackValue(int64_t value) {
+ return
TypeTraits<PrimExpr>::ConvertFallbackValue(value).as_or_throw<IntExpr>();
+ }
+
+ TVM_FFI_INLINE static std::string TypeStr() { return "ir.IntExpr"; }
+
+ TVM_FFI_INLINE static std::string GetMismatchTypeInfo(const TVMFFIAny* src) {
+ return TypeTraits<TypedExpr<PrimType>>::GetMismatchTypeInfo(src);
+ }
};
+template <>
+inline constexpr bool use_default_type_traits_v<tvm::StringImm> = false;
+
+template <>
+struct TypeTraits<tvm::StringImm>
+ : public ObjectRefWithFallbackTraitsBase<tvm::StringImm, ffi::String> {
+ TVM_FFI_INLINE static tvm::StringImm ConvertFallbackValue(ffi::String value)
{
+ return tvm::StringImm(value);
+ }
+};
+
+template <>
+inline constexpr bool use_default_type_traits_v<IntImm> = false;
+
+template <>
+struct TypeTraits<IntImm> : public ObjectRefWithFallbackTraitsBase<IntImm,
int64_t> {
+ TVM_FFI_INLINE static IntImm ConvertFallbackValue(int64_t value) {
+ auto value_ty =
+ (value > std::numeric_limits<int>::max() || value <
std::numeric_limits<int>::min())
+ ? PrimType::Int(64)
+ : PrimType::Int(32);
+ return IntImm(value_ty, value);
+ }
+};
+
+template <>
+inline constexpr bool object_ref_contains_v<PrimExpr, IntImmNode> = true;
+
+template <>
+inline constexpr bool use_default_type_traits_v<FloatImm> = false;
+
+template <>
+struct TypeTraits<FloatImm> : public ObjectRefWithFallbackTraitsBase<FloatImm,
double> {
+ TVM_FFI_INLINE static FloatImm ConvertFallbackValue(double value) {
+ return FloatImm(PrimType::Float(32), value);
+ }
+};
+
+template <>
+inline constexpr bool object_ref_contains_v<PrimExpr, FloatImmNode> = true;
+
+template <>
+inline constexpr bool object_ref_contains_v<PrimExpr, TensorLoadNode> = true;
+
template <>
inline constexpr bool use_default_type_traits_v<PrimVar> = false;
@@ -1180,29 +913,15 @@ struct TypeTraits<PrimVar> : public
ObjectRefTypeTraitsBase<PrimVar> {
};
template <>
-inline constexpr bool object_ref_contains_v<PrimExpr, IntImmNode> = true;
-template <>
-inline constexpr bool object_ref_contains_v<PrimExpr, FloatImmNode> = true;
+inline constexpr bool use_default_type_traits_v<TensorRegion> = false;
+
template <>
-inline constexpr bool object_ref_contains_v<PrimExpr, TensorLoadNode> = true;
+struct TypeTraits<TensorRegion> : public
ObjectRefWithFallbackTraitsBase<TensorRegion, TensorLoad> {
+ TVM_TIRX_DLL static TensorRegion ConvertFallbackValue(TensorLoad value);
+};
} // namespace ffi
-namespace op_attr {
-/*! \brief Use integer to record the kind. */
-inline constexpr ffi::reflection::AttrKey<int64_t>
kCallEffectKind{"TCallEffectKind"};
-} // namespace op_attr
-
-// Compatibility names; new callers can deduce the value type from the key.
-using TCallEffectKind = decltype(op_attr::kCallEffectKind)::ValueType;
-
-namespace type_attr {
-inline constexpr ffi::reflection::AttrKey<FTensorLoadInferType>
kTensorLoadInferType{
- "__tvm_tensor_load_infer_type__"};
-inline constexpr ffi::reflection::AttrKey<ffi::Function> kSubscriptExprRealize{
- "__tvm_subscript_expr_realize__"};
-} // namespace type_attr
-
} // namespace tvm
/* \brief Allow tvm.Var and tvm.GlobalVar as keys in STL tables
diff --git a/tirx/include/tvm/ir/op.h b/tirx/include/tvm/ir/op.h
index 9ae353a8c5..4b77eb316b 100644
--- a/tirx/include/tvm/ir/op.h
+++ b/tirx/include/tvm/ir/op.h
@@ -199,6 +199,22 @@ class Op : public Expr {
TVM_TIRX_DLL static ffi::List<ffi::Any> GetAttrColumn(const ffi::String&
attr_name);
};
+namespace op_attr {
+/*! \brief Infer a Call's result type from its explicit inputs without builder
state. */
+inline constexpr ffi::reflection::AttrKey<
+ ffi::reflection::NativeFunctionView<Type(const CallNode* call)>>
+ kInferType{"FInferType"};
+/*!
+ * \brief An operator's result type independent of operands, attributes, and
type arguments.
+ * When present, this concrete type takes precedence over FInferType.
+ */
+inline constexpr ffi::reflection::AttrKey<Type>
kFixedReturnType{"TFixedReturnType"};
+} // namespace op_attr
+
+// Compatibility names; new callers can deduce the value type from the key.
+using FInferType = decltype(op_attr::kInferType)::ValueType;
+using TFixedReturnType = decltype(op_attr::kFixedReturnType)::ValueType;
+
namespace sig {
/*! \brief Base counts for descriptors accepted by OpDef::signature. */
@@ -743,21 +759,5 @@ OpAttrMap<ValueType>
Op::GetAttrMap(ffi::reflection::AttrKey<ValueType> key) {
return GetAttrMap<ValueType>(key.name);
}
-namespace op_attr {
-/*! \brief Infer a Call's result type from its explicit inputs without builder
state. */
-inline constexpr ffi::reflection::AttrKey<
- ffi::reflection::NativeFunctionView<Type(const CallNode* call)>>
- kInferType{"FInferType"};
-/*!
- * \brief An operator's result type independent of operands, attributes, and
type arguments.
- * When present, this concrete type takes precedence over FInferType.
- */
-inline constexpr ffi::reflection::AttrKey<Type>
kFixedReturnType{"TFixedReturnType"};
-} // namespace op_attr
-
-// Compatibility names; new callers can deduce the value type from the key.
-using FInferType = decltype(op_attr::kInferType)::ValueType;
-using TFixedReturnType = decltype(op_attr::kFixedReturnType)::ValueType;
-
} // namespace tvm
#endif // TVM_IR_OP_H_
diff --git a/tirx/include/tvm/ir/prim/op.h b/tirx/include/tvm/ir/prim/op.h
index 1d059dad9b..f1eca89c4e 100644
--- a/tirx/include/tvm/ir/prim/op.h
+++ b/tirx/include/tvm/ir/prim/op.h
@@ -30,6 +30,239 @@
#include <type_traits>
#include <utility>
namespace tvm {
+
+/*!
+ * \brief add operator
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator+(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief subtraction operator
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator-(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief negation.
+ *
+ * \param a input.
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator-(PrimExpr a);
+
+/*!
+ * \brief multiplication operator
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator*(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief division operator
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator/(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief left shift operator
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator<<(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief right shift operator
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator>>(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief greater
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator>(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief greater_equal
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator>=(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief less
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator<(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief less_equal
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator<=(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief equal
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator==(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief not_equal
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator!=(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief and
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note This operator does eager constant folding.
+ */
+TVM_TIRX_DLL PrimExpr operator&&(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief or
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note This operator does eager constant folding.
+ */
+TVM_TIRX_DLL PrimExpr operator||(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief not
+ *
+ * \param a left operand
+ * \return The result expression.
+ * \note This operator does eager constant folding.
+ */
+TVM_TIRX_DLL PrimExpr operator!(PrimExpr a);
+
+/*!
+ * \brief take bitwise and of two values
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator&(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief take bitwise or of two values
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator|(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief take bitwise xor of two values
+ *
+ * \param a left operand
+ * \param b right operand
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator^(PrimExpr a, PrimExpr b);
+
+/*!
+ * \brief take bitwise negation of two values
+ *
+ * \param a the input expression.
+ * \return The result expression.
+ * \note this function does eager constant folding for
+ * index types(int32, int64) when possible.
+ */
+TVM_TIRX_DLL PrimExpr operator~(PrimExpr a);
+
+/*! \brief Add an expression in place. */
+inline PrimExpr operator+=(PrimExpr& a, PrimExpr b) {
+ a = a + b;
+ return a;
+}
+
+/*! \brief Subtract an expression in place. */
+inline PrimExpr operator-=(PrimExpr& a, PrimExpr b) {
+ a = a - b;
+ return a;
+}
+
+/*! \brief Multiply an expression in place. */
+inline PrimExpr operator*=(PrimExpr& a, PrimExpr b) {
+ a = a * b;
+ return a;
+}
+
namespace prim {
/*!
@@ -565,12 +798,6 @@ inline PrimExpr MakeConst(PrimType dtype, ValueType value,
Location loc) {
} // namespace prim
// additional const expression overloading
-#define TVM_DEFINE_ASSIGN_OP_OVERLOAD(Name, OpFunc) \
- inline PrimExpr Name(PrimExpr& a, PrimExpr b) { \
- a = OpFunc(a, b); \
- return a; \
- }
-
#define TVM_DEFINE_BINOP_CONST_VAL_OVERLOAD(Name)
\
inline PrimExpr Name(const PrimExpr& a, float b) { return Name(a,
PrimExpr(b)); } \
inline PrimExpr Name(float a, const PrimExpr& b) { return Name(PrimExpr(a),
b); } \
@@ -621,9 +848,6 @@ inline PrimExpr MakeConst(PrimType dtype, ValueType value,
Location loc) {
return Name(prim::MakeConst(b.ty(), a), b, loc);
\
}
-TVM_DEFINE_ASSIGN_OP_OVERLOAD(operator+=, operator+);
-TVM_DEFINE_ASSIGN_OP_OVERLOAD(operator-=, operator-);
-TVM_DEFINE_ASSIGN_OP_OVERLOAD(operator*=, operator*);
TVM_DEFINE_BINOP_CONST_VAL_OVERLOAD(operator+);
TVM_DEFINE_BINOP_CONST_VAL_OVERLOAD(operator-);
TVM_DEFINE_BINOP_CONST_VAL_OVERLOAD(operator*);
diff --git a/tirx/include/tvm/ir/stmt.h b/tirx/include/tvm/ir/stmt.h
index 16768fced7..53c832dcb8 100644
--- a/tirx/include/tvm/ir/stmt.h
+++ b/tirx/include/tvm/ir/stmt.h
@@ -233,6 +233,29 @@ class RegionStmt : public Stmt {
TVM_DEFINE_OBJECT_REF_COW_METHOD(RegionStmtNode);
};
+namespace op_attr {
+/*!
+ * \brief Construct fresh typed variables for a region's lexical body
parameters.
+ *
+ * The input carries only the operation, operands and attributes, without a
body
+ * or builder state. Parameters are ordered, distinct definitions and may have
+ * name hints. Every region operation must register this hook, returning an
empty
+ * array when it has no body parameters. Presence of the attribute identifies
+ * region support without invoking the hook or allocating variables.
+ */
+inline constexpr ffi::reflection::AttrKey<
+ ffi::reflection::NativeFunctionView<ffi::Array<Var>(const CallNode* call)>>
+ kRegionGetBodyParams{"FRegionGetBodyParams"};
+/*! \brief Optional dialect validation of a complete region statement. */
+inline constexpr ffi::reflection::AttrKey<
+ ffi::reflection::NativeFunctionView<void(const RegionStmtNode*)>>
+ kRegionValidate{"FRegionValidate"};
+} // namespace op_attr
+
+// Compatibility names; new callers can deduce the value type from the key.
+using FRegionGetBodyParams =
decltype(op_attr::kRegionGetBodyParams)::ValueType;
+using FRegionValidate = decltype(op_attr::kRegionValidate)::ValueType;
+
/*!
* \brief Assert condition, if an error occurs, return the error message.
*
@@ -328,6 +351,13 @@ class TensorStore : public Stmt {
TVM_DEFINE_OBJECT_REF_COW_METHOD(TensorStoreNode);
};
+namespace type_attr {
+/*! \brief Validate a tensor store by its destination type before constructing
the statement. */
+inline constexpr
ffi::reflection::AttrKey<ffi::reflection::NativeFunctionView<void(
+ const Expr&, const ffi::Array<PrimExpr>&, const PrimExpr&)>>
+ kTensorStoreValidateByTy{"__tvm_tensor_store_validate__"};
+} // namespace type_attr
+
/*!
* \brief Evaluates an expression.
* This is mostly used for putting a Call node into Stmt.
@@ -657,35 +687,5 @@ inline const char* ForKind2String(ForKind t) {
TVM_FFI_UNREACHABLE();
}
-namespace op_attr {
-/*!
- * \brief Construct fresh typed variables for a region's lexical body
parameters.
- *
- * The input carries only the operation, operands and attributes, without a
body
- * or builder state. Parameters are ordered, distinct definitions and may have
- * name hints. Every region operation must register this hook, returning an
empty
- * array when it has no body parameters. Presence of the attribute identifies
- * region support without invoking the hook or allocating variables.
- */
-inline constexpr ffi::reflection::AttrKey<
- ffi::reflection::NativeFunctionView<ffi::Array<Var>(const CallNode* call)>>
- kRegionGetBodyParams{"FRegionGetBodyParams"};
-/*! \brief Optional dialect validation of a complete region statement. */
-inline constexpr ffi::reflection::AttrKey<
- ffi::reflection::NativeFunctionView<void(const RegionStmtNode*)>>
- kRegionValidate{"FRegionValidate"};
-} // namespace op_attr
-
-// Compatibility names; new callers can deduce the value type from the key.
-using FRegionGetBodyParams =
decltype(op_attr::kRegionGetBodyParams)::ValueType;
-using FRegionValidate = decltype(op_attr::kRegionValidate)::ValueType;
-
-namespace type_attr {
-inline constexpr ffi::reflection::AttrKey<ffi::Function> kEvaluateValidate{
- "__tvm_evaluate_validate__"};
-inline constexpr ffi::reflection::AttrKey<ffi::Function> kTensorStoreValidate{
- "__tvm_tensor_store_validate__"};
-} // namespace type_attr
-
} // namespace tvm
#endif // TVM_IR_STMT_H_
diff --git a/tirx/include/tvm/script/printer/doc_translator.h
b/tirx/include/tvm/script/printer/doc_translator.h
index 37e9926146..3287aac909 100644
--- a/tirx/include/tvm/script/printer/doc_translator.h
+++ b/tirx/include/tvm/script/printer/doc_translator.h
@@ -451,9 +451,9 @@ inline ffi::Optional<ExprDoc>
DocTranslatorObj::DefaultTranslate(ffi::AnyView va
tvm::script::printer::type_attr::kDocTranslate.name);
ffi::AnyView attr = column[value.type_index()];
if (attr.type_index() == ffi::TypeIndex::kTVMFFIOpaquePtr) {
- return
ffi::details::ExpectedUnsafe::MoveFromTVMFFIAny<ffi::Optional<ExprDoc>>(
-
reinterpret_cast<decltype(DocTranslatorVTable::translate)>(attr.cast<void*>())(
- this, value, destination))
+ return type_attr::kDocTranslate.ValueFrom(attr)
+ .value()
+ .CallExpected(this, value, destination)
.value();
}
if (attr.type_index() == ffi::TypeIndex::kTVMFFIFunction) {
diff --git a/tirx/include/tvm/target/target.h b/tirx/include/tvm/target/target.h
index e6a9e21052..d1a2fe99c4 100644
--- a/tirx/include/tvm/target/target.h
+++ b/tirx/include/tvm/target/target.h
@@ -35,12 +35,6 @@
namespace tvm {
-namespace backend::attr {
-/*! \brief Optional backend configuration on a Target, distinct from
serialized IR/runtime JSON. */
-inline constexpr ffi::reflection::AttrKey<ffi::Map<ffi::String, ffi::Any>>
kBackendConfig{
- "backend_config"};
-} // namespace backend::attr
-
class TargetInternal;
class Target;
@@ -208,5 +202,11 @@ class Target : public ffi::ObjectRef {
TVM_TIRX_DLL void ExitWithScope();
};
+namespace attr {
+/*! \brief Optional backend configuration on a Target, distinct from
serialized IR/runtime JSON. */
+inline constexpr ffi::reflection::AttrKey<ffi::Map<ffi::String, ffi::Any>>
kBackendConfig{
+ "backend_config"};
+} // namespace attr
+
} // namespace tvm
#endif // TVM_TARGET_TARGET_H_
diff --git a/tirx/src/backend/cuda/codegen/intrin_rule_cuda.cc
b/tirx/src/backend/cuda/codegen/intrin_rule_cuda.cc
index c34bff568e..df263acd14 100644
--- a/tirx/src/backend/cuda/codegen/intrin_rule_cuda.cc
+++ b/tirx/src/backend/cuda/codegen/intrin_rule_cuda.cc
@@ -289,7 +289,7 @@ void RegisterCudaIntrinRules() {
sig::arg<IntExpr>("width", "The warp thread width, must be a power
of 2."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "__shfl_sync")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque)
.set_attr(tvm::backend::cuda::op_attr::kNeedWarpShuffle, true);
OpDef("tirx.cuda.__shfl_up_sync")
@@ -299,7 +299,7 @@ void RegisterCudaIntrinRules() {
sig::arg<IntExpr>("width", "The warp thread width, must be a power
of 2."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "__shfl_up_sync")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque)
.set_attr(tvm::backend::cuda::op_attr::kNeedWarpShuffle, true);
OpDef("tirx.cuda.__shfl_down_sync")
@@ -309,7 +309,7 @@ void RegisterCudaIntrinRules() {
sig::arg<IntExpr>("width", "The warp thread width, must be a power
of 2."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "__shfl_down_sync")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque)
.set_attr(tvm::backend::cuda::op_attr::kNeedWarpShuffle, true);
OpDef("tirx.cuda.__shfl_xor_sync")
@@ -319,13 +319,13 @@ void RegisterCudaIntrinRules() {
sig::arg<IntExpr>("width", "The warp thread width, must be a power
of 2."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "__shfl_xor_sync")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque)
.set_attr(tvm::backend::cuda::op_attr::kNeedWarpShuffle, true);
OpDef("tirx.cuda.__activemask")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::UInt(32))
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "__activemask")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::backend::cuda::op_attr::kNeedWarpShuffle, true);
// clang-format on
}
diff --git a/tirx/src/backend/cuda/codegen/target_kind.cc
b/tirx/src/backend/cuda/codegen/target_kind.cc
index 9bd9e4c4f4..d0d2d99382 100644
--- a/tirx/src/backend/cuda/codegen/target_kind.cc
+++ b/tirx/src/backend/cuda/codegen/target_kind.cc
@@ -145,7 +145,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TargetKindDef("cuda")
.set_default_device_type(kDLCUDA)
- .def_option<ffi::Map<ffi::String,
ffi::Any>>(backend::attr::kBackendConfig.name)
+ .def_option<ffi::Map<ffi::String,
ffi::Any>>(tvm::attr::kBackendConfig.name)
.def_option<ffi::String>("mcpu")
.def_option<ffi::String>("arch")
.def_option<int64_t>("max_shared_memory_per_block")
diff --git a/tirx/src/backend/cuda/op/iket.cc b/tirx/src/backend/cuda/op/iket.cc
index f6a3c87763..9c6e329b6f 100644
--- a/tirx/src/backend/cuda/op/iket.cc
+++ b/tirx/src/backend/cuda/op/iket.cc
@@ -41,7 +41,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.cuda.iket_mark")
.signature(sig::arg("name", "The name."), sig::var_args("args"))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& iket_range_start_op() {
@@ -53,7 +53,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.cuda.iket_range_start")
.signature(sig::arg("name", "The name."), sig::var_args("args"))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::UInt(32))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& iket_range_end_op() {
@@ -65,7 +65,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.cuda.iket_range_end")
.signature(sig::arg<IntExpr>("token", "The token."),
sig::var_args("args"))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& iket_range_push_op() {
@@ -77,7 +77,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.cuda.iket_range_push")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
.signature(sig::arg("name", "The name."), sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& iket_range_pop_op() {
@@ -88,7 +88,7 @@ const Op& iket_range_pop_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.cuda.iket_range_pop")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& iket_sentinel_token_op() {
@@ -100,7 +100,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.cuda.iket_sentinel_token")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::UInt(32))
.signature(sig::arg("name", "The name."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -108,7 +108,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::UInt(32))
.signature(sig::arg("event_id", "The event identifier."),
sig::arg("source_code", "The source code."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
} // namespace cuda
diff --git a/tirx/src/backend/cuda/op/legacy.cc
b/tirx/src/backend/cuda/op/legacy.cc
index 42841e8804..57f54fa229 100644
--- a/tirx/src/backend/cuda/op/legacy.cc
+++ b/tirx/src/backend/cuda/op/legacy.cc
@@ -35,26 +35,26 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg("src_ptr", "The source pointer."),
sig::arg<IntExpr>("src_offset", "The source offset."),
sig::arg<IntExpr>("dst_stride", "The destination stride."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.cuda.mma_fill")
.signature(sig::arg<IntExpr>("local_size", "The local allocation size."),
sig::arg("local_ptr", "The local pointer."),
sig::arg<IntExpr>("offset", "The offset."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.ptx_legacy.ldmatrix")
.signature(sig::arg("trans"), sig::arg<IntExpr>("num"),
sig::arg("dtype"),
sig::arg("local_ptr"), sig::arg<IntExpr>("local_offset"),
sig::arg("smem_ptr"),
sig::arg<IntExpr>("smem_offset"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.ptx_legacy.mma")
.signature(sig::arg("shape"), sig::arg("a_layout"),
sig::arg("b_layout"), sig::arg("a_dtype"),
sig::arg("b_dtype"), sig::arg("c_dtype"), sig::arg("a_ptr"),
sig::arg<IntExpr>("a_offset"), sig::arg("b_ptr"),
sig::arg<IntExpr>("b_offset"),
sig::arg("acc_ptr"), sig::arg<IntExpr>("c_offset"),
sig::arg("saturate"),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
} // namespace tirx
diff --git a/tirx/src/backend/cuda/op/target_builtin.cc
b/tirx/src/backend/cuda/op/target_builtin.cc
index edbc2e0e54..9e6d3c8209 100644
--- a/tirx/src/backend/cuda/op/target_builtin.cc
+++ b/tirx/src/backend/cuda/op/target_builtin.cc
@@ -102,7 +102,7 @@ void RegisterCudaTargetBuiltins() {
.set_validator(ffi::reflection::NativeFunctionView<void(
const CallNode*)>::FromNative<&ValidateDeclTmem>(),
true)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("tirx.cuda.bmma_sync")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
@@ -114,7 +114,7 @@ void RegisterCudaTargetBuiltins() {
sig::arg<IntExpr>("index_b", "The B fragment index."),
sig::arg("fragment_c", "The C fragment."),
sig::arg<IntExpr>("index_c", "The C fragment index."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
// Raw legacy cp.async form emitted by InjectPTXAsyncCopy (and round-tripped
by
// the T.s_tir.cp_async_raw.legacy 6-arg surface). It carries the element
dtype in Call.dtype
@@ -125,7 +125,7 @@ void RegisterCudaTargetBuiltins() {
sig::arg("src_ptr", "The source pointer."),
sig::arg<IntExpr>("src_offset", "The source offset."),
sig::arg<IntExpr>("cp_size", "The copy size."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.cuda.timer_init")
.signature(sig::arg("profiler_buffer", "The profiler buffer."),
@@ -133,7 +133,7 @@ void RegisterCudaTargetBuiltins() {
sig::arg<IntExpr>("profiler_write_offset", "The profiler
write offset."),
sig::arg<IntExpr>("num_groups", "The number of groups."),
sig::arg<IntExpr>("group_id", "The group identifier."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.cuda.timer_start")
.signature(sig::arg("event_type", "The event type."),
@@ -142,7 +142,7 @@ void RegisterCudaTargetBuiltins() {
sig::arg<IntExpr>("profiler_write_offset", "The profiler
write offset."),
sig::arg<IntExpr>("profiler_write_stride", "The profiler
write stride."),
sig::arg("leader_cond", "The leader condition."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.cuda.timer_end")
.signature(sig::arg("event_type", "The event type."),
@@ -151,7 +151,7 @@ void RegisterCudaTargetBuiltins() {
sig::arg<IntExpr>("profiler_write_offset", "The profiler
write offset."),
sig::arg<IntExpr>("profiler_write_stride", "The profiler
write stride."),
sig::arg("leader_cond", "The leader condition."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.cuda.timer_finalize")
.signature(sig::arg("profiler_buffer", "The profiler buffer."),
@@ -159,7 +159,7 @@ void RegisterCudaTargetBuiltins() {
sig::arg<IntExpr>("profiler_write_offset", "The profiler
write offset."),
sig::arg<IntExpr>("profiler_write_stride", "The profiler
write stride."),
sig::arg("leader_cond", "The leader condition."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
RegisterDeviceIntrinsics();
}
@@ -167,7 +167,7 @@ void RegisterCudaTargetBuiltins() {
namespace {
TVM_FFI_NO_INLINE void RegisterDeviceIntrinsicAttrs(OpDef& def, CallEffectKind
effect_kind) {
- def.set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(effect_kind));
+ def.set_attr(tvm::op_attr::kCallEffectKind, effect_kind);
}
template <typename... Specs>
diff --git a/tirx/src/backend/cuda/op/tcgen05.cc
b/tirx/src/backend/cuda/op/tcgen05.cc
index 8e3def9559..c50f6eddce 100644
--- a/tirx/src/backend/cuda/op/tcgen05.cc
+++ b/tirx/src/backend/cuda/op/tcgen05.cc
@@ -73,17 +73,17 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.cuda.tcgen05_encode_instr_descriptor")
.signature(sig::arg("desc"),
sig::call_attrs<backend::cuda::TCGen05InstrDescriptorAttrs>())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque)
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void());
OpDef("tirx.cuda.tcgen05_encode_instr_descriptor_block_scaled")
.signature(sig::arg("desc"),
sig::call_attrs<backend::cuda::TCGen05InstrDescriptorBlockScaledAttrs>())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque)
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void());
OpDef("tirx.cuda.tcgen05_encode_matrix_descriptor")
.signature(sig::arg("desc"), sig::arg("addr"), sig::arg<IntExpr>("ldo"),
sig::arg<IntExpr>("sdo"), sig::arg<IntExpr>("swizzle"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque)
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void());
}
diff --git a/tirx/src/backend/cuda/op/tensormap.cc
b/tirx/src/backend/cuda/op/tensormap.cc
index 3f138b27f8..f9ad36f95b 100644
--- a/tirx/src/backend/cuda/op/tensormap.cc
+++ b/tirx/src/backend/cuda/op/tensormap.cc
@@ -63,7 +63,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Int(32))
.signature(sig::arg("descriptor", "The descriptor."), sig::arg("data",
"The input data."),
sig::var_args<PrimExpr>("args"),
sig::call_attrs<TensorMapEncodeTiledAttr>())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
} // namespace cuda
diff --git a/tirx/src/backend/cuda/tile/exec_context.cc
b/tirx/src/backend/cuda/tile/exec_context.cc
index 740f139ecf..53af5f5d4a 100644
--- a/tirx/src/backend/cuda/tile/exec_context.cc
+++ b/tirx/src/backend/cuda/tile/exec_context.cc
@@ -24,6 +24,7 @@
#include "exec_context.h"
#include <tvm/ir/prim/expr.h>
+#include <tvm/ir/prim/op.h>
#include <tvm/runtime/logging.h>
#include <tvm/sym/analyzer.h>
diff --git a/tirx/src/backend/metal/codegen/intrin_rule_metal.cc
b/tirx/src/backend/metal/codegen/intrin_rule_metal.cc
index 766743b297..c92a9b7808 100644
--- a/tirx/src/backend/metal/codegen/intrin_rule_metal.cc
+++ b/tirx/src/backend/metal/codegen/intrin_rule_metal.cc
@@ -161,21 +161,21 @@ void RegisterMetalIntrinRules() {
sig::arg<IntExpr>("lane", "The source thread id."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "simd_shuffle")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.metal.simd_shuffle_up")
.signature(sig::arg("var", "The variable to sync."),
sig::arg<IntExpr>("delta", "The source lane id offset to be added."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "simd_shuffle_up")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.metal.simd_shuffle_down")
.signature(sig::arg("var", "The variable to sync."),
sig::arg<IntExpr>("delta", "The source lane id offset to be
subtracted."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "simd_shuffle_down")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
// clang-format on
}
diff --git a/tirx/src/backend/metal/op/cooperative_tensor.cc
b/tirx/src/backend/metal/op/cooperative_tensor.cc
index a3a202ef18..fcb6d07214 100644
--- a/tirx/src/backend/metal/op/cooperative_tensor.cc
+++ b/tirx/src/backend/metal/op/cooperative_tensor.cc
@@ -40,7 +40,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<PrimExpr>("value", "The value to use."),
sig::arg<IntExpr>("rows", "The number of rows."),
sig::arg<IntExpr>("cols", "The number of columns."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& cooperative_tensor_load_op() {
@@ -60,7 +60,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("mma_N", "The N dimension of the matrix
operation."),
sig::arg<IntExpr>("mma_K", "The K dimension of the matrix
operation."),
sig::arg<IntExpr>("operand_role", "The matrix operand role."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& cooperative_tensor_store_op() {
@@ -80,7 +80,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("mma_N", "The N dimension of the matrix
operation."),
sig::arg<IntExpr>("mma_K", "The K dimension of the matrix
operation."),
sig::arg<IntExpr>("operand_role", "The matrix operand role."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& cooperative_tensor_multiply_accumulate_op() {
@@ -100,7 +100,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("K", "The K dimension."),
sig::arg<PrimExpr>("transpose_a", "Whether to transpose A."),
sig::arg<PrimExpr>("transpose_b", "Whether to transpose B."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
} // namespace metal
diff --git a/tirx/src/backend/metal/op/target_builtin.cc
b/tirx/src/backend/metal/op/target_builtin.cc
index 2c9bb888b9..a2bc2afafb 100644
--- a/tirx/src/backend/metal/op/target_builtin.cc
+++ b/tirx/src/backend/metal/op/target_builtin.cc
@@ -44,7 +44,7 @@ void RegisterMetalTargetBuiltins() {
sig::arg("value", "The value to use."),
sig::arg<IntExpr>("col", "The column index."),
sig::arg<IntExpr>("row", "The row index."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.metal.simdgroup_load")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
@@ -53,7 +53,7 @@ void RegisterMetalTargetBuiltins() {
sig::arg<IntExpr>("col", "The column index."),
sig::arg<IntExpr>("row", "The row index."),
sig::arg("transpose_matrix", "Whether to transpose the
matrix."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.metal.simdgroup_store")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
@@ -62,7 +62,7 @@ void RegisterMetalTargetBuiltins() {
sig::arg<IntExpr>("col", "The column index."),
sig::arg<IntExpr>("row", "The row index."),
sig::arg("transpose_matrix", "Whether to transpose the
matrix."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.metal.simdgroup_multiply_accumulate")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
@@ -71,7 +71,7 @@ void RegisterMetalTargetBuiltins() {
sig::arg("a", "The A operand."), sig::arg<IntExpr>("index_a", "The A
fragment index."),
sig::arg("b", "The B operand."), sig::arg<IntExpr>("index_b", "The B
fragment index."),
sig::arg("c", "The C operand."), sig::arg<IntExpr>("index_c", "The C
fragment index."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
TVM_FFI_STATIC_INIT_BLOCK() { RegisterMetalTargetBuiltins(); }
diff --git a/tirx/src/backend/opencl/codegen/intrin_rule_opencl.cc
b/tirx/src/backend/opencl/codegen/intrin_rule_opencl.cc
index 99b749c1cc..1d0dcbe878 100644
--- a/tirx/src/backend/opencl/codegen/intrin_rule_opencl.cc
+++ b/tirx/src/backend/opencl/codegen/intrin_rule_opencl.cc
@@ -22,6 +22,7 @@
* \brief OpenCL intrinsic rules.
*/
#include <tvm/codegen/intrin_rule.h>
+#include <tvm/ir/prim/op.h>
#include <tvm/sym/analyzer.h>
#include <tvm/tirx/op/abi.h>
#include <tvm/tirx/op/attr.h>
diff --git a/tirx/src/backend/opencl/op/memory.cc
b/tirx/src/backend/opencl/op/memory.cc
index e37d618e5e..6e8406984b 100644
--- a/tirx/src/backend/opencl/op/memory.cc
+++ b/tirx/src/backend/opencl/op/memory.cc
@@ -40,7 +40,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("channel_size", "The number of channels."),
sig::arg<PrimExpr>("value", "The value to use."))
.set_attr(tvm::tirx::op_attr::kVectorizable, true)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& texture2d_load_op() {
@@ -56,7 +56,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("channel_size", "The number of channels."),
sig::arg<PrimExpr>("element_index", "The element index within
a texture channel."))
.set_attr(tvm::tirx::op_attr::kVectorizable, true)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& nd_mem_alloc_with_scope_op() {
@@ -69,7 +69,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg("storage_scope", "The storage scope."),
sig::arg<IntExpr>("ndim", "The number of dimensions."),
sig::arg("shape", "The shape."), sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
} // namespace opencl
diff --git a/tirx/src/backend/trn/op/target_builtin.cc
b/tirx/src/backend/trn/op/target_builtin.cc
index 3b1674583c..51cb30d224 100644
--- a/tirx/src/backend/trn/op/target_builtin.cc
+++ b/tirx/src/backend/trn/op/target_builtin.cc
@@ -69,7 +69,7 @@ TVM_FFI_NO_INLINE std::string MakeNKIIntrinsicName(const
char* op_name) {
TVM_FFI_NO_INLINE void RegisterNKIIntrinsicAttrs(OpDef& def) {
def.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
template <typename... Specs>
diff --git a/tirx/src/backend/webgpu/codegen/intrin_rule_webgpu.cc
b/tirx/src/backend/webgpu/codegen/intrin_rule_webgpu.cc
index 012a02f3b0..b59539439c 100644
--- a/tirx/src/backend/webgpu/codegen/intrin_rule_webgpu.cc
+++ b/tirx/src/backend/webgpu/codegen/intrin_rule_webgpu.cc
@@ -187,21 +187,21 @@ void RegisterWebGPUIntrinRules() {
sig::arg<IntExpr>("lane", "The source thread id."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "subgroupShuffle")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.webgpu.subgroup_shuffle_up")
.signature(sig::arg("var", "The variable to sync."),
sig::arg<IntExpr>("delta", "The source lane id offset to be added."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "subgroupShuffleUp")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
OpDef("tirx.webgpu.subgroup_shuffle_down")
.signature(sig::arg("var", "The variable to sync."),
sig::arg<IntExpr>("delta", "The source lane id offset to be
subtracted."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(
tvm::op_attr::kInferType)
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "subgroupShuffleDown")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
// clang-format on
}
diff --git a/tirx/src/ir/expr.cc b/tirx/src/ir/expr.cc
index beebedaf04..a23aa87f58 100644
--- a/tirx/src/ir/expr.cc
+++ b/tirx/src/ir/expr.cc
@@ -39,6 +39,43 @@
namespace tvm {
+namespace ffi {
+
+Expr TypeTraits<Expr>::ConvertFallbackValue(ffi::String value) {
+ return StringImm(std::move(value));
+}
+
+std::optional<Expr> TypeTraits<Expr>::TryCastFromAnyView(const TVMFFIAny* src)
{
+ if (auto value =
+ ObjectRefWithFallbackTraitsBase<Expr, PrimExpr,
ffi::String>::TryCastFromAnyView(src)) {
+ return value;
+ }
+ if (auto fields = TypeTraits<ffi::Array<Expr>>::TryCastFromAnyView(src)) {
+ return tvm::Tuple(std::move(*fields));
+ }
+ return std::nullopt;
+}
+
+std::optional<PrimExpr> TypeTraits<PrimExpr>::TryCastFromAnyView(const
TVMFFIAny* src) {
+ // A required expression cannot accept None.
+ if (src->type_index == TypeIndex::kTVMFFINone) return std::nullopt;
+ return Base::TryCastFromAnyView(src);
+}
+
+PrimExpr TypeTraits<PrimExpr>::ConvertFallbackValue(StrictBool value) {
+ return IntImm::Bool(value);
+}
+
+PrimExpr TypeTraits<PrimExpr>::ConvertFallbackValue(int64_t value) {
+ return TypeTraits<IntImm>::ConvertFallbackValue(value);
+}
+
+PrimExpr TypeTraits<PrimExpr>::ConvertFallbackValue(double value) {
+ return TypeTraits<FloatImm>::ConvertFallbackValue(value);
+}
+
+} // namespace ffi
+
namespace {
template <typename TNode>
@@ -702,13 +739,13 @@ TensorLoad::TensorLoad(Expr source, ffi::Array<PrimExpr>
indices, Location loc)
<< "TensorLoad requires a source with a defined type";
namespace refl = ffi::reflection;
static const refl::TypeAttrColumn
infer_column(type_attr::kTensorLoadInferType.name);
- auto infer = infer_column[source->ty->type_index()];
- TVM_FFI_CHECK(infer != nullptr, TypeError)
+ auto infer =
type_attr::kTensorLoadInferType.ValueFrom(infer_column[source->ty->type_index()]);
+ TVM_FFI_CHECK(infer.has_value(), TypeError)
<< "Type " << source->ty->GetTypeKey() << " does not support TensorLoad";
auto node = ffi::make_object<TensorLoadNode>(std::move(source));
node->indices = std::move(indices);
node->loc = loc;
- PrimType ty =
infer.cast<FTensorLoadInferType>().CallExpected(node.get()).value();
+ PrimType ty = infer->CallExpected(node.get()).value();
TVM_FFI_CHECK(ty.defined() && ty.as<PrimTypeNode>(), TypeError)
<< "TensorLoad inference requires a concrete PrimType";
node->ty = std::move(ty);
diff --git a/tirx/src/ir/prim/builtin.cc b/tirx/src/ir/prim/builtin.cc
index 5ef75f691b..de7069e05c 100644
--- a/tirx/src/ir/prim/builtin.cc
+++ b/tirx/src/ir/prim/builtin.cc
@@ -49,8 +49,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("prim.likely")
.signature(sig::arg("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
- static_cast<int64_t>(CallEffectKind::kExprAnnotation))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kExprAnnotation)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.if_then_else")
@@ -58,28 +57,28 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg("true_value", "The value when the condition is
true."),
sig::arg("false_value", "The value when the condition is
false."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.vscale")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Int(32))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.ceil")
.signature(sig::arg("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.log2")
.signature(sig::arg("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.clz")
.signature(sig::arg("x", "The input value."))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Int(32))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
} // namespace prim
diff --git a/tirx/src/ir/prim/math.cc b/tirx/src/ir/prim/math.cc
index 96a98d1fec..76e2cdda2d 100644
--- a/tirx/src/ir/prim/math.cc
+++ b/tirx/src/ir/prim/math.cc
@@ -387,206 +387,206 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg<PrimExpr>("x", "The input value."),
sig::arg<PrimExpr>("y", "The second input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.fabs")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.fmod")
.signature(sig::arg<PrimExpr>("x", "The input value."),
sig::arg<PrimExpr>("y", "The second input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.floor")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.round")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.nearbyint")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.trunc")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.exp")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.exp2")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.exp10")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.erf")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.tanh")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.sigmoid")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.sqrt")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.rsqrt")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.log")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.log1p")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.log10")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.tan")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.cos")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.cosh")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.sin")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.sinh")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.asin")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.acos")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.atan")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.acosh")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.asinh")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.atanh")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.atan2")
.signature(sig::arg<PrimExpr>("x1", "The first input value."),
sig::arg<PrimExpr>("x2", "The second input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.nextafter")
.signature(sig::arg<PrimExpr>("x1", "The first input value."),
sig::arg<PrimExpr>("x2", "The second input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.hypot")
.signature(sig::arg<PrimExpr>("x1", "The first input value."),
sig::arg<PrimExpr>("x2", "The second input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.copysign")
.signature(sig::arg<PrimExpr>("x1", "The first input value."),
sig::arg<PrimExpr>("x2", "The second input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.ldexp")
.signature(sig::arg<PrimExpr>("x1", "The first input value."),
sig::arg<PrimExpr>("x2", "The second input value."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.isnan")
.signature(sig::arg<PrimExpr>("x", "The input value."))
.set_native_fn_attr<&InferTypeIsNaN>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
OpDef("prim.popcount")
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
.signature(sig::arg<PrimExpr>("x", "The input value."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.fma")
@@ -594,13 +594,13 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg<PrimExpr>("x", "The input value."),
sig::arg<PrimExpr>("y", "The second input value."),
sig::arg<PrimExpr>("z", "The third input value."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
OpDef("prim.assume")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Bool())
.signature(sig::arg<PrimExpr>("cond", "The condition."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kEmbedInfo));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kEmbedInfo);
ffi::reflection::GlobalDef()
.def("prim.infinity", prim::infinity)
diff --git a/tirx/src/ir/side_effect.cc b/tirx/src/ir/side_effect.cc
index 30eda9c617..1916c95576 100644
--- a/tirx/src/ir/side_effect.cc
+++ b/tirx/src/ir/side_effect.cc
@@ -35,8 +35,7 @@ CallEffectKind SideEffect(const Expr& expr) {
expr,
[&](const CallNode* node,
ffi::StructuralVisitorObj* visitor) ->
ffi::Expected<ffi::Optional<ffi::VisitInterrupt>> {
- auto effect = static_cast<CallEffectKind>(
- effects.get(node->op,
static_cast<TCallEffectKind>(CallEffectKind::kOpaque)));
+ auto effect = effects.get(node->op, CallEffectKind::kOpaque);
kind = std::max(kind, std::min(effect, CallEffectKind::kUpdateState));
if (kind == CallEffectKind::kUpdateState) return ffi::VisitInterrupt();
return visitor->DefaultVisitExpected(node);
diff --git a/tirx/src/ir/stmt.cc b/tirx/src/ir/stmt.cc
index be6d5717a0..c315904326 100644
--- a/tirx/src/ir/stmt.cc
+++ b/tirx/src/ir/stmt.cc
@@ -649,8 +649,7 @@ TVM_FFI_INLINE ffi::Expected<ffi::UnchangedOr<ffi::Any>>
TensorStoreMaybeInplace
TVM_FFI_STATIC_INIT_BLOCK() {
StmtNode::RegisterReflection();
-
ffi::reflection::EnsureTypeAttrColumn(tvm::type_attr::kTensorStoreValidate.name);
-
ffi::reflection::EnsureTypeAttrColumn(tvm::type_attr::kEvaluateValidate.name);
+
ffi::reflection::EnsureTypeAttrColumn(tvm::type_attr::kTensorStoreValidateByTy.name);
}
// Bind
@@ -1059,12 +1058,6 @@ TVM_FFI_STATIC_INIT_BLOCK() {
// Evaluate
Evaluate::Evaluate(Expr value, Location loc) : Stmt(ffi::UnsafeInit{}) {
TVM_FFI_ICHECK(value.defined());
- static const ffi::reflection::TypeAttrColumn validate_column(
- tvm::type_attr::kEvaluateValidate.name);
- if (auto validate = validate_column[value->ty->type_index()]; validate !=
nullptr) {
- validate.cast<ffi::Function>()(value);
- }
-
ffi::ObjectPtr<EvaluateNode> node =
ffi::make_object<EvaluateNode>(std::move(value));
node->loc = loc;
data_ = std::move(node);
@@ -1088,11 +1081,12 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TensorStore::TensorStore(Expr dest, ffi::Array<PrimExpr> indices, PrimExpr
value, Location loc)
: Stmt(ffi::UnsafeInit{}) {
namespace refl = ffi::reflection;
- static const refl::TypeAttrColumn
validate_column(tvm::type_attr::kTensorStoreValidate.name);
- auto validate = validate_column[dest->ty->type_index()];
- TVM_FFI_CHECK(validate != nullptr, TypeError)
+ static const refl::TypeAttrColumn
validate_column(tvm::type_attr::kTensorStoreValidateByTy.name);
+ auto validate =
+
type_attr::kTensorStoreValidateByTy.ValueFrom(validate_column[dest->ty->type_index()]);
+ TVM_FFI_CHECK(validate.has_value(), TypeError)
<< "Type " << dest->ty->GetTypeKey() << " does not support TensorStore";
- validate.cast<ffi::Function>()(dest, indices, value);
+ validate->CallExpected(dest, indices, value).value();
auto node = ffi::make_object<TensorStoreNode>(std::move(dest),
std::move(value));
node->indices = std::move(indices);
node->loc = loc;
diff --git a/tirx/src/ir/subscript_expr.cc b/tirx/src/ir/subscript_expr.cc
index 7409d1a305..c7e0c3ecfc 100644
--- a/tirx/src/ir/subscript_expr.cc
+++ b/tirx/src/ir/subscript_expr.cc
@@ -28,15 +28,11 @@
namespace tvm {
-using SubscriptSlice = ffi::Array<ffi::Variant<
- ffi::Tuple<ffi::Optional<PrimExpr>, ffi::Optional<PrimExpr>,
ffi::Optional<PrimExpr>>,
- PrimExpr>>;
-
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::EnsureTypeAttrColumn(tvm::type_attr::kSubscriptExprRealize.name);
- refl::TypeAttrDef<TupleTypeNode>().def(
- tvm::type_attr::kSubscriptExprRealize.name,
+ refl::EnsureTypeAttrColumn(tvm::type_attr::kExprSubscriptRealizeByTy);
+ refl::TypeAttrDef<TupleTypeNode>().attr(
+ tvm::type_attr::kExprSubscriptRealizeByTy,
[](Expr value, SubscriptSlice slice, Location loc) -> ffi::ObjectRef {
TVM_FFI_CHECK_EQ(slice.size(), 1, IndexError)
<< "A tuple expression requires exactly one index";
@@ -51,14 +47,14 @@ TVM_FFI_STATIC_INIT_BLOCK() {
"ir.SubscriptExprRealize",
[](Expr value, SubscriptSlice slice, Location loc) -> ffi::ObjectRef {
TVM_FFI_CHECK(value.defined(), TypeError) << "Cannot subscript an
undefined expression";
- static refl::TypeAttrColumn
realize_column(tvm::type_attr::kSubscriptExprRealize.name);
- ffi::AnyView packed_realize = realize_column[value->ty->type_index()];
- TVM_FFI_CHECK(packed_realize != nullptr, TypeError)
+ static refl::TypeAttrColumn
realize_column(tvm::type_attr::kExprSubscriptRealizeByTy);
+ auto realize = tvm::type_attr::kExprSubscriptRealizeByTy.ValueFrom(
+ realize_column[value->ty->type_index()]);
+ TVM_FFI_CHECK(realize.has_value(), TypeError)
<< "Type " << value->ty->GetTypeKey() << " does not support
subscript";
- ffi::ObjectRef result =
- packed_realize.cast<ffi::Function>()(value, slice,
loc).cast<ffi::ObjectRef>();
+ ffi::ObjectRef result = (*realize)(value, slice, loc);
TVM_FFI_CHECK(result.defined(), TypeError)
- << "__tvm_subscript_expr_realize__ for type " <<
value->ty->GetTypeKey()
+ << "__tvm_expr_subscript_realize__ for type " <<
value->ty->GetTypeKey()
<< " returned an undefined object";
return result;
});
diff --git a/tirx/src/script/printer/ir/call.cc
b/tirx/src/script/printer/ir/call.cc
index a66749b247..4b4ddf7535 100644
--- a/tirx/src/script/printer/ir/call.cc
+++ b/tirx/src/script/printer/ir/call.cc
@@ -48,7 +48,10 @@ ffi::Optional<ExprDoc> CallDocTranslate(DocTranslatorObj* d,
ffi::AnyView input,
if (overrides.count(op.value())) {
ffi::Any hook = overrides[op.value()];
if (hook.type_index() == ffi::TypeIndex::kTVMFFIOpaquePtr) {
- return hook.cast<FDocTranslate>().CallExpected(d, input,
destination).value();
+ return op_attr::kDocTranslateOpCall.ValueFrom(hook)
+ .value()
+ .CallExpected(d, input, destination)
+ .value();
}
ffi::Any binding = nullptr;
if (destination) binding = ffi::GetRef<ffi::ObjectRef>(destination);
diff --git a/tirx/src/tirx/ir/stmt.cc b/tirx/src/tirx/ir/stmt.cc
index d8f7e412eb..dd64e6471a 100644
--- a/tirx/src/tirx/ir/stmt.cc
+++ b/tirx/src/tirx/ir/stmt.cc
@@ -45,7 +45,8 @@ TVM_FFI_INLINE int GetLanesOrVScaleFactor(const PrimType& ty)
{
return ty.IsScalableVector() ? ty.VScaleFactor() : ty.lanes();
}
-void ValidateTensorStore(Expr dest, ffi::Array<PrimExpr> indices, PrimExpr
value) {
+void ValidateTensorStore(const Expr& dest, const ffi::Array<PrimExpr>& indices,
+ const PrimExpr& value) {
TensorType type = dest->ty.as_or_throw<TensorType>();
TVM_FFI_ICHECK_EQ(type->shape.size(), indices.size())
<< "Destination " << dest << " is " << type->shape.size()
@@ -95,18 +96,12 @@ void ValidateTensorStore(Expr dest, ffi::Array<PrimExpr>
indices, PrimExpr value
}
}
-void ValidateTensorEvaluate(Expr value) {
- TVM_FFI_ICHECK(!value->IsInstance<VarNode>())
- << "A tensor variable cannot be used as a scalar Evaluate value; "
- << "use tensor.data to evaluate its physical pointer";
-}
} // namespace
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = ffi::reflection;
- refl::TypeAttrDef<TensorTypeNode>()
- .def(tvm::type_attr::kTensorStoreValidate.name, ValidateTensorStore)
- .def(tvm::type_attr::kEvaluateValidate.name, ValidateTensorEvaluate);
+ refl::TypeAttrDef<TensorTypeNode>().native_fn_attr<&ValidateTensorStore>(
+ type_attr::kTensorStoreValidateByTy);
}
} // namespace tirx
diff --git a/tirx/src/tirx/ir/tensor.cc b/tirx/src/tirx/ir/tensor.cc
index 5890b18681..a21d8917c5 100644
--- a/tirx/src/tirx/ir/tensor.cc
+++ b/tirx/src/tirx/ir/tensor.cc
@@ -58,10 +58,6 @@ using namespace tvm::prim;
namespace {
-using SubscriptSlice = ffi::Array<ffi::Variant<
- ffi::Tuple<ffi::Optional<PrimExpr>, ffi::Optional<PrimExpr>,
ffi::Optional<PrimExpr>>,
- PrimExpr>>;
-
PrimExpr SliceExtent(const PrimExpr& start, const PrimExpr& stop, const
sym::Analyzer& analyzer) {
PrimExpr extent = Range::GetExtentFromBeginEnd(start, stop);
if (const auto* add = stop.as<AddNode>();
@@ -71,13 +67,7 @@ PrimExpr SliceExtent(const PrimExpr& start, const PrimExpr&
stop, const sym::Ana
return analyzer->Simplify(extent);
}
-ffi::ObjectRef RealizeTensorSubscript(
- Expr value,
- ffi::Array<ffi::Variant<
- ffi::Tuple<ffi::Optional<PrimExpr>, ffi::Optional<PrimExpr>,
ffi::Optional<PrimExpr>>,
- PrimExpr>>
- slice,
- Location loc) {
+ffi::ObjectRef RealizeTensorSubscript(Expr value, SubscriptSlice slice,
Location loc) {
TensorVar tensor = value.as_or_throw<TensorVar>();
TensorType tensor_ty = tensor.ty();
TVM_FFI_CHECK_LE(slice.size(), tensor_ty->shape.size(), IndexError)
@@ -194,10 +184,10 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
-
refl::TypeAttrDef<TensorTypeNode>().def(tvm::type_attr::kSubscriptExprRealize.name,
- RealizeTensorSubscript);
-
refl::TypeAttrDef<TensorRegionTypeNode>().def(tvm::type_attr::kSubscriptExprRealize.name,
- RealizeTensorRegionSubscript);
+
refl::TypeAttrDef<TensorTypeNode>().attr(tvm::type_attr::kExprSubscriptRealizeByTy,
+ RealizeTensorSubscript);
+
refl::TypeAttrDef<TensorRegionTypeNode>().attr(tvm::type_attr::kExprSubscriptRealizeByTy,
+ RealizeTensorRegionSubscript);
}
ffi::Array<PrimExpr> SimplifyArray(sym::AnalyzerObj* ana, ffi::Array<PrimExpr>
array) {
diff --git a/tirx/src/tirx/ir/tensor_load.cc b/tirx/src/tirx/ir/tensor_load.cc
index 3129f59d16..4bc3bf1b84 100644
--- a/tirx/src/tirx/ir/tensor_load.cc
+++ b/tirx/src/tirx/ir/tensor_load.cc
@@ -70,9 +70,8 @@ PrimType InferTensorLoadType(const TensorLoadNode* load) {
TVM_FFI_STATIC_INIT_BLOCK() {
namespace refl = tvm::ffi::reflection;
- refl::TypeAttrDef<TensorTypeNode>().attr(
- type_attr::kTensorLoadInferType.name,
- FTensorLoadInferType::FromNative<&InferTensorLoadType>());
+ refl::TypeAttrDef<TensorTypeNode>().native_fn_attr<&InferTensorLoadType>(
+ type_attr::kTensorLoadInferType);
}
} // namespace tirx
diff --git a/tirx/src/tirx/op/abi.cc b/tirx/src/tirx/op/abi.cc
index 9f25bd8ca3..d5419ceab1 100644
--- a/tirx/src/tirx/op/abi.cc
+++ b/tirx/src/tirx/op/abi.cc
@@ -61,7 +61,7 @@ const Op& call_extern_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.call_extern")
.signature(sig::arg("func_name", "The function name."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& call_pure_extern_op() {
@@ -72,7 +72,7 @@ const Op& call_pure_extern_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.call_pure_extern")
.signature(sig::arg("func_name", "The function name."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& call_llvm_intrin_op() {
@@ -83,7 +83,7 @@ const Op& call_llvm_intrin_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.call_llvm_intrin")
.signature(sig::arg<IntExpr>("intrin_id", "The intrinsic identifier."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& call_llvm_pure_intrin_op() {
@@ -94,7 +94,7 @@ const Op& call_llvm_pure_intrin_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.call_llvm_pure_intrin")
.signature(sig::arg<IntExpr>("intrin_id", "The intrinsic identifier."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure))
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure)
.set_attr(tvm::tirx::op_attr::kVectorizable, true);
}
@@ -107,7 +107,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.call_spirv_pure_glsl450")
.signature(sig::arg<IntExpr>("intrin_id", "The intrinsic identifier."),
sig::var_args<PrimExpr>("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& abi_field_get_op() {
@@ -119,7 +119,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.abi_field_get")
.signature(sig::arg("arr", "The array."), sig::arg<IntExpr>("index",
"The index."),
sig::arg<IntExpr>("field", "The field index."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kReadState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kReadState);
}
const Op& abi_field_set_op() {
@@ -133,7 +133,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg("arr", "The array."), sig::arg<IntExpr>("index",
"The index."),
sig::arg<IntExpr>("field", "The field index."),
sig::arg("value", "The value to use."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kUpdateState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kUpdateState);
}
const Op& throw_last_error_op() {
@@ -144,7 +144,7 @@ const Op& throw_last_error_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.throw_last_error")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& stack_alloca_op() {
@@ -157,7 +157,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.set_native_fn_attr<&InferTypeStackAlloca>(tvm::op_attr::kInferType)
.signature(sig::arg("dtype_str", "The data type name."),
sig::arg<IntExpr>("num", "The number of entries."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& stack_make_shape_op() {
@@ -169,7 +169,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.stack_make_shape")
.set_attr(tvm::op_attr::kFixedReturnType, PtrType(PrimType::Int(64)))
.signature(sig::var_args<IntExpr>("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& stack_make_dltensor_op() {
@@ -185,7 +185,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("ndim", "The number of dimensions."),
sig::arg("arr_dtype", "The array data type."),
sig::arg<IntExpr>("elem_offset", "The element offset."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& call_packed_op() {
@@ -197,7 +197,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.call_packed")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Int(32))
.signature(sig::arg("func_name", "The function name."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -225,7 +225,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg("kernel", "The kernel."), sig::var_args("args"),
sig::call_attrs<CallFFIKernelAttr>())
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Int(32))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& call_cpacked_op() {
@@ -237,7 +237,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.call_cpacked")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Int(32))
.signature(sig::arg("func_name", "The function name."),
sig::var_args("args"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& call_packed_lowered_op() {
@@ -252,7 +252,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg("args_stack", "The argument stack."),
sig::arg<IntExpr>("begin", "The start index."),
sig::arg<IntExpr>("end", "The end index."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& call_cpacked_lowered_op() {
@@ -267,7 +267,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg("args_stack", "The argument stack."),
sig::arg<IntExpr>("begin", "The start index."),
sig::arg<IntExpr>("end", "The end index."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -279,7 +279,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("dtype_code_hint", "The data type code
hint."),
sig::arg<IntExpr>("dtype_bits_hint", "The data type bit-width
hint."))
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "TVMBackendAllocWorkspace")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -289,7 +289,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("device_id", "The device index."),
sig::arg("ptr", "The pointer."))
.set_attr(tvm::tirx::op_attr::kGlobalSymbol, "TVMBackendFreeWorkspace")
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
} // namespace tirx
diff --git a/tirx/src/tirx/op/annotation.cc b/tirx/src/tirx/op/annotation.cc
index 63d36d6350..a488797d51 100644
--- a/tirx/src/tirx/op/annotation.cc
+++ b/tirx/src/tirx/op/annotation.cc
@@ -39,7 +39,7 @@ const Op& kernel_replace_point_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.kernel_replace_point")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& ignore_loop_partition_op() {
@@ -51,7 +51,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.ignore_loop_partition")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Bool())
.signature(sig::arg<PrimExpr>("predicate", "The predicate."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
} // namespace tirx
diff --git a/tirx/src/tirx/op/cpu.cc b/tirx/src/tirx/op/cpu.cc
index 2d1347601b..cc652174ef 100644
--- a/tirx/src/tirx/op/cpu.cc
+++ b/tirx/src/tirx/op/cpu.cc
@@ -40,7 +40,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.cpu_parallel_barrier")
.signature()
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
} // namespace tirx
diff --git a/tirx/src/tirx/op/gpu.cc b/tirx/src/tirx/op/gpu.cc
index d943f39a86..fbe69f92e1 100644
--- a/tirx/src/tirx/op/gpu.cc
+++ b/tirx/src/tirx/op/gpu.cc
@@ -51,7 +51,7 @@ PrimExpr gpu_thread_return(Location loc) {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.gpu_thread_return")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kControlJump));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kControlJump);
}
const Op& gpu_thread_filter_op() {
@@ -64,7 +64,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Bool())
.signature(sig::arg<PrimVar>("var", "The thread-axis variable."),
sig::arg<PrimExpr>("pred", "The predicate."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& gpu_active_thread_selector_op() {
@@ -77,7 +77,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg<PrimVar>("var", "The thread-axis variable."),
sig::arg<PrimExpr>("pred", "The predicate."))
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& gpu_thread_invariant_op() {
@@ -89,7 +89,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.gpu_thread_invariant")
.set_native_fn_attr<&InferTypeReturnArgType<0>>(tvm::op_attr::kInferType)
.signature(sig::arg<PrimExpr>("cond", "The condition."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& gpu_storage_sync_op() {
@@ -101,7 +101,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.gpu_storage_sync")
.signature(sig::arg<StringImm>("storage_scope", "The storage scope."))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& gpu_warp_shuffle_op() {
@@ -117,7 +117,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("width", "The width."),
sig::arg<IntExpr>("warp_size", "The number of threads per
warp."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& gpu_warp_shuffle_up_op() {
@@ -132,7 +132,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("offset", "The offset."),
sig::arg<IntExpr>("width", "The width."),
sig::arg<IntExpr>("warp_size", "The number of threads per warp."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& gpu_warp_shuffle_down_op() {
@@ -147,7 +147,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("offset", "The offset."),
sig::arg<IntExpr>("width", "The width."),
sig::arg<IntExpr>("warp_size", "The number of threads per warp."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& gpu_warp_shuffle_xor_op() {
@@ -163,7 +163,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("width", "The width."),
sig::arg<IntExpr>("warp_size", "The number of threads per
warp."))
.set_native_fn_attr<&InferTypeReturnArgType<1>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& gpu_warp_activemask_op() {
@@ -174,7 +174,7 @@ const Op& gpu_warp_activemask_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.gpu_warp_activemask")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::UInt(32))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& gpu_thread_allreduce_op() {
@@ -191,7 +191,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<Expr>("destinations", "The destination tensor
loads."),
sig::arg<Expr>("thread_axes", "The reduction thread axes."))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& gpu_dp4a_op() {
@@ -205,7 +205,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<PrimExpr>("vec2", "The second input vector."),
sig::arg<PrimExpr>("acc", "The accumulator."))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Int(32))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -216,7 +216,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("n", "The N dimension."), sig::arg<IntExpr>("k",
"The K dimension."),
sig::arg<IntExpr>("index", "The index."), sig::arg("buffer_ptr",
"The buffer pointer."),
sig::arg<IntExpr>("stride", "The stride."), sig::arg("layout", "The
layout."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kReadState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kReadState);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -230,7 +230,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("index_b", "The B fragment index."),
sig::arg("fragment_c", "The C fragment."),
sig::arg<IntExpr>("index_c", "The C fragment index."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -240,7 +240,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg("fragment", "The matrix fragment."), sig::arg<IntExpr>("m",
"The M dimension."),
sig::arg<IntExpr>("n", "The N dimension."), sig::arg<IntExpr>("k",
"The K dimension."),
sig::arg<IntExpr>("index", "The index."), sig::arg("value", "The
value to use."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
TVM_FFI_STATIC_INIT_BLOCK() {
@@ -251,7 +251,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<IntExpr>("n", "The N dimension."), sig::arg<IntExpr>("k",
"The K dimension."),
sig::arg<IntExpr>("index", "The index."), sig::arg("buffer_ptr",
"The buffer pointer."),
sig::arg<IntExpr>("stride", "The stride."), sig::arg("layout", "The
layout."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
TVM_FFI_STATIC_INIT_BLOCK() {
diff --git a/tirx/src/tirx/op/memory.cc b/tirx/src/tirx/op/memory.cc
index a0373ff38f..5ee527db92 100644
--- a/tirx/src/tirx/op/memory.cc
+++ b/tirx/src/tirx/op/memory.cc
@@ -172,7 +172,7 @@ Expr reinterpret(Type target_ty, Expr value, Location loc) {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.reinterpret")
.signature(sig::arg("x", "The input value."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& address_of_op() {
@@ -184,7 +184,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.address_of")
.signature(sig::arg("obj", "The referenced object."))
.set_native_fn_attr<&InferTypeAddressOf>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& isnullptr_op() {
@@ -196,7 +196,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.isnullptr")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Bool())
.signature(sig::arg("x", "The input value."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& prefetch_op() {
@@ -209,7 +209,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg("ptr", "The pointer."), sig::arg<IntExpr>("rw", "The
read/write mode."),
sig::arg<IntExpr>("locality", "The locality hint."),
sig::arg<IntExpr>("cache_type", "The cache policy."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& ptr_byte_offset_op() {
@@ -221,7 +221,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.ptr_byte_offset")
.signature(sig::arg("data", "Base pointer."),
sig::arg<IntExpr>("byte_offset", "Offset in bytes."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& static_handle_op() {
@@ -231,8 +231,7 @@ const Op& static_handle_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.static_handle")
- .set_attr(tvm::op_attr::kCallEffectKind,
- static_cast<int64_t>(CallEffectKind::kSpecialCallArg));
+ .set_attr(tvm::op_attr::kCallEffectKind,
CallEffectKind::kSpecialCallArg);
}
const Op& handle_add_byte_offset_op() {
@@ -244,7 +243,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.handle_add_byte_offset")
.signature(sig::arg("handle", "The handle."),
sig::arg<IntExpr>("offset", "The offset."))
.set_native_fn_attr<&InferTypePointerOffset<0,
-1>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& atomic_add_op() {
@@ -255,7 +254,7 @@ const Op& atomic_add_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.atomic_add")
.signature(sig::arg("ptr", "The pointer."), sig::arg("value", "The value
to use."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& assume_aligned_op() {
@@ -268,7 +267,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg<TensorVar>("tensor", "The tensor whose base address
is aligned."),
sig::arg<IntImm>("alignment_bytes", "The constant byte
alignment."))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kEmbedInfo));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kEmbedInfo);
}
const Op& undef_op() {
@@ -279,7 +278,7 @@ const Op& undef_op() {
TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.undef")
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Int(32))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kReadState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kReadState);
}
const Op& masked_load_op() {
@@ -292,7 +291,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg<TensorVar>("tensor", "The tensor."),
sig::arg<PrimExpr>("index", "The index."),
sig::var_args<PrimExpr>("args"))
.set_native_fn_attr<&InferTypeMaskedLoad>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kReadState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kReadState);
}
const Op& masked_store_op() {
@@ -306,7 +305,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
sig::arg<PrimExpr>("value", "The value to use."),
sig::arg<PrimExpr>("index", "The index."),
sig::var_args<PrimExpr>("args"))
.set_attr(tvm::op_attr::kFixedReturnType, PrimType::Void())
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kUpdateState));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kUpdateState);
}
const Op& alloc_tensor_op() {
@@ -323,7 +322,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::var_args<tvm::Tuple>("placement", "Optional
producer-owned placement."),
sig::ty_arg<TensorType>("tensor_type"))
.set_attrs_type_key(DictAttrsNode::_type_key)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kOpaque));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kOpaque);
}
const Op& decl_tensor_op() {
@@ -339,7 +338,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
true)
.signature(sig::arg("data", "The existing data pointer."),
sig::ty_arg<TensorType>("tensor_type"))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& tensor_data_ptr_op() {
@@ -351,7 +350,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.tensor_data_ptr")
.signature(sig::arg("tensor", "The tensor variable."))
.set_native_fn_attr<&InferTypeTensorDataPtr>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
TVM_FFI_STATIC_INIT_BLOCK() {
diff --git a/tirx/src/tirx/op/vector.cc b/tirx/src/tirx/op/vector.cc
index 46c5f72fb5..225105a582 100644
--- a/tirx/src/tirx/op/vector.cc
+++ b/tirx/src/tirx/op/vector.cc
@@ -59,7 +59,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.vector_high")
.signature(sig::arg<PrimExpr>("vec", "The input vector."))
.set_native_fn_attr<&InferTypeVectorPart<false>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& vector_low_op() {
@@ -71,7 +71,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.vector_low")
.signature(sig::arg<PrimExpr>("vec", "The input vector."))
.set_native_fn_attr<&InferTypeVectorPart<false>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& vector_combine_op() {
@@ -84,7 +84,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
.signature(sig::arg<PrimExpr>("vec1", "The first input vector."),
sig::arg<PrimExpr>("vec2", "The second input vector."))
.set_native_fn_attr<&InferTypeVectorPart<true>>(tvm::op_attr::kInferType)
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
const Op& get_active_lane_mask_op() {
@@ -96,7 +96,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
OpDef("tirx.get_active_lane_mask")
.signature(sig::arg<IntExpr>("base", "The base value."),
sig::arg<IntExpr>("limit", "The limit value."))
- .set_attr(tvm::op_attr::kCallEffectKind,
static_cast<int64_t>(CallEffectKind::kPure));
+ .set_attr(tvm::op_attr::kCallEffectKind, CallEffectKind::kPure);
}
} // namespace tirx
diff --git a/tirx/tests/cpp/ir/tensor_load_test.cc
b/tirx/tests/cpp/ir/tensor_load_test.cc
index a74ad753d3..78accce96a 100644
--- a/tirx/tests/cpp/ir/tensor_load_test.cc
+++ b/tirx/tests/cpp/ir/tensor_load_test.cc
@@ -56,8 +56,8 @@ TVM_FFI_STATIC_INIT_BLOCK() {
if (load->indices.empty()) return Type::Missing();
return nullptr;
}));
-
refl::TypeAttrDef<LoadSourceTypeNode>().attr(type_attr::kTensorLoadInferType.name,
-
FTensorLoadInferType::FromNative<&InferTestLoad>());
+ refl::TypeAttrDef<LoadSourceTypeNode>().native_fn_attr<&InferTestLoad>(
+ type_attr::kTensorLoadInferType);
}
Var LoadSource() {
diff --git a/tirx/tests/cpp/target/target_test.cc
b/tirx/tests/cpp/target/target_test.cc
index d8c3eb974e..d657a2fb2b 100644
--- a/tirx/tests/cpp/target/target_test.cc
+++ b/tirx/tests/cpp/target/target_test.cc
@@ -27,11 +27,11 @@ TVM_FFI_STATIC_INIT_BLOCK() {
TargetKindDef("TestTargetKind")
.set_default_device_type(kDLCPU)
.def_option<bool>("my_bool")
- .def_option<ffi::Map<ffi::String,
ffi::Any>>(backend::attr::kBackendConfig.name);
+ .def_option<ffi::Map<ffi::String, ffi::Any>>(attr::kBackendConfig.name);
}
TEST(TargetCreation, TypedBackendConfig) {
- constexpr auto key = backend::attr::kBackendConfig;
+ constexpr auto key = attr::kBackendConfig;
using Config = decltype(key)::ValueType;
Config fallback{{"cuda", Config{{"arch", ffi::String("sm_80")}}}};
Target absent("TestTargetKind");
diff --git a/tirx/tests/python/tirx/script/test_error_handling.py
b/tirx/tests/python/tirx/script/test_error_handling.py
index e9a0dcdf60..69a822cec0 100644
--- a/tirx/tests/python/tirx/script/test_error_handling.py
+++ b/tirx/tests/python/tirx/script/test_error_handling.py
@@ -203,11 +203,12 @@ def test_tvm_exception_catch_from_scope_handler():
check_error(scope_handler_except, 2, TypeError)
-def test_tvm_exception_catch_from_bare_intrin():
- def intrin_except_unassign(A: T.Tensor((16, 16), "float32")) -> None:
- T.evaluate(A) # error
+def test_evaluate_tensor():
+ @T.function
+ def evaluate_tensor(A: T.Tensor((16, 16), "float32")) -> None:
+ T.evaluate(A)
- check_error(intrin_except_unassign, 2, RuntimeError)
+ assert evaluate_tensor.body.seq[0].value.same_as(evaluate_tensor.params[0])
def test_tvm_exception_catch_from_assigned_intrin():