CINXE.COM

Traits - 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>Traits - 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/Traits/><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>Traits</h1><p><nav id=TableOfContents><ul><li><a href=#defining-a-trait>Defining a Trait</a><ul><li><a href=#extra-declarations-and-definitions>Extra Declarations and Definitions</a></li><li><a href=#parametric-traits>Parametric Traits</a></li></ul></li><li><a href=#attaching-a-trait>Attaching a Trait</a><ul><li><a href=#attaching-operation-traits-in-ods>Attaching Operation Traits in ODS</a></li></ul></li><li><a href=#using-a-trait>Using a Trait</a></li><li><a href=#operation-traits-list>Operation Traits List</a><ul><li><a href=#affinescope>AffineScope</a></li><li><a href=#automaticallocationscope>AutomaticAllocationScope</a></li><li><a href=#broadcastable>Broadcastable</a></li><li><a href=#commutative>Commutative</a></li><li><a href=#elementwisemappable>ElementwiseMappable</a></li><li><a href=#hasparent>HasParent</a></li><li><a href=#isolatedfromabove>IsolatedFromAbove</a></li><li><a href=#memrefsnormalizable>MemRefsNormalizable</a></li><li><a href=#single-block-region>Single Block Region</a></li><li><a href=#single-block-with-implicit-terminator>Single Block with Implicit Terminator</a></li><li><a href=#symboltable>SymbolTable</a></li><li><a href=#terminator>Terminator</a></li></ul></li></ul></nav><p>MLIR allows for a truly open ecosystem, as any dialect may define attributes, operations, and types that suit a specific level of abstraction. <code>Traits</code> are a mechanism which abstracts implementation details and properties that are common across many different attributes/operations/types/etc.. <code>Traits</code> may be used to specify special properties and constraints of the object, including whether an operation has side effects or that its output has the same type as the input. Some examples of operation traits are <code>Commutative</code>, <code>SingleResult</code>, <code>Terminator</code>, etc. See the more comprehensive list of <a href=#operation-traits-list>operation traits</a> below for more examples of what is possible.</p><h2 id=defining-a-trait>Defining a Trait</h2><p>Traits may be defined in C++ by inheriting from the <code>TraitBase&lt;ConcreteType, TraitType></code> class for the specific IR type. For attributes, this is <code>AttributeTrait::TraitBase</code>. For operations, this is <code>OpTrait::TraitBase</code>. For types, this is <code>TypeTrait::TraitBase</code>. This base class takes as template parameters:</p><ul><li>ConcreteType<ul><li>The concrete class type that this trait was attached to.</li></ul></li><li>TraitType<ul><li>The type of the trait class that is being defined, for use with the <a href=https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern><code>Curiously Recurring Template Pattern</code></a>.</li></ul></li></ul><p>A derived trait class is expected to take a single template that corresponds to the <code>ConcreteType</code>. An example trait definition is shown below:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-c++ data-lang=c++><span class=line><span class=cl><span class=k>template</span> <span class=o>&lt;</span><span class=k>typename</span> <span class=n>ConcreteType</span><span class=o>&gt;</span> </span></span><span class=line><span class=cl><span class=k>class</span> <span class=nc>MyTrait</span> <span class=o>:</span> <span class=k>public</span> <span class=n>TraitBase</span><span class=o>&lt;</span><span class=n>ConcreteType</span><span class=p>,</span> <span class=n>MyTrait</span><span class=o>&gt;</span> <span class=p>{</span> </span></span><span class=line><span class=cl><span class=p>};</span> </span></span></code></pre></div><p>Operation traits may also provide a <code>verifyTrait</code> or <code>verifyRegionTrait</code> hook that is called when verifying the concrete operation. The difference between these two is that whether the verifier needs to access the regions, if so, the operations in the regions will be verified before the verification of this trait. The <a href=/docs/DefiningDialects/Operations/#verification-ordering>verification order</a> determines when a verifier will be invoked.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-c++ data-lang=c++><span class=line><span class=cl><span class=k>template</span> <span class=o>&lt;</span><span class=k>typename</span> <span class=n>ConcreteType</span><span class=o>&gt;</span> </span></span><span class=line><span class=cl><span class=k>class</span> <span class=nc>MyTrait</span> <span class=o>:</span> <span class=k>public</span> <span class=n>OpTrait</span><span class=o>::</span><span class=n>TraitBase</span><span class=o>&lt;</span><span class=n>ConcreteType</span><span class=p>,</span> <span class=n>MyTrait</span><span class=o>&gt;</span> <span class=p>{</span> </span></span><span class=line><span class=cl><span class=k>public</span><span class=o>:</span> </span></span><span class=line><span class=cl> <span class=c1>/// Override the &#39;verifyTrait&#39; hook to add additional verification on the </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=c1>/// concrete operation. </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=k>static</span> <span class=n>LogicalResult</span> <span class=n>verifyTrait</span><span class=p>(</span><span class=n>Operation</span> <span class=o>*</span><span class=n>op</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=c1>// ... </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=p>}</span> </span></span><span class=line><span class=cl><span class=p>};</span> </span></span></code></pre></div><p>Note: It is generally good practice to define the implementation of the <code>verifyTrait</code> or <code>verifyRegionTrait</code> hook out-of-line as a free function when possible to avoid instantiating the implementation for every concrete operation type.</p><p>Operation traits may also provide a <code>foldTrait</code> hook that is called when folding the concrete operation. The trait folders will only be invoked if the concrete operation fold is either not implemented, fails, or performs an in-place fold.</p><p>The following signature of fold will be called if it is implemented and the op has a single result.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-c++ data-lang=c++><span class=line><span class=cl><span class=k>template</span> <span class=o>&lt;</span><span class=k>typename</span> <span class=n>ConcreteType</span><span class=o>&gt;</span> </span></span><span class=line><span class=cl><span class=k>class</span> <span class=nc>MyTrait</span> <span class=o>:</span> <span class=k>public</span> <span class=n>OpTrait</span><span class=o>::</span><span class=n>TraitBase</span><span class=o>&lt;</span><span class=n>ConcreteType</span><span class=p>,</span> <span class=n>MyTrait</span><span class=o>&gt;</span> <span class=p>{</span> </span></span><span class=line><span class=cl><span class=k>public</span><span class=o>:</span> </span></span><span class=line><span class=cl> <span class=c1>/// Override the &#39;foldTrait&#39; hook to support trait based folding on the </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=c1>/// concrete operation. </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=k>static</span> <span class=n>OpFoldResult</span> <span class=n>foldTrait</span><span class=p>(</span><span class=n>Operation</span> <span class=o>*</span><span class=n>op</span><span class=p>,</span> <span class=n>ArrayRef</span><span class=o>&lt;</span><span class=n>Attribute</span><span class=o>&gt;</span> <span class=n>operands</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=c1>// ... </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=p>}</span> </span></span><span class=line><span class=cl><span class=p>};</span> </span></span></code></pre></div><p>Otherwise, if the operation has a single result and the above signature is not implemented, or the operation has multiple results, then the following signature will be used (if implemented):</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-c++ data-lang=c++><span class=line><span class=cl><span class=k>template</span> <span class=o>&lt;</span><span class=k>typename</span> <span class=n>ConcreteType</span><span class=o>&gt;</span> </span></span><span class=line><span class=cl><span class=k>class</span> <span class=nc>MyTrait</span> <span class=o>:</span> <span class=k>public</span> <span class=n>OpTrait</span><span class=o>::</span><span class=n>TraitBase</span><span class=o>&lt;</span><span class=n>ConcreteType</span><span class=p>,</span> <span class=n>MyTrait</span><span class=o>&gt;</span> <span class=p>{</span> </span></span><span class=line><span class=cl><span class=k>public</span><span class=o>:</span> </span></span><span class=line><span class=cl> <span class=c1>/// Override the &#39;foldTrait&#39; hook to support trait based folding on the </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=c1>/// concrete operation. </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=k>static</span> <span class=n>LogicalResult</span> <span class=n>foldTrait</span><span class=p>(</span><span class=n>Operation</span> <span class=o>*</span><span class=n>op</span><span class=p>,</span> <span class=n>ArrayRef</span><span class=o>&lt;</span><span class=n>Attribute</span><span class=o>&gt;</span> <span class=n>operands</span><span class=p>,</span> </span></span><span class=line><span class=cl> <span class=n>SmallVectorImpl</span><span class=o>&lt;</span><span class=n>OpFoldResult</span><span class=o>&gt;</span> <span class=o>&amp;</span><span class=n>results</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=c1>// ... </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=p>}</span> </span></span><span class=line><span class=cl><span class=p>};</span> </span></span></code></pre></div><p>Note: It is generally good practice to define the implementation of the <code>foldTrait</code> hook out-of-line as a free function when possible to avoid instantiating the implementation for every concrete operation type.</p><h3 id=extra-declarations-and-definitions>Extra Declarations and Definitions</h3><p>A trait may require additional declarations and definitions directly on the Operation, Attribute or Type instances which specify that trait. The <code>extraConcreteClassDeclaration</code> and <code>extraConcreteClassDefinition</code> fields under the <code>NativeTrait</code> class are mechanisms designed for injecting code directly into generated C++ Operation, Attribute or Type classes.</p><p>Code within the <code>extraConcreteClassDeclaration</code> field will be formatted and copied into the generated C++ Operation, Attribute or Type class. Code within <code>extraConcreteClassDefinition</code> will be added to the generated source file inside the class’s C++ namespace. The substitution <code>$cppClass</code> is replaced by the C++ class name.</p><p>The intention is to group trait specific logic together and reduce redundant extra declarations and definitions on the instances themselves.</p><h3 id=parametric-traits>Parametric Traits</h3><p>The above demonstrates the definition of a simple self-contained trait. It is also often useful to provide some static parameters to the trait to control its behavior. Given that the definition of the trait class is rigid, i.e. we must have a single template argument for the concrete object, the templates for the parameters will need to be split out. An example is shown below:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-c++ data-lang=c++><span class=line><span class=cl><span class=k>template</span> <span class=o>&lt;</span><span class=kt>int</span> <span class=n>Parameter</span><span class=o>&gt;</span> </span></span><span class=line><span class=cl><span class=k>class</span> <span class=nc>MyParametricTrait</span> <span class=p>{</span> </span></span><span class=line><span class=cl><span class=k>public</span><span class=o>:</span> </span></span><span class=line><span class=cl> <span class=k>template</span> <span class=o>&lt;</span><span class=k>typename</span> <span class=n>ConcreteType</span><span class=o>&gt;</span> </span></span><span class=line><span class=cl> <span class=k>class</span> <span class=nc>Impl</span> <span class=o>:</span> <span class=k>public</span> <span class=n>TraitBase</span><span class=o>&lt;</span><span class=n>ConcreteType</span><span class=p>,</span> <span class=n>Impl</span><span class=o>&gt;</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=c1>// Inside of &#39;Impl&#39; we have full access to the template parameters </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=c1>// specified above. </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=p>};</span> </span></span><span class=line><span class=cl><span class=p>};</span> </span></span></code></pre></div><h2 id=attaching-a-trait>Attaching a Trait</h2><p>Traits may be used when defining a derived object type, by simply appending the name of the trait class to the end of the base object class operation type:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-c++ data-lang=c++><span class=line><span class=cl><span class=c1>/// Here we define &#39;MyAttr&#39; along with the &#39;MyTrait&#39; and `MyParametric trait </span></span></span><span class=line><span class=cl><span class=c1>/// classes we defined previously. </span></span></span><span class=line><span class=cl><span class=c1></span><span class=k>class</span> <span class=nc>MyAttr</span> <span class=o>:</span> <span class=k>public</span> <span class=n>Attribute</span><span class=o>::</span><span class=n>AttrBase</span><span class=o>&lt;</span><span class=n>MyAttr</span><span class=p>,</span> <span class=p>...,</span> <span class=n>MyTrait</span><span class=p>,</span> <span class=n>MyParametricTrait</span><span class=o>&lt;</span><span class=mi>10</span><span class=o>&gt;::</span><span class=n>Impl</span><span class=o>&gt;</span> <span class=p>{};</span> </span></span><span class=line><span class=cl><span class=c1>/// Here we define &#39;MyOp&#39; along with the &#39;MyTrait&#39; and `MyParametric trait </span></span></span><span class=line><span class=cl><span class=c1>/// classes we defined previously. </span></span></span><span class=line><span class=cl><span class=c1></span><span class=k>class</span> <span class=nc>MyOp</span> <span class=o>:</span> <span class=k>public</span> <span class=n>Op</span><span class=o>&lt;</span><span class=n>MyOp</span><span class=p>,</span> <span class=n>MyTrait</span><span class=p>,</span> <span class=n>MyParametricTrait</span><span class=o>&lt;</span><span class=mi>10</span><span class=o>&gt;::</span><span class=n>Impl</span><span class=o>&gt;</span> <span class=p>{};</span> </span></span><span class=line><span class=cl><span class=c1>/// Here we define &#39;MyType&#39; along with the &#39;MyTrait&#39; and `MyParametric trait </span></span></span><span class=line><span class=cl><span class=c1>/// classes we defined previously. </span></span></span><span class=line><span class=cl><span class=c1></span><span class=k>class</span> <span class=nc>MyType</span> <span class=o>:</span> <span class=k>public</span> <span class=n>Type</span><span class=o>::</span><span class=n>TypeBase</span><span class=o>&lt;</span><span class=n>MyType</span><span class=p>,</span> <span class=p>...,</span> <span class=n>MyTrait</span><span class=p>,</span> <span class=n>MyParametricTrait</span><span class=o>&lt;</span><span class=mi>10</span><span class=o>&gt;::</span><span class=n>Impl</span><span class=o>&gt;</span> <span class=p>{};</span> </span></span></code></pre></div><h3 id=attaching-operation-traits-in-ods>Attaching Operation Traits in ODS</h3><p>To use an operation trait in the <a href=/docs/DefiningDialects/Operations/>ODS</a> framework, we need to provide a definition of the trait class. This can be done using the <code>NativeOpTrait</code> and <code>ParamNativeOpTrait</code> classes. <code>ParamNativeOpTrait</code> provides a mechanism in which to specify arguments to a parametric trait class with an internal <code>Impl</code>.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-tablegen data-lang=tablegen><span class=line><span class=cl><span class=c>// The argument is the c++ trait class name. </span></span></span><span class=line><span class=cl><span class=c></span><span class=k>def</span> <span class=nv>MyTrait</span> <span class=p>:</span> <span class=nv>NativeOpTrait</span><span class=p>&lt;</span><span class=s>&#34;MyTrait&#34;</span><span class=p>&gt;;</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// The first argument is the parent c++ class name. The second argument is a </span></span></span><span class=line><span class=cl><span class=c>// string containing the parameter list. </span></span></span><span class=line><span class=cl><span class=c></span><span class=k>class</span> <span class=nv>MyParametricTrait</span><span class=p>&lt;</span><span class=k>int</span> <span class=nv>prop</span><span class=p>&gt;</span> </span></span><span class=line><span class=cl> <span class=p>:</span> <span class=nv>NativeOpTrait</span><span class=p>&lt;</span><span class=s>&#34;MyParametricTrait&#34;</span><span class=p>,</span> <span class=p>!</span><span class=nv>cast</span><span class=p>&lt;</span><span class=k>string</span><span class=p>&gt;(!</span><span class=nv>head</span><span class=p>(</span><span class=nv>parameters</span><span class=p>))&gt;;</span> </span></span></code></pre></div><p>These can then be used in the <code>traits</code> list of an op definition:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-tablegen data-lang=tablegen><span class=line><span class=cl><span class=k>def</span> <span class=nv>OpWithInferTypeInterfaceOp</span> <span class=p>:</span> <span class=nv>Op</span><span class=p>&lt;...[</span><span class=nv>MyTrait</span><span class=p>,</span> <span class=nv>MyParametricTrait</span><span class=p>&lt;</span><span class=m>10</span><span class=p>&gt;]&gt;</span> <span class=p>{</span> <span class=p>...</span> <span class=p>}</span> </span></span></code></pre></div><p>See the documentation on <a href=/docs/DefiningDialects/Operations/>operation definitions</a> for more details.</p><h2 id=using-a-trait>Using a Trait</h2><p>Traits may be used to provide additional methods, static fields, or other information directly on the concrete object. <code>Traits</code> internally become <code>Base</code> classes of the concrete operation, so all of these are directly accessible. To expose this information opaquely to transformations and analyses, <a href=/docs/Interfaces/><code>interfaces</code></a> may be used.</p><p>To query if a specific object contains a specific trait, the <code>hasTrait&lt;></code> method may be used. This takes as a template parameter the trait class, which is the same as the one passed when attaching the trait to an operation.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-c++ data-lang=c++><span class=line><span class=cl><span class=n>Operation</span> <span class=o>*</span><span class=n>op</span> <span class=o>=</span> <span class=p>..;</span> </span></span><span class=line><span class=cl><span class=k>if</span> <span class=p>(</span><span class=n>op</span><span class=o>-&gt;</span><span class=n>hasTrait</span><span class=o>&lt;</span><span class=n>MyTrait</span><span class=o>&gt;</span><span class=p>()</span> <span class=o>||</span> <span class=n>op</span><span class=o>-&gt;</span><span class=n>hasTrait</span><span class=o>&lt;</span><span class=n>MyParametricTrait</span><span class=o>&lt;</span><span class=mi>10</span><span class=o>&gt;::</span><span class=n>Impl</span><span class=o>&gt;</span><span class=p>())</span> </span></span><span class=line><span class=cl> <span class=p>...;</span> </span></span></code></pre></div><h2 id=operation-traits-list>Operation Traits List</h2><p>MLIR provides a suite of traits that provide various functionalities that are common across many different operations. Below is a list of some key traits that may be used directly by any dialect. The format of the header for each trait section goes as follows:</p><ul><li><code>Header</code><ul><li>(<code>C++ class</code> &ndash; <code>ODS class</code>(if applicable))</li></ul></li></ul><h3 id=affinescope>AffineScope</h3><ul><li><code>OpTrait::AffineScope</code> &ndash; <code>AffineScope</code></li></ul><p>This trait is carried by region holding operations that define a new scope for the purposes of polyhedral optimization and the affine dialect in particular. Any SSA values of &lsquo;index&rsquo; type that either dominate such operations, or are defined at the top-level of such operations, or appear as region arguments for such operations automatically become valid symbols for the polyhedral scope defined by that operation. As a result, such SSA values could be used as the operands or index operands of various affine dialect operations like affine.for, affine.load, and affine.store. The polyhedral scope defined by an operation with this trait includes all operations in its region excluding operations that are nested inside of other operations that themselves have this trait.</p><h3 id=automaticallocationscope>AutomaticAllocationScope</h3><ul><li><code>OpTrait::AutomaticAllocationScope</code> &ndash; <code>AutomaticAllocationScope</code></li></ul><p>This trait is carried by region holding operations that define a new scope for automatic allocation. Such allocations are automatically freed when control is transferred back from the regions of such operations. As an example, allocations performed by <a href=/docs/Dialects/MemRef/#memrefalloca-memrefallocaop><code>memref.alloca</code></a> are automatically freed when control leaves the region of its closest surrounding op that has the trait AutomaticAllocationScope.</p><h3 id=broadcastable>Broadcastable</h3><ul><li><code>OpTrait::ResultsBroadcastableShape</code> &ndash; <code>ResultsBroadcastableShape</code></li></ul><p>This trait adds the property that the operation is known to have <a href=https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html>broadcast-compatible</a> operands and that its result type is compatible with the inferred broadcast shape. See <a href=/docs/Traits/Broadcastable/>The <code>Broadcastable</code> Trait</a> for details.</p><h3 id=commutative>Commutative</h3><ul><li><code>OpTrait::IsCommutative</code> &ndash; <code>Commutative</code></li></ul><p>This trait adds the property that the operation is commutative, i.e. <code>X op Y == Y op X</code></p><h3 id=elementwisemappable>ElementwiseMappable</h3><ul><li><code>OpTrait::ElementwiseMappable</code> &ndash; <code>ElementwiseMappable</code></li></ul><p>This trait tags scalar ops that also can be applied to vectors/tensors, with their semantics on vectors/tensors being elementwise application. This trait establishes a set of properties that allow reasoning about / converting between scalar/vector/tensor code. These same properties allow blanket implementations of various analyses/transformations for all <code>ElementwiseMappable</code> ops.</p><p>Note: Not all ops that are &ldquo;elementwise&rdquo; in some abstract sense satisfy this trait. In particular, broadcasting behavior is not allowed. See the comments on <code>OpTrait::ElementwiseMappable</code> for the precise requirements.</p><h3 id=hasparent>HasParent</h3><ul><li><code>OpTrait::HasParent&lt;typename ParentOpType></code> &ndash; <code>HasParent&lt;string op></code> or <code>ParentOneOf&lt;list&lt;string> opList></code></li></ul><p>This trait provides APIs and verifiers for operations that can only be nested within regions that are attached to operations of <code>ParentOpType</code>.</p><h3 id=isolatedfromabove>IsolatedFromAbove</h3><ul><li><code>OpTrait::IsIsolatedFromAbove</code> &ndash; <code>IsolatedFromAbove</code></li></ul><p>This trait signals that the regions of an operations are known to be isolated from above. This trait asserts that the regions of an operation will not capture, or reference, SSA values defined above the region scope. This means that the following is invalid if <code>foo.region_op</code> is defined as <code>IsolatedFromAbove</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=nv>%result</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>10</span> <span class=p>:</span> <span class=k>i32</span> </span></span><span class=line><span class=cl>foo<span class=p>.</span>region_op <span class=p>{</span> </span></span><span class=line><span class=cl> foo<span class=p>.</span>yield <span class=nv>%result</span> <span class=p>:</span> <span class=k>i32</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>This trait is an important structural property of the IR, and enables operations to have <a href=/docs/PassManagement/>passes</a> scheduled under them.</p><h3 id=memrefsnormalizable>MemRefsNormalizable</h3><ul><li><code>OpTrait::MemRefsNormalizable</code> &ndash; <code>MemRefsNormalizable</code></li></ul><p>This trait is used to flag operations that consume or produce values of <code>MemRef</code> type where those references can be &rsquo;normalized&rsquo;. In cases where an associated <code>MemRef</code> has a non-identity memory-layout specification, such normalizable operations can be modified so that the <code>MemRef</code> has an identity layout specification. This can be implemented by associating the operation with its own index expression that can express the equivalent of the memory-layout specification of the MemRef type. See <a href=/docs/Passes/#-normalize-memrefs>the -normalize-memrefs pass</a>.</p><h3 id=single-block-region>Single Block Region</h3><ul><li><code>OpTrait::SingleBlock</code> &ndash; <code>SingleBlock</code></li></ul><p>This trait provides APIs and verifiers for operations with regions that have a single block.</p><h3 id=single-block-with-implicit-terminator>Single Block with Implicit Terminator</h3><ul><li><code>OpTrait::SingleBlockImplicitTerminator&lt;typename TerminatorOpType></code> &ndash; <code>SingleBlockImplicitTerminator&lt;string op></code></li></ul><p>This trait implies the <code>SingleBlock</code> above, but adds the additional requirement that the single block must terminate with <code>TerminatorOpType</code>.</p><h3 id=symboltable>SymbolTable</h3><ul><li><code>OpTrait::SymbolTable</code> &ndash; <code>SymbolTable</code></li></ul><p>This trait is used for operations that define a <a href=/docs/SymbolsAndSymbolTables/#symbol-table><code>SymbolTable</code></a>.</p><h3 id=terminator>Terminator</h3><ul><li><code>OpTrait::IsTerminator</code> &ndash; <code>Terminator</code></li></ul><p>This trait provides verification and functionality for operations that are known to be <a href=/docs/LangRef/#control-flow-and-ssacfg-regions>terminators</a>.</p><ul><li><code>OpTrait::NoTerminator</code> &ndash; <code>NoTerminator</code></li></ul><p>This trait removes the requirement on regions held by an operation to have <a href=/docs/LangRef/#control-flow-and-ssacfg-regions>terminator operations</a> at the end of a block. This requires that these regions have a single block. An example of operation using this trait is the top-level <code>ModuleOp</code>.</p><h2>Traits Docs</h2><ul><li><a href=https://mlir.llvm.org/docs/Traits/Broadcastable/>The `Broadcastable` Trait</a></li></ul><div class=edit-meta><br></div><nav class=pagination><a class="nav nav-prev" href=https://mlir.llvm.org/docs/DeclarativeRewrites/ title="Table-driven Declarative Rewrite Rule (DRR)"><i class="fas fa-arrow-left" aria-hidden=true></i> Prev - Table-driven Declarative Rewrite Rule (DRR)</a> <a class="nav nav-next" href=https://mlir.llvm.org/docs/Traits/Broadcastable/ title="The `Broadcastable` Trait">Next - The `Broadcastable` Trait <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></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=has-sub-menu><a href=https://mlir.llvm.org/docs/Dialects/>Dialects<span class="mark closed">+</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><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="active 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