CINXE.COM

'bufferization' 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>'bufferization' 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/BufferizationOps/><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__&amp;list_id=177877&amp;order=changeddate%20DESC%2Cpriority%2Cbug_severity&amp;product=MLIR&amp;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>'bufferization' Dialect</h1><p>Bufferization in MLIR is the process of converting the <code>tensor</code> type to the <code>memref</code> type. Simply put, bufferization is the process of converting computations on the mathematical tensor construct to computations on physical memory buffers. The <code>bufferization</code> dialect contains operations/interfaces specific to the bufferization passes.</p><p>An overview of the bufferization infrastructure and important conceptual details related to using the MLIR dialect conversion infrastructure can be found in <a href=/docs/Bufferization/>bufferization</a> and <a href=/docs/OwnershipBasedBufferDeallocation/>ownership-based buffer deallocation</a>.</p><p><nav id=TableOfContents><ul><li><a href=#operations>Operations</a><ul><li><a href=#bufferizationalloc_tensor-bufferizationalloctensorop><code>bufferization.alloc_tensor</code> (bufferization::AllocTensorOp)</a></li><li><a href=#bufferizationclone-bufferizationcloneop><code>bufferization.clone</code> (bufferization::CloneOp)</a></li><li><a href=#bufferizationdealloc-bufferizationdeallocop><code>bufferization.dealloc</code> (bufferization::DeallocOp)</a></li><li><a href=#bufferizationdealloc_tensor-bufferizationdealloctensorop><code>bufferization.dealloc_tensor</code> (bufferization::DeallocTensorOp)</a></li><li><a href=#bufferizationmaterialize_in_destination-bufferizationmaterializeindestinationop><code>bufferization.materialize_in_destination</code> (bufferization::MaterializeInDestinationOp)</a></li><li><a href=#bufferizationto_memref-bufferizationtomemrefop><code>bufferization.to_memref</code> (bufferization::ToMemrefOp)</a></li><li><a href=#bufferizationto_tensor-bufferizationtotensorop><code>bufferization.to_tensor</code> (bufferization::ToTensorOp)</a></li></ul></li></ul></nav><h2 id=operations>Operations&nbsp;<a class=headline-hash href=#operations>¶</a></h2><p><a href=https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationOps.td>source</a></p><h3 id=bufferizationalloc_tensor-bufferizationalloctensorop><code>bufferization.alloc_tensor</code> (bufferization::AllocTensorOp)&nbsp;<a class=headline-hash href=#bufferizationalloc_tensor-bufferizationalloctensorop>¶</a></h3><p><em>Allocate buffer for a tensor</em></p><p><code>bufferization.alloc_tensor</code> materializes an uninitialized tensor with a given shape (dynamic or static). It always bufferizes to a new buffer allocation of the given shape. The optional <code>copy</code> operand specifies the contents of the tensors. If no <code>copy</code> operand is specified, reading from the result of an <code>alloc_tensor</code> op yields an undefined value.</p><p>If <code>copy</code> is specified, no dynamic sizes should be passed, since they are the same as the dynamic sizes of the <code>copy</code> operand.</p><p><code>alloc_tensor</code> is a helper op for bufferization. The operation is provided as an anchor that marks the beginning of a new tensor SSA use-def chain. It can be used to control in-place bufferization decisions during One-Shot Bufferize: The bufferized result of a <code>bufferization.alloc_tensor</code> does not alias with any other buffer, so it can be used to resolve read-after-write conflicts that would have been introduced by the in-place bufferization of another op.</p><p>The optional <code>memory_space</code> attribute specifies the memory space when bufferizing this op. The memory space is inferred from <code>copy</code> if specified. If neither <code>copy</code> nor <code>memory_space</code> is specified, the default memory space is used during bufferization.</p><p>The optional <code>size_hint</code> operand specifies the number of non-zero elements for sparse tensors. The value of <code>size_hint</code> should be not less than 1 and not larger than the linear size of the corresponding dense tensor type. If this requirement is not met, the behavior of the operator is undefined.</p><p>Both dense and sparse tensor types are supported. The result of a <code>bufferization.alloc_tensor</code> is a tensor value that can be used like any other tensor value. In practice, it is often used as the &ldquo;out&rdquo; operand of another op. Sparse tensor allocations should always be used in a local construction operation and never escape the function boundary directly.</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=nv>%c</span> <span class=p>=</span> bufferization<span class=p>.</span>alloc_tensor<span class=p>(</span><span class=nv>%d1</span><span class=p>,</span> <span class=nv>%d2</span><span class=p>)</span> <span class=p>:</span> <span class=kt>tensor</span><span class=p>&lt;</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#SparseMatrix</span><span class=p>&gt;</span> </span></span><span class=line><span class=cl><span class=nv>%0</span> <span class=p>=</span> linalg<span class=p>.</span>matmul </span></span><span class=line><span class=cl> ins<span class=p>(</span><span class=nv>%a</span><span class=p>,</span> <span class=nv>%b</span><span class=p>:</span> <span class=kt>tensor</span><span class=p>&lt;</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#SparseMatrix</span><span class=p>&gt;,</span> <span class=kt>tensor</span><span class=p>&lt;</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#SparseMatrix</span><span class=p>&gt;)</span> </span></span><span class=line><span class=cl> outs<span class=p>(</span><span class=nv>%c</span><span class=p>:</span> <span class=kt>tensor</span><span class=p>&lt;</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#SparseMatrix</span><span class=p>&gt;)</span> <span class=p>-&gt;</span> <span class=kt>tensor</span><span class=p>&lt;</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#SparseMatrix</span><span class=p>&gt;</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=kt>tensor</span><span class=p>&lt;</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#SparseMatrix</span><span class=p>&gt;</span> </span></span></code></pre></div><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=nv>%c</span> <span class=p>=</span> bufferization<span class=p>.</span>alloc_tensor<span class=p>(</span><span class=nv>%d1</span><span class=p>,</span> <span class=nv>%d2</span><span class=p>)</span> <span class=nl>size_hint =</span> <span class=nv>%noe</span> </span></span><span class=line><span class=cl> <span class=p>:</span> <span class=kt>tensor</span><span class=p>&lt;</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#SparseMatrix</span><span class=p>&gt;</span> </span></span></code></pre></div><p>Note: An <code>alloc_tensor</code> with a <code>copy</code> should also be expressed as an <code>alloc_tensor</code> without <code>copy</code>, followed by a <code>copy_tensor</code>.</p><p>Traits: <code>AttrSizedOperandSegments</code></p><p>Interfaces: <code>BufferizableOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes>Attributes:&nbsp;<a class=headline-hash href=#attributes>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>memory_space</code></td><td>::mlir::Attribute</td><td>any attribute</td></tr></table><h4 id=operands>Operands:&nbsp;<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>dynamic_sizes</code></td><td>variadic of index</td></tr><tr><td style=text-align:center><code>copy</code></td><td>tensor of any type values</td></tr><tr><td style=text-align:center><code>size_hint</code></td><td>index</td></tr></tbody></table><h4 id=results>Results:&nbsp;<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>result</code></td><td>tensor of any type values</td></tr></tbody></table><h3 id=bufferizationclone-bufferizationcloneop><code>bufferization.clone</code> (bufferization::CloneOp)&nbsp;<a class=headline-hash href=#bufferizationclone-bufferizationcloneop>¶</a></h3><p><em>Clone a memref</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `bufferization.clone` $input attr-dict `:` type($input) `to` type($output) </code></pre><p>Clones the data in the input view into an implicitly defined output view.</p><p>Usage:</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>%arg1</span> <span class=p>=</span> bufferization<span class=p>.</span>clone <span class=nv>%arg0</span> <span class=p>:</span> <span class=kt>memref</span><span class=p>&lt;</span><span class=m>?x</span><span class=k>f32</span><span class=p>&gt;</span> to <span class=kt>memref</span><span class=p>&lt;</span><span class=m>?x</span><span class=k>f32</span><span class=p>&gt;</span> </span></span></code></pre></div><p>Valid implementations of this operation may alias the input and output views or create an actual copy. Mutating the source or result of the clone operation after the clone operation thus leads to undefined behavior.</p><p>Interfaces: <code>AllocationOpInterface</code>, <code>CopyOpInterface</code>, <code>MemoryEffectsOpInterface</code></p><h4 id=operands-1>Operands:&nbsp;<a class=headline-hash href=#operands-1>¶</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>input</code></td><td>ranked or unranked memref of any type values</td></tr></tbody></table><h4 id=results-1>Results:&nbsp;<a class=headline-hash href=#results-1>¶</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>output</code></td><td>ranked or unranked memref of any type values</td></tr></tbody></table><h3 id=bufferizationdealloc-bufferizationdeallocop><code>bufferization.dealloc</code> (bufferization::DeallocOp)&nbsp;<a class=headline-hash href=#bufferizationdealloc-bufferizationdeallocop>¶</a></h3><p><em>Deallocates the given memrefs if no alias is retained</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `bufferization.dealloc` (` ``(` $memrefs^ `:` type($memrefs) `)` `if` ` ` `(` $conditions `)` )? (`retain` ` ` `(` $retained^ `:` type($retained) `)` )? attr-dict </code></pre><p>This operation deallocates each of the given memrefs if there is no alias to that memref in the list of retained memrefs and the corresponding condition value is set. This condition can be used to indicate and pass on ownership of memref values (or in other words, the responsibility of deallocating that memref). If two memrefs alias each other, only one will be deallocated to avoid double free situations.</p><p>The number of variadic <code>memref</code> operands (the memrefs to be deallocated) must equal the number of variadic <code>condition</code> operands and correspond to each other element-wise.</p><p>The <code>memref</code> operands must be the originally allocated memrefs, however, the <code>retained</code> memref operands may be arbitrary memrefs.</p><p>This operation returns a variadic number of <code>updatedConditions</code> operands, one updated condition per retained memref. An updated condition indicates the ownership of the respective retained memref. It is computed as the disjunction of all <code>conditions</code> operands where the corresponding to <code>memrefs</code> operand aliases with the retained memref. If the retained memref has no aliases among <code>memrefs</code>, the resulting updated condition is &lsquo;false&rsquo;. This is because all memrefs that need to be deallocated within one basic block should be added to the same <code>bufferization.dealloc</code> operation at the end of the block; if no aliasing memref is present, then it does not have to be deallocated and thus we don&rsquo;t need to claim ownership. If the memrefs to be deallocated are split over multiple dealloc operations (e.g., to avoid aliasing checks at runtime between the <code>memref</code> operands), then the results have to be manually combined using an <code>arith.ori</code> operation and all of them still require the same list of <code>retained</code> memref operands unless the (potentially empty) set of aliasing memrefs can be determined statically. In that case, the <code>updatedCondition</code> operand can be replaced accordingly (e.g., by a canonicalizer).</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=nv>%0</span><span class=p>:</span><span class=nl>3 =</span> bufferization<span class=p>.</span>dealloc <span class=p>(</span><span class=nv>%a0</span><span class=p>,</span> <span class=nv>%a1</span> <span class=p>:</span> <span class=kt>memref</span><span class=p>&lt;</span><span class=m>2x</span><span class=k>f32</span><span class=p>&gt;,</span> <span class=kt>memref</span><span class=p>&lt;</span><span class=m>4x</span><span class=k>i32</span><span class=p>&gt;)</span> </span></span><span class=line><span class=cl> if <span class=p>(</span><span class=nv>%cond0</span><span class=p>,</span> <span class=nv>%cond1</span><span class=p>)</span> retain <span class=p>(</span><span class=nv>%r0</span><span class=p>,</span> <span class=nv>%r1</span><span class=p>,</span> <span class=nv>%r2</span> <span class=p>:</span> <span class=kt>memref</span><span class=p>&lt;</span><span class=m>?x</span><span class=k>f32</span><span class=p>&gt;,</span> <span class=kt>memref</span><span class=p>&lt;</span><span class=k>f64</span><span class=p>&gt;,</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p>&lt;</span><span class=m>2x</span><span class=k>i32</span><span class=p>&gt;)</span> </span></span></code></pre></div><p>Deallocation will be called on <code>%a0</code> if <code>%cond0</code> is &rsquo;true&rsquo; and neither <code>%r0</code>, <code>%r1</code>, or <code>%r2</code> are aliases of <code>%a0</code>. <code>%a1</code> will be deallocated when <code>%cond1</code> is set to &rsquo;true&rsquo; and none of <code>%r0</code>, <code>%r1</code>, <code>%r2</code>, and <code>%a0</code> are aliases.</p><p>Note that this can be an expensive operation if there are many operands that cannot be optimized away. The runtime cost of this operation (assuming that nothing is optimized away) is <code>O(|memrefs|^2+|memrefs|*|retained|)</code>. The cost in terms of memory space is <code>O(|memrefs|+|retained|)</code>. As a result, it is recommended to place it carefully in the IR such that most operands can be optimized away by running the <code>buffer-deallocation-simplification</code> pass.</p><p>Traits: <code>AttrSizedOperandSegments</code></p><p>Interfaces: <code>InferTypeOpInterface</code></p><h4 id=operands-2>Operands:&nbsp;<a class=headline-hash href=#operands-2>¶</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>memrefs</code></td><td>variadic of ranked or unranked memref of any type values</td></tr><tr><td style=text-align:center><code>conditions</code></td><td>variadic of 1-bit signless integer</td></tr><tr><td style=text-align:center><code>retained</code></td><td>variadic of ranked or unranked memref of any type values</td></tr></tbody></table><h4 id=results-2>Results:&nbsp;<a class=headline-hash href=#results-2>¶</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>updatedConditions</code></td><td>variadic of 1-bit signless integer</td></tr></tbody></table><h3 id=bufferizationdealloc_tensor-bufferizationdealloctensorop><code>bufferization.dealloc_tensor</code> (bufferization::DeallocTensorOp)&nbsp;<a class=headline-hash href=#bufferizationdealloc_tensor-bufferizationdealloctensorop>¶</a></h3><p><em>Release underlying storage format of given tensor</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `bufferization.dealloc_tensor` $tensor attr-dict `:` type($tensor) </code></pre><p><code>bufferization.dealloc_tensor</code> is a buffer deallocation in tensor land. This op can be used for manual buffer deallocation. Some bufferizations (such as One-Shot Bufferize) take care of buffer deallocation, in which case this op is usually not needed. Details can be found in the documentation of the respective bufferization passes.</p><p>In case of a dense tensor, this op lowers to a <code>memref.dealloc</code> op during bufferization.</p><p>In case of a sparse tensor, this op releases the underlying sparse storage format for a tensor that materialized earlier through a <code>new</code> operation, a <code>convert</code> operation with annotated destination tensor type (unless the convert is folded away), or a <code>bufferization.alloc_tensor</code> operation. The release operation should only be called once for any materialized tensor. After this operation, any subsequent <code>memref</code> querying operation on the tensor returns undefined results.</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>bufferization<span class=p>.</span>dealloc_tensor <span class=nv>%tensor</span> <span class=p>:</span> <span class=kt>tensor</span><span class=p>&lt;</span><span class=m>1024x1024x</span><span class=k>f64</span><span class=p>,</span> <span class=nv>#CSR</span><span class=p>&gt;</span> </span></span></code></pre></div><p>Interfaces: <code>BufferizableOpInterface</code></p><h4 id=operands-3>Operands:&nbsp;<a class=headline-hash href=#operands-3>¶</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>tensor</code></td><td>tensor of any type values</td></tr></tbody></table><h3 id=bufferizationmaterialize_in_destination-bufferizationmaterializeindestinationop><code>bufferization.materialize_in_destination</code> (bufferization::MaterializeInDestinationOp)&nbsp;<a class=headline-hash href=#bufferizationmaterialize_in_destination-bufferizationmaterializeindestinationop>¶</a></h3><p><em>Copy a tensor</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `bufferization.materialize_in_destination` $source `in` (`restrict` $restrict^)? (`writable` $writable^)? $dest attr-dict `:` functional-type(operands, results) </code></pre><p>This op indicates that the data of the <code>source</code> tensor is guaranteed to materialize in <code>dest</code>, which can be a tensor or a memref. In case of a tensor, <code>source</code> materializes in the future buffer of <code>dest</code> and a the updated destination tensor is returned. If this is not possible, e.g., because the destination tensor is read-only or because its original contents are still read later, the input IR fails to bufferize. In case of a memref, <code>source</code> materializes in <code>dest</code>, which is already a buffer. The op has no results in that case.</p><p><code>source</code>, <code>dest</code> and <code>result</code> (if present) must have the same runtime shape and element type. If the op has a result, the types of <code>result</code> and <code>dest</code> must match exactly (e.g., including any tensor encodings).</p><p>By default, this op bufferizes to a memcpy from the future buffer of the <code>source</code> tensor to the future buffer of the <code>dest</code> tensor or to the <code>dest</code> buffer. However, transformations such as &ldquo;empty tensor elimination&rdquo; may rewrite IR such that a computation is performed directly in <code>dest</code> and no memcpy is needed.</p><p>If <code>dest</code> is a buffer, the <code>writable</code> attribute must be specified and the <code>restrict</code> keyword can be specified. These attributes have the same meaning as the respective attributes of <code>bufferization.to_tensor</code>.</p><p><code>writable</code> indicates that the <code>dest</code> buffer is considered writable. It does not make sense to materialize a computation in a read-only buffer, so <code>writable</code> is required.</p><p><code>restrict</code> indicates that there is no <code>bufferization.to_tensor</code> op and no other <code>bufferization.materialize_in_destination</code> op with <code>dest</code> (or an alias thereof) and &ldquo;restrict&rdquo;. Only ops with this attribute are considered for &ldquo;empty tensor elimination&rdquo;. As part of empty tensor elimination, a new <code>to_tensor</code> op with <code>dest</code> may be inserted and the <code>restrict</code> attribute is transferred from this op to the new <code>to_tensor</code> op. Having &ldquo;restrict&rdquo; on this op guarantees that performing empty tensor elimination would not create invalid IR (i.e., having multiple <code>to_tensor restrict</code> with aliasing buffers).</p><p>Note: <code>writable</code> could be removed from this op because it must always be set for memref destinations. This op has that attribute to make clear the requirements on the <code>dest</code> operand in the op assembly format.</p><p>Note: If <code>dest</code> is a tensor, <code>tensor.insert_slice</code> could be used for the same purpose, but since tensor dialect ops only indicate <em>what</em> should be computed but not <em>where</em>, it could fold away, causing the computation to materialize in a different buffer.</p><p>Interfaces: <code>BufferizableOpInterface</code>, <code>DestinationStyleOpInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code>, <code>SubsetInsertionOpInterface</code>, <code>SubsetOpInterface</code></p><h4 id=attributes-1>Attributes:&nbsp;<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>restrict</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr><tr><td><code>writable</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr></table><h4 id=operands-4>Operands:&nbsp;<a class=headline-hash href=#operands-4>¶</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>source</code></td><td>tensor of any type values</td></tr><tr><td style=text-align:center><code>dest</code></td><td>shaped of any type values</td></tr></tbody></table><h4 id=results-3>Results:&nbsp;<a class=headline-hash href=#results-3>¶</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>result</code></td><td>tensor of any type values</td></tr></tbody></table><h3 id=bufferizationto_memref-bufferizationtomemrefop><code>bufferization.to_memref</code> (bufferization::ToMemrefOp)&nbsp;<a class=headline-hash href=#bufferizationto_memref-bufferizationtomemrefop>¶</a></h3><p><em>Cast a tensor to memref</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `bufferization.to_memref` $tensor (`read_only` $read_only^)? attr-dict `:` type($memref) </code></pre><p>An operation that returns the future buffer of a <code>tensor</code>.</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>// Result type is memref&lt;4x?xf32, #layout, 0&gt; </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%m</span> <span class=p>=</span> bufferization<span class=p>.</span>to_memref <span class=nv>%t</span> <span class=p>:</span> <span class=kt>memref</span><span class=p>&lt;</span><span class=m>4x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#layout</span><span class=p>,</span> <span class=m>0</span><span class=p>&gt;</span> </span></span></code></pre></div><p>This operation is a specialized variant of the built-in <code>unrealized_conversion_cast</code> and is used to make sure that the IR stays valid at any point during the bufferization.</p><p>The <code>read_only</code> attribute can optionally be set, indicating to the bufferization that the buffer returned by this op (or an alias created from the returned buffer) will not be written to.</p><p>Traits: <code>AlwaysSpeculatableImplTrait</code>, <code>SameOperandsAndResultElementType</code>, <code>SameOperandsAndResultShape</code></p><p>Interfaces: <code>BufferizableOpInterface</code>, <code>ConditionallySpeculatable</code>, <code>NoMemoryEffect (MemoryEffectOpInterface)</code></p><p>Effects: <code>MemoryEffects::Effect{}</code></p><h4 id=attributes-2>Attributes:&nbsp;<a class=headline-hash href=#attributes-2>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>read_only</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr></table><h4 id=operands-5>Operands:&nbsp;<a class=headline-hash href=#operands-5>¶</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>tensor</code></td><td>tensor of any type values</td></tr></tbody></table><h4 id=results-4>Results:&nbsp;<a class=headline-hash href=#results-4>¶</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>memref</code></td><td>ranked or unranked memref of any type values</td></tr></tbody></table><h3 id=bufferizationto_tensor-bufferizationtotensorop><code>bufferization.to_tensor</code> (bufferization::ToTensorOp)&nbsp;<a class=headline-hash href=#bufferizationto_tensor-bufferizationtotensorop>¶</a></h3><p><em>Create a tensor from a <code>memref</code></em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `bufferization.to_tensor` $memref (`restrict` $restrict^)? (`writable` $writable^)? attr-dict `:` type($memref) </code></pre><p>An operation that creates a tensor from a <code>memref</code>. The result value is a tensor whose shape and element type match the memref operand.</p><p>The opposite of this op is <code>to_memref</code>. Together, these two ops are useful for source/target materializations when doing type conversions involving tensors and memrefs.</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>// Produces a value of tensor&lt;4x?xf32&gt; type. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%t</span> <span class=p>=</span> bufferization<span class=p>.</span>to_tensor <span class=nv>%m</span> <span class=p>:</span> <span class=kt>memref</span><span class=p>&lt;</span><span class=m>4x?x</span><span class=k>f32</span><span class=p>,</span> <span class=nv>#layout</span><span class=p>,</span> <span class=m>0</span><span class=p>&gt;</span> </span></span></code></pre></div><p>If the <code>writable</code> unit attribute is set, the produced tensor is considered &ldquo;writable&rdquo; during bufferization. Otherwise, every OpOperand that bufferizes to a write to the future buffer of the resulting tensor (or an alias thereof) will bufferize out-of-place to prevent emitting any writes to <code>memref</code> during bufferization.</p><p>The <code>restrict</code> unit attribute (similar to the C <code>restrict</code> keyword) indicates that the produced tensor result is the only way for the tensor IR to gain access to the <code>memref</code> operand (or an alias thereof). E.g., there must be no other <code>to_tensor</code> op with the same or with an aliasing <code>memref</code> operand.</p><p>Note: Only <code>to_tensor</code> ops with the <code>restrict</code> unit attribute are supported by One-Shot Bufferize. Other IR is rejected. (To support <code>to_tensor</code> without <code>restrict</code>, One-Shot Bufferize would have to analyze memref IR.) Ops that have incorrect usage of <code>restrict</code> may bufferize incorrectly.</p><p>Example:</p><pre tabindex=0><code>%t = bufferization.to_tensor %m restrict writable : memref&lt;4xf32&gt; // %t is writable, so the tensor.insert may bufferize in-place in the // absence of other conflicts. %r = tensor.insert %f into %t[%idx] : tensor&lt;4xf32&gt; </code></pre><p><code>to_tensor</code> ops are not bufferized. They are expected to fold away after bufferization. If there are non-bufferizable ops in the IR and <code>allowUnknownOps</code> is set, they may be part of the resulting IR and not fold away. However, such IR is no longer bufferizable with One-Shot Bufferize.</p><p>Traits: <code>SameOperandsAndResultElementType</code>, <code>SameOperandsAndResultShape</code></p><p>Interfaces: <code>BufferizableOpInterface</code>, <code>InferTypeOpInterface</code></p><h4 id=attributes-3>Attributes:&nbsp;<a class=headline-hash href=#attributes-3>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>restrict</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr><tr><td><code>writable</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr></table><h4 id=operands-6>Operands:&nbsp;<a class=headline-hash href=#operands-6>¶</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>memref</code></td><td>ranked or unranked memref of any type values</td></tr></tbody></table><h4 id=results-5>Results:&nbsp;<a class=headline-hash href=#results-5>¶</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>result</code></td><td>tensor of any type values</td></tr></tbody></table><div class=edit-meta><br></div><nav class=pagination><a class="nav nav-prev" href=https://mlir.llvm.org/docs/Dialects/AsyncDialect/ title="'async' Dialect"><i class="fas fa-arrow-left" aria-hidden=true></i> Prev - 'async' Dialect</a> <a class="nav nav-next" href=https://mlir.llvm.org/docs/Dialects/ControlFlowDialect/ title="'cf' Dialect">Next - 'cf' Dialect <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 class=active><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><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>

Pages: 1 2 3 4 5 6 7 8 9 10