tvm
Loading...
Searching...
No Matches
layout.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 */
23#ifndef TVM_TIRX_LAYOUT_H_
24#define TVM_TIRX_LAYOUT_H_
25
26#include <tvm/ffi/container/array.h>
27#include <tvm/ffi/container/tuple.h>
28#include <tvm/ffi/enum.h>
29#include <tvm/ffi/function.h>
30#include <tvm/ffi/object.h>
31#include <tvm/ir/expr.h>
32#include <tvm/ir/module.h>
33#include <tvm/target/target.h>
35
36namespace tvm {
37
38namespace tirx {
39
40class Layout;
41class TileLayout;
42class Iter;
43using ffi::Array;
44using ffi::Tuple;
45
46// Base class for layout
47class LayoutNode : public ffi::Object {
48 public:
50 virtual bool CompatibleWithShape(const ffi::Array<PrimExpr>& shape) const = 0;
51
53 virtual bool VerifyWellFormed() const = 0;
54
56 virtual PrimExpr GetSize(ffi::Optional<ffi::String> axis_name = std::nullopt) const = 0;
57
59 virtual PrimExpr GetSpan(ffi::Optional<ffi::String> axis_name = std::nullopt) const = 0;
60
62 virtual ffi::Map<ffi::String, PrimExpr> Apply(ffi::Array<PrimExpr> coord) const = 0;
63 virtual ffi::Map<ffi::String, PrimExpr> Apply(PrimExpr coord) const = 0;
64 virtual ffi::Map<ffi::String, PrimExpr> Apply(const ffi::Array<PrimExpr>& coord,
65 const ffi::Array<PrimExpr>& shape) const;
66
68 virtual Layout Canonicalize() const = 0;
69
71 virtual Layout Tile(const TileLayout& outer, const ffi::Array<PrimExpr>& outer_shape,
72 const ffi::Array<PrimExpr>& inner_shape) const = 0;
73
75 virtual ffi::Optional<Layout> Slice(const ffi::Array<PrimExpr>& shape,
76 const ffi::Array<Range>& region) const = 0;
77
82 virtual Layout DirectSum(const TileLayout& left, const ffi::Array<PrimExpr>& left_shape,
83 const ffi::Array<PrimExpr>& right_shape) const = 0;
84
92 virtual ffi::Optional<TileLayout> IsTileInner(const Layout& tile_layout,
93 const ffi::Array<PrimExpr>& tiled_shape,
94 const ffi::Array<PrimExpr>& inner_shape) const = 0;
95
103 virtual ffi::Optional<Layout> IsTileOuter(const Layout& tile_layout,
104 const ffi::Array<PrimExpr>& tiled_shape,
105 const ffi::Array<PrimExpr>& outer_shape) const = 0;
106
113 virtual ffi::Optional<TileLayout> IsDirectSumRight(
114 const Layout& sum_layout, const ffi::Array<PrimExpr>& interleaved_shape,
115 const ffi::Array<PrimExpr>& right_shape) const = 0;
116
123 virtual ffi::Optional<Layout> IsDirectSumLeft(const Layout& sum_layout,
124 const ffi::Array<PrimExpr>& interleaved_shape,
125 const ffi::Array<PrimExpr>& left_shape) const = 0;
126
127 static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindTreeNode;
128 TVM_FFI_DECLARE_OBJECT_INFO("tirx.Layout", LayoutNode, ffi::Object);
129};
130
131class Layout : public ffi::ObjectRef {
132 public:
134};
135
136// target, subscope, scope, iter -> fused_iter
137using FAxisFuser = ffi::TypedFunction<ffi::Optional<Iter>(Target, ffi::String, ffi::String, Iter)>;
138// target, scope, iter -> (outer_iter, inner_iter)
139// Note(@bohao): use ffi::Array<Iter, void> to avoid incomplete type error (SFINAE)
140using FAxisSplitter = ffi::TypedFunction<ffi::Array<Iter, void>(Target, ffi::String, Iter)>;
141
142// Axis
143class AxisNode : public ffi::EnumObj {
144 public:
146 bool IsThreadAxis() const;
147
149 bool IsMemoryAxis() const;
150
152 ffi::Optional<ffi::String> GetBackend() const;
153
155 ffi::Optional<ExecScope> GetScope() const;
156
158 ffi::Optional<ExecScope> GetSubscope() const;
159
161 ffi::Optional<FAxisFuser> GetFuser() const;
162
164 ffi::Optional<FAxisSplitter> GetSplitter() const;
165
166 TVM_FFI_DECLARE_OBJECT_INFO_FINAL("tirx.Axis", AxisNode, ffi::EnumObj);
167};
168
169class Axis : public ffi::Enum {
170 public:
172 const ffi::String& name() const { return get()->_str_index; }
173
179 TVM_TIRX_DLL static Axis Get(const ffi::String& name);
180
182};
183
184class IterNode : public ffi::Object {
185 public:
186 explicit IterNode(ffi::UnsafeInit tag) : extent(tag), stride(tag), axis(tag) {}
187
189 : extent(std::move(extent)), stride(std::move(stride)), axis(std::move(axis)) {}
190
194
195 static void RegisterReflection() {
196 namespace refl = tvm::ffi::reflection;
197 refl::ObjectDef<IterNode>()
198 .def_ro("extent", &IterNode::extent)
199 .def_ro("stride", &IterNode::stride)
200 .def_ro("axis", &IterNode::axis);
201 }
202
203 static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindTreeNode;
204 TVM_FFI_DECLARE_OBJECT_INFO_FINAL("tirx.Iter", IterNode, ffi::Object);
205};
206
207class Iter : public ffi::ObjectRef {
208 public:
209 TVM_TIRX_DLL explicit Iter(PrimExpr extent, PrimExpr stride, Axis axis);
211};
212
214 public:
215 ffi::Array<Iter> shard;
216 ffi::Array<Iter> replica;
217 ffi::Map<Axis, PrimExpr> offset;
218
219 static void RegisterReflection() {
220 namespace refl = tvm::ffi::reflection;
221 refl::ObjectDef<TileLayoutNode>()
222 .def_ro("shard", &TileLayoutNode::shard)
223 .def_ro("replica", &TileLayoutNode::replica)
224 .def_ro("offset", &TileLayoutNode::offset);
225 }
226
228 bool CompatibleWithShape(const ffi::Array<PrimExpr>& shape) const final;
229
231 bool VerifyWellFormed() const final;
232
234 PrimExpr GetSize(ffi::Optional<ffi::String> axis_name = std::nullopt) const final;
235
237 PrimExpr GetSpan(ffi::Optional<ffi::String> axis_name = std::nullopt) const final;
238
240 ffi::Map<ffi::String, PrimExpr> Apply(ffi::Array<PrimExpr> coord) const final;
241 ffi::Map<ffi::String, PrimExpr> Apply(PrimExpr coord) const final;
246 ffi::Map<ffi::String, PrimExpr> Apply(const ffi::Array<PrimExpr>& coord,
247 const ffi::Array<PrimExpr>& shape) const final;
248
250 Layout Canonicalize() const final;
251
253 Layout Tile(const TileLayout& outer, const ffi::Array<PrimExpr>& outer_shape,
254 const ffi::Array<PrimExpr>& inner_shape) const final;
255
256 Layout DirectSum(const TileLayout& left, const ffi::Array<PrimExpr>& left_shape,
257 const ffi::Array<PrimExpr>& right_shape) const final;
258
260 ffi::Optional<TileLayout> IsTileInner(const Layout& tile_layout,
261 const ffi::Array<PrimExpr>& tiled_shape,
262 const ffi::Array<PrimExpr>& inner_shape) const final;
263
265 ffi::Optional<Layout> IsTileOuter(const Layout& tile_layout,
266 const ffi::Array<PrimExpr>& tiled_shape,
267 const ffi::Array<PrimExpr>& outer_shape) const final;
268
269 ffi::Optional<TileLayout> IsDirectSumRight(const Layout& sum_layout,
270 const ffi::Array<PrimExpr>& interleaved_shape,
271 const ffi::Array<PrimExpr>& right_shape) const final;
272
273 ffi::Optional<Layout> IsDirectSumLeft(const Layout& sum_layout,
274 const ffi::Array<PrimExpr>& interleaved_shape,
275 const ffi::Array<PrimExpr>& left_shape) const final;
276
278 ffi::Array<PrimExpr> GetShardShape() const;
279
281 ffi::Optional<Layout> Slice(const ffi::Array<PrimExpr>& shape,
282 const ffi::Array<Range>& region) const final;
283
285 bool IsTrivial() const;
286
288 bool HasMemoryAxis() const;
289
291 bool HasThreadAxis() const;
292
294 ffi::Optional<Tuple<ExecScope, ExecScope>> GetScope() const;
295
297 static TileLayout DefaultLayout(ffi::Array<PrimExpr> shape);
298
300};
301
302class TileLayout : public Layout {
303 public:
304 TVM_TIRX_DLL explicit TileLayout(ffi::Array<Iter> shard, ffi::Array<Iter> replica,
305 ffi::Map<Axis, PrimExpr> offset);
306
309};
310
311// ComposeLayout
313 public:
314 explicit ComposeLayoutNode(TileLayout tile_layout) : tile_layout(std::move(tile_layout)) {}
315 explicit ComposeLayoutNode(ffi::UnsafeInit) : tile_layout(ffi::UnsafeInit{}) {}
316
322 // Cached swizzle masks: inner_mask = (1 << swizzle_len) - 1;
323 // outer_mask = inner_mask << atom_len. Set by the ComposeLayout ctor.
326
327 static void RegisterReflection() {
328 namespace refl = tvm::ffi::reflection;
329 refl::ObjectDef<ComposeLayoutNode>()
330 .def_ro("per_element", &ComposeLayoutNode::per_element)
331 .def_ro("swizzle_len", &ComposeLayoutNode::swizzle_len)
332 .def_ro("atom_len", &ComposeLayoutNode::atom_len)
333 .def_ro("swizzle_inner", &ComposeLayoutNode::swizzle_inner)
334 .def_ro("inner_mask", &ComposeLayoutNode::inner_mask)
335 .def_ro("outer_mask", &ComposeLayoutNode::outer_mask)
336 .def_ro("tile_layout", &ComposeLayoutNode::tile_layout);
337 }
338
340 bool CompatibleWithShape(const ffi::Array<PrimExpr>& shape) const final;
341
343 bool VerifyWellFormed() const final;
344
346 PrimExpr GetSize(ffi::Optional<ffi::String> axis_name = std::nullopt) const final;
347
349 PrimExpr GetSpan(ffi::Optional<ffi::String> axis_name = std::nullopt) const final;
350
352 ffi::Map<ffi::String, PrimExpr> Apply(ffi::Array<PrimExpr> coord) const final;
353 ffi::Map<ffi::String, PrimExpr> Apply(PrimExpr coord) const final;
354 ffi::Map<ffi::String, PrimExpr> Apply(const ffi::Array<PrimExpr>& coord,
355 const ffi::Array<PrimExpr>& shape) const final;
356
358 Layout Canonicalize() const final;
359
361 Layout Tile(const TileLayout& outer, const ffi::Array<PrimExpr>& outer_shape,
362 const ffi::Array<PrimExpr>& inner_shape) const final;
363
364 Layout DirectSum(const TileLayout& left, const ffi::Array<PrimExpr>& left_shape,
365 const ffi::Array<PrimExpr>& right_shape) const final;
366
368 ffi::Optional<TileLayout> IsTileInner(const Layout& tile_layout,
369 const ffi::Array<PrimExpr>& tiled_shape,
370 const ffi::Array<PrimExpr>& inner_shape) const final;
371
373 ffi::Optional<Layout> IsTileOuter(const Layout& tile_layout,
374 const ffi::Array<PrimExpr>& tiled_shape,
375 const ffi::Array<PrimExpr>& outer_shape) const final;
376
377 ffi::Optional<TileLayout> IsDirectSumRight(const Layout& sum_layout,
378 const ffi::Array<PrimExpr>& interleaved_shape,
379 const ffi::Array<PrimExpr>& right_shape) const final;
380
381 ffi::Optional<Layout> IsDirectSumLeft(const Layout& sum_layout,
382 const ffi::Array<PrimExpr>& interleaved_shape,
383 const ffi::Array<PrimExpr>& left_shape) const final;
384
386 ffi::Optional<Layout> Slice(const ffi::Array<PrimExpr>& shape,
387 const ffi::Array<Range>& region) const final;
388
389 TVM_FFI_DECLARE_OBJECT_INFO_FINAL("tirx.ComposeLayout", ComposeLayoutNode, LayoutNode);
390};
391
392class ComposeLayout : public Layout {
393 public:
394 TVM_TIRX_DLL explicit ComposeLayout(int per_element, int swizzle_len, int atom_len,
395 TileLayout tile_layout, bool swizzle_inner = true);
396
399};
400
401constexpr int kPSUMMaxElemPerBank = 512;
402constexpr int kPSUMBankNum = 8;
403
404} // namespace tirx
405} // namespace tvm
406
407#endif // TVM_TIRX_LAYOUT_H_
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:447
Range container
Definition expr.h:1025
Managed reference class to TargetObj.
Definition target.h:136
Definition layout.h:143
bool IsThreadAxis() const
Check if the axis is a thread axis.
ffi::Optional< FAxisSplitter > GetSplitter() const
Get the splitter of the (thread) axis.
ffi::Optional< ExecScope > GetScope() const
Get the scope of the (thread) axis.
ffi::Optional< ffi::String > GetBackend() const
The backend owning this axis, if any.
bool IsMemoryAxis() const
Check if the axis is a memory axis.
ffi::Optional< ExecScope > GetSubscope() const
Get the subscope of the (thread) axis.
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("tirx.Axis", AxisNode, ffi::EnumObj)
ffi::Optional< FAxisFuser > GetFuser() const
Get the fuser of the (thread) axis.
Definition layout.h:169
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Axis, ffi::Enum, AxisNode)
static TVM_TIRX_DLL Axis Get(const ffi::String &name)
Get or create the axis with the given name.
const ffi::String & name() const
Return the canonical axis name.
Definition layout.h:172
Definition layout.h:312
int atom_len
Definition layout.h:319
int swizzle_len
Definition layout.h:318
int inner_mask
Definition layout.h:324
TileLayout tile_layout
Definition layout.h:321
bool CompatibleWithShape(const ffi::Array< PrimExpr > &shape) const final
Check if the layout is compatible with the shape.
ComposeLayoutNode(ffi::UnsafeInit)
Definition layout.h:315
bool swizzle_inner
Definition layout.h:320
int outer_mask
Definition layout.h:325
ComposeLayoutNode(TileLayout tile_layout)
Definition layout.h:314
static void RegisterReflection()
Definition layout.h:327
bool VerifyWellFormed() const final
Verify if the layout is well-formed.
int per_element
Definition layout.h:317
Definition layout.h:392
TVM_DEFINE_OBJECT_REF_COW_METHOD(ComposeLayoutNode)
TVM_TIRX_DLL ComposeLayout(int per_element, int swizzle_len, int atom_len, TileLayout tile_layout, bool swizzle_inner=true)
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(ComposeLayout, Layout, ComposeLayoutNode)
Definition exec_scope.h:47
Definition layout.h:184
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition layout.h:203
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("tirx.Iter", IterNode, ffi::Object)
IterNode(PrimExpr extent, PrimExpr stride, Axis axis)
Definition layout.h:188
Axis axis
Definition layout.h:193
PrimExpr extent
Definition layout.h:191
PrimExpr stride
Definition layout.h:192
IterNode(ffi::UnsafeInit tag)
Definition layout.h:186
static void RegisterReflection()
Definition layout.h:195
Definition layout.h:207
TVM_TIRX_DLL Iter(PrimExpr extent, PrimExpr stride, Axis axis)
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Iter, ffi::ObjectRef, IterNode)
Definition layout.h:47
virtual PrimExpr GetSpan(ffi::Optional< ffi::String > axis_name=std::nullopt) const =0
Get the span of the layout (of some axis)
TVM_FFI_DECLARE_OBJECT_INFO("tirx.Layout", LayoutNode, ffi::Object)
virtual bool VerifyWellFormed() const =0
Verify if the layout is well-formed.
virtual ffi::Optional< Layout > IsTileOuter(const Layout &tile_layout, const ffi::Array< PrimExpr > &tiled_shape, const ffi::Array< PrimExpr > &outer_shape) const =0
Check if the layout is the outer layout of a tiled layout.
virtual ffi::Optional< Layout > IsDirectSumLeft(const Layout &sum_layout, const ffi::Array< PrimExpr > &interleaved_shape, const ffi::Array< PrimExpr > &left_shape) const =0
Check if this layout is the left addend A in a direct-sum A + B over the interleaved domain S_A \otim...
virtual PrimExpr GetSize(ffi::Optional< ffi::String > axis_name=std::nullopt) const =0
Get the size of the layout (of some axis)
virtual Layout Canonicalize() const =0
Turn the layout to canonical form.
virtual Layout DirectSum(const TileLayout &left, const ffi::Array< PrimExpr > &left_shape, const ffi::Array< PrimExpr > &right_shape) const =0
Direct-sum on the tiling domain (unscaled composition) Given left layout A (grouped by left_shape) an...
virtual ffi::Map< ffi::String, PrimExpr > Apply(PrimExpr coord) const =0
virtual bool CompatibleWithShape(const ffi::Array< PrimExpr > &shape) const =0
Compatible with shape.
virtual ffi::Optional< Layout > Slice(const ffi::Array< PrimExpr > &shape, const ffi::Array< Range > &region) const =0
Slice the layout with a given shape and region.
virtual ffi::Map< ffi::String, PrimExpr > Apply(ffi::Array< PrimExpr > coord) const =0
Apply layout on the input coordinate and get the mapped output.
virtual Layout Tile(const TileLayout &outer, const ffi::Array< PrimExpr > &outer_shape, const ffi::Array< PrimExpr > &inner_shape) const =0
Tile the current layout with a given layout.
virtual ffi::Map< ffi::String, PrimExpr > Apply(const ffi::Array< PrimExpr > &coord, const ffi::Array< PrimExpr > &shape) const
virtual ffi::Optional< TileLayout > IsTileInner(const Layout &tile_layout, const ffi::Array< PrimExpr > &tiled_shape, const ffi::Array< PrimExpr > &inner_shape) const =0
Check if the layout is the inner layout of a tiled layout.
static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind
Definition layout.h:127
virtual ffi::Optional< TileLayout > IsDirectSumRight(const Layout &sum_layout, const ffi::Array< PrimExpr > &interleaved_shape, const ffi::Array< PrimExpr > &right_shape) const =0
Check if this layout is the right addend B in a direct-sum A + B over the interleaved domain S_A \oti...
Definition layout.h:131
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Layout, ffi::ObjectRef, LayoutNode)
Definition layout.h:213
ffi::Map< Axis, PrimExpr > offset
Definition layout.h:217
PrimExpr GetSpan(ffi::Optional< ffi::String > axis_name=std::nullopt) const final
Get the span of the layout (of some axis)
PrimExpr GetSize(ffi::Optional< ffi::String > axis_name=std::nullopt) const final
Get the size of the layout (of some axis)
ffi::Optional< Layout > Slice(const ffi::Array< PrimExpr > &shape, const ffi::Array< Range > &region) const final
Slice the layout with a given shape and region.
ffi::Optional< Layout > IsTileOuter(const Layout &tile_layout, const ffi::Array< PrimExpr > &tiled_shape, const ffi::Array< PrimExpr > &outer_shape) const final
Check if the layout is the outer layout of a tiled layout.
ffi::Array< Iter > replica
Definition layout.h:216
bool IsTrivial() const
Is the layout trivial (pure memory, identical mapping)
ffi::Map< ffi::String, PrimExpr > Apply(ffi::Array< PrimExpr > coord) const final
Apply the input coordinate and get the mapped output.
ffi::Array< Iter > shard
Definition layout.h:215
ffi::Array< PrimExpr > GetShardShape() const
Get the shape of the shard.
ffi::Optional< Layout > IsDirectSumLeft(const Layout &sum_layout, const ffi::Array< PrimExpr > &interleaved_shape, const ffi::Array< PrimExpr > &left_shape) const final
Check if this layout is the left addend A in a direct-sum A + B over the interleaved domain S_A \otim...
static void RegisterReflection()
Definition layout.h:219
bool VerifyWellFormed() const final
Verify if the layout is well-formed.
ffi::Optional< TileLayout > IsDirectSumRight(const Layout &sum_layout, const ffi::Array< PrimExpr > &interleaved_shape, const ffi::Array< PrimExpr > &right_shape) const final
Check if this layout is the right addend B in a direct-sum A + B over the interleaved domain S_A \oti...
ffi::Optional< TileLayout > IsTileInner(const Layout &tile_layout, const ffi::Array< PrimExpr > &tiled_shape, const ffi::Array< PrimExpr > &inner_shape) const final
Check if the layout is the inner layout of a tiled layout.
bool HasMemoryAxis() const
Has Memory Axis.
Layout Canonicalize() const final
Turn the layout to canonical form.
Layout DirectSum(const TileLayout &left, const ffi::Array< PrimExpr > &left_shape, const ffi::Array< PrimExpr > &right_shape) const final
Direct-sum on the tiling domain (unscaled composition) Given left layout A (grouped by left_shape) an...
bool HasThreadAxis() const
Has Thread Axis.
static TileLayout DefaultLayout(ffi::Array< PrimExpr > shape)
Get the default layout for the shape.
bool CompatibleWithShape(const ffi::Array< PrimExpr > &shape) const final
Check if the layout is compatible with the shape.
ffi::Optional< Tuple< ExecScope, ExecScope > > GetScope() const
Get the scope pair of the layout.
Layout Tile(const TileLayout &outer, const ffi::Array< PrimExpr > &outer_shape, const ffi::Array< PrimExpr > &inner_shape) const final
Tile the layout with an outer layout.
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("tirx.TileLayout", TileLayoutNode, LayoutNode)
Definition layout.h:302
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(TileLayout, Layout, TileLayoutNode)
TVM_DEFINE_OBJECT_REF_COW_METHOD(TileLayoutNode)
TVM_TIRX_DLL TileLayout(ffi::Array< Iter > shard, ffi::Array< Iter > replica, ffi::Map< Axis, PrimExpr > offset)
Base expr nodes in TVM.
IRModule that holds the functions and type definitions.
ffi::TypedFunction< ffi::Array< Iter, void >(Target, ffi::String, Iter)> FAxisSplitter
Definition layout.h:140
constexpr int kPSUMMaxElemPerBank
Definition layout.h:401
constexpr int kPSUMBankNum
Definition layout.h:402
ffi::TypedFunction< ffi::Optional< Iter >(Target, ffi::String, ffi::String, Iter)> FAxisFuser
Definition layout.h:137
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition attr.h:23
#define TVM_TIRX_DLL
Definition base.h:83
Compilation target object.