CINXE.COM
Builtin Dialect - MLIR
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Builtin Dialect - MLIR</title><meta name=description content="Multi-Level IR Compiler Framework"><meta name=generator content="Hugo 0.119.0"><link href=https://mlir.llvm.org/index.xml rel=alternate type=application/rss+xml><link rel=canonical href=https://mlir.llvm.org/docs/Dialects/Builtin/><link rel=stylesheet href=https://mlir.llvm.org/css/theme.css><script src=https://use.fontawesome.com/releases/v5.0.6/js/all.js></script> <link rel=stylesheet href=https://mlir.llvm.org/css/chroma.min.css><script src=https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js></script> <script src=https://cdn.jsdelivr.net/npm/jquery.easing@1.4.1/jquery.easing.min.js></script> <script src=https://mlir.llvm.org/js/bundle.js></script> <script type=text/javascript src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> <script type=text/x-mathjax-config> MathJax.Hub.Config({ tex2jax: { inlineMath: [['$', '$'] ], displayMath: [ ['$$','$$'], ["\\[","\\]"] ] } }); </script><link rel=apple-touch-icon sizes=180x180 href="/apple-touch-icon.png?v=1"><link rel=icon type=image/png sizes=32x32 href="/favicon-32x32.png?v=1"><link rel=icon type=image/png sizes=16x16 href="/favicon-16x16.png?v=1"><link rel=manifest href="/site.webmanifest?v=1"><link rel=mask-icon href="/safari-pinned-tab.svg?v=1" color=#3775e0><link rel="shortcut icon" href="/favicon.ico?v=1"><meta name=msapplication-TileColor content="#2d89ef"><meta name=theme-color content="#ffffff"><link rel=icon href=/favicon.svg type=image/svg+xml sizes=any><style>:root{}</style></head><body><div class=container><header><h1><div><img src=https://mlir.llvm.org//mlir-logo.png width=40px align=absmiddle> MLIR</div></h1><p class=description>Multi-Level IR Compiler Framework</p></header><div class=global-menu><nav><ul><li class=parent><a href>Community<i class="fas fa-angle-right"></i></a><ul class=sub-menu><li class=child><a href=https://llvm.discourse.group/c/mlir/31>Forums</a></li><li class=child><a href=https://discord.gg/xS7Z362>Chat</a></li></ul></li><li><a href=/getting_started/Debugging/>Debugging Tips</a></li><li><a href=/getting_started/Faq/>FAQ</a></li><li class=parent><a href=https://github.com/llvm/llvm-project/tree/main/mlir>Source<i class="fas fa-angle-right"></i></a><ul class=sub-menu><li class=child><a href=/doxygen/>Doxygen</a></li><li class=child><a href=https://github.com/llvm/llvm-project/tree/main/mlir>GitHub</a></li></ul></li><li><a href="https://bugs.llvm.org/buglist.cgi?bug_status=__open__&list_id=177877&order=changeddate%20DESC%2Cpriority%2Cbug_severity&product=MLIR&query_format=specific">Bugs</a></li><li><a href=https://github.com/llvm/mlir-www/tree/main/website/static/LogoAssets>Logo Assets</a></li><li><a href=https://www.youtube.com/MLIRCompiler>Youtube Channel</a></li></ul></nav></div><div class=content-container><main><h1>Builtin Dialect</h1><p>The builtin dialect contains a core set of Attributes, Operations, and Types that have wide applicability across a very large number of domains and abstractions. Many of the components of this dialect are also instrumental in the implementation of the core IR. As such, this dialect is implicitly loaded in every <code>MLIRContext</code>, and available directly to all users of MLIR.</p><p>Given the far-reaching nature of this dialect and the fact that MLIR is extensible by design, any potential additions are heavily scrutinized.</p><p><nav id=TableOfContents><ul><li><a href=#attributes>Attributes</a><ul><li><a href=#affinemapattr>AffineMapAttr</a></li><li><a href=#arrayattr>ArrayAttr</a></li><li><a href=#densearrayattr>DenseArrayAttr</a></li><li><a href=#denseintorfpelementsattr>DenseIntOrFPElementsAttr</a></li><li><a href=#denseresourceelementsattr>DenseResourceElementsAttr</a></li><li><a href=#densestringelementsattr>DenseStringElementsAttr</a></li><li><a href=#dictionaryattr>DictionaryAttr</a></li><li><a href=#floatattr>FloatAttr</a></li><li><a href=#integerattr>IntegerAttr</a></li><li><a href=#integersetattr>IntegerSetAttr</a></li><li><a href=#opaqueattr>OpaqueAttr</a></li><li><a href=#sparseelementsattr>SparseElementsAttr</a></li><li><a href=#stringattr>StringAttr</a></li><li><a href=#symbolrefattr>SymbolRefAttr</a></li><li><a href=#typeattr>TypeAttr</a></li><li><a href=#unitattr>UnitAttr</a></li><li><a href=#stridedlayoutattr>StridedLayoutAttr</a></li></ul></li><li><a href=#location-attributes>Location Attributes</a><ul><li><a href=#callsiteloc>CallSiteLoc</a></li><li><a href=#filelinecolrange>FileLineColRange</a></li><li><a href=#fusedloc>FusedLoc</a></li><li><a href=#nameloc>NameLoc</a></li><li><a href=#opaqueloc>OpaqueLoc</a></li><li><a href=#unknownloc>UnknownLoc</a></li></ul></li><li><a href=#distinctattribute>DistinctAttribute</a></li><li><a href=#operations>Operations</a><ul><li><a href=#builtinmodule-moduleop><code>builtin.module</code> (ModuleOp)</a></li><li><a href=#builtinunrealized_conversion_cast-unrealizedconversioncastop><code>builtin.unrealized_conversion_cast</code> (UnrealizedConversionCastOp)</a></li></ul></li><li><a href=#types>Types</a><ul><li><a href=#bfloat16type>BFloat16Type</a></li><li><a href=#complextype>ComplexType</a></li><li><a href=#float4e2m1fntype>Float4E2M1FNType</a></li><li><a href=#float6e2m3fntype>Float6E2M3FNType</a></li><li><a href=#float6e3m2fntype>Float6E3M2FNType</a></li><li><a href=#float8e3m4type>Float8E3M4Type</a></li><li><a href=#float8e4m3type>Float8E4M3Type</a></li><li><a href=#float8e4m3b11fnuztype>Float8E4M3B11FNUZType</a></li><li><a href=#float8e4m3fntype>Float8E4M3FNType</a></li><li><a href=#float8e4m3fnuztype>Float8E4M3FNUZType</a></li><li><a href=#float8e5m2type>Float8E5M2Type</a></li><li><a href=#float8e5m2fnuztype>Float8E5M2FNUZType</a></li><li><a href=#float8e8m0fnutype>Float8E8M0FNUType</a></li><li><a href=#float16type>Float16Type</a></li><li><a href=#float32type>Float32Type</a></li><li><a href=#float64type>Float64Type</a></li><li><a href=#float80type>Float80Type</a></li><li><a href=#float128type>Float128Type</a></li><li><a href=#floattf32type>FloatTF32Type</a></li><li><a href=#functiontype>FunctionType</a></li><li><a href=#indextype>IndexType</a></li><li><a href=#integertype>IntegerType</a></li><li><a href=#memreftype>MemRefType</a></li><li><a href=#nonetype>NoneType</a></li><li><a href=#opaquetype>OpaqueType</a></li><li><a href=#rankedtensortype>RankedTensorType</a></li><li><a href=#tupletype>TupleType</a></li><li><a href=#unrankedmemreftype>UnrankedMemRefType</a></li><li><a href=#unrankedtensortype>UnrankedTensorType</a></li><li><a href=#vectortype>VectorType</a></li></ul></li><li><a href=#type-interfaces>Type Interfaces</a></li></ul></nav><h2 id=attributes>Attributes <a class=headline-hash href=#attributes>¶</a></h2><h3 id=affinemapattr>AffineMapAttr <a class=headline-hash href=#affinemapattr>¶</a></h3><p>An Attribute containing an AffineMap object</p><p>Syntax:</p><pre tabindex=0><code>affine-map-attribute ::= `affine_map` `<` affine-map `>` </code></pre><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>affine_map<span class=p><(</span>d0<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>d0<span class=p>)></span> </span></span><span class=line><span class=cl>affine_map<span class=p><(</span>d0<span class=p>,</span> d1<span class=p>,</span> d2<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>d0<span class=p>,</span> d1<span class=p>)></span> </span></span></code></pre></div><h4 id=parameters>Parameters: <a class=headline-hash href=#parameters>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>value</td><td style=text-align:center><code>AffineMap</code></td><td></td></tr></tbody></table><h3 id=arrayattr>ArrayAttr <a class=headline-hash href=#arrayattr>¶</a></h3><p>A collection of other Attribute values</p><p>Syntax:</p><pre tabindex=0><code>array-attribute ::= `[` (attribute-value (`,` attribute-value)*)? `]` </code></pre><p>An array attribute is an attribute that represents a collection of attribute values.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=p>[]</span> </span></span><span class=line><span class=cl><span class=p>[</span><span class=m>10</span><span class=p>,</span> <span class=k>i32</span><span class=p>]</span> </span></span><span class=line><span class=cl><span class=p>[</span>affine_map<span class=p><(</span>d0<span class=p>,</span> d1<span class=p>,</span> d2<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>d0<span class=p>,</span> d1<span class=p>)>,</span> <span class=k>i32</span><span class=p>,</span> <span class=s>"string attribute"</span><span class=p>]</span> </span></span></code></pre></div><h4 id=parameters-1>Parameters: <a class=headline-hash href=#parameters-1>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>value</td><td style=text-align:center><code>::llvm::ArrayRef<Attribute></code></td><td></td></tr></tbody></table><h3 id=densearrayattr>DenseArrayAttr <a class=headline-hash href=#densearrayattr>¶</a></h3><p>A dense array of integer or floating point elements.</p><p>A dense array attribute is an attribute that represents a dense array of primitive element types. Contrary to DenseIntOrFPElementsAttr this is a flat unidimensional array which does not have a storage optimization for splat. This allows to expose the raw array through a C++ API as <code>ArrayRef<T></code> for compatible types. The element type must be bool or an integer or float whose bitwidth is a multiple of 8. Bool elements are stored as bytes.</p><p>This is the base class attribute. Access to C++ types is intended to be managed through the subclasses <code>DenseI8ArrayAttr</code>, <code>DenseI16ArrayAttr</code>, <code>DenseI32ArrayAttr</code>, <code>DenseI64ArrayAttr</code>, <code>DenseF32ArrayAttr</code>, and <code>DenseF64ArrayAttr</code>.</p><p>Syntax:</p><pre tabindex=0><code>dense-array-attribute ::= `array` `<` (integer-type | float-type) (`:` tensor-literal)? `>` </code></pre><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>array<span class=p><</span><span class=k>i8</span><span class=p>></span> </span></span><span class=line><span class=cl>array<span class=p><</span><span class=k>i32</span><span class=p>:</span> <span class=m>10</span><span class=p>,</span> <span class=m>42</span><span class=p>></span> </span></span><span class=line><span class=cl>array<span class=p><</span><span class=k>f64</span><span class=p>:</span> <span class=m>42</span><span class=p>.,</span> <span class=m>12</span><span class=p>.></span> </span></span></code></pre></div><p>When a specific subclass is used as argument of an operation, the declarative assembly will omit the type and print directly:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=p>[</span><span class=m>1</span><span class=p>,</span> <span class=m>2</span><span class=p>,</span> <span class=m>3</span><span class=p>]</span> </span></span></code></pre></div><h4 id=parameters-2>Parameters: <a class=headline-hash href=#parameters-2>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>elementType</td><td style=text-align:center><code>Type</code></td><td></td></tr><tr><td style=text-align:center>size</td><td style=text-align:center><code>int64_t</code></td><td></td></tr><tr><td style=text-align:center>rawData</td><td style=text-align:center><code>::llvm::ArrayRef<char></code></td><td>64-bit aligned storage for dense array elements</td></tr></tbody></table><h3 id=denseintorfpelementsattr>DenseIntOrFPElementsAttr <a class=headline-hash href=#denseintorfpelementsattr>¶</a></h3><p>An Attribute containing a dense multi-dimensional array of integer or floating-point values</p><p>Syntax:</p><pre tabindex=0><code>tensor-literal ::= integer-literal | float-literal | bool-literal | [] | [tensor-literal (, tensor-literal)* ] dense-intorfloat-elements-attribute ::= `dense` `<` tensor-literal `>` `:` ( tensor-type | vector-type ) </code></pre><p>A dense int-or-float elements attribute is an elements attribute containing a densely packed vector or tensor of integer or floating-point values. The element type of this attribute is required to be either an <code>IntegerType</code> or a <code>FloatType</code>.</p><p>Examples:</p><pre tabindex=0><code>// A splat tensor of integer values. dense<10> : tensor<2xi32> // A tensor of 2 float32 elements. dense<[10.0, 11.0]> : tensor<2xf32> </code></pre><h4 id=parameters-3>Parameters: <a class=headline-hash href=#parameters-3>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>type</td><td style=text-align:center><code>ShapedType</code></td><td></td></tr><tr><td style=text-align:center>rawData</td><td style=text-align:center><code>ArrayRef<char></code></td><td></td></tr></tbody></table><h3 id=denseresourceelementsattr>DenseResourceElementsAttr <a class=headline-hash href=#denseresourceelementsattr>¶</a></h3><p>An Attribute containing a dense multi-dimensional array backed by a resource</p><p>Syntax:</p><pre tabindex=0><code>dense-resource-elements-attribute ::= `dense_resource` `<` resource-handle `>` `:` shaped-type </code></pre><p>A dense resource elements attribute is an elements attribute backed by a handle to a builtin dialect resource containing a densely packed array of values. This class provides the low-level attribute, which should only be interacted with in very generic terms, actual access to the underlying resource data is intended to be managed through one of the subclasses, such as; <code>DenseBoolResourceElementsAttr</code>, <code>DenseUI64ResourceElementsAttr</code>, <code>DenseI32ResourceElementsAttr</code>, <code>DenseF32ResourceElementsAttr</code>, <code>DenseF64ResourceElementsAttr</code>, etc.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=s>"example.user_op"</span><span class=p>()</span> <span class=p>{</span><span class=nl>attr =</span> dense_resource<span class=p><</span>blob1<span class=p>></span> <span class=p>:</span> <span class=kt>tensor</span><span class=p><</span><span class=m>3x</span><span class=k>i64</span><span class=p>></span> <span class=p>}</span> <span class=p>:</span> <span class=p>()</span> <span class=p>-></span> <span class=p>()</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=p>{</span><span class=err>-#</span> </span></span><span class=line><span class=cl>dialect_resources<span class=p>:</span> <span class=p>{</span> </span></span><span class=line><span class=cl> builtin<span class=p>:</span> <span class=p>{</span> </span></span><span class=line><span class=cl> blob1<span class=p>:</span> <span class=s>"0x08000000010000000000000002000000000000000300000000000000"</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl><span class=err>#-</span><span class=p>}</span> </span></span></code></pre></div><h4 id=parameters-4>Parameters: <a class=headline-hash href=#parameters-4>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>type</td><td style=text-align:center><code>ShapedType</code></td><td></td></tr><tr><td style=text-align:center>rawHandle</td><td style=text-align:center><code>DenseResourceElementsHandle</code></td><td></td></tr></tbody></table><h3 id=densestringelementsattr>DenseStringElementsAttr <a class=headline-hash href=#densestringelementsattr>¶</a></h3><p>An Attribute containing a dense multi-dimensional array of strings</p><p>Syntax:</p><pre tabindex=0><code>dense-string-elements-attribute ::= `dense` `<` attribute-value `>` `:` ( tensor-type | vector-type ) </code></pre><p>A dense string elements attribute is an elements attribute containing a densely packed vector or tensor of string values. There are no restrictions placed on the element type of this attribute, enabling the use of dialect specific string types.</p><p>Examples:</p><pre tabindex=0><code>// A splat tensor of strings. dense<"example"> : tensor<2x!foo.string> // A tensor of 2 string elements. dense<["example1", "example2"]> : tensor<2x!foo.string> </code></pre><h4 id=parameters-5>Parameters: <a class=headline-hash href=#parameters-5>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>type</td><td style=text-align:center><code>ShapedType</code></td><td></td></tr><tr><td style=text-align:center>value</td><td style=text-align:center><code>ArrayRef<StringRef></code></td><td></td></tr></tbody></table><h3 id=dictionaryattr>DictionaryAttr <a class=headline-hash href=#dictionaryattr>¶</a></h3><p>An dictionary of named Attribute values</p><p>Syntax:</p><pre tabindex=0><code>dictionary-attribute ::= `{` (attribute-entry (`,` attribute-entry)*)? `}` </code></pre><p>A dictionary attribute is an attribute that represents a sorted collection of named attribute values. The elements are sorted by name, and each name must be unique within the collection.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=p>{}</span> </span></span><span class=line><span class=cl><span class=p>{</span><span class=nl>attr_name =</span> <span class=s>"string attribute"</span><span class=p>}</span> </span></span><span class=line><span class=cl><span class=p>{</span><span class=nl>int_attr =</span> <span class=m>10</span><span class=p>,</span> <span class=s>"string attr name"</span> <span class=p>=</span> <span class=s>"string attribute"</span><span class=p>}</span> </span></span></code></pre></div><h4 id=parameters-6>Parameters: <a class=headline-hash href=#parameters-6>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>value</td><td style=text-align:center><code>::llvm::ArrayRef<NamedAttribute></code></td><td></td></tr></tbody></table><h3 id=floatattr>FloatAttr <a class=headline-hash href=#floatattr>¶</a></h3><p>An Attribute containing a floating-point value</p><p>Syntax:</p><pre tabindex=0><code>float-attribute ::= (float-literal (`:` float-type)?) | (hexadecimal-literal `:` float-type) </code></pre><p>A float attribute is a literal attribute that represents a floating point value of the specified <a href=#floating-point-types>float type</a>. It can be represented in the hexadecimal form where the hexadecimal value is interpreted as bits of the underlying binary representation. This form is useful for representing infinity and NaN floating point values. To avoid confusion with integer attributes, hexadecimal literals <em>must</em> be followed by a float type to define a float attribute.</p><p>Examples:</p><pre tabindex=0><code>42.0 // float attribute defaults to f64 type 42.0 : f32 // float attribute of f32 type 0x7C00 : f16 // positive infinity 0x7CFF : f16 // NaN (one of possible values) 42 : f32 // Error: expected integer type </code></pre><h4 id=parameters-7>Parameters: <a class=headline-hash href=#parameters-7>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>type</td><td style=text-align:center><code>::mlir::Type</code></td><td></td></tr><tr><td style=text-align:center>value</td><td style=text-align:center><code>::llvm::APFloat</code></td><td></td></tr></tbody></table><h3 id=integerattr>IntegerAttr <a class=headline-hash href=#integerattr>¶</a></h3><p>An Attribute containing a integer value</p><p>Syntax:</p><pre tabindex=0><code>integer-attribute ::= (integer-literal ( `:` (index-type | integer-type) )?) | `true` | `false` </code></pre><p>An integer attribute is a literal attribute that represents an integral value of the specified integer or index type. <code>i1</code> integer attributes are treated as <code>boolean</code> attributes, and use a unique assembly format of either <code>true</code> or <code>false</code> depending on the value. The default type for non-boolean integer attributes, if a type is not specified, is signless 64-bit integer.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=m>10</span> <span class=p>:</span> <span class=k>i32</span> </span></span><span class=line><span class=cl><span class=m>10</span> <span class=c>// : i64 is implied here. </span></span></span><span class=line><span class=cl><span class=c></span>true <span class=c>// A bool, i.e. i1, value. </span></span></span><span class=line><span class=cl><span class=c></span>false <span class=c>// A bool, i.e. i1, value. </span></span></span></code></pre></div><h4 id=parameters-8>Parameters: <a class=headline-hash href=#parameters-8>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>type</td><td style=text-align:center><code>::mlir::Type</code></td><td></td></tr><tr><td style=text-align:center>value</td><td style=text-align:center><code>APInt</code></td><td></td></tr></tbody></table><h3 id=integersetattr>IntegerSetAttr <a class=headline-hash href=#integersetattr>¶</a></h3><p>An Attribute containing an IntegerSet object</p><p>Syntax:</p><pre tabindex=0><code>integer-set-attribute ::= `affine_set` `<` integer-set `>` </code></pre><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>affine_set<span class=p><(</span>d0<span class=p>)</span> <span class=p>:</span> <span class=p>(</span>d0 <span class=err>-</span> <span class=m>2</span> <span class=p>>=</span> <span class=m>0</span><span class=p>)></span> </span></span></code></pre></div><h4 id=parameters-9>Parameters: <a class=headline-hash href=#parameters-9>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>value</td><td style=text-align:center><code>IntegerSet</code></td><td></td></tr></tbody></table><h3 id=opaqueattr>OpaqueAttr <a class=headline-hash href=#opaqueattr>¶</a></h3><p>An opaque representation of another Attribute</p><p>Syntax:</p><pre tabindex=0><code>opaque-attribute ::= dialect-namespace `<` attr-data `>` </code></pre><p>Opaque attributes represent attributes of non-registered dialects. These are attribute represented in their raw string form, and can only usefully be tested for attribute equality.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=nv>#dialect</span><span class=p><</span><span class=s>"opaque attribute data"</span><span class=p>></span> </span></span></code></pre></div><h4 id=parameters-10>Parameters: <a class=headline-hash href=#parameters-10>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>dialectNamespace</td><td style=text-align:center><code>StringAttr</code></td><td></td></tr><tr><td style=text-align:center>attrData</td><td style=text-align:center><code>::llvm::StringRef</code></td><td></td></tr><tr><td style=text-align:center>type</td><td style=text-align:center><code>::mlir::Type</code></td><td></td></tr></tbody></table><h3 id=sparseelementsattr>SparseElementsAttr <a class=headline-hash href=#sparseelementsattr>¶</a></h3><p>An opaque representation of a multi-dimensional array</p><p>Syntax:</p><pre tabindex=0><code>sparse-elements-attribute ::= `sparse` `<` attribute-value `,` attribute-value `>` `:` ( tensor-type | vector-type ) </code></pre><p>A sparse elements attribute is an elements attribute that represents a sparse vector or tensor object. This is where very few of the elements are non-zero.</p><p>The attribute uses COO (coordinate list) encoding to represent the sparse elements of the elements attribute. The indices are stored via a 2-D tensor of 64-bit integer elements with shape [N, ndims], which specifies the indices of the elements in the sparse tensor that contains non-zero values. The element values are stored via a 1-D tensor with shape [N], that supplies the corresponding values for the indices.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>sparse<span class=p><[[</span><span class=m>0</span><span class=p>,</span> <span class=m>0</span><span class=p>],</span> <span class=p>[</span><span class=m>1</span><span class=p>,</span> <span class=m>2</span><span class=p>]],</span> <span class=p>[</span><span class=m>1</span><span class=p>,</span> <span class=m>5</span><span class=p>]></span> <span class=p>:</span> <span class=kt>tensor</span><span class=p><</span><span class=m>3x4x</span><span class=k>i32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// This represents the following tensor: </span></span></span><span class=line><span class=cl><span class=c>/// [[1, 0, 0, 0], </span></span></span><span class=line><span class=cl><span class=c>/// [0, 0, 5, 0], </span></span></span><span class=line><span class=cl><span class=c>/// [0, 0, 0, 0]] </span></span></span></code></pre></div><h4 id=parameters-11>Parameters: <a class=headline-hash href=#parameters-11>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>type</td><td style=text-align:center><code>ShapedType</code></td><td></td></tr><tr><td style=text-align:center>indices</td><td style=text-align:center><code>DenseIntElementsAttr</code></td><td></td></tr><tr><td style=text-align:center>values</td><td style=text-align:center><code>DenseElementsAttr</code></td><td></td></tr></tbody></table><h3 id=stringattr>StringAttr <a class=headline-hash href=#stringattr>¶</a></h3><p>An Attribute containing a string</p><p>Syntax:</p><pre tabindex=0><code>string-attribute ::= string-literal (`:` type)? </code></pre><p>A string attribute is an attribute that represents a string literal value.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=s>"An important string"</span> </span></span><span class=line><span class=cl><span class=s>"string with a type"</span> <span class=p>:</span> <span class=p>!</span>dialect<span class=p>.</span>string </span></span></code></pre></div><h4 id=parameters-12>Parameters: <a class=headline-hash href=#parameters-12>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>value</td><td style=text-align:center><code>::llvm::StringRef</code></td><td></td></tr><tr><td style=text-align:center>type</td><td style=text-align:center><code>::mlir::Type</code></td><td></td></tr></tbody></table><h3 id=symbolrefattr>SymbolRefAttr <a class=headline-hash href=#symbolrefattr>¶</a></h3><p>An Attribute containing a symbolic reference to an Operation</p><p>Syntax:</p><pre tabindex=0><code>symbol-ref-attribute ::= symbol-ref-id (`::` symbol-ref-id)* </code></pre><p>A symbol reference attribute is a literal attribute that represents a named reference to an operation that is nested within an operation with the <code>OpTrait::SymbolTable</code> trait. As such, this reference is given meaning by the nearest parent operation containing the <code>OpTrait::SymbolTable</code> trait. It may optionally contain a set of nested references that further resolve to a symbol nested within a different symbol table.</p><p><strong>Rationale:</strong> Identifying accesses to global data is critical to enabling efficient multi-threaded compilation. Restricting global data access to occur through symbols and limiting the places that can legally hold a symbol reference simplifies reasoning about these data accesses.</p><p>See <a href=/docs/SymbolsAndSymbolTables/><code>Symbols And SymbolTables</code></a> for more information.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=nf>@flat_reference</span> </span></span><span class=line><span class=cl><span class=nf>@parent_reference</span><span class=p>::</span><span class=nf>@nested_reference</span> </span></span></code></pre></div><h4 id=parameters-13>Parameters: <a class=headline-hash href=#parameters-13>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>rootReference</td><td style=text-align:center><code>StringAttr</code></td><td></td></tr><tr><td style=text-align:center>nestedReferences</td><td style=text-align:center><code>::llvm::ArrayRef<FlatSymbolRefAttr></code></td><td></td></tr></tbody></table><h3 id=typeattr>TypeAttr <a class=headline-hash href=#typeattr>¶</a></h3><p>An Attribute containing a Type</p><p>Syntax:</p><pre tabindex=0><code>type-attribute ::= type </code></pre><p>A type attribute is an attribute that represents a <a href=#type-system>type object</a>.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=k>i32</span> </span></span><span class=line><span class=cl><span class=p>!</span>dialect<span class=p>.</span>type </span></span></code></pre></div><h4 id=parameters-14>Parameters: <a class=headline-hash href=#parameters-14>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>value</td><td style=text-align:center><code>Type</code></td><td></td></tr></tbody></table><h3 id=unitattr>UnitAttr <a class=headline-hash href=#unitattr>¶</a></h3><p>An Attribute value of <code>unit</code> type</p><p>Syntax:</p><pre tabindex=0><code>unit-attribute ::= `unit` </code></pre><p>A unit attribute is an attribute that represents a value of <code>unit</code> type. The <code>unit</code> type allows only one value forming a singleton set. This attribute value is used to represent attributes that only have meaning from their existence.</p><p>One example of such an attribute could be the <code>swift.self</code> attribute. This attribute indicates that a function parameter is the self/context parameter. It could be represented as a <a href=#boolean-attribute>boolean attribute</a>(true or false), but a value of false doesn’t really bring any value. The parameter either is the self/context or it isn’t.</p><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// A unit attribute defined with the `unit` value specifier. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@verbose_form</span><span class=p>()</span> attributes <span class=p>{</span><span class=nl>dialectName.unitAttr =</span> unit<span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A unit attribute in an attribute dictionary can also be defined without </span></span></span><span class=line><span class=cl><span class=c>// the value specifier. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@simple_form</span><span class=p>()</span> attributes <span class=p>{</span>dialectName<span class=p>.</span>unitAttr<span class=p>}</span> </span></span></code></pre></div><h3 id=stridedlayoutattr>StridedLayoutAttr <a class=headline-hash href=#stridedlayoutattr>¶</a></h3><p>An Attribute representing a strided layout of a shaped type</p><p>Syntax:</p><pre tabindex=0><code>strided-layout-attribute ::= `strided` `<` `[` stride-list `]` (`,` `offset` `:` dimension)? `>` stride-list ::= /*empty*/ | dimension (`,` dimension)* dimension ::= decimal-literal | `?` </code></pre><p>A strided layout attribute captures layout information of the memref type in the canonical form. Specifically, it contains a list of <em>strides</em>, one for each dimension. A stride is the number of elements in the linear storage one must step over to reflect an increment in the given dimension. For example, a <code>MxN</code> row-major contiguous shaped type would have the strides <code>[N, 1]</code>. The layout attribute also contains the <em>offset</em> from the base pointer of the shaped type to the first effectively accessed element, expressed in terms of the number of contiguously stored elements.</p><p>Strides must be positive and the offset must be non-negative. Both the strides and the offset may be <em>dynamic</em>, i.e. their value may not be known at compile time. This is expressed as a <code>?</code> in the assembly syntax and as <code>ShapedType::kDynamic</code> in the code. Stride and offset values must satisfy the constraints above at runtime, the behavior is undefined otherwise.</p><p>See [Dialects/Builtin.md#memreftype](MemRef type) for more information.</p><h4 id=parameters-15>Parameters: <a class=headline-hash href=#parameters-15>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>offset</td><td style=text-align:center><code>int64_t</code></td><td></td></tr><tr><td style=text-align:center>strides</td><td style=text-align:center><code>::llvm::ArrayRef<int64_t></code></td><td>array of strides (64-bit integer)</td></tr></tbody></table><h2 id=location-attributes>Location Attributes <a class=headline-hash href=#location-attributes>¶</a></h2><p>A subset of the builtin attribute values correspond to <a href=/docs/Diagnostics/#source-locations>source locations</a>, that may be attached to Operations.</p><h3 id=callsiteloc>CallSiteLoc <a class=headline-hash href=#callsiteloc>¶</a></h3><p>A callsite source location</p><p>Syntax:</p><pre tabindex=0><code>callsite-location ::= `callsite` `(` location `at` location `)` </code></pre><p>An instance of this location allows for representing a directed stack of location usages. This connects a location of a <code>callee</code> with the location of a <code>caller</code>.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>loc</span><span class=p>(</span>callsite<span class=p>(</span><span class=s>"foo"</span> at <span class=s>"mysource.cc"</span><span class=p>:</span><span class=m>10</span><span class=p>:</span><span class=m>8</span><span class=p>))</span> </span></span></code></pre></div><h4 id=parameters-16>Parameters: <a class=headline-hash href=#parameters-16>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>callee</td><td style=text-align:center><code>Location</code></td><td></td></tr><tr><td style=text-align:center>caller</td><td style=text-align:center><code>Location</code></td><td></td></tr></tbody></table><h3 id=filelinecolrange>FileLineColRange <a class=headline-hash href=#filelinecolrange>¶</a></h3><p>A file:line:column source location range</p><p>Syntax:</p><pre tabindex=0><code>filelinecol-location ::= string-literal `:` integer-literal `:` integer-literal (`to` (integer-literal ?) `:` integer-literal ?) </code></pre><p>An instance of this location represents a tuple of file, start and end line number, and start and end column number. It allows for the following configurations:</p><ul><li>A single file line location: <code>file:line</code>;</li><li>A single file line col location: <code>file:line:column</code>;</li><li>A single line range: <code>file:line:column to :column</code>;</li><li>A single file range: <code>file:line:column to line:column</code>;</li></ul><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>loc</span><span class=p>(</span><span class=s>"mysource.cc"</span><span class=p>:</span><span class=m>10</span><span class=p>:</span><span class=m>8</span> to <span class=m>12</span><span class=p>:</span><span class=m>18</span><span class=p>)</span> </span></span></code></pre></div><h4 id=parameters-17>Parameters: <a class=headline-hash href=#parameters-17>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>filename</td><td style=text-align:center><code>StringAttr</code></td><td></td></tr><tr><td style=text-align:center>start_line</td><td style=text-align:center><code>unsigned</code></td><td></td></tr><tr><td style=text-align:center>start_column</td><td style=text-align:center><code>unsigned</code></td><td></td></tr><tr><td style=text-align:center>end_line</td><td style=text-align:center><code>unsigned</code></td><td></td></tr><tr><td style=text-align:center>end_column</td><td style=text-align:center><code>unsigned</code></td><td></td></tr></tbody></table><h3 id=fusedloc>FusedLoc <a class=headline-hash href=#fusedloc>¶</a></h3><p>A tuple of other source locations</p><p>Syntax:</p><pre tabindex=0><code>fusion-metadata ::= `<` attribute-value `>` fused-location ::= `fused` fusion-metadata? `[` (location (`,` location)* )? `]` </code></pre><p>An instance of a <code>fused</code> location represents a grouping of several other source locations, with optional metadata that describes the context of the fusion. There are many places within a compiler in which several constructs may be fused together, e.g. pattern rewriting, that normally result partial or even total loss of location information. With <code>fused</code> locations, this is a non-issue.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>loc</span><span class=p>(</span>fused<span class=p>[</span><span class=s>"mysource.cc"</span><span class=p>:</span><span class=m>10</span><span class=p>:</span><span class=m>8</span><span class=p>,</span> <span class=s>"mysource.cc"</span><span class=p>:</span><span class=m>22</span><span class=p>:</span><span class=m>8</span><span class=p>])</span> </span></span><span class=line><span class=cl><span class=kt>loc</span><span class=p>(</span>fused<span class=p><</span><span class=s>"CSE"</span><span class=p>>[</span><span class=s>"mysource.cc"</span><span class=p>:</span><span class=m>10</span><span class=p>:</span><span class=m>8</span><span class=p>,</span> <span class=s>"mysource.cc"</span><span class=p>:</span><span class=m>22</span><span class=p>:</span><span class=m>8</span><span class=p>])</span> </span></span></code></pre></div><h4 id=parameters-18>Parameters: <a class=headline-hash href=#parameters-18>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>locations</td><td style=text-align:center><code>::llvm::ArrayRef<Location></code></td><td></td></tr><tr><td style=text-align:center>metadata</td><td style=text-align:center><code>Attribute</code></td><td></td></tr></tbody></table><h3 id=nameloc>NameLoc <a class=headline-hash href=#nameloc>¶</a></h3><p>A named source location</p><p>Syntax:</p><pre tabindex=0><code>name-location ::= string-literal (`(` location `)`)? </code></pre><p>An instance of this location allows for attaching a name to a child location. This can be useful for representing the locations of variable, or node, definitions.</p><h4 id=example>Example: <a class=headline-hash href=#example>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>loc</span><span class=p>(</span><span class=s>"CSE"</span><span class=p>(</span><span class=s>"mysource.cc"</span><span class=p>:</span><span class=m>10</span><span class=p>:</span><span class=m>8</span><span class=p>))</span> </span></span></code></pre></div><h4 id=parameters-19>Parameters: <a class=headline-hash href=#parameters-19>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>name</td><td style=text-align:center><code>StringAttr</code></td><td></td></tr><tr><td style=text-align:center>childLoc</td><td style=text-align:center><code>Location</code></td><td></td></tr></tbody></table><h3 id=opaqueloc>OpaqueLoc <a class=headline-hash href=#opaqueloc>¶</a></h3><p>An opaque source location</p><p>An instance of this location essentially contains a pointer to some data structure that is external to MLIR and an optional location that can be used if the first one is not suitable. Since it contains an external structure, only the optional location is used during serialization.</p><h4 id=example-1>Example: <a class=headline-hash href=#example-1>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=nv>%0</span> <span class=p>=</span> <span class=s>"example.operation"</span><span class=p>()</span> <span class=p>:</span> <span class=p>()</span> <span class=p>-></span> <span class=k>i32</span> <span class=kt>loc</span><span class=p>(</span><span class=s>"mysource"</span><span class=p>)</span> </span></span><span class=line><span class=cl><span class=nv>%1</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>4</span> <span class=p>:</span> <span class=k>index</span> <span class=kt>loc</span><span class=p>(</span>callsite<span class=p>(</span><span class=s>"mysum"</span> at <span class=s>"mysource.cc"</span><span class=p>:</span><span class=m>10</span><span class=p>:</span><span class=m>8</span><span class=p>))</span> </span></span></code></pre></div><h4 id=parameters-20>Parameters: <a class=headline-hash href=#parameters-20>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>underlyingLocation</td><td style=text-align:center><code>uintptr_t</code></td><td></td></tr><tr><td style=text-align:center>underlyingTypeID</td><td style=text-align:center><code>TypeID</code></td><td></td></tr><tr><td style=text-align:center>fallbackLocation</td><td style=text-align:center><code>Location</code></td><td></td></tr></tbody></table><h3 id=unknownloc>UnknownLoc <a class=headline-hash href=#unknownloc>¶</a></h3><p>An unspecified source location</p><p>Syntax:</p><pre tabindex=0><code>unknown-location ::= `?` </code></pre><p>Source location information is an extremely integral part of the MLIR infrastructure. As such, location information is always present in the IR, and must explicitly be set to unknown. Thus, an instance of the <code>unknown</code> location represents an unspecified source location.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>loc</span><span class=p>(</span><span class=err>?</span><span class=p>)</span> </span></span></code></pre></div><h2 id=distinctattribute>DistinctAttribute <a class=headline-hash href=#distinctattribute>¶</a></h2><p>A DistinctAttribute associates an attribute with a unique identifier. As a result, multiple DistinctAttribute instances may point to the same attribute. Every call to the <code>create</code> function allocates a new DistinctAttribute instance. The address of the attribute instance serves as a temporary unique identifier. Similar to the names of SSA values, the final unique identifiers are generated during pretty printing. This delayed numbering ensures the printed identifiers are deterministic even if multiple DistinctAttribute instances are created in-parallel.</p><p>Syntax:</p><pre tabindex=0><code>distinct-id ::= integer-literal distinct-attribute ::= `distinct` `[` distinct-id `]<` attribute `>` </code></pre><p>Examples:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=nv>#distinct</span> <span class=p>=</span> distinct<span class=p>[</span><span class=m>0</span><span class=p>]<</span><span class=m>42.0</span> <span class=p>:</span> <span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl><span class=nv>#distinct1</span> <span class=p>=</span> distinct<span class=p>[</span><span class=m>1</span><span class=p>]<</span><span class=m>42.0</span> <span class=p>:</span> <span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl><span class=nv>#distinct2</span> <span class=p>=</span> distinct<span class=p>[</span><span class=m>2</span><span class=p>]<</span>array<span class=p><</span><span class=k>i32</span><span class=p>:</span> <span class=m>10</span><span class=p>,</span> <span class=m>42</span><span class=p>>></span> </span></span></code></pre></div><p>This mechanism is meant to generate attributes with a unique identifier, which can be used to mark groups of operations that share a common property. For example, groups of aliasing memory operations may be marked using one DistinctAttribute instance per alias group.</p><h2 id=operations>Operations <a class=headline-hash href=#operations>¶</a></h2><p><a href=https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/IR/BuiltinOps.td>source</a></p><h3 id=builtinmodule-moduleop><code>builtin.module</code> (ModuleOp) <a class=headline-hash href=#builtinmodule-moduleop>¶</a></h3><p><em>A top level container operation</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `builtin.module` ($sym_name^)? attr-dict-with-keyword $bodyRegion </code></pre><p>A <code>module</code> represents a top-level container operation. It contains a single <a href=/docs/LangRef/>graph region</a> containing a single block which can contain any operations and does not have a terminator. Operations within this region cannot implicitly capture values defined outside the module, i.e. Modules are <a href=../Traits.md#isolatedfromabove>IsolatedFromAbove</a>. Modules have an optional <a href=/docs/SymbolsAndSymbolTables/>symbol name</a> which can be used to refer to them in operations.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>module <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@foo</span><span class=p>()</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>Traits: <code>AffineScope</code>, <code>HasOnlyGraphRegion</code>, <code>IsolatedFromAbove</code>, <code>NoRegionArguments</code>, <code>NoTerminator</code>, <code>SingleBlock</code>, <code>SymbolTable</code></p><p>Interfaces: <code>OpAsmOpInterface</code>, <code>RegionKindInterface</code>, <code>Symbol</code></p><h4 id=attributes-1>Attributes: <a class=headline-hash href=#attributes-1>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>sym_name</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr><tr><td><code>sym_visibility</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr></table><h3 id=builtinunrealized_conversion_cast-unrealizedconversioncastop><code>builtin.unrealized_conversion_cast</code> (UnrealizedConversionCastOp) <a class=headline-hash href=#builtinunrealized_conversion_cast-unrealizedconversioncastop>¶</a></h3><p><em>An unrealized conversion from one set of types to another</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `builtin.unrealized_conversion_cast` ($inputs^ `:` type($inputs))? `to` type($outputs) attr-dict </code></pre><p>An <code>unrealized_conversion_cast</code> operation represents an unrealized conversion from one set of types to another, that is used to enable the inter-mixing of different type systems. This operation should not be attributed any special representational or execution semantics, and is generally only intended to be used to satisfy the temporary intermixing of type systems during the conversion of one type system to another.</p><p>This operation may produce results of arity 1-N, and accept as input operands of arity 0-N.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// An unrealized 0-1 conversion. These types of conversions are useful in </span></span></span><span class=line><span class=cl><span class=c>// cases where a type is removed from the type system, but not all uses have </span></span></span><span class=line><span class=cl><span class=c>// been converted. For example, imagine we have a tuple type that is </span></span></span><span class=line><span class=cl><span class=c>// expanded to its element types. If only some uses of an empty tuple type </span></span></span><span class=line><span class=cl><span class=c>// instance are converted we still need an instance of the tuple type, but </span></span></span><span class=line><span class=cl><span class=c>// have no inputs to the unrealized conversion. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%result</span> <span class=p>=</span> unrealized_conversion_cast to <span class=p>!</span>bar<span class=p>.</span>tuple_type<span class=p><></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// An unrealized 1-1 conversion. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%result1</span> <span class=p>=</span> unrealized_conversion_cast <span class=nv>%operand</span> <span class=p>:</span> <span class=p>!</span>foo<span class=p>.</span>type to <span class=p>!</span>bar<span class=p>.</span>lowered_type </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// An unrealized 1-N conversion. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%results2</span><span class=p>:</span><span class=nl>2 =</span> unrealized_conversion_cast <span class=nv>%tuple_operand</span> <span class=p>:</span> <span class=p>!</span>foo<span class=p>.</span>tuple_type<span class=p><!</span>foo<span class=p>.</span>type<span class=p>,</span> <span class=p>!</span>foo<span class=p>.</span>type<span class=p>></span> to <span class=p>!</span>foo<span class=p>.</span>type<span class=p>,</span> <span class=p>!</span>foo<span class=p>.</span>type </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// An unrealized N-1 conversion. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%result3</span> <span class=p>=</span> unrealized_conversion_cast <span class=nv>%operand</span><span class=p>,</span> <span class=nv>%operand</span> <span class=p>:</span> <span class=p>!</span>foo<span class=p>.</span>type<span class=p>,</span> <span class=p>!</span>foo<span class=p>.</span>type to <span class=p>!</span>bar<span class=p>.</span>tuple_type<span class=p><!</span>foo<span class=p>.</span>type<span class=p>,</span> <span class=p>!</span>foo<span class=p>.</span>type<span class=p>></span> </span></span></code></pre></div><p>Traits: <code>AlwaysSpeculatableImplTrait</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>NoMemoryEffect (MemoryEffectOpInterface)</code></p><p>Effects: <code>MemoryEffects::Effect{}</code></p><h4 id=operands>Operands: <a class=headline-hash href=#operands>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr></tbody></table><h4 id=results>Results: <a class=headline-hash href=#results>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>outputs</code></td><td>variadic of any type</td></tr></tbody></table><h2 id=types>Types <a class=headline-hash href=#types>¶</a></h2><h3 id=bfloat16type>BFloat16Type <a class=headline-hash href=#bfloat16type>¶</a></h3><p>bfloat16 floating-point type</p><h3 id=complextype>ComplexType <a class=headline-hash href=#complextype>¶</a></h3><p>Complex number with a parameterized element type</p><p>Syntax:</p><pre tabindex=0><code>complex-type ::= `complex` `<` type `>` </code></pre><p>The value of <code>complex</code> type represents a complex number with a parameterized element type, which is composed of a real and imaginary value of that element type. The element must be a floating point or integer scalar type.</p><h4 id=example-2>Example: <a class=headline-hash href=#example-2>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>complex<span class=p><</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl>complex<span class=p><</span><span class=k>i32</span><span class=p>></span> </span></span></code></pre></div><h4 id=parameters-21>Parameters: <a class=headline-hash href=#parameters-21>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>elementType</td><td style=text-align:center><code>Type</code></td><td></td></tr></tbody></table><h3 id=float4e2m1fntype>Float4E2M1FNType <a class=headline-hash href=#float4e2m1fntype>¶</a></h3><p>4-bit floating point with 2-bit exponent and 1-bit mantissa</p><p>An 4-bit floating point type with 1 sign bit, 2 bits exponent and 1 bit mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:</p><ul><li>bit encoding: S1E2M1</li><li>exponent bias: 1</li><li>infinities: Not supported</li><li>NaNs: Not supported</li><li>denormals when exponent is 0</li></ul><p>Open Compute Project (OCP) microscaling formats (MX) specification: <a href=https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf>https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf</a></p><h3 id=float6e2m3fntype>Float6E2M3FNType <a class=headline-hash href=#float6e2m3fntype>¶</a></h3><p>6-bit floating point with 2-bit exponent and 3-bit mantissa</p><p>An 6-bit floating point type with 1 sign bit, 2 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:</p><ul><li>bit encoding: S1E2M3</li><li>exponent bias: 1</li><li>infinities: Not supported</li><li>NaNs: Not supported</li><li>denormals when exponent is 0</li></ul><p>Open Compute Project (OCP) microscaling formats (MX) specification: <a href=https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf>https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf</a></p><h3 id=float6e3m2fntype>Float6E3M2FNType <a class=headline-hash href=#float6e3m2fntype>¶</a></h3><p>6-bit floating point with 3-bit exponent and 2-bit mantissa</p><p>An 6-bit floating point type with 1 sign bit, 3 bits exponent and 2 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:</p><ul><li>bit encoding: S1E3M2</li><li>exponent bias: 3</li><li>infinities: Not supported</li><li>NaNs: Not supported</li><li>denormals when exponent is 0</li></ul><p>Open Compute Project (OCP) microscaling formats (MX) specification: <a href=https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf>https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf</a></p><h3 id=float8e3m4type>Float8E3M4Type <a class=headline-hash href=#float8e3m4type>¶</a></h3><p>8-bit floating point with 3 bits exponent and 4 bit mantissa</p><p>An 8-bit floating point type with 1 sign bit, 3 bits exponent and 4 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:</p><ul><li>bit encoding: S1E3M4</li><li>exponent bias: 3</li><li>infinities: supported with exponent set to all 1s and mantissa 0s</li><li>NaNs: supported with exponent bits set to all 1s and mantissa values of {0,1}⁴ except S.111.0000</li><li>denormals when exponent is 0</li></ul><h3 id=float8e4m3type>Float8E4M3Type <a class=headline-hash href=#float8e4m3type>¶</a></h3><p>8-bit floating point with 3 bit mantissa</p><p>An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:</p><ul><li>bit encoding: S1E4M3</li><li>exponent bias: 7</li><li>infinities: supported with exponent set to all 1s and mantissa 0s</li><li>NaNs: supported with exponent bits set to all 1s and mantissa of (001, 010, 011, 100, 101, 110, 111)</li><li>denormals when exponent is 0</li></ul><h3 id=float8e4m3b11fnuztype>Float8E4M3B11FNUZType <a class=headline-hash href=#float8e4m3b11fnuztype>¶</a></h3><p>8-bit floating point with 3 bit mantissa</p><p>An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions, with the exception that there are no infinity values, no negative zero, and only one NaN representation. This type has the following characteristics:</p><ul><li>bit encoding: S1E4M3</li><li>exponent bias: 11</li><li>infinities: Not supported</li><li>NaNs: Supported with sign bit set to 1, exponent bits and mantissa bits set to all 0s</li><li>denormals when exponent is 0</li></ul><p>Related to: <a href=https://dl.acm.org/doi/10.5555/3454287.3454728>https://dl.acm.org/doi/10.5555/3454287.3454728</a></p><h3 id=float8e4m3fntype>Float8E4M3FNType <a class=headline-hash href=#float8e4m3fntype>¶</a></h3><p>8-bit floating point with 3 bit mantissa</p><p>An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions, with the exception that there are no infinity values and only two NaN representations. This type has the following characteristics:</p><ul><li>bit encoding: S1E4M3</li><li>exponent bias: 7</li><li>infinities: Not supported</li><li>NaNs: supported with exponent bits and mantissa bits set to all 1s</li><li>denormals when exponent is 0</li></ul><p>Described in: <a href=https://arxiv.org/abs/2209.05433>https://arxiv.org/abs/2209.05433</a></p><h3 id=float8e4m3fnuztype>Float8E4M3FNUZType <a class=headline-hash href=#float8e4m3fnuztype>¶</a></h3><p>8-bit floating point with 3 bit mantissa</p><p>An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions, with the exception that there are no infinity values, no negative zero, and only one NaN representation. This type has the following characteristics:</p><ul><li>bit encoding: S1E4M3</li><li>exponent bias: 8</li><li>infinities: Not supported</li><li>NaNs: Supported with sign bit set to 1, exponent bits and mantissa bits set to all 0s</li><li>denormals when exponent is 0</li></ul><p>Described in: <a href=https://arxiv.org/abs/2209.05433>https://arxiv.org/abs/2209.05433</a></p><h3 id=float8e5m2type>Float8E5M2Type <a class=headline-hash href=#float8e5m2type>¶</a></h3><p>8-bit floating point with 2 bit mantissa</p><p>An 8-bit floating point type with 1 sign bit, 5 bits exponent and 2 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:</p><ul><li>bit encoding: S1E5M2</li><li>exponent bias: 15</li><li>infinities: supported with exponent set to all 1s and mantissa 0s</li><li>NaNs: supported with exponent bits set to all 1s and mantissa of (01, 10, or 11)</li><li>denormals when exponent is 0</li></ul><p>Described in: <a href=https://arxiv.org/abs/2209.05433>https://arxiv.org/abs/2209.05433</a></p><h3 id=float8e5m2fnuztype>Float8E5M2FNUZType <a class=headline-hash href=#float8e5m2fnuztype>¶</a></h3><p>8-bit floating point with 2 bit mantissa</p><p>An 8-bit floating point type with 1 sign bit, 5 bits exponent and 2 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions, with the exception that there are no infinity values, no negative zero, and only one NaN representation. This type has the following characteristics:</p><ul><li>bit encoding: S1E5M2</li><li>exponent bias: 16</li><li>infinities: Not supported</li><li>NaNs: Supported with sign bit set to 1, exponent bits and mantissa bits set to all 0s</li><li>denormals when exponent is 0</li></ul><p>Described in: <a href=https://arxiv.org/abs/2206.02915>https://arxiv.org/abs/2206.02915</a></p><h3 id=float8e8m0fnutype>Float8E8M0FNUType <a class=headline-hash href=#float8e8m0fnutype>¶</a></h3><p>8-bit floating point with 8-bit exponent, no mantissa or sign</p><p>An 8-bit floating point type with no sign bit, 8 bits exponent and no mantissa. This is not a standard type as defined by IEEE-754; it is intended to be used for representing scaling factors, so it cannot represent zeros and negative numbers. The values it can represent are powers of two in the range [-127,127] and NaN.</p><ul><li>bit encoding: S0E8M0</li><li>exponent bias: 127</li><li>infinities: Not supported</li><li>NaNs: Supported with all bits set to 1</li><li>denormals: Not supported</li></ul><p>Open Compute Project (OCP) microscaling formats (MX) specification: <a href=https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf>https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf</a></p><h3 id=float16type>Float16Type <a class=headline-hash href=#float16type>¶</a></h3><p>16-bit floating-point type</p><h3 id=float32type>Float32Type <a class=headline-hash href=#float32type>¶</a></h3><p>32-bit floating-point type</p><h3 id=float64type>Float64Type <a class=headline-hash href=#float64type>¶</a></h3><p>64-bit floating-point type</p><h3 id=float80type>Float80Type <a class=headline-hash href=#float80type>¶</a></h3><p>80-bit floating-point type</p><h3 id=float128type>Float128Type <a class=headline-hash href=#float128type>¶</a></h3><p>128-bit floating-point type</p><h3 id=floattf32type>FloatTF32Type <a class=headline-hash href=#floattf32type>¶</a></h3><p>TF32 floating-point type</p><h3 id=functiontype>FunctionType <a class=headline-hash href=#functiontype>¶</a></h3><p>Map from a list of inputs to a list of results</p><p>Syntax:</p><pre tabindex=0><code>// Function types may have multiple results. function-result-type ::= type-list-parens | non-function-type function-type ::= type-list-parens `->` function-result-type </code></pre><p>The function type can be thought of as a function signature. It consists of a list of formal parameter types and a list of formal result types.</p><h4 id=example-3>Example: <a class=headline-hash href=#example-3>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@add_one</span><span class=p>(</span><span class=nv>%arg0</span> <span class=p>:</span> <span class=k>i64</span><span class=p>)</span> <span class=p>-></span> <span class=k>i64</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%c1</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>1</span> <span class=p>:</span> <span class=k>i64</span> </span></span><span class=line><span class=cl> <span class=nv>%0</span> <span class=p>=</span> arith<span class=p>.</span>addi <span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%c1</span> <span class=p>:</span> <span class=k>i64</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> <span class=nv>%0</span> <span class=p>:</span> <span class=k>i64</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><h4 id=parameters-22>Parameters: <a class=headline-hash href=#parameters-22>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>inputs</td><td style=text-align:center><code>ArrayRef<Type></code></td><td></td></tr><tr><td style=text-align:center>results</td><td style=text-align:center><code>ArrayRef<Type></code></td><td></td></tr></tbody></table><h3 id=indextype>IndexType <a class=headline-hash href=#indextype>¶</a></h3><p>Integer-like type with unknown platform-dependent bit width</p><p>Syntax:</p><pre tabindex=0><code>// Target word-sized integer. index-type ::= `index` </code></pre><p>The index type is a signless integer whose size is equal to the natural machine word of the target ( <a href=../../Rationale/Rationale/#integer-signedness-semantics>rationale</a> ) and is used by the affine constructs in MLIR.</p><p><strong>Rationale:</strong> integers of platform-specific bit widths are practical to express sizes, dimensionalities and subscripts.</p><h3 id=integertype>IntegerType <a class=headline-hash href=#integertype>¶</a></h3><p>Integer type with arbitrary precision up to a fixed limit</p><p>Syntax:</p><pre tabindex=0><code>// Sized integers like i1, i4, i8, i16, i32. signed-integer-type ::= `si` [1-9][0-9]* unsigned-integer-type ::= `ui` [1-9][0-9]* signless-integer-type ::= `i` [1-9][0-9]* integer-type ::= signed-integer-type | unsigned-integer-type | signless-integer-type </code></pre><p>Integer types have a designated bit width and may optionally have signedness semantics.</p><p><strong>Rationale:</strong> low precision integers (like <code>i2</code>, <code>i4</code> etc) are useful for low-precision inference chips, and arbitrary precision integers are useful for hardware synthesis (where a 13 bit multiplier is a lot cheaper/smaller than a 16 bit one).</p><h4 id=parameters-23>Parameters: <a class=headline-hash href=#parameters-23>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>width</td><td style=text-align:center><code>unsigned</code></td><td></td></tr><tr><td style=text-align:center>signedness</td><td style=text-align:center><code>SignednessSemantics</code></td><td></td></tr></tbody></table><h3 id=memreftype>MemRefType <a class=headline-hash href=#memreftype>¶</a></h3><p>Shaped reference to a region of memory</p><p>Syntax:</p><pre tabindex=0><code>layout-specification ::= attribute-value memory-space ::= attribute-value memref-type ::= `memref` `<` dimension-list-ranked type (`,` layout-specification)? (`,` memory-space)? `>` </code></pre><p>A <code>memref</code> type is a reference to a region of memory (similar to a buffer pointer, but more powerful). The buffer pointed to by a memref can be allocated, aliased and deallocated. A memref can be used to read and write data from/to the memory region which it references. Memref types use the same shape specifier as tensor types. Note that <code>memref<f32></code>, <code>memref<0 x f32></code>, <code>memref<1 x 0 x f32></code>, and <code>memref<0 x 1 x f32></code> are all different types.</p><p>A <code>memref</code> is allowed to have an unknown rank (e.g. <code>memref<*xf32></code>). The purpose of unranked memrefs is to allow external library functions to receive memref arguments of any rank without versioning the functions based on the rank. Other uses of this type are disallowed or will have undefined behavior.</p><p>Are accepted as elements:</p><ul><li>built-in integer types;</li><li>built-in index type;</li><li>built-in floating point types;</li><li>built-in vector types with elements of the above types;</li><li>another memref type;</li><li>any other type implementing <code>MemRefElementTypeInterface</code>.</li></ul><h5 id=layout>Layout <a class=headline-hash href=#layout>¶</a></h5><p>A memref may optionally have a layout that indicates how indices are transformed from the multi-dimensional form into a linear address. The layout must avoid internal aliasing, i.e., two distinct tuples of <em>in-bounds</em> indices must be pointing to different elements in memory. The layout is an attribute that implements <code>MemRefLayoutAttrInterface</code>. The bulitin dialect offers two kinds of layouts: strided and affine map, each of which is available as an attribute. Other attributes may be used to represent the layout as long as they can be converted to a <a href=/docs/Dialects/Affine/#semi-affine-maps>semi-affine map</a> and implement the required interface. Users of memref are expected to fallback to the affine representation when handling unknown memref layouts. Multi-dimensional affine forms are interpreted in <em>row-major</em> fashion.</p><p>In absence of an explicit layout, a memref is considered to have a multi-dimensional identity affine map layout. Identity layout maps do not contribute to the MemRef type identification and are discarded on construction. That is, a type with an explicit identity map is <code>memref<?x?xf32, (i,j)->(i,j)></code> is strictly the same as the one without a layout, <code>memref<?x?xf32></code>.</p><h5 id=affine-map-layout>Affine Map Layout <a class=headline-hash href=#affine-map-layout>¶</a></h5><p>The layout may be represented directly as an affine map from the index space to the storage space. For example, the following figure shows an index map which maps a 2-dimensional index from a 2x2 index space to a 3x3 index space, using symbols <code>S0</code> and <code>S1</code> as offsets.</p><p><img src=/includes/img/index-map.svg alt="Index Map Example"></p><p>Semi-affine maps are sufficiently flexible to represent a wide variety of dense storage layouts, including row- and column-major and tiled:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// MxN matrix stored in row major layout in memory: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#layout_map_row_major</span> <span class=p>=</span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// MxN matrix stored in column major layout in memory: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#layout_map_col_major</span> <span class=p>=</span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>j<span class=p>,</span> i<span class=p>)</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// MxN matrix stored in a 2-d blocked/tiled layout with 64x64 tiles. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#layout_tiled</span> <span class=p>=</span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>i floordiv <span class=m>64</span><span class=p>,</span> j floordiv <span class=m>64</span><span class=p>,</span> i mod <span class=m>64</span><span class=p>,</span> j mod <span class=m>64</span><span class=p>)</span> </span></span></code></pre></div><h5 id=strided-layout>Strided Layout <a class=headline-hash href=#strided-layout>¶</a></h5><p>Memref layout can be expressed using strides to encode the distance, in number of elements, in (linear) memory between successive entries along a particular dimension. For example, a row-major strided layout for <code>memref<2x3x4xf32></code> is <code>strided<[12, 4, 1]></code>, where the last dimension is contiguous as indicated by the unit stride and the remaining strides are products of the sizes of faster-variying dimensions. Strided layout can also express non-contiguity, e.g., <code>memref<2x3, strided<[6, 2]>></code> only accesses even elements of the dense consecutive storage along the innermost dimension.</p><p>The strided layout supports an optional <em>offset</em> that indicates the distance, in the number of elements, between the beginning of the memref and the first accessed element. When omitted, the offset is considered to be zero. That is, <code>memref<2, strided<[2], offset: 0>></code> and <code>memref<2, strided<[2]>></code> are strictly the same type.</p><p>Both offsets and strides may be <em>dynamic</em>, that is, unknown at compile time. This is represented by using a question mark (<code>?</code>) instead of the value in the textual form of the IR.</p><p>The strided layout converts into the following canonical one-dimensional affine form through explicit linearization:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>affine_map<span class=p><(</span>d0<span class=p>,</span> <span class=p>...</span> dN<span class=p>)[</span>offset<span class=p>,</span> stride0<span class=p>,</span> <span class=p>...</span> strideN<span class=p>]</span> <span class=p>-></span> </span></span><span class=line><span class=cl> <span class=p>(</span>offset <span class=err>+</span> d0 <span class=p>*</span> stride0 <span class=err>+</span> <span class=p>...</span> dN <span class=p>*</span> strideN<span class=p>)></span> </span></span></code></pre></div><p>Therefore, it is never subject to the implicit row-major layout interpretation.</p><h5 id=codegen-of-unranked-memref>Codegen of Unranked Memref <a class=headline-hash href=#codegen-of-unranked-memref>¶</a></h5><p>Using unranked memref in codegen besides the case mentioned above is highly discouraged. Codegen is concerned with generating loop nests and specialized instructions for high-performance, unranked memref is concerned with hiding the rank and thus, the number of enclosing loops required to iterate over the data. However, if there is a need to code-gen unranked memref, one possible path is to cast into a static ranked type based on the dynamic rank. Another possible path is to emit a single while loop conditioned on a linear index and perform delinearization of the linear index to a dynamic array containing the (unranked) indices. While this is possible, it is expected to not be a good idea to perform this during codegen as the cost of the translations is expected to be prohibitive and optimizations at this level are not expected to be worthwhile. If expressiveness is the main concern, irrespective of performance, passing unranked memrefs to an external C++ library and implementing rank-agnostic logic there is expected to be significantly simpler.</p><p>Unranked memrefs may provide expressiveness gains in the future and help bridge the gap with unranked tensors. Unranked memrefs will not be expected to be exposed to codegen but one may query the rank of an unranked memref (a special op will be needed for this purpose) and perform a switch and cast to a ranked memref as a prerequisite to codegen.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// With static ranks, we need a function for each possible argument type </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%A</span> <span class=p>=</span> alloc<span class=p>()</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>16x32x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl><span class=nv>%B</span> <span class=p>=</span> alloc<span class=p>()</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>16x32x64x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl>call <span class=nf>@helper_2D</span><span class=p>(</span><span class=nv>%A</span><span class=p>)</span> <span class=p>:</span> <span class=p>(</span><span class=kt>memref</span><span class=p><</span><span class=m>16x32x</span><span class=k>f32</span><span class=p>>)->()</span> </span></span><span class=line><span class=cl>call <span class=nf>@helper_3D</span><span class=p>(</span><span class=nv>%B</span><span class=p>)</span> <span class=p>:</span> <span class=p>(</span><span class=kt>memref</span><span class=p><</span><span class=m>16x32x64x</span><span class=k>f32</span><span class=p>>)->()</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// With unknown rank, the functions can be unified under one unranked type </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%A</span> <span class=p>=</span> alloc<span class=p>()</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>16x32x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl><span class=nv>%B</span> <span class=p>=</span> alloc<span class=p>()</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>16x32x64x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl><span class=c>// Remove rank info </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%A_u</span> <span class=p>=</span> <span class=kt>memref</span>_cast <span class=nv>%A</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>16x32x</span><span class=k>f32</span><span class=p>></span> <span class=p>-></span> <span class=kt>memref</span><span class=p><*</span>xf32<span class=p>></span> </span></span><span class=line><span class=cl><span class=nv>%B_u</span> <span class=p>=</span> <span class=kt>memref</span>_cast <span class=nv>%B</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>16x32x64x</span><span class=k>f32</span><span class=p>></span> <span class=p>-></span> <span class=kt>memref</span><span class=p><*</span>xf32<span class=p>></span> </span></span><span class=line><span class=cl><span class=c>// call same function with dynamic ranks </span></span></span><span class=line><span class=cl><span class=c></span>call <span class=nf>@helper</span><span class=p>(</span><span class=nv>%A_u</span><span class=p>)</span> <span class=p>:</span> <span class=p>(</span><span class=kt>memref</span><span class=p><*</span>xf32<span class=p>>)->()</span> </span></span><span class=line><span class=cl>call <span class=nf>@helper</span><span class=p>(</span><span class=nv>%B_u</span><span class=p>)</span> <span class=p>:</span> <span class=p>(</span><span class=kt>memref</span><span class=p><*</span>xf32<span class=p>>)->()</span> </span></span></code></pre></div><p>The core syntax and representation of a layout specification is a <a href=/docs/Dialects/Affine/#semi-affine-maps>semi-affine map</a>. Additionally, syntactic sugar is supported to make certain layout specifications more intuitive to read. For the moment, a <code>memref</code> supports parsing a strided form which is converted to a semi-affine map automatically.</p><p>The memory space of a memref is specified by a target-specific attribute. It might be an integer value, string, dictionary or custom dialect attribute. The empty memory space (attribute is None) is target specific.</p><p>The notionally dynamic value of a memref value includes the address of the buffer allocated, as well as the symbols referred to by the shape, layout map, and index maps.</p><p>Examples of memref static type</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Identity index/layout map </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#identity</span> <span class=p>=</span> affine_map<span class=p><(</span>d0<span class=p>,</span> d1<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>d0<span class=p>,</span> d1<span class=p>)></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Column major layout. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#col_major</span> <span class=p>=</span> affine_map<span class=p><(</span>d0<span class=p>,</span> d1<span class=p>,</span> d2<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>d2<span class=p>,</span> d1<span class=p>,</span> d0<span class=p>)></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A 2-d tiled layout with tiles of size 128 x 256. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#tiled_2d_128x256</span> <span class=p>=</span> affine_map<span class=p><(</span>d0<span class=p>,</span> d1<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>d0 div <span class=m>128</span><span class=p>,</span> d1 div <span class=m>256</span><span class=p>,</span> d0 mod <span class=m>128</span><span class=p>,</span> d1 mod <span class=m>256</span><span class=p>)></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A tiled data layout with non-constant tile sizes. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#tiled_dynamic</span> <span class=p>=</span> affine_map<span class=p><(</span>d0<span class=p>,</span> d1<span class=p>)[</span>s0<span class=p>,</span> s1<span class=p>]</span> <span class=p>-></span> <span class=p>(</span>d0 floordiv s0<span class=p>,</span> d1 floordiv s1<span class=p>,</span> </span></span><span class=line><span class=cl> d0 mod s0<span class=p>,</span> d1 mod s1<span class=p>)></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A layout that yields a padding on two at either end of the minor dimension. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#padded</span> <span class=p>=</span> affine_map<span class=p><(</span>d0<span class=p>,</span> d1<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>d0<span class=p>,</span> <span class=p>(</span>d1 <span class=err>+</span> <span class=m>2</span><span class=p>)</span> floordiv <span class=m>2</span><span class=p>,</span> <span class=p>(</span>d1 <span class=err>+</span> <span class=m>2</span><span class=p>)</span> mod <span class=m>2</span><span class=p>)></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// The dimension list "16x32" defines the following 2D index space: </span></span></span><span class=line><span class=cl><span class=c>// </span></span></span><span class=line><span class=cl><span class=c>// { (i, j) : 0 <= i < 16, 0 <= j < 32 } </span></span></span><span class=line><span class=cl><span class=c>// </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>memref</span><span class=p><</span><span class=m>16x32x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#identity</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// The dimension list "16x4x?" defines the following 3D index space: </span></span></span><span class=line><span class=cl><span class=c>// </span></span></span><span class=line><span class=cl><span class=c>// { (i, j, k) : 0 <= i < 16, 0 <= j < 4, 0 <= k < N } </span></span></span><span class=line><span class=cl><span class=c>// </span></span></span><span class=line><span class=cl><span class=c>// where N is a symbol which represents the runtime value of the size of </span></span></span><span class=line><span class=cl><span class=c>// the third dimension. </span></span></span><span class=line><span class=cl><span class=c>// </span></span></span><span class=line><span class=cl><span class=c>// %N here binds to the size of the third dimension. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%A</span> <span class=p>=</span> alloc<span class=p>(</span><span class=nv>%N</span><span class=p>)</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>16x4x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#col_major</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A 2-d dynamic shaped memref that also has a dynamically sized tiled </span></span></span><span class=line><span class=cl><span class=c>// layout. The memref index space is of size %M x %N, while %B1 and %B2 </span></span></span><span class=line><span class=cl><span class=c>// bind to the symbols s0, s1 respectively of the layout map #tiled_dynamic. </span></span></span><span class=line><span class=cl><span class=c>// Data tiles of size %B1 x %B2 in the logical space will be stored </span></span></span><span class=line><span class=cl><span class=c>// contiguously in memory. The allocation size will be </span></span></span><span class=line><span class=cl><span class=c>// (%M ceildiv %B1) * %B1 * (%N ceildiv %B2) * %B2 f32 elements. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%T</span> <span class=p>=</span> alloc<span class=p>(</span><span class=nv>%M</span><span class=p>,</span> <span class=nv>%N</span><span class=p>)</span> <span class=p>[</span><span class=nv>%B1</span><span class=p>,</span> <span class=nv>%B2</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#tiled_dynamic</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A memref that has a two-element padding at either end. The allocation </span></span></span><span class=line><span class=cl><span class=c>// size will fit 16 * 64 float elements of data. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%P</span> <span class=p>=</span> alloc<span class=p>()</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>16x64x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#padded</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Affine map with symbol 's0' used as offset for the first dimension. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#imapS</span> <span class=p>=</span> affine_map<span class=p><(</span>d0<span class=p>,</span> d1<span class=p>)</span> <span class=p>[</span>s0<span class=p>]</span> <span class=p>-></span> <span class=p>(</span>d0 <span class=err>+</span> s0<span class=p>,</span> d1<span class=p>)></span> </span></span><span class=line><span class=cl><span class=c>// Allocate memref and bind the following symbols: </span></span></span><span class=line><span class=cl><span class=c>// '%n' is bound to the dynamic second dimension of the memref type. </span></span></span><span class=line><span class=cl><span class=c>// '%o' is bound to the symbol 's0' in the affine map of the memref type. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%n</span> <span class=p>=</span> <span class=p>...</span> </span></span><span class=line><span class=cl><span class=nv>%o</span> <span class=p>=</span> <span class=p>...</span> </span></span><span class=line><span class=cl><span class=nv>%A</span> <span class=p>=</span> alloc <span class=p>(</span><span class=nv>%n</span><span class=p>)[</span><span class=nv>%o</span><span class=p>]</span> <span class=p>:</span> <span class=p><</span><span class=m>16x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#imapS</span><span class=p>></span> </span></span></code></pre></div><h4 id=parameters-24>Parameters: <a class=headline-hash href=#parameters-24>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>shape</td><td style=text-align:center><code>::llvm::ArrayRef<int64_t></code></td><td></td></tr><tr><td style=text-align:center>elementType</td><td style=text-align:center><code>Type</code></td><td></td></tr><tr><td style=text-align:center>layout</td><td style=text-align:center><code>MemRefLayoutAttrInterface</code></td><td></td></tr><tr><td style=text-align:center>memorySpace</td><td style=text-align:center><code>Attribute</code></td><td></td></tr></tbody></table><h3 id=nonetype>NoneType <a class=headline-hash href=#nonetype>¶</a></h3><p>A unit type</p><p>Syntax:</p><pre tabindex=0><code>none-type ::= `none` </code></pre><p>NoneType is a unit type, i.e. a type with exactly one possible value, where its value does not have a defined dynamic representation.</p><h4 id=example-4>Example: <a class=headline-hash href=#example-4>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@none_type</span><span class=p>()</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%none_val</span> <span class=p>=</span> <span class=s>"foo.unknown_op"</span><span class=p>()</span> <span class=p>:</span> <span class=p>()</span> <span class=p>-></span> none </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><h3 id=opaquetype>OpaqueType <a class=headline-hash href=#opaquetype>¶</a></h3><p>Type of a non-registered dialect</p><p>Syntax:</p><pre tabindex=0><code>opaque-type ::= `opaque` `<` type `>` </code></pre><p>Opaque types represent types of non-registered dialects. These are types represented in their raw string form, and can only usefully be tested for type equality.</p><h4 id=example-5>Example: <a class=headline-hash href=#example-5>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>opaque<span class=p><</span><span class=s>"llvm"</span><span class=p>,</span> <span class=s>"struct<(i32, float)>"</span><span class=p>></span> </span></span><span class=line><span class=cl>opaque<span class=p><</span><span class=s>"pdl"</span><span class=p>,</span> <span class=s>"value"</span><span class=p>></span> </span></span></code></pre></div><h4 id=parameters-25>Parameters: <a class=headline-hash href=#parameters-25>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>dialectNamespace</td><td style=text-align:center><code>StringAttr</code></td><td></td></tr><tr><td style=text-align:center>typeData</td><td style=text-align:center><code>::llvm::StringRef</code></td><td></td></tr></tbody></table><h3 id=rankedtensortype>RankedTensorType <a class=headline-hash href=#rankedtensortype>¶</a></h3><p>Multi-dimensional array with a fixed number of dimensions</p><p>Syntax:</p><pre tabindex=0><code>tensor-type ::= `tensor` `<` dimension-list type (`,` encoding)? `>` dimension-list ::= (dimension `x`)* dimension ::= `?` | decimal-literal encoding ::= attribute-value </code></pre><p>Values with tensor type represents aggregate N-dimensional data values, and have a known element type and a fixed rank with a list of dimensions. Each dimension may be a static non-negative decimal constant or be dynamically determined (indicated by <code>?</code>).</p><p>The runtime representation of the MLIR tensor type is intentionally abstracted - you cannot control layout or get a pointer to the data. For low level buffer access, MLIR has a <a href=#memreftype><code>memref</code> type</a>. This abstracted runtime representation holds both the tensor data values as well as information about the (potentially dynamic) shape of the tensor. The <a href=/docs/Dialects/MemRef/#memrefdim-mlirmemrefdimop><code>dim</code> operation</a> returns the size of a dimension from a value of tensor type.</p><p>The <code>encoding</code> attribute provides additional information on the tensor. An empty attribute denotes a straightforward tensor without any specific structure. But particular properties, like sparsity or other specific characteristics of the data of the tensor can be encoded through this attribute. The semantics are defined by a type and attribute interface and must be respected by all passes that operate on tensor types. TODO: provide this interface, and document it further.</p><p>Note: hexadecimal integer literals are not allowed in tensor type declarations to avoid confusion between <code>0xf32</code> and <code>0 x f32</code>. Zero sizes are allowed in tensors and treated as other sizes, e.g., <code>tensor<0 x 1 x i32></code> and <code>tensor<1 x 0 x i32></code> are different types. Since zero sizes are not allowed in some other types, such tensors should be optimized away before lowering tensors to vectors.</p><h4 id=example-6>Example: <a class=headline-hash href=#example-6>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Known rank but unknown dimensions. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>tensor</span><span class=p><</span><span class=m>? x</span> <span class=m>? x</span> <span class=m>? x</span> <span class=m>? x</span> <span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Partially known dimensions. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>tensor</span><span class=p><</span><span class=m>? x</span> <span class=m>? x</span> <span class=m>13 x</span> <span class=m>? x</span> <span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Full static shape. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>tensor</span><span class=p><</span><span class=m>17 x</span> <span class=m>4 x</span> <span class=m>13 x</span> <span class=m>4 x</span> <span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Tensor with rank zero. Represents a scalar. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>tensor</span><span class=p><</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Zero-element dimensions are allowed. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>tensor</span><span class=p><</span><span class=m>0</span> <span class=p>x</span> <span class=m>42 x</span> <span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Zero-element tensor of f32 type (hexadecimal literals not allowed here). </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>tensor</span><span class=p><</span><span class=m>0xf32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Tensor with an encoding attribute (where #ENCODING is a named alias). </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>tensor</span><span class=p><</span><span class=m>?x?x</span><span class=k>f64</span><span class=p>,</span> <span class=nv>#ENCODING</span><span class=p>></span> </span></span></code></pre></div><h4 id=parameters-26>Parameters: <a class=headline-hash href=#parameters-26>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>shape</td><td style=text-align:center><code>::llvm::ArrayRef<int64_t></code></td><td></td></tr><tr><td style=text-align:center>elementType</td><td style=text-align:center><code>Type</code></td><td></td></tr><tr><td style=text-align:center>encoding</td><td style=text-align:center><code>Attribute</code></td><td></td></tr></tbody></table><h3 id=tupletype>TupleType <a class=headline-hash href=#tupletype>¶</a></h3><p>Fixed-sized collection of other types</p><p>Syntax:</p><pre tabindex=0><code>tuple-type ::= `tuple` `<` (type ( `,` type)*)? `>` </code></pre><p>The value of <code>tuple</code> type represents a fixed-size collection of elements, where each element may be of a different type.</p><p><strong>Rationale:</strong> Though this type is first class in the type system, MLIR provides no standard operations for operating on <code>tuple</code> types ( <a href=../../Rationale/Rationale/#tuple-types>rationale</a>).</p><h4 id=example-7>Example: <a class=headline-hash href=#example-7>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Empty tuple. </span></span></span><span class=line><span class=cl><span class=c></span>tuple<span class=p><></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Single element </span></span></span><span class=line><span class=cl><span class=c></span>tuple<span class=p><</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Many elements. </span></span></span><span class=line><span class=cl><span class=c></span>tuple<span class=p><</span><span class=k>i32</span><span class=p>,</span> <span class=k>f32</span><span class=p>,</span> <span class=kt>tensor</span><span class=p><</span><span class=k>i1</span><span class=p>>,</span> <span class=k>i5</span><span class=p>></span> </span></span></code></pre></div><h4 id=parameters-27>Parameters: <a class=headline-hash href=#parameters-27>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>types</td><td style=text-align:center><code>ArrayRef<Type></code></td><td></td></tr></tbody></table><h3 id=unrankedmemreftype>UnrankedMemRefType <a class=headline-hash href=#unrankedmemreftype>¶</a></h3><p>Shaped reference, with unknown rank, to a region of memory</p><p>Syntax:</p><pre tabindex=0><code>unranked-memref-type ::= `memref` `<*x` type (`,` memory-space)? `>` memory-space ::= attribute-value </code></pre><p>A <code>memref</code> type with an unknown rank (e.g. <code>memref<*xf32></code>). The purpose of unranked memrefs is to allow external library functions to receive memref arguments of any rank without versioning the functions based on the rank. Other uses of this type are disallowed or will have undefined behavior.</p><p>See <a href=#memreftype>MemRefType</a> for more information on memref types.</p><h4 id=examples>Examples: <a class=headline-hash href=#examples>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>memref</span><span class=p><*</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// An unranked memref with a memory space of 10. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>memref</span><span class=p><*</span><span class=k>f32</span><span class=p>,</span> <span class=m>10</span><span class=p>></span> </span></span></code></pre></div><h4 id=parameters-28>Parameters: <a class=headline-hash href=#parameters-28>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>elementType</td><td style=text-align:center><code>Type</code></td><td></td></tr><tr><td style=text-align:center>memorySpace</td><td style=text-align:center><code>Attribute</code></td><td></td></tr></tbody></table><h3 id=unrankedtensortype>UnrankedTensorType <a class=headline-hash href=#unrankedtensortype>¶</a></h3><p>Multi-dimensional array with unknown dimensions</p><p>Syntax:</p><pre tabindex=0><code>tensor-type ::= `tensor` `<` `*` `x` type `>` </code></pre><p>An unranked tensor is a type of tensor in which the set of dimensions have unknown rank. See <a href=#rankedtensortype>RankedTensorType</a> for more information on tensor types.</p><h4 id=examples-1>Examples: <a class=headline-hash href=#examples-1>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>tensor</span><span class=p><*</span>xf32<span class=p>></span> </span></span></code></pre></div><h4 id=parameters-29>Parameters: <a class=headline-hash href=#parameters-29>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>elementType</td><td style=text-align:center><code>Type</code></td><td></td></tr></tbody></table><h3 id=vectortype>VectorType <a class=headline-hash href=#vectortype>¶</a></h3><p>Multi-dimensional SIMD vector type</p><p>Syntax:</p><pre tabindex=0><code>vector-type ::= `vector` `<` vector-dim-list vector-element-type `>` vector-element-type ::= float-type | integer-type | index-type vector-dim-list := (static-dim-list `x`)? static-dim-list ::= static-dim (`x` static-dim)* static-dim ::= (decimal-literal | `[` decimal-literal `]`) </code></pre><p>The vector type represents a SIMD style vector used by target-specific operation sets like AVX or SVE. While the most common use is for 1D vectors (e.g. vector<16 x f32>) we also support multidimensional registers on targets that support them (like TPUs). The dimensions of a vector type can be fixed-length, scalable, or a combination of the two. The scalable dimensions in a vector are indicated between square brackets ([ ]).</p><p>Vector shapes must be positive decimal integers. 0D vectors are allowed by omitting the dimension: <code>vector<f32></code>.</p><p>Note: hexadecimal integer literals are not allowed in vector type declarations, <code>vector<0x42xi32></code> is invalid because it is interpreted as a 2D vector with shape <code>(0, 42)</code> and zero shapes are not allowed.</p><h4 id=examples-2>Examples: <a class=headline-hash href=#examples-2>¶</a></h4><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// A 2D fixed-length vector of 3x42 i32 elements. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>vector</span><span class=p><</span><span class=m>3x42x</span><span class=k>i32</span><span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A 1D scalable-length vector that contains a multiple of 4 f32 elements. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>vector</span><span class=p><[</span><span class=m>4</span><span class=p>]</span>xf32<span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A 2D scalable-length vector that contains a multiple of 2x8 f32 elements. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>vector</span><span class=p><[</span><span class=m>2</span><span class=p>]x[</span><span class=m>8</span><span class=p>]</span>xf32<span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A 2D mixed fixed/scalable vector that contains 4 scalable vectors of 4 f32 elements. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=p>[</span><span class=m>4</span><span class=p>]</span>xf32<span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// A 3D mixed fixed/scalable vector in which only the inner dimension is </span></span></span><span class=line><span class=cl><span class=c>// scalable. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>vector</span><span class=p><</span><span class=m>2x</span><span class=p>[</span><span class=m>4</span><span class=p>]</span>x8xf32<span class=p>></span> </span></span></code></pre></div><h4 id=parameters-30>Parameters: <a class=headline-hash href=#parameters-30>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>shape</td><td style=text-align:center><code>::llvm::ArrayRef<int64_t></code></td><td></td></tr><tr><td style=text-align:center>elementType</td><td style=text-align:center><code>::mlir::Type</code></td><td>integer or index or floating-point</td></tr><tr><td style=text-align:center>scalableDims</td><td style=text-align:center><code>::llvm::ArrayRef<bool></code></td><td></td></tr></tbody></table><h2 id=type-interfaces>Type Interfaces <a class=headline-hash href=#type-interfaces>¶</a></h2><div class=edit-meta><br></div><nav class=pagination><a class="nav nav-prev" href=https://mlir.llvm.org/docs/Dialects/XeGPU/ title="'xegpu' Dialect"><i class="fas fa-arrow-left" aria-hidden=true></i> Prev - 'xegpu' Dialect</a> <a class="nav nav-next" href=https://mlir.llvm.org/docs/Dialects/MatchOpInterfaces/ title="OpInterface definitions">Next - OpInterface definitions <i class="fas fa-arrow-right" aria-hidden=true></i></a></nav><footer><p class=powered>Powered by <a href=https://gohugo.io>Hugo</a>. Theme by <a href=https://themes.gohugo.io/hugo-theme-techdoc/>TechDoc</a>. Designed by <a href=https://github.com/thingsym/hugo-theme-techdoc>Thingsym</a>.</p></footer></main><div class=sidebar><nav class=slide-menu><ul><li><a href=https://mlir.llvm.org/>Home</a></li><li><a href=https://mlir.llvm.org/users/>Users of MLIR</a></li><li><a href=https://mlir.llvm.org/pubs/>MLIR Related Publications</a></li><li><a href=https://mlir.llvm.org/talks/>Talks</a></li><li><a href=https://mlir.llvm.org/deprecation/>Deprecations & Current Refactoring</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/getting_started/>Getting Started<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/getting_started/ReportingIssues/>Reporting Issues</a></li><li><a href=https://mlir.llvm.org/getting_started/Debugging/>Debugging Tips</a></li><li><a href=https://mlir.llvm.org/getting_started/Faq/>FAQ</a></li><li><a href=https://mlir.llvm.org/getting_started/Contributing/>How to Contribute</a></li><li><a href=https://mlir.llvm.org/getting_started/DeveloperGuide/>Developer Guide</a></li><li><a href=https://mlir.llvm.org/getting_started/openprojects/>Open Projects</a></li><li><a href=https://mlir.llvm.org/getting_started/Glossary/>Glossary</a></li><li><a href=https://mlir.llvm.org/getting_started/TestingGuide/>Testing Guide</a></li></ul></li><li class="parent has-sub-menu"><a href=https://mlir.llvm.org/docs/>Code Documentation<span class="mark opened">-</span></a><ul class=sub-menu><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Bindings/>Bindings<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Bindings/Python/>MLIR Python Bindings</a></li></ul></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Tools/>Tools<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Tools/MLIRLSP/>MLIR : Language Server Protocol</a></li><li><a href=https://mlir.llvm.org/docs/Tools/mlir-reduce/>MLIR Reduce</a></li><li><a href=https://mlir.llvm.org/docs/Tools/mlir-rewrite/>mlir-rewrite</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/QuantPasses/></a></li><li><a href=https://mlir.llvm.org/docs/ActionTracing/>Action: Tracing and Debugging MLIR-based Compilers</a></li><li><a href=https://mlir.llvm.org/docs/BufferDeallocationInternals/>Buffer Deallocation - Internals</a></li><li><a href=https://mlir.llvm.org/docs/Bufferization/>Bufferization</a></li><li><a href=https://mlir.llvm.org/docs/DataLayout/>Data Layout Modeling</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/DefiningDialects/>Defining Dialects<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/DefiningDialects/Constraints/>Constraints</a></li><li><a href=https://mlir.llvm.org/docs/DefiningDialects/AttributesAndTypes/>Defining Dialect Attributes and Types</a></li><li><a href=https://mlir.llvm.org/docs/DefiningDialects/Operations/>Operation Definition Specification (ODS)</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Diagnostics/>Diagnostic Infrastructure</a></li><li><a href=https://mlir.llvm.org/docs/DialectConversion/>Dialect Conversion</a></li><li class="parent has-sub-menu"><a href=https://mlir.llvm.org/docs/Dialects/>Dialects<span class="mark opened">-</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Dialects/DLTITransformOps/></a></li><li><a href=https://mlir.llvm.org/docs/Dialects/OpenACCDialect/>'acc' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Affine/>'affine' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/AMDGPU/>'amdgpu' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/AMX/>'amx' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ArithOps/>'arith' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ArmNeon/>'arm_neon' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ArmSVE/>'arm_sve' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ArmSME/>'ArmSME' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/AsyncDialect/>'async' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/BufferizationOps/>'bufferization' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ControlFlowDialect/>'cf' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ComplexOps/>'complex' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/DLTIDialect/>'dlti' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/EmitC/>'emitc' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Func/>'func' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/GPU/>'gpu' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/IndexOps/>'index' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/IRDL/>'irdl' Dialect</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Dialects/Linalg/>'linalg' Dialect<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Dialects/Linalg/OpDSL/>Linalg OpDSL</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Dialects/LLVM/>'llvm' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MathOps/>'math' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MemRef/>'memref' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Mesh/>'mesh' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MLProgramOps/>'ml_program' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MPI/>'mpi' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/NVGPU/>'nvgpu' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/NVVMDialect/>'nvvm' Dialect</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Dialects/OpenMPDialect/>'omp' Dialect<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Dialects/OpenMPDialect/ODS/>ODS Documentation</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Dialects/PDLInterpOps/>'pdl_interp' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/PDLOps/>'pdl' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/PolynomialDialect/>'polynomial' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/PtrOps/>'ptr' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/QuantDialect/>'quant' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ROCDLDialect/>'rocdl' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/SCFDialect/>'scf' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ShapeDialect/>'shape' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/SparseTensorOps/>'sparse_tensor' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/TensorOps/>'tensor' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/UBOps/>'ub' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/VCIXDialect/>'vcix' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Vector/>'vector' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/X86Vector/>'x86vector' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/XeGPU/>'xegpu' Dialect</a></li><li class=active><a href=https://mlir.llvm.org/docs/Dialects/Builtin/>Builtin Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MatchOpInterfaces/>OpInterface definitions</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/SPIR-V/>SPIR-V Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/TOSA/>Tensor Operator Set Architecture (TOSA) Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Transform/>Transform Dialect</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Interfaces/>Interfaces</a></li><li><a href=https://mlir.llvm.org/docs/TargetLLVMIR/>LLVM IR Target</a></li><li><a href=https://mlir.llvm.org/docs/BytecodeFormat/>MLIR Bytecode Format</a></li><li><a href=https://mlir.llvm.org/docs/CAPI/>MLIR C API</a></li><li><a href=https://mlir.llvm.org/docs/LangRef/>MLIR Language Reference</a></li><li><a href=https://mlir.llvm.org/docs/ReleaseNotes/>MLIR Release Notes</a></li><li><a href=https://mlir.llvm.org/docs/Canonicalization/>Operation Canonicalization</a></li><li><a href=https://mlir.llvm.org/docs/OwnershipBasedBufferDeallocation/>Ownership-based Buffer Deallocation</a></li><li><a href=https://mlir.llvm.org/docs/PassManagement/>Pass Infrastructure</a></li><li><a href=https://mlir.llvm.org/docs/Passes/>Passes</a></li><li><a href=https://mlir.llvm.org/docs/PatternRewriter/>Pattern Rewriting : Generic DAG-to-DAG Rewriting</a></li><li><a href=https://mlir.llvm.org/docs/PDLL/>PDLL - PDL Language</a></li><li><a href=https://mlir.llvm.org/docs/Quantization/>Quantization</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Rationale/>Rationale<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Rationale/RationaleGenericDAGRewriter/>Generic DAG Rewriter Infrastructure Rationale</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/RationaleLinalgDialect/>Linalg Dialect Rationale: The Case For Compiler-Friendly Custom Operations</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/Rationale/>MLIR Rationale</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/MLIRForGraphAlgorithms/>MLIR: Incremental Application to Graph Algorithms in ML Frameworks</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/RationaleSimplifiedPolyhedralForm/>MLIR: The case for a simplified polyhedral form</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/SideEffectsAndSpeculation/>Side Effects & Speculation</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/UsageOfConst/>Usage of 'const' in MLIR, for core IR types</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/ShapeInference/>Shape Inference</a></li><li><a href=https://mlir.llvm.org/docs/SPIRVToLLVMDialectConversion/>SPIR-V Dialect to LLVM Dialect conversion manual</a></li><li><a href=https://mlir.llvm.org/docs/SymbolsAndSymbolTables/>Symbols and Symbol Tables</a></li><li><a href=https://mlir.llvm.org/docs/DeclarativeRewrites/>Table-driven Declarative Rewrite Rule (DRR)</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Traits/>Traits<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Traits/Broadcastable/>The `Broadcastable` Trait</a></li></ul></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Tutorials/>Tutorials<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Tutorials/CreatingADialect/>Creating a Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/QuickstartRewrites/>Quickstart tutorial to adding MLIR graph rewrite</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Tutorials/Toy/>Toy Tutorial<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-1/>Chapter 1: Toy Language and AST</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-2/>Chapter 2: Emitting Basic MLIR</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-3/>Chapter 3: High-level Language-Specific Analysis and Transformation</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-4/>Chapter 4: Enabling Generic Transformation with Interfaces</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-5/>Chapter 5: Partial Lowering to Lower-Level Dialects for Optimization</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-6/>Chapter 6: Lowering to LLVM and CodeGeneration</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-7/>Chapter 7: Adding a Composite Type to Toy</a></li></ul></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Tutorials/transform/>Transform Dialect Tutorial<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch0/>Chapter 0: A Primer on “Structured” Linalg Operations</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch1/>Chapter 1: Combining Existing Transformations</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch2/>Chapter 2: Adding a Simple New Transformation Operation</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch3/>Chapter 3: More than Simple Transform Operations</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch4/>Chapter 4: Matching Payload with Transform Operations</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/ChH/>Chapter H: Reproducing Halide Schedule</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Tutorials/UnderstandingTheIRStructure/>Understanding the IR Structure</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/MlirOpt/>Using `mlir-opt`</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/DataFlowAnalysis/>Writing DataFlow Analyses in MLIR</a></li></ul></li></ul></li></ul></nav><div class=sidebar-footer></div></div></div><a href=# id=backtothetop-fixed class=backtothetop data-backtothetop-duration=600 data-backtothetop-easing=easeOutQuart data-backtothetop-fixed-fadein=1000 data-backtothetop-fixed-fadeout=1000 data-backtothetop-fixed-bottom=10 data-backtothetop-fixed-right=20><span class="fa-layers fa-fw"><i class="fas fa-circle"></i> <i class="fas fa-arrow-circle-up"></i></span></a></div></body></html>