tvm
Loading...
Searching...
No Matches
buffer.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_TIRX_BUFFER_H_
25#define TVM_TIRX_BUFFER_H_
26
27#include <tvm/ffi/container/array.h>
28#include <tvm/ffi/reflection/registry.h>
29#include <tvm/ffi/string.h>
30#include <tvm/ir/expr.h>
31#include <tvm/tirx/layout.h>
32#include <tvm/tirx/var.h>
33
34#include <string>
35
36namespace tvm {
37namespace tirx {
38
39#ifndef TVM_INDEX_DEFAULT_I64
40#define TVM_INDEX_DEFAULT_I64 1
41#endif
44#if TVM_INDEX_DEFAULT_I64
45 static const PrimType default_index_ty = PrimType::Int(64);
46#else
47 static const PrimType default_index_ty = PrimType::Int(32);
48#endif
49 return default_index_ty;
50}
51
53#if TVM_INDEX_DEFAULT_I64
54 return DLDataType{kDLInt, 64, 1};
55#else
56 return DLDataType{kDLInt, 32, 1};
57#endif
58}
59
60// forward declare Stmt
61class Stmt;
62
71class BufferTypeNode : public TypeNode {
72 public:
76 ffi::String storage_scope;
83 ffi::Array<PrimExpr> shape;
88 ffi::Array<PrimExpr> strides;
99 ffi::Optional<Layout> layout;
100
105 ffi::Array<PrimExpr> allocated_addr;
106
109
110 static void RegisterReflection() {
111 namespace refl = tvm::ffi::reflection;
112 refl::ObjectDef<BufferTypeNode>()
113 .def_ro("dtype", &BufferTypeNode::dtype)
114 .def_ro("storage_scope", &BufferTypeNode::storage_scope)
115 // TODO(tqchen): use SEqHashDefNonRecursive after the next pypi tvm-ffi release
116 .def_ro("shape", &BufferTypeNode::shape, refl::AttachFieldFlag::SEqHashDefRecursive())
117 // TODO(tqchen): use SEqHashDefNonRecursive after the next pypi tvm-ffi release
118 .def_ro("strides", &BufferTypeNode::strides, refl::AttachFieldFlag::SEqHashDefRecursive())
119 // TODO(tqchen): use SEqHashDefNonRecursive after the next pypi tvm-ffi release
120 .def_ro("elem_offset", &BufferTypeNode::elem_offset,
121 refl::AttachFieldFlag::SEqHashDefRecursive())
122 .def_ro("data_alignment", &BufferTypeNode::data_alignment)
123 .def_ro("offset_factor", &BufferTypeNode::offset_factor)
124 .def_ro("layout", &BufferTypeNode::layout)
125 .def_ro("allocated_addr", &BufferTypeNode::allocated_addr);
126 }
127
130 return shape.size() != 0 ? shape[0].ty()->dtype : tvm::tirx::DefaultIndexType();
131 }
132
134 PrimType ElementType() const { return dtype; }
135
138
148 ffi::Array<PrimExpr> ElemOffset(ffi::Array<PrimExpr> index, bool inner = false) const;
149
151};
152
156class BufferType : public Type {
157 public:
158 TVM_DLL BufferType(ffi::String storage_scope, PrimType dtype, ffi::Array<PrimExpr> shape,
159 ffi::Array<PrimExpr> strides, PrimExpr elem_offset, int data_alignment,
160 int offset_factor, ffi::Optional<Layout> layout = std::nullopt,
161 ffi::Array<PrimExpr> allocated_addr = {}, Span span = Span());
162
164
165 explicit BufferType(ffi::ObjectPtr<BufferTypeNode> n) : Type(ffi::UnsafeInit{}) {
166 TVM_FFI_ICHECK(n != nullptr);
167 data_ = std::move(n);
168 }
169};
170
179class BufferVar : public Var {
180 public:
182 TVM_DLL explicit BufferVar(ffi::String name, BufferType type, Span span = Span());
183
185 explicit BufferVar(Var var) : Var(std::move(var)) {
186 TVM_FFI_ICHECK(get() != nullptr && get()->ty.as<BufferTypeNode>())
187 << "Expected a non-null Var with BufferType";
188 }
189
191 Var var() const { return ffi::GetRef<Var>(get()); }
192
194 BufferType type() const { return get()->ty.as_or_throw<BufferType>(); }
195
197 const ffi::String& name() const { return get()->name; }
198
200 const Span& span() const { return get()->span; }
201
204
219 TVM_DLL BufferVar MakeSlice(ffi::Array<PrimExpr> begins, ffi::Array<PrimExpr> extents) const;
229 int content_lanes = 1, PrimExpr offset = IntImm::Int32(0),
230 ffi::Optional<PrimExpr> input_extent = std::nullopt) const;
236 TVM_DLL PrimExpr vload(ffi::Array<PrimExpr> begin, PrimType dtype) const;
242 TVM_DLL Stmt vstore(ffi::Array<PrimExpr> begin, PrimExpr value) const;
243
252
259 ffi::Array<PrimExpr> OffsetOf(ffi::Array<PrimExpr> index) const;
260
266 PrimExpr OffsetOf_p(const ffi::Array<PrimExpr>& indices) const;
267
271 TVM_DLL ffi::String scope() const;
272
276 TVM_DLL BufferVar with_allocated_addr(ffi::Array<PrimExpr> allocated_addr) const;
277
283 TVM_DLL bool IsScalar(bool alloc_or_decl = true) const;
284
289
291 PrimType ElementType() const { return (*this)->ElementType(); }
292
294 PointerType DataPointerType() const { return (*this)->DataPointerType(); }
295
296 BufferVar() = default;
297 explicit BufferVar(ffi::ObjectPtr<VarNode> n) : Var(std::move(n)) {}
298 explicit BufferVar(ffi::UnsafeInit tag) : Var(tag) {}
300
301 const BufferTypeNode* operator->() const {
302 const auto* var_node = static_cast<const VarNode*>(data_.get());
303 TVM_FFI_ICHECK(var_node != nullptr);
304 const auto* type_node = var_node->ty.as<BufferTypeNode>();
305 TVM_FFI_ICHECK(type_node != nullptr)
306 << "Expected a Var with BufferType, but " << var_node->name << " has type " << var_node->ty;
307 return type_node;
308 }
309
310 const VarNode* get() const { return static_cast<const VarNode*>(data_.get()); }
311
312 [[maybe_unused]] static constexpr bool _type_is_nullable = false;
313 static constexpr bool _type_container_is_exact = false;
315};
316
317// Preserve ObjectRef-style identity comparison for exact BufferVar operands.
318// Comparisons widened to Var or Expr continue to build symbolic expressions.
319inline bool operator==(const BufferVar& lhs, const BufferVar& rhs) { return lhs.same_as(rhs); }
320
321inline bool operator!=(const BufferVar& lhs, const BufferVar& rhs) { return !lhs.same_as(rhs); }
322
324inline BufferVar GetBufferVar(const VarNode* var) { return BufferVar(ffi::GetRef<Var>(var)); }
325
326inline ffi::ObjectPtr<BufferTypeNode> CopyBufferType(const BufferVar& var) {
327 return ffi::make_object<BufferTypeNode>(*var.operator->());
328}
329
330inline BufferVar RebuildBufferVar(const BufferVar& var, ffi::ObjectPtr<BufferTypeNode> type,
331 ffi::Optional<ffi::String> name = std::nullopt) {
332 return BufferVar(name.value_or(var.name()), BufferType(std::move(type)), var.span());
333}
334
345TVM_DLL BufferVar decl_buffer(ffi::Array<PrimExpr> shape, PrimType dtype = PrimType::Float(32),
346 ffi::String name = "buffer", ffi::String storage_scope = "",
347 Span span = Span());
348
362 std::string name, int data_alignment,
363 int offset_factor, std::string memory_scope = "");
364
372TVM_DLL TensorLoad BufferLoad(BufferVar buffer, ffi::Array<PrimExpr> indices, Span span = Span());
373} // namespace tirx
374} // namespace tvm
375
376namespace tvm::ffi {
377
378template <>
379inline constexpr bool use_default_type_traits_v<tirx::BufferVar> = false;
380
381template <>
382struct TypeTraits<tirx::BufferVar> : public ObjectRefTypeTraitsBase<tirx::BufferVar> {
384 using Base::CopyFromAnyViewAfterCheck;
385 using Base::CopyToAnyView;
386 using Base::GetMismatchTypeInfo;
387 using Base::MoveFromAnyAfterCheck;
388 using Base::MoveToAny;
389 using Base::TypeSchema;
390 using Base::TypeStr;
391
392 TVM_FFI_INLINE static bool CheckAnyStrict(const TVMFFIAny* src) {
393 if (src->type_index == TypeIndex::kTVMFFINone) {
394 return false;
395 }
396 if (src->type_index != tirx::VarNode::RuntimeTypeIndex()) {
397 return false;
398 }
399 const auto* var = static_cast<const tirx::VarNode*>(
400 details::ObjectUnsafe::ObjectPtrFromUnowned<Object>(src->v_obj).get());
401 return details::AnyUnsafe::CheckAnyStrict<tirx::BufferType>(var->ExprNode::ty);
402 }
403
404 TVM_FFI_INLINE static std::optional<tirx::BufferVar> TryCastFromAnyView(const TVMFFIAny* src) {
405 if (CheckAnyStrict(src)) {
406 return details::ObjectUnsafe::ObjectRefFromObjectPtr<tirx::BufferVar>(
407 details::ObjectUnsafe::ObjectPtrFromUnowned<tirx::VarNode>(src->v_obj));
408 }
409 return std::nullopt;
410 }
411};
412
413} // namespace tvm::ffi
414
415#endif // TVM_TIR_BUFFER_H_
Managed reference to ExprNode.
Definition base_expr.h:335
static IntImm Int32(int64_t value, Span span=Span())
Construct a scalar int32 constant.
Definition expr.h:528
Definition type.h:71
static PointerType VoidPointerTy(ffi::String storage_scope="")
Construct an opaque pointer with void element type.
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:401
Definition base_expr.h:137
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).
static PrimType Int(int bits, int lanes=1)
Construct a signed integer type with fixed lanes.
Definition source_map.h:111
Managed reference to TensorLoadNode.
Definition expr.h:127
Type is the base type of all types.
Definition base_expr.h:52
Managed reference to TypeNode.
Definition base_expr.h:77
A local variable in the IR.
Definition expr.h:355
Managed reference to VarNode.
Definition expr.h:372
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Structural type of a TIRx buffer variable.
Definition buffer.h:71
PrimType ElementType() const
Definition buffer.h:134
ffi::Array< PrimExpr > allocated_addr
The allocated address of the buffer. The address might be multi-dimensional based on its scope....
Definition buffer.h:105
static void RegisterReflection()
Definition buffer.h:110
ffi::Optional< Layout > layout
The layout of the buffer.
Definition buffer.h:99
PrimExpr elem_offset
The offset in terms of number of dtype elements (including lanes)
Definition buffer.h:90
ffi::String storage_scope
Storage scope/address space of the buffer.
Definition buffer.h:76
ffi::Array< PrimExpr > shape
The type of the buffer prior to flattening.
Definition buffer.h:83
ffi::Array< PrimExpr > ElemOffset(ffi::Array< PrimExpr > index, bool inner=false) const
Determine the offset in the buffer of the given index.
DLDataType DefaultIndexType() const
Definition buffer.h:129
PrimType dtype
dtype in the content of the tensor
Definition buffer.h:74
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("tirx.BufferType", BufferTypeNode, TypeNode)
BufferTypeNode()
constructor
Definition buffer.h:108
int offset_factor
Factor of elem_offset field, elem_offset is guaranteed to be multiple of offset_factor.
Definition buffer.h:97
PointerType DataPointerType() const
Definition buffer.h:137
int data_alignment
Alignment requirement of data pointer in bytes.
Definition buffer.h:92
ffi::Array< PrimExpr > strides
The strides of each dimension This can be an empty array, indicating array is contiguous.
Definition buffer.h:88
Managed reference to BufferTypeNode.
Definition buffer.h:156
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(BufferType, Type, BufferTypeNode)
BufferType(ffi::String storage_scope, PrimType dtype, ffi::Array< PrimExpr > shape, ffi::Array< PrimExpr > strides, PrimExpr elem_offset, int data_alignment, int offset_factor, ffi::Optional< Layout > layout=std::nullopt, ffi::Array< PrimExpr > allocated_addr={}, Span span=Span())
BufferType(ffi::ObjectPtr< BufferTypeNode > n)
Definition buffer.h:165
Checked zero-state view over an ordinary VarNode with BufferType.
Definition buffer.h:179
const BufferTypeNode * operator->() const
Definition buffer.h:301
BufferVar with_allocated_addr(ffi::Array< PrimExpr > allocated_addr) const
Return a new buffer with the allocated address.
Expr access_ptr(int access_mask, PointerType ptr_type=PointerType::VoidPointerTy(), int content_lanes=1, PrimExpr offset=IntImm::Int32(0), ffi::Optional< PrimExpr > input_extent=std::nullopt) const
Get access ptr to the entire buffer.
static constexpr bool _type_is_nullable
Definition buffer.h:312
BufferType type() const
Return the buffer type carried by the ordinary variable.
Definition buffer.h:194
const Span & span() const
Return the source span carried by the ordinary Var.
Definition buffer.h:200
bool IsScalar(bool alloc_or_decl=true) const
Return true if the buffer is a scalar.
ffi::String scope() const
Return the storage scope associated with this buffer.
Var var() const
Return the ordinary variable view over the same identity.
Definition buffer.h:191
PointerType DataPointerType() const
Definition buffer.h:294
static constexpr bool _type_container_is_exact
Definition buffer.h:313
BufferVar MakeStrideView() const
Return a new buffer that is equivalent with current one but always add stride field.
BufferVar(ffi::UnsafeInit tag)
Definition buffer.h:298
BufferVar GetFlattenedBuffer() const
Get a flattened version of the buffer.
ffi::Array< PrimExpr > OffsetOf(ffi::Array< PrimExpr > index) const
Determine the offset in the buffer of the given index.
const VarNode * get() const
Definition buffer.h:310
BufferVar(ffi::ObjectPtr< VarNode > n)
Definition buffer.h:297
BufferVar(ffi::String name, BufferType type, Span span=Span())
Construct a fresh buffer variable from an explicit BufferType.
BufferVar(Var var)
Create a checked buffer view over an existing ordinary Var.
Definition buffer.h:185
PrimType ElementType() const
Definition buffer.h:291
const ffi::String & name() const
Return the buffer's diagnostic name.
Definition buffer.h:197
PrimExpr OffsetOf_p(const ffi::Array< PrimExpr > &indices) const
Get the buffer_offset op for the given index.
BufferVar MakeSlice(ffi::Array< PrimExpr > begins, ffi::Array< PrimExpr > extents) const
Make a new symbolic buffer representing a slice of the buffer.
PrimExpr vload(ffi::Array< PrimExpr > begin, PrimType dtype) const
Create an Expr that does a vector load at begin index.
Expr data() const
Project the physical pointer established by the definition site.
BufferVar with_dtype(PrimType dtype) const
Return a new buffer with the dtype.
TVM_FFI_DEFINE_DEFAULT_COPY_MOVE_AND_ASSIGN(BufferVar)
Stmt vstore(ffi::Array< PrimExpr > begin, PrimExpr value) const
Create a Stmt that does a vector store at begin index.
Container of all statements.
Definition stmt.h:67
Base expr nodes in TVM.
Definition of layout.
Definition iter_affine_map.h:231
BufferVar decl_buffer(ffi::Array< PrimExpr > shape, PrimType dtype=PrimType::Float(32), ffi::String name="buffer", ffi::String storage_scope="", Span span=Span())
Construct a new buffer given shape, and dtype.
PrimType DefaultIndexPrimType()
if TVM_INDEX_DEFAULT_I64 is set, return int64, otherwise return int32
Definition buffer.h:43
DLDataType DefaultIndexType()
Definition buffer.h:52
bool operator==(const BufferVar &lhs, const BufferVar &rhs)
Definition buffer.h:319
BufferVar GetBufferVar(const VarNode *var)
Recover a checked buffer view from an ordinary VarNode pointer.
Definition buffer.h:324
TensorLoad BufferLoad(BufferVar buffer, ffi::Array< PrimExpr > indices, Span span=Span())
Construct a TensorLoad from a BufferVar.
bool operator!=(const BufferVar &lhs, const BufferVar &rhs)
Definition buffer.h:321
tvm::VarNode VarNode
Definition var.h:37
ffi::ObjectPtr< BufferTypeNode > CopyBufferType(const BufferVar &var)
Definition buffer.h:326
BufferVar RebuildBufferVar(const BufferVar &var, ffi::ObjectPtr< BufferTypeNode > type, ffi::Optional< ffi::String > name=std::nullopt)
Definition buffer.h:330
tirx::BufferVar BufferWithOffsetAlignment(ffi::Array< PrimExpr > shape, PrimType dtype, std::string name, int data_alignment, int offset_factor, std::string memory_scope="")
Creates a TIR buffer for the provided parameters.
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
static TVM_FFI_INLINE std::optional< tirx::BufferVar > TryCastFromAnyView(const TVMFFIAny *src)
Definition buffer.h:404
ObjectRefTypeTraitsBase< tirx::BufferVar > Base
Definition buffer.h:383
static TVM_FFI_INLINE bool CheckAnyStrict(const TVMFFIAny *src)
Definition buffer.h:392
Variables in the TIR.