tvm
Loading...
Searching...
No Matches
base_expr.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
24#ifndef TVM_IR_BASE_EXPR_H_
25#define TVM_IR_BASE_EXPR_H_
26
27#include <tvm/ffi/cast.h>
28#include <tvm/ffi/dtype.h>
29#include <tvm/ffi/reflection/registry.h>
30#include <tvm/ffi/string.h>
31#include <tvm/ir/source_map.h>
32
33#include <cstddef>
34#include <cstdint>
35#include <optional>
36#include <type_traits>
37
38namespace tvm {
39
52class TypeNode : public ffi::Object {
53 public:
58 mutable Span span;
59
60 static void RegisterReflection() {
61 namespace refl = tvm::ffi::reflection;
62 // span do not participate in structural equal and hash.
63 refl::ObjectDef<TypeNode>().def_ro("span", &TypeNode::span, refl::DefaultValue(Span()),
64 refl::AttachFieldFlag::SEqHashIgnore());
65 }
66
68
69 static constexpr const uint32_t _type_child_slots = 14;
70 TVM_FFI_DECLARE_OBJECT_INFO("ir.Type", TypeNode, ffi::Object);
71};
72
77class Type : public ffi::ObjectRef {
78 public:
81
83 TVM_DLL bool IsMissing() const;
84
86};
87
95 public:
96 static void RegisterReflection() {
97 namespace refl = tvm::ffi::reflection;
98 refl::ObjectDef<OpaqueTypeNode>();
99 }
100
102};
103
111
120 public:
125
126 static void RegisterReflection() {
127 namespace refl = tvm::ffi::reflection;
128 refl::ObjectDef<PrimTypeNode>().def_ro("dtype", &PrimTypeNode::dtype);
129 }
131};
132
133/*
134 * \brief Managed reference to PrimTypeNode.
135 * \sa PrimTypeNode
136 */
137class PrimType final : public Type {
138 public:
143 TVM_DLL explicit PrimType(DLDataType dtype);
144
152
154 TVM_DLL static PrimType Int(int bits, int lanes = 1);
156 TVM_DLL static PrimType UInt(int bits, int lanes = 1);
158 TVM_DLL static PrimType Float(int bits, int lanes = 1);
160 TVM_DLL static PrimType BFloat(int bits, int lanes = 1);
162 TVM_DLL static PrimType Bool(int lanes = 1);
172
175 return static_cast<DLDataTypeCode>(static_cast<int>(get()->dtype.code));
176 }
177
179 TVM_FFI_INLINE int32_t bits() const { return get()->dtype.bits; }
180
186 int16_t encoded_lanes = static_cast<int16_t>(get()->dtype.lanes);
189 << "Can't fetch the lanes of a scalable vector at a compile time.";
190 }
191 return encoded_lanes;
192 }
193
199 DLDataType dtype = get()->dtype;
200 return dtype.code == static_cast<uint8_t>(code) && dtype.bits == bits;
201 }
202
207 template <typename... Codes>
209 uint8_t dtype_code = get()->dtype.code;
210 return ((dtype_code == static_cast<uint8_t>(codes)) || ...);
211 }
212
215 int16_t encoded_lanes = static_cast<int16_t>(get()->dtype.lanes);
216 return encoded_lanes == 1;
217 }
218
220 TVM_FFI_INLINE bool IsVoid() const {
221 DLDataType dtype = get()->dtype;
222 return dtype.code == static_cast<uint8_t>(DLDataTypeCode::kDLOpaqueHandle) && dtype.bits == 0 &&
223 static_cast<int16_t>(dtype.lanes) == 0;
224 }
225
228 return static_cast<int16_t>(get()->dtype.lanes) < -1;
229 }
230
233 return static_cast<int16_t>(get()->dtype.lanes) > 1;
234 }
235
243 DLDataType dtype = get()->dtype;
244 int16_t encoded_lanes = static_cast<int16_t>(dtype.lanes);
247 << "Cannot compute compile-time storage bytes for non-fixed vector type " << dtype;
248 }
249 return static_cast<size_t>(
250 (static_cast<uint64_t>(dtype.bits) * static_cast<uint64_t>(dtype.lanes) + 7) / 8);
251 }
252
255 DLDataType dtype = get()->dtype;
256 int16_t encoded_lanes = static_cast<int16_t>(dtype.lanes);
257 if (encoded_lanes < -1) {
258 return ScalableVector(code, dtype.bits, -encoded_lanes);
259 }
260 return PrimType(code, dtype.bits, encoded_lanes);
261 }
262
265 DLDataType dtype = get()->dtype;
266 int16_t encoded_lanes = static_cast<int16_t>(dtype.lanes);
267 if (encoded_lanes < -1) {
268 return ScalableVector(this->code(), bits, -encoded_lanes);
269 }
270 return PrimType(this->code(), bits, encoded_lanes);
271 }
272
275 return PrimType(this->code(), this->bits(), lanes);
276 }
277
280 int16_t encoded_lanes = static_cast<int16_t>(get()->dtype.lanes);
281 if (encoded_lanes >= -1) {
282 TVM_FFI_THROW(InternalError) << "A fixed length vector doesn't have a vscale factor.";
283 }
284 return -encoded_lanes;
285 }
286
288};
289
290inline bool operator==(const PrimType& lhs, const PrimType& rhs) {
291 return lhs->dtype == rhs->dtype;
292}
293
294inline bool operator!=(const PrimType& lhs, const PrimType& rhs) { return !(lhs == rhs); }
295
300class ExprNode : public ffi::Object {
301 public:
306 mutable Span span;
307
314 mutable Type ty = Type::Missing();
315
316 static void RegisterReflection() {
317 namespace refl = tvm::ffi::reflection;
318 // span does not participate in structural equal and hash.
319 refl::ObjectDef<ExprNode>()
320 .def_ro("span", &ExprNode::span, refl::DefaultValue(Span()),
321 refl::AttachFieldFlag::SEqHashIgnore())
322 .def_ro("ty", &ExprNode::ty, refl::DefaultValue(Type::Missing()));
323 }
324
326
327 static constexpr const uint32_t _type_child_slots = 64;
328 TVM_FFI_DECLARE_OBJECT_INFO("ir.Expr", ExprNode, ffi::Object);
329};
330
335class Expr : public ffi::ObjectRef {
336 public:
337 // Expressions do not implicitly compare by object identity or address. Callers must name
338 // whether they intend object identity, structural equality, or primitive symbolic comparison.
339 bool operator==(const Expr& other) const = delete;
340 bool operator!=(const Expr& other) const = delete;
341 bool operator<(const Expr& other) const = delete;
342
344};
345
352class OpaqueExprNode : public ExprNode {
353 public:
354 static void RegisterReflection() {
355 namespace refl = tvm::ffi::reflection;
356 refl::ObjectDef<OpaqueExprNode>();
357 }
358
359 static constexpr const uint32_t _type_child_slots = 2;
361};
362
368
369class Call;
370
376template <typename ExpectedType>
377class TypedExpr : public Expr {
378 public:
380 ExpectedType ty() const {
381 const auto* node = get();
382 TVM_FFI_DCHECK(node != nullptr);
383 const auto* ty_node = node->ExprNode::ty.template as<typename ExpectedType::ContainerType>();
384 TVM_FFI_DCHECK(ty_node != nullptr);
385 return ffi::GetRef<ExpectedType>(ty_node);
386 }
387
389 static constexpr bool _type_container_is_exact = false;
390};
391
401class PrimExpr : public TypedExpr<PrimType> {
402 public:
403 using TypedExpr<PrimType>::ty;
404
410 TVM_DLL PrimExpr(Call call); // NOLINT(*)
411
416 TVM_DLL PrimExpr(int32_t value); // NOLINT(*)
421 TVM_DLL PrimExpr(float value); // NOLINT(*)
422
424 static constexpr bool _type_container_is_exact = false;
425
430 TVM_DLL static PrimExpr ConvertFallbackValue(ffi::String value); // NOLINT(*)
431};
432
438class PrimExprConvertibleNode : public ffi::Object {
439 public:
441 virtual PrimExpr ToPrimExpr() const = 0;
442 TVM_FFI_DECLARE_OBJECT_INFO("ir.PrimExprConvertible", PrimExprConvertibleNode, ffi::Object);
443};
444
449class PrimExprConvertible : public ffi::ObjectRef {
450 public:
453};
454
455namespace ffi {
456template <>
457inline constexpr bool use_default_type_traits_v<PrimType> = false;
458
459template <>
460struct TypeTraits<PrimType> : public ObjectRefWithFallbackTraitsBase<PrimType, DLDataType> {
462};
463
464template <typename ExpectedType>
466
467template <typename ExpectedType>
468struct TypeTraits<TypedExpr<ExpectedType>>
469 : public ObjectRefTypeTraitsBase<TypedExpr<ExpectedType>> {
471 using Base::CopyFromAnyViewAfterCheck;
472 using Base::CopyToAnyView;
473 using Base::GetMismatchTypeInfo;
474 using Base::MoveFromAnyAfterCheck;
475 using Base::MoveToAny;
476 using Base::TypeSchema;
477 using Base::TypeStr;
478
479 TVM_FFI_INLINE static bool CheckAnyStrict(const TVMFFIAny* src) {
480 if (src->type_index == TypeIndex::kTVMFFINone) {
482 }
483 if (src->type_index < TypeIndex::kTVMFFIStaticObjectBegin ||
484 !details::IsObjectInstance<ExprNode>(src->type_index)) {
485 return false;
486 }
487 const auto* expr = static_cast<const ExprNode*>(
488 details::ObjectUnsafe::ObjectPtrFromUnowned<Object>(src->v_obj).get());
489 return details::AnyUnsafe::CheckAnyStrict<ExpectedType>(expr->ty);
490 }
491
492 TVM_FFI_INLINE static std::optional<TypedExpr<ExpectedType>> TryCastFromAnyView(
493 const TVMFFIAny* src) {
494 if (CheckAnyStrict(src)) {
495 if (src->type_index == TypeIndex::kTVMFFINone) {
496 return details::ObjectUnsafe::ObjectRefFromObjectPtr<TypedExpr<ExpectedType>>(nullptr);
497 }
498 return details::ObjectUnsafe::ObjectRefFromObjectPtr<TypedExpr<ExpectedType>>(
499 details::ObjectUnsafe::ObjectPtrFromUnowned<ExprNode>(src->v_obj));
500 }
501 return std::nullopt;
502 }
503};
504
505template <>
506inline constexpr bool use_default_type_traits_v<PrimExpr> = false;
507
508template <typename ObjectRefType, typename ExpectedType, typename... FallbackTypes>
510 : public ObjectRefWithFallbackTraitsBase<ObjectRefType, FallbackTypes...> {
511 using Base = ObjectRefWithFallbackTraitsBase<ObjectRefType, FallbackTypes...>;
512
516
517 TVM_FFI_INLINE static std::optional<ObjectRefType> TryCastFromAnyView(const TVMFFIAny* src) {
518 if (TypeTraits<TypedExpr<ExpectedType>>::TryCastFromAnyView(src)) {
519 return details::ObjectUnsafe::ObjectRefFromObjectPtr<ObjectRefType>(
520 details::ObjectUnsafe::ObjectPtrFromUnowned<ExprNode>(src->v_obj));
521 }
523 }
524};
525
526// define automatic conversion from bool, int64_t, double, ffi::String to PrimExpr
527// These functions are declared early to avoid circular dependency
528template <>
529struct TypeTraits<PrimExpr>
530 : public TypedExprWithFallbackTraitsBase<PrimExpr, PrimType, StrictBool, int64_t, double,
531 ffi::String, PrimExprConvertible> {
533 ffi::String, PrimExprConvertible>;
534 using Base::CheckAnyStrict;
535 using Base::CopyFromAnyViewAfterCheck;
536 using Base::CopyToAnyView;
537 using Base::GetMismatchTypeInfo;
538 using Base::MoveFromAnyAfterCheck;
539 using Base::MoveToAny;
540 using Base::TryCastFromAnyView;
541 using Base::TypeSchema;
542 using Base::TypeStr;
543
547 TVM_FFI_INLINE static PrimExpr ConvertFallbackValue(ffi::String value) {
548 return PrimExpr::ConvertFallbackValue(value);
549 }
551 return value->ToPrimExpr();
552 }
553};
554
555template <>
556inline constexpr bool use_default_type_traits_v<Expr> = false;
557
558// Allow generic Expr arguments to use the primitive-literal conversions
559// already defined by PrimExpr.
560template <>
561struct TypeTraits<Expr> : public ObjectRefWithFallbackTraitsBase<Expr, PrimExpr> {
562 TVM_FFI_INLINE static Expr ConvertFallbackValue(PrimExpr value) { return value; }
563};
564} // namespace ffi
565
566} // namespace tvm
567
568#endif // TVM_IR_BASE_EXPR_H_
Managed reference to CallNode.
Definition expr.h:474
Base type of all the expressions.
Definition base_expr.h:300
Type ty
The deduced or annotated type of the expression.
Definition base_expr.h:314
Span span
Span that points to the original source code. Reserved debug information.
Definition base_expr.h:306
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition base_expr.h:325
TVM_FFI_DECLARE_OBJECT_INFO("ir.Expr", ExprNode, ffi::Object)
static constexpr const uint32_t _type_child_slots
Definition base_expr.h:327
static void RegisterReflection()
Definition base_expr.h:316
Managed reference to ExprNode.
Definition base_expr.h:335
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(Expr, ffi::ObjectRef, ExprNode)
bool operator==(const Expr &other) const =delete
bool operator!=(const Expr &other) const =delete
bool operator<(const Expr &other) const =delete
Base node for opaque construction-time expressions.
Definition base_expr.h:352
static constexpr const uint32_t _type_child_slots
Definition base_expr.h:359
TVM_FFI_DECLARE_OBJECT_INFO("ir.OpaqueExpr", OpaqueExprNode, ExprNode)
static void RegisterReflection()
Definition base_expr.h:354
Managed reference to OpaqueExprNode.
Definition base_expr.h:364
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(OpaqueExpr, Expr, OpaqueExprNode)
Type marker for opaque construction-time expressions.
Definition base_expr.h:94
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.OpaqueType", OpaqueTypeNode, TypeNode)
static void RegisterReflection()
Definition base_expr.h:96
Managed reference to OpaqueTypeNode.
Definition base_expr.h:105
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(OpaqueType, Type, OpaqueTypeNode)
Base class for other IR constructs that can be converted to PrimExpr. This is useful for the FFI to c...
Definition base_expr.h:438
virtual ~PrimExprConvertibleNode()
Definition base_expr.h:440
virtual PrimExpr ToPrimExpr() const =0
TVM_FFI_DECLARE_OBJECT_INFO("ir.PrimExprConvertible", PrimExprConvertibleNode, ffi::Object)
Managed reference to PrimExprConvertibleNode.
Definition base_expr.h:449
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(PrimExprConvertible, ffi::ObjectRef, PrimExprConvertibleNode)
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:401
static constexpr bool _type_container_is_exact
Definition base_expr.h:424
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(PrimExpr, TypedExpr< PrimType >, ExprNode)
PrimExpr(float value)
construct from float.
PrimExpr(int32_t value)
construct from integer.
static PrimExpr ConvertFallbackValue(ffi::String value)
construct from string to form a StringImm.
PrimExpr(Call call)
Construct from a call after checking that its result type is PrimType.
Primitive data types used in the low-level IR.
Definition base_expr.h:119
DLDataType dtype
The raw DLPack dtype represented by this primitive type.
Definition base_expr.h:124
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.PrimType", PrimTypeNode, TypeNode)
static void RegisterReflection()
Definition base_expr.h:126
Definition base_expr.h:137
static PrimType ScalableVector(DLDataTypeCode code, int bits, int lanes)
Construct a scalable vector type.
TVM_FFI_INLINE DLDataTypeCode code() const
Definition base_expr.h:174
static PrimType Float(int bits, int lanes=1)
Construct a floating-point type with fixed lanes.
static PrimType Void()
Construct the void sentinel type, encoded as handle(0, 0).
TVM_FFI_INLINE bool IsVoid() const
Whether this type is the void sentinel handle(0, 0).
Definition base_expr.h:220
TVM_FFI_INLINE PrimType WithLanes(int lanes) const
Return the same scalar element type with a fixed lane count.
Definition base_expr.h:274
static PrimType Int(int bits, int lanes=1)
Construct a signed integer type with fixed lanes.
TVM_FFI_INLINE bool IsScalableVector() const
Whether this type is a scalable vector.
Definition base_expr.h:227
static PrimType Bool(int lanes=1)
Construct a boolean type with fixed lanes.
TVM_FFI_INLINE int32_t bits() const
Definition base_expr.h:179
TVM_FFI_INLINE bool IsFixedLengthVector() const
Whether this type is a fixed-length vector.
Definition base_expr.h:232
TVM_FFI_INLINE bool IsScalar() const
Whether this type is a scalar, excluding fixed and scalable vectors.
Definition base_expr.h:214
TVM_FFI_INLINE bool MatchesCode(Codes... codes) const
Check whether the dtype code matches any of the provided DLPack codes.
Definition base_expr.h:208
static PrimType BFloat(int bits, int lanes=1)
Construct a bfloat type with fixed lanes.
TVM_FFI_INLINE bool MatchesElementType(DLDataTypeCode code, int bits) const
Check the scalar element code and bit width.
Definition base_expr.h:198
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(PrimType, Type, PrimTypeNode)
TVM_FFI_INLINE int32_t VScaleFactor() const
Definition base_expr.h:279
PrimType(DLDataTypeCode code, int bits, int lanes=1)
Construct from DLPack dtype fields.
TVM_FFI_INLINE int32_t lanes() const
Definition base_expr.h:185
TVM_FFI_INLINE PrimType WithBits(int bits) const
Return the same type with a different scalar bit width, preserving code and lanes.
Definition base_expr.h:264
TVM_FFI_INLINE size_t StorageBytes() const
Return the number of bytes needed to store one value of this type.
Definition base_expr.h:242
static PrimType UInt(int bits, int lanes=1)
Construct an unsigned integer type with fixed lanes.
PrimType(DLDataType dtype)
Construct from a raw DLPack dtype.
TVM_FFI_INLINE PrimType WithCode(DLDataTypeCode code) const
Return the same type with a different dtype code, preserving bits and lanes.
Definition base_expr.h:254
Definition source_map.h:111
Type is the base type of all types.
Definition base_expr.h:52
static constexpr const uint32_t _type_child_slots
Definition base_expr.h:69
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition base_expr.h:67
TVM_FFI_DECLARE_OBJECT_INFO("ir.Type", TypeNode, ffi::Object)
static void RegisterReflection()
Definition base_expr.h:60
Span span
Span that points to the original source code. Reserved debug information.
Definition base_expr.h:58
Managed reference to TypeNode.
Definition base_expr.h:77
static Type Missing()
Sentinel for a type that has not been populated yet.
bool IsMissing() const
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Type, ffi::ObjectRef, TypeNode)
Typed reference/view over an expression whose result type is a specific Type subtype.
Definition base_expr.h:377
static constexpr bool _type_container_is_exact
Definition base_expr.h:389
ExpectedType ty() const
Definition base_expr.h:380
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TypedExpr, Expr, ExprNode)
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
With(Args &&... args)
constructor. Enter the scope of the context.
Definition with_context.h:66
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
bool operator!=(const PrimType &lhs, const PrimType &rhs)
Definition base_expr.h:294
bool operator==(const PrimType &lhs, const PrimType &rhs)
Definition base_expr.h:290
A map from source names to source code.
static TVM_FFI_INLINE Expr ConvertFallbackValue(PrimExpr value)
Definition base_expr.h:562
static TVM_FFI_INLINE PrimExpr ConvertFallbackValue(ffi::String value)
Definition base_expr.h:547
static PrimExpr ConvertFallbackValue(int64_t value)
static TVM_FFI_INLINE PrimExpr ConvertFallbackValue(PrimExprConvertible value)
Definition base_expr.h:550
static PrimExpr ConvertFallbackValue(StrictBool value)
static PrimExpr ConvertFallbackValue(double value)
static TVM_FFI_INLINE PrimType ConvertFallbackValue(DLDataType dtype)
Definition base_expr.h:461
ObjectRefTypeTraitsBase< TypedExpr< ExpectedType > > Base
Definition base_expr.h:470
static TVM_FFI_INLINE std::optional< TypedExpr< ExpectedType > > TryCastFromAnyView(const TVMFFIAny *src)
Definition base_expr.h:492
static TVM_FFI_INLINE bool CheckAnyStrict(const TVMFFIAny *src)
Definition base_expr.h:479
static TVM_FFI_INLINE std::optional< ObjectRefType > TryCastFromAnyView(const TVMFFIAny *src)
Definition base_expr.h:517
static TVM_FFI_INLINE bool CheckAnyStrict(const TVMFFIAny *src)
Definition base_expr.h:513