CINXE.COM
'linalg' 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>'linalg' 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/Linalg/><link rel=stylesheet href=https://mlir.llvm.org/css/theme.css><script src=https://use.fontawesome.com/releases/v5.0.6/js/all.js></script> <link rel=stylesheet href=https://mlir.llvm.org/css/chroma.min.css><script src=https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js></script> <script src=https://cdn.jsdelivr.net/npm/jquery.easing@1.4.1/jquery.easing.min.js></script> <script src=https://mlir.llvm.org/js/bundle.js></script> <script type=text/javascript src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> <script type=text/x-mathjax-config> MathJax.Hub.Config({ tex2jax: { inlineMath: [['$', '$'] ], displayMath: [ ['$$','$$'], ["\\[","\\]"] ] } }); </script><link rel=apple-touch-icon sizes=180x180 href="/apple-touch-icon.png?v=1"><link rel=icon type=image/png sizes=32x32 href="/favicon-32x32.png?v=1"><link rel=icon type=image/png sizes=16x16 href="/favicon-16x16.png?v=1"><link rel=manifest href="/site.webmanifest?v=1"><link rel=mask-icon href="/safari-pinned-tab.svg?v=1" color=#3775e0><link rel="shortcut icon" href="/favicon.ico?v=1"><meta name=msapplication-TileColor content="#2d89ef"><meta name=theme-color content="#ffffff"><link rel=icon href=/favicon.svg type=image/svg+xml sizes=any><style>:root{}</style></head><body><div class=container><header><h1><div><img src=https://mlir.llvm.org//mlir-logo.png width=40px align=absmiddle> MLIR</div></h1><p class=description>Multi-Level IR Compiler Framework</p></header><div class=global-menu><nav><ul><li class=parent><a href>Community<i class="fas fa-angle-right"></i></a><ul class=sub-menu><li class=child><a href=https://llvm.discourse.group/c/mlir/31>Forums</a></li><li class=child><a href=https://discord.gg/xS7Z362>Chat</a></li></ul></li><li><a href=/getting_started/Debugging/>Debugging Tips</a></li><li><a href=/getting_started/Faq/>FAQ</a></li><li class=parent><a href=https://github.com/llvm/llvm-project/tree/main/mlir>Source<i class="fas fa-angle-right"></i></a><ul class=sub-menu><li class=child><a href=/doxygen/>Doxygen</a></li><li class=child><a href=https://github.com/llvm/llvm-project/tree/main/mlir>GitHub</a></li></ul></li><li><a href="https://bugs.llvm.org/buglist.cgi?bug_status=__open__&list_id=177877&order=changeddate%20DESC%2Cpriority%2Cbug_severity&product=MLIR&query_format=specific">Bugs</a></li><li><a href=https://github.com/llvm/mlir-www/tree/main/website/static/LogoAssets>Logo Assets</a></li><li><a href=https://www.youtube.com/MLIRCompiler>Youtube Channel</a></li></ul></nav></div><div class=content-container><main><h1>'linalg' Dialect</h1><p><nav id=TableOfContents><ul><li><a href=#rationale>Rationale</a></li><li><a href=#set-of-key-transformationsa-namekey_transformationsa>Set of Key Transformations<a name=key_transformations></a></a></li><li><a href=#high-level-description-of-linalg-opsa-namelinalg_opsa>High-Level Description of Linalg Ops<a name=linalg_ops></a></a><ul><li><a href=#payload-carrying-opsa-namepayload_opsa>Payload-Carrying Ops<a name=payload_ops></a></a></li><li><a href=#data-representation-viewsa-nameviewsa>Data Representation: Views<a name=views></a></a></li><li><a href=#metadata-opsa-namemetadata_opsa>Metadata Ops<a name=metadata_ops></a></a></li><li><a href=#named-payload-carrying-opsa-namenamed_opsa>Named Payload-Carrying Ops<a name=named_ops></a></a></li><li><a href=#named-payload-ops-specification>Named Payload Ops Specification</a></li><li><a href=#yaml-based-named-structured-opsa-nameyaml-gena>YAML Based Named Structured Ops<a name=yaml-gen></a></a></li></ul></li><li><a href=#open-issues-and-design-alternativesa-nameopen_issuesa>Open Issues and Design Alternatives<a name=open_issues></a></a></li><li><a href=#operations>Operations</a><ul><li><a href=#linalgabs-linalgabsop><code>linalg.abs</code> (linalg::AbsOp)</a></li><li><a href=#linalgadd-linalgaddop><code>linalg.add</code> (linalg::AddOp)</a></li><li><a href=#linalgbatch_matmul-linalgbatchmatmulop><code>linalg.batch_matmul</code> (linalg::BatchMatmulOp)</a></li><li><a href=#linalgbatch_matmul_transpose_a-linalgbatchmatmultransposeaop><code>linalg.batch_matmul_transpose_a</code> (linalg::BatchMatmulTransposeAOp)</a></li><li><a href=#linalgbatch_matmul_transpose_b-linalgbatchmatmultransposebop><code>linalg.batch_matmul_transpose_b</code> (linalg::BatchMatmulTransposeBOp)</a></li><li><a href=#linalgbatch_matvec-linalgbatchmatvecop><code>linalg.batch_matvec</code> (linalg::BatchMatvecOp)</a></li><li><a href=#linalgbatch_mmt4d-linalgbatchmmt4dop><code>linalg.batch_mmt4d</code> (linalg::BatchMmt4DOp)</a></li><li><a href=#linalgbatch_reduce_matmul-linalgbatchreducematmulop><code>linalg.batch_reduce_matmul</code> (linalg::BatchReduceMatmulOp)</a></li><li><a href=#linalgbatch_vecmat-linalgbatchvecmatop><code>linalg.batch_vecmat</code> (linalg::BatchVecmatOp)</a></li><li><a href=#linalgbroadcast-linalgbroadcastop><code>linalg.broadcast</code> (linalg::BroadcastOp)</a></li><li><a href=#linalgceil-linalgceilop><code>linalg.ceil</code> (linalg::CeilOp)</a></li><li><a href=#linalgcontract-linalgcontractop><code>linalg.contract</code> (linalg::ContractOp)</a></li><li><a href=#linalgconv_1d_ncw_fcw-linalgconv1dncwfcwop><code>linalg.conv_1d_ncw_fcw</code> (linalg::Conv1DNcwFcwOp)</a></li><li><a href=#linalgconv_1d_nwc_wcf-linalgconv1dnwcwcfop><code>linalg.conv_1d_nwc_wcf</code> (linalg::Conv1DNwcWcfOp)</a></li><li><a href=#linalgconv_1d-linalgconv1dop><code>linalg.conv_1d</code> (linalg::Conv1DOp)</a></li><li><a href=#linalgconv_2d_nchw_fchw-linalgconv2dnchwfchwop><code>linalg.conv_2d_nchw_fchw</code> (linalg::Conv2DNchwFchwOp)</a></li><li><a href=#linalgconv_2d_nchw_fchw_q-linalgconv2dnchwfchwqop><code>linalg.conv_2d_nchw_fchw_q</code> (linalg::Conv2DNchwFchwQOp)</a></li><li><a href=#linalgconv_2d_ngchw_fgchw-linalgconv2dngchwfgchwop><code>linalg.conv_2d_ngchw_fgchw</code> (linalg::Conv2DNgchwFgchwOp)</a></li><li><a href=#linalgconv_2d_ngchw_gfchw-linalgconv2dngchwgfchwop><code>linalg.conv_2d_ngchw_gfchw</code> (linalg::Conv2DNgchwGfchwOp)</a></li><li><a href=#linalgconv_2d_ngchw_gfchw_q-linalgconv2dngchwgfchwqop><code>linalg.conv_2d_ngchw_gfchw_q</code> (linalg::Conv2DNgchwGfchwQOp)</a></li><li><a href=#linalgconv_2d_nhwc_fhwc-linalgconv2dnhwcfhwcop><code>linalg.conv_2d_nhwc_fhwc</code> (linalg::Conv2DNhwcFhwcOp)</a></li><li><a href=#linalgconv_2d_nhwc_fhwc_q-linalgconv2dnhwcfhwcqop><code>linalg.conv_2d_nhwc_fhwc_q</code> (linalg::Conv2DNhwcFhwcQOp)</a></li><li><a href=#linalgconv_2d_nhwc_hwcf-linalgconv2dnhwchwcfop><code>linalg.conv_2d_nhwc_hwcf</code> (linalg::Conv2DNhwcHwcfOp)</a></li><li><a href=#linalgconv_2d_nhwc_hwcf_q-linalgconv2dnhwchwcfqop><code>linalg.conv_2d_nhwc_hwcf_q</code> (linalg::Conv2DNhwcHwcfQOp)</a></li><li><a href=#linalgconv_2d_nhwgc_gfhwc-linalgconv2dnhwgcgfhwcop><code>linalg.conv_2d_nhwgc_gfhwc</code> (linalg::Conv2DNhwgcGfhwcOp)</a></li><li><a href=#linalgconv_2d_nhwgc_gfhwc_q-linalgconv2dnhwgcgfhwcqop><code>linalg.conv_2d_nhwgc_gfhwc_q</code> (linalg::Conv2DNhwgcGfhwcQOp)</a></li><li><a href=#linalgconv_2d-linalgconv2dop><code>linalg.conv_2d</code> (linalg::Conv2DOp)</a></li><li><a href=#linalgconv_3d_ncdhw_fcdhw-linalgconv3dncdhwfcdhwop><code>linalg.conv_3d_ncdhw_fcdhw</code> (linalg::Conv3DNcdhwFcdhwOp)</a></li><li><a href=#linalgconv_3d_ndhwc_dhwcf-linalgconv3dndhwcdhwcfop><code>linalg.conv_3d_ndhwc_dhwcf</code> (linalg::Conv3DNdhwcDhwcfOp)</a></li><li><a href=#linalgconv_3d_ndhwc_dhwcf_q-linalgconv3dndhwcdhwcfqop><code>linalg.conv_3d_ndhwc_dhwcf_q</code> (linalg::Conv3DNdhwcDhwcfQOp)</a></li><li><a href=#linalgconv_3d-linalgconv3dop><code>linalg.conv_3d</code> (linalg::Conv3DOp)</a></li><li><a href=#linalgcopy-linalgcopyop><code>linalg.copy</code> (linalg::CopyOp)</a></li><li><a href=#linalgdepthwise_conv_1d_ncw_cw-linalgdepthwiseconv1dncwcwop><code>linalg.depthwise_conv_1d_ncw_cw</code> (linalg::DepthwiseConv1DNcwCwOp)</a></li><li><a href=#linalgdepthwise_conv_1d_nwc_wc-linalgdepthwiseconv1dnwcwcop><code>linalg.depthwise_conv_1d_nwc_wc</code> (linalg::DepthwiseConv1DNwcWcOp)</a></li><li><a href=#linalgdepthwise_conv_1d_nwc_wcm-linalgdepthwiseconv1dnwcwcmop><code>linalg.depthwise_conv_1d_nwc_wcm</code> (linalg::DepthwiseConv1DNwcWcmOp)</a></li><li><a href=#linalgdepthwise_conv_2d_nchw_chw-linalgdepthwiseconv2dnchwchwop><code>linalg.depthwise_conv_2d_nchw_chw</code> (linalg::DepthwiseConv2DNchwChwOp)</a></li><li><a href=#linalgdepthwise_conv_2d_nhwc_hwc-linalgdepthwiseconv2dnhwchwcop><code>linalg.depthwise_conv_2d_nhwc_hwc</code> (linalg::DepthwiseConv2DNhwcHwcOp)</a></li><li><a href=#linalgdepthwise_conv_2d_nhwc_hwc_q-linalgdepthwiseconv2dnhwchwcqop><code>linalg.depthwise_conv_2d_nhwc_hwc_q</code> (linalg::DepthwiseConv2DNhwcHwcQOp)</a></li><li><a href=#linalgdepthwise_conv_2d_nhwc_hwcm-linalgdepthwiseconv2dnhwchwcmop><code>linalg.depthwise_conv_2d_nhwc_hwcm</code> (linalg::DepthwiseConv2DNhwcHwcmOp)</a></li><li><a href=#linalgdepthwise_conv_2d_nhwc_hwcm_q-linalgdepthwiseconv2dnhwchwcmqop><code>linalg.depthwise_conv_2d_nhwc_hwcm_q</code> (linalg::DepthwiseConv2DNhwcHwcmQOp)</a></li><li><a href=#linalgdepthwise_conv_3d_ncdhw_cdhw-linalgdepthwiseconv3dncdhwcdhwop><code>linalg.depthwise_conv_3d_ncdhw_cdhw</code> (linalg::DepthwiseConv3DNcdhwCdhwOp)</a></li><li><a href=#linalgdepthwise_conv_3d_ndhwc_dhwc-linalgdepthwiseconv3dndhwcdhwcop><code>linalg.depthwise_conv_3d_ndhwc_dhwc</code> (linalg::DepthwiseConv3DNdhwcDhwcOp)</a></li><li><a href=#linalgdepthwise_conv_3d_ndhwc_dhwcm-linalgdepthwiseconv3dndhwcdhwcmop><code>linalg.depthwise_conv_3d_ndhwc_dhwcm</code> (linalg::DepthwiseConv3DNdhwcDhwcmOp)</a></li><li><a href=#linalgdiv-linalgdivop><code>linalg.div</code> (linalg::DivOp)</a></li><li><a href=#linalgdiv_unsigned-linalgdivunsignedop><code>linalg.div_unsigned</code> (linalg::DivUnsignedOp)</a></li><li><a href=#linalgdot-linalgdotop><code>linalg.dot</code> (linalg::DotOp)</a></li><li><a href=#linalgelemwise_binary-linalgelemwisebinaryop><code>linalg.elemwise_binary</code> (linalg::ElemwiseBinaryOp)</a></li><li><a href=#linalgelemwise_unary-linalgelemwiseunaryop><code>linalg.elemwise_unary</code> (linalg::ElemwiseUnaryOp)</a></li><li><a href=#linalgerf-linalgerfop><code>linalg.erf</code> (linalg::ErfOp)</a></li><li><a href=#linalgexp-linalgexpop><code>linalg.exp</code> (linalg::ExpOp)</a></li><li><a href=#linalgfill-linalgfillop><code>linalg.fill</code> (linalg::FillOp)</a></li><li><a href=#linalgfill_rng_2d-linalgfillrng2dop><code>linalg.fill_rng_2d</code> (linalg::FillRng2DOp)</a></li><li><a href=#linalgfloor-linalgfloorop><code>linalg.floor</code> (linalg::FloorOp)</a></li><li><a href=#linalggeneric-linalggenericop><code>linalg.generic</code> (linalg::GenericOp)</a></li><li><a href=#linalgindex-linalgindexop><code>linalg.index</code> (linalg::IndexOp)</a></li><li><a href=#linalgsoftmax-linalgsoftmaxop><code>linalg.softmax</code> (linalg::SoftmaxOp)</a></li><li><a href=#linalgwinograd_filter_transform-linalgwinogradfiltertransformop><code>linalg.winograd_filter_transform</code> (linalg::WinogradFilterTransformOp)</a></li><li><a href=#linalgwinograd_input_transform-linalgwinogradinputtransformop><code>linalg.winograd_input_transform</code> (linalg::WinogradInputTransformOp)</a></li><li><a href=#linalgwinograd_output_transform-linalgwinogradoutputtransformop><code>linalg.winograd_output_transform</code> (linalg::WinogradOutputTransformOp)</a></li><li><a href=#linalgyield-linalgyieldop><code>linalg.yield</code> (linalg::YieldOp)</a></li><li><a href=#linalglog-linalglogop><code>linalg.log</code> (linalg::LogOp)</a></li><li><a href=#linalgmap-linalgmapop><code>linalg.map</code> (linalg::MapOp)</a></li><li><a href=#linalgmatmul-linalgmatmulop><code>linalg.matmul</code> (linalg::MatmulOp)</a></li><li><a href=#linalgmatmul_transpose_a-linalgmatmultransposeaop><code>linalg.matmul_transpose_a</code> (linalg::MatmulTransposeAOp)</a></li><li><a href=#linalgmatmul_transpose_b-linalgmatmultransposebop><code>linalg.matmul_transpose_b</code> (linalg::MatmulTransposeBOp)</a></li><li><a href=#linalgmatvec-linalgmatvecop><code>linalg.matvec</code> (linalg::MatvecOp)</a></li><li><a href=#linalgmax-linalgmaxop><code>linalg.max</code> (linalg::MaxOp)</a></li><li><a href=#linalgmin-linalgminop><code>linalg.min</code> (linalg::MinOp)</a></li><li><a href=#linalgmmt4d-linalgmmt4dop><code>linalg.mmt4d</code> (linalg::Mmt4DOp)</a></li><li><a href=#linalgmul-linalgmulop><code>linalg.mul</code> (linalg::MulOp)</a></li><li><a href=#linalgnegf-linalgnegfop><code>linalg.negf</code> (linalg::NegFOp)</a></li><li><a href=#linalgpooling_nchw_max-linalgpoolingnchwmaxop><code>linalg.pooling_nchw_max</code> (linalg::PoolingNchwMaxOp)</a></li><li><a href=#linalgpooling_nchw_sum-linalgpoolingnchwsumop><code>linalg.pooling_nchw_sum</code> (linalg::PoolingNchwSumOp)</a></li><li><a href=#linalgpooling_ncw_max-linalgpoolingncwmaxop><code>linalg.pooling_ncw_max</code> (linalg::PoolingNcwMaxOp)</a></li><li><a href=#linalgpooling_ncw_sum-linalgpoolingncwsumop><code>linalg.pooling_ncw_sum</code> (linalg::PoolingNcwSumOp)</a></li><li><a href=#linalgpooling_ndhwc_max-linalgpoolingndhwcmaxop><code>linalg.pooling_ndhwc_max</code> (linalg::PoolingNdhwcMaxOp)</a></li><li><a href=#linalgpooling_ndhwc_min-linalgpoolingndhwcminop><code>linalg.pooling_ndhwc_min</code> (linalg::PoolingNdhwcMinOp)</a></li><li><a href=#linalgpooling_ndhwc_sum-linalgpoolingndhwcsumop><code>linalg.pooling_ndhwc_sum</code> (linalg::PoolingNdhwcSumOp)</a></li><li><a href=#linalgpooling_nhwc_max-linalgpoolingnhwcmaxop><code>linalg.pooling_nhwc_max</code> (linalg::PoolingNhwcMaxOp)</a></li><li><a href=#linalgpooling_nhwc_max_unsigned-linalgpoolingnhwcmaxunsignedop><code>linalg.pooling_nhwc_max_unsigned</code> (linalg::PoolingNhwcMaxUnsignedOp)</a></li><li><a href=#linalgpooling_nhwc_min-linalgpoolingnhwcminop><code>linalg.pooling_nhwc_min</code> (linalg::PoolingNhwcMinOp)</a></li><li><a href=#linalgpooling_nhwc_min_unsigned-linalgpoolingnhwcminunsignedop><code>linalg.pooling_nhwc_min_unsigned</code> (linalg::PoolingNhwcMinUnsignedOp)</a></li><li><a href=#linalgpooling_nhwc_sum-linalgpoolingnhwcsumop><code>linalg.pooling_nhwc_sum</code> (linalg::PoolingNhwcSumOp)</a></li><li><a href=#linalgpooling_nwc_max-linalgpoolingnwcmaxop><code>linalg.pooling_nwc_max</code> (linalg::PoolingNwcMaxOp)</a></li><li><a href=#linalgpooling_nwc_max_unsigned-linalgpoolingnwcmaxunsignedop><code>linalg.pooling_nwc_max_unsigned</code> (linalg::PoolingNwcMaxUnsignedOp)</a></li><li><a href=#linalgpooling_nwc_min-linalgpoolingnwcminop><code>linalg.pooling_nwc_min</code> (linalg::PoolingNwcMinOp)</a></li><li><a href=#linalgpooling_nwc_min_unsigned-linalgpoolingnwcminunsignedop><code>linalg.pooling_nwc_min_unsigned</code> (linalg::PoolingNwcMinUnsignedOp)</a></li><li><a href=#linalgpooling_nwc_sum-linalgpoolingnwcsumop><code>linalg.pooling_nwc_sum</code> (linalg::PoolingNwcSumOp)</a></li><li><a href=#linalgpowf-linalgpowfop><code>linalg.powf</code> (linalg::PowFOp)</a></li><li><a href=#linalgquantized_batch_matmul-linalgquantizedbatchmatmulop><code>linalg.quantized_batch_matmul</code> (linalg::QuantizedBatchMatmulOp)</a></li><li><a href=#linalgquantized_matmul-linalgquantizedmatmulop><code>linalg.quantized_matmul</code> (linalg::QuantizedMatmulOp)</a></li><li><a href=#linalgreciprocal-linalgreciprocalop><code>linalg.reciprocal</code> (linalg::ReciprocalOp)</a></li><li><a href=#linalgreduce-linalgreduceop><code>linalg.reduce</code> (linalg::ReduceOp)</a></li><li><a href=#linalground-linalgroundop><code>linalg.round</code> (linalg::RoundOp)</a></li><li><a href=#linalgrsqrt-linalgrsqrtop><code>linalg.rsqrt</code> (linalg::RsqrtOp)</a></li><li><a href=#linalgselect-linalgselectop><code>linalg.select</code> (linalg::SelectOp)</a></li><li><a href=#linalgsqrt-linalgsqrtop><code>linalg.sqrt</code> (linalg::SqrtOp)</a></li><li><a href=#linalgsquare-linalgsquareop><code>linalg.square</code> (linalg::SquareOp)</a></li><li><a href=#linalgsub-linalgsubop><code>linalg.sub</code> (linalg::SubOp)</a></li><li><a href=#linalgtanh-linalgtanhop><code>linalg.tanh</code> (linalg::TanhOp)</a></li><li><a href=#linalgtranspose-linalgtransposeop><code>linalg.transpose</code> (linalg::TransposeOp)</a></li><li><a href=#linalgvecmat-linalgvecmatop><code>linalg.vecmat</code> (linalg::VecmatOp)</a></li></ul></li></ul></nav><h2 id=rationale>Rationale</h2><img width=90 align=left alt="MLIR Codegen Flow" src=https://user-images.githubusercontent.com/10148468/73613629-c5586580-45c5-11ea-94b7-074aeea94c7b.png><p>Linalg is designed to solve the High-level Hierarchical Optimization (HHO box) in MLIR and to interoperate nicely within a <em>Mixture Of Expert Compilers</em> environment (i.e. the <em>CGSel</em> box).</p><p>The <a href=/docs/Rationale/RationaleLinalgDialect/>Rationale Document</a> goes into significantly more design and architectural decision details.</p><h2 id=set-of-key-transformationsa-namekey_transformationsa>Set of Key Transformations<a name=key_transformations></a></h2><p>The following key transformations have been central to driving the design of Linalg. They are all implemented in terms of the properties of the <code>linalg.generic</code> OpInterface and avoid the pitfall of relying on hardcoded one-off op knowledge.</p><p>The textual form description of these transformations is left for future work. Still, it is useful to list the key transformations that are performed on the Linalg IR and that have influenced its design:</p><ol><li>Progressive Buffer Allocation.</li><li>Parametric Tiling.</li><li>Promotion to Temporary Buffer in Fast Memory.</li><li>Tiled Producer-Consumer Fusion with Parametric Tile-And-Fuse.</li><li>Map to Parallel and Reduction Loops and Hardware.</li><li>Vectorization: Rewrite in Vector Form.</li><li>Lower to Loops (Affine, Generic, and Parallel).</li><li>Lower to Library Calls or Special Instructions, Intrinsics or ISA.</li><li>Partially Lower to Iterations Over a Finer-Grained Linalg Op.</li></ol><h2 id=high-level-description-of-linalg-opsa-namelinalg_opsa>High-Level Description of Linalg Ops<a name=linalg_ops></a></h2><p>Linalg takes at least some inspiration from all previously <a href=/docs/Rationale/RationaleLinalgDialect/#prior-art>listed prior art</a>. The design enables the definition of <em><strong>CustomOps</strong></em> with generic properties that enable <a href=#key_transformations>key transformations</a>, including lowering to scalar load/store and other operations or to external library calls and intrinsics.</p><p>These ops can have <em><strong>either tensor or buffer</strong></em> as both input and output operands. Output tensors operands serve the purpose of providing a unifying abstraction and give a shape to the results. Output tensors can come in 2 flavors and are always associated with a corresponding op result:</p><ol><li><p>an “init tensor” output value which provides an initial value for a tensor that is created by iteratively updating the result (also called “destructive updates”). Such tensor is always materialized in some form. If enough fusion occurs it may end up being materialized only as a register-level SSA value. It is expected (but not required) that the destructive update pattern can be rewritten as an inplace update on buffers.</p></li><li><p>a “shape-only” tensor output value whose underlying elements are not used in the payload computation and only serves the purpose of carrying shape information to lower levels of abstraction. In the future this will be replaced by an appropriate shape type when it is available as a builtin type (see the discourse discussion <a href=https://llvm.discourse.group/t/linalg-and-shapes/2421>Linalg and Shapes</a> for more details).</p></li></ol><h3 id=payload-carrying-opsa-namepayload_opsa>Payload-Carrying Ops<a name=payload_ops></a></h3><p>Linalg defines a payload carrying operation that implements the <a href="https://docs.google.com/presentation/d/1P-j1GrH6Q5gLBjao0afQ-GfvcAeF-QU4GXXeSy0eJ9I/edit#slide=id.p">structured op</a> abstraction on tensors and buffers. This <code>linalg.generic</code> operation can express custom operations that optionally have <em>indexing semantics</em> (by accessing the iteration indices using the <code>linalg.index</code> operation). The properties of <code>linalg.generic</code> are the result of applying the guiding principles described in the <a href=/docs/Rationale/RationaleLinalgDialect/>Rationale Document</a>. They are listed next, with a brief example and discussion for each.</p><h4 id=property-1-input-and-output-operands-define-the-iteration-spacea-nameprop1a>Property 1: Input and Output Operands Define The Iteration Space<a name=prop1></a></h4><p>A <code>linalg.generic</code> op fully <em>derives</em> the specification of its iteration space from its operands. The property enforces that a localized IR element (the op) <em>has</em> all the information needed to synthesize the control-flow required to iterate over its operands, according to their type. This notion of IR localization bears some resemblance to <a href=http://icps.u-strasbg.fr/~bastoul/research/papers/GVBCPST06-IJPP.pdf>URUK</a>.</p><p>Consider the following fully specified <code>linalg.generic</code> example. Here, the first operand is a <code>memref</code> of <code>f32</code> scalar elements that has an ordinary identity layout, and the second one is a <code>memref</code> of 4-element vectors with a 2-strided, 1-offset layout.</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>// File name: example1.mlir </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#accesses</span> <span class=p>=</span> <span class=p>[</span> </span></span><span class=line><span class=cl> affine_map<span class=p><(</span>m<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>m<span class=p>)>,</span> </span></span><span class=line><span class=cl> affine_map<span class=p><(</span>m<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>m<span class=p>)></span> </span></span><span class=line><span class=cl><span class=p>]</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=nv>#attrs</span> <span class=p>=</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>indexing_maps =</span> <span class=nv>#accesses</span><span class=p>,</span> </span></span><span class=line><span class=cl> <span class=nl>iterator_types =</span> <span class=p>[</span><span class=s>"parallel"</span><span class=p>]</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%A</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=m>1</span><span class=p>]>>,</span> </span></span><span class=line><span class=cl> <span class=nv>%B</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>],</span> offset<span class=p>:</span> <span class=m>1</span><span class=p>>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>generic <span class=nv>#attrs</span> </span></span><span class=line><span class=cl> ins<span class=p>(</span><span class=nv>%A</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=m>1</span><span class=p>]>>)</span> </span></span><span class=line><span class=cl> outs<span class=p>(</span><span class=nv>%B</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>],</span> offset<span class=p>:</span> <span class=m>1</span><span class=p>>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>^bb0</span><span class=p>(</span><span class=nv>%a</span><span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=nv>%b</span><span class=p>:</span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>):</span> </span></span><span class=line><span class=cl> <span class=nv>%c</span> <span class=p>=</span> <span class=s>"some_compute"</span><span class=p>(</span><span class=nv>%a</span><span class=p>,</span> <span class=nv>%b</span><span class=p>):</span> <span class=p>(</span><span class=k>f32</span><span class=p>,</span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>-></span> <span class=p>(</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>)</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>yield <span class=nv>%c</span><span class=p>:</span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>The property “<em>Input and Output Operands Define The Iteration Space</em>” is materialized by a lowering into a form that will resemble:</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>// Run: mlir-opt example1.mlir -allow-unregistered-dialect -convert-linalg-to-loops </span></span></span><span class=line><span class=cl><span class=c>// This converted representation is in the `scf` dialect. </span></span></span><span class=line><span class=cl><span class=c>// It's syntax can be found here: https://mlir.llvm.org/docs/Dialects/SCFDialect/ </span></span></span><span class=line><span class=cl><span class=c></span> </span></span><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=k>f32</span><span class=p>>,</span> </span></span><span class=line><span class=cl> <span class=nv>%arg1</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>],</span> offset<span class=p>:</span> <span class=m>1</span><span class=p>>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%c0</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>0</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> <span class=nv>%c1</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>1</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> <span class=nv>%0</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>dim <span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%c0</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> scf<span class=p>.</span>for <span class=nv>%arg2</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%0</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%1</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>load <span class=nv>%arg0</span><span class=p>[</span><span class=nv>%arg2</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=nv>%2</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>load <span class=nv>%arg1</span><span class=p>[</span><span class=nv>%arg2</span><span class=p>]</span> </span></span><span class=line><span class=cl> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>],</span> offset<span class=p>:</span> <span class=m>1</span><span class=p>>></span> </span></span><span class=line><span class=cl> <span class=nv>%3</span> <span class=p>=</span> <span class=s>"some_compute"</span><span class=p>(</span><span class=nv>%1</span><span class=p>,</span> <span class=nv>%2</span><span class=p>)</span> <span class=p>:</span> <span class=p>(</span><span class=k>f32</span><span class=p>,</span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>-></span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p>.</span>store <span class=nv>%3</span><span class=p>,</span> <span class=nv>%arg1</span><span class=p>[</span><span class=nv>%arg2</span><span class=p>]</span> </span></span><span class=line><span class=cl> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>],</span> offset<span class=p>:</span> <span class=m>1</span><span class=p>>></span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>The property participates in simplifying analyses and transformations. For instance, it guarantees no out-of bounds access can occur by construction (assuming dynamic operand dimensions agree with each other, which is the purpose of the <code>assert</code> runtime check).</p><p>Before lowering to loop form, loop induction variables and iterators are implicit (i.e. <em>not yet materialized</em>).</p><p>The main implications are that:</p><ol><li><p>The semantics of the ops are <em>restricted to operate on structured data types</em>, on which we can define an iterator.</p></li><li><p>This does not model arbitrary code with side-effects.</p></li></ol><p>We do not think these are serious limitations in practice because MLIR is all about mixing different levels of abstractions in the same IR. As long as Linalg can progressively lower to the next level of abstraction, it can also be just bypassed for things that do not fit.</p><p>At the same time, conditioning op semantics on structured data types is a very promising path towards extensibility to non-dense tensors as experience with LIFT abstractions for <a href=https://www.lift-project.org/publications/2016/harries16sparse.pdf>sparse</a> and <a href=https://www.lift-project.org/publications/2019/pizzuti19positiondependentarrays.pdf>position-dependent arrays</a>, as well as <a href=http://tensor-compiler.org/>TACO</a>, has shown.</p><h4 id=property-2-reversible-mappings-between-control-and-data-structuresa-nameprop2a>Property 2: Reversible Mappings Between Control and Data Structures<a name=prop2></a></h4><p>A <code>linalg.generic</code> <em>defines</em> the mapping between the iteration space (i.e. the loops) and the data.</p><p>Consider the following fully specified <code>linalg.generic</code> example. Here, the first <code>memref</code> is a 2-strided one on both of its dimensions, and the second <code>memref</code> uses an identity layout.</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>// File name: example2.mlir </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#indexing_maps</span> <span class=p>=</span> <span class=p>[</span> </span></span><span class=line><span class=cl> affine_map<span class=p><(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>j<span class=p>,</span> i<span class=p>)>,</span> </span></span><span class=line><span class=cl> affine_map<span class=p><(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>j<span class=p>)></span> </span></span><span class=line><span class=cl><span class=p>]</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=nv>#attrs</span> <span class=p>=</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>indexing_maps =</span> <span class=nv>#indexing_maps</span><span class=p>,</span> </span></span><span class=line><span class=cl> <span class=nl>iterator_types =</span> <span class=p>[</span><span class=s>"parallel"</span><span class=p>,</span> <span class=s>"parallel"</span><span class=p>]</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%A</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>8x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>,</span> <span class=m>2</span><span class=p>],</span> offset<span class=p>:</span> <span class=m>0</span><span class=p>>>,</span> </span></span><span class=line><span class=cl> <span class=nv>%B</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>generic <span class=nv>#attrs</span> </span></span><span class=line><span class=cl> ins<span class=p>(</span><span class=nv>%A</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>8x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>,</span> <span class=m>2</span><span class=p>],</span> offset<span class=p>:</span> <span class=m>0</span><span class=p>>>)</span> </span></span><span class=line><span class=cl> outs<span class=p>(</span><span class=nv>%B</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>^bb0</span><span class=p>(</span><span class=nv>%a</span><span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=nv>%b</span><span class=p>:</span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>):</span> </span></span><span class=line><span class=cl> <span class=nv>%c</span> <span class=p>=</span> <span class=s>"some_compute"</span><span class=p>(</span><span class=nv>%a</span><span class=p>,</span> <span class=nv>%b</span><span class=p>):</span> <span class=p>(</span><span class=k>f32</span><span class=p>,</span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>-></span> <span class=p>(</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>)</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>yield <span class=nv>%c</span><span class=p>:</span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>The property “<em>Reversible Mappings Between Control and Data Structures</em>” is materialized by a lowering into a form that will resemble:</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>// Run: mlir-opt example2.mlir -allow-unregistered-dialect -convert-linalg-to-loops </span></span></span><span class=line><span class=cl><span class=c></span> </span></span><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>8x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>,</span> <span class=m>2</span><span class=p>]>>,</span> <span class=nv>%arg1</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%c8</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>8</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> <span class=nv>%c0</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>0</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> <span class=nv>%c1</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>1</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> <span class=nv>%0</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>dim <span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%c1</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>8x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>,</span> <span class=m>2</span><span class=p>]>></span> </span></span><span class=line><span class=cl> scf<span class=p>.</span>for <span class=nv>%arg2</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%0</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> scf<span class=p>.</span>for <span class=nv>%arg3</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%c8</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%1</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>load <span class=nv>%arg0</span><span class=p>[</span><span class=nv>%arg3</span><span class=p>,</span> <span class=nv>%arg2</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>8x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=m>2</span><span class=p>,</span> <span class=m>2</span><span class=p>]>></span> </span></span><span class=line><span class=cl> <span class=nv>%2</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>load <span class=nv>%arg1</span><span class=p>[</span><span class=nv>%arg3</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>></span> </span></span><span class=line><span class=cl> <span class=nv>%3</span> <span class=p>=</span> <span class=s>"some_compute"</span><span class=p>(</span><span class=nv>%1</span><span class=p>,</span> <span class=nv>%2</span><span class=p>)</span> <span class=p>:</span> <span class=p>(</span><span class=k>f32</span><span class=p>,</span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>-></span> <span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p>.</span>store <span class=nv>%3</span><span class=p>,</span> <span class=nv>%arg1</span><span class=p>[</span><span class=nv>%arg3</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x</span><span class=kt>vector</span><span class=p><</span><span class=m>4x</span><span class=k>f32</span><span class=p>>></span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>This mapping needs to be reversible because we want to be able to go back and forth between the two and answer questions such as:</p><ul><li>Given a subset of the iteration space, what subset of data does it read and write?</li><li>Given a subset of data read or written, what subset of the iteration space is responsible for this read or write?</li></ul><p>Answering these <code>2</code> questions is one of the main analyses that Linalg uses to implement transformations such as tiling, tiled producer-consumer fusion, and promotion to temporary buffers in fast memory.</p><p>In the current implementation, <code>linalg.generic</code> uses a list of <a href=https://mlir.llvm.org/docs/LangRef/#affinemap-attribute>AffineMaps</a> (see the <code>#indexing_maps</code> attribute in the previous examples). This is a pragmatic short-term solution, but in the longer term note that this property could be even evaluated dynamically, similarly to inspector-executor algorithms.</p><h4 id=property-3-the-type-of-iterators-is-defined-explicitlya-nameprop3a>Property 3: The Type Of Iterators is Defined Explicitly<a name=prop3></a></h4><p>A <code>linalg.generic</code> op fully <em>declares</em> the type of its iterators. This information is used in transformations.</p><p>These properties are derived from established practice in the field and mirror the properties from Ken Kennedy’s <a href=https://www.elsevier.com/books/optimizing-compilers-for-modern-architectures/allen/978-0-08-051324-9>Optimizing Compilers for Modern Architectures</a>. The key idea of legality of loop transformations expressed by Kennedy is that <em><strong>the lexicographic order of all dependence vectors must be preserved</strong></em>.</p><p>This can be better captured directly at the loop level thanks to specific iterator types, among which: <em>parallel</em>, <em>reduction</em>, <em>partition</em>, <em>permutable/monotonic</em>, <em>sequential</em>, <em>dependence distance</em>, …</p><p>These types are traditionally the result of complex dependence analyses and have been referred to as “<em>bands</em>” in the polyhedral community (e.g. <em>parallel bands</em>, <em>permutable bands</em>, etc, in <a href=https://en.wikipedia.org/wiki/Integer_set_library>ISL</a> schedule tree parlance).</p><p>Specifying the information declaratively in a <code>linalg.generic</code> allows conveying properties that may be hard (or even impossible) to derive from lower-level information. These properties can be brought all the way to the moment when they are useful for transformations, used and then discarded.</p><p>Additionally, these properties may also be viewed as a contract that the frontend/user guarantees and that the compiler may take advantage of. The common example is the use of data-dependent reduction semantics for specifying histogram computations. If the frontend has additional knowledge that proper atomic operations are available, it may be better to specify parallel semantics and use the special atomic in the computation region.</p><p>At this time, Linalg only has an explicit use for <em>parallel</em> and <em>reduction</em> loops but previous experience shows that the abstraction generalizes.</p><h4 id=property-4-the-compute-payload-is-specified-with-a-regiona-nameprop4a>Property 4: The Compute Payload is Specified With a Region<a name=prop4></a></h4><p>A <code>linalg.generic</code> op has a compute payload that is fully generic thanks to the use of <a href=https://github.com/llvm/llvm-project/blob/58265ad42a90ae8905be6a447cb42e53529a54a0/mlir/docs/LangRef.md/#regions>Regions</a>.</p><p>The region takes as arguments the scalar elemental types of the tensor or buffer operands of the <code>linalg.generic</code>. For flexibility and ability to match library calls, additional special values may be passed. For instance, a <code>linalg.fill</code> operation takes a buffer and an additional scalar value.</p><p>At this time there are no additional restrictions to the region semantics. This is meant to allow the exploration of various design tradeoffs at the intersection of regions and iterator types. In particular, the frontend is responsible for the semantics of iterator types to correspond to the operations inside the region: the region can capture buffers arbitrarily and write into them. If this conflicts with some parallel iterator requirement, this is undefined behavior.</p><p>Previous examples already elaborate compute payloads with an unregistered function <code>"some_compute"</code>. The following code snippet shows what the result will be when using a concrete operation <code>addf</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>// File name: example3.mlir </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#map</span> <span class=p>=</span> affine_map<span class=p><(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=nv>#attrs</span> <span class=p>=</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>indexing_maps =</span> <span class=p>[</span><span class=nv>#map</span><span class=p>,</span> <span class=nv>#map</span><span class=p>,</span> <span class=nv>#map</span><span class=p>],</span> </span></span><span class=line><span class=cl> <span class=nl>iterator_types =</span> <span class=p>[</span><span class=s>"parallel"</span><span class=p>,</span> <span class=s>"parallel"</span><span class=p>]</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%A</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=nv>%B</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=nv>%C</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>generic <span class=nv>#attrs</span> </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>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>)</span> </span></span><span class=line><span class=cl> outs<span class=p>(</span><span class=nv>%C</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>^bb0</span><span class=p>(</span><span class=nv>%a</span><span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=nv>%b</span><span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=nv>%c</span><span class=p>:</span> <span class=k>f32</span><span class=p>):</span> </span></span><span class=line><span class=cl> <span class=nv>%d</span> <span class=p>=</span> arith<span class=p>.</span>addf <span class=nv>%a</span><span class=p>,</span> <span class=nv>%b</span> <span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>yield <span class=nv>%d</span> <span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>This function basically element-wise adds up two matrices (<code>%A</code> and <code>%B</code>) and stores the result into another one (<code>%C</code>).</p><p>The property “<em>The Compute Payload is Specified With a Region</em>” is materialized by a lowering into a form that will resemble:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=nv>%arg1</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=nv>%arg2</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%c0</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>0</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> <span class=nv>%c1</span> <span class=p>=</span> arith<span class=p>.</span><span class=kt>constant</span> <span class=m>1</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> <span class=nv>%0</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>dim <span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%c0</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=nv>%1</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>dim <span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%c1</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> scf<span class=p>.</span>for <span class=nv>%arg3</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%0</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> scf<span class=p>.</span>for <span class=nv>%arg4</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%1</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%2</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>load <span class=nv>%arg0</span><span class=p>[</span><span class=nv>%arg3</span><span class=p>,</span> <span class=nv>%arg4</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=nv>%3</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>load <span class=nv>%arg1</span><span class=p>[</span><span class=nv>%arg3</span><span class=p>,</span> <span class=nv>%arg4</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=nv>%4</span> <span class=p>=</span> arith<span class=p>.</span>addf <span class=nv>%2</span><span class=p>,</span> <span class=nv>%3</span> <span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p>.</span>store <span class=nv>%4</span><span class=p>,</span> <span class=nv>%arg2</span><span class=p>[</span><span class=nv>%arg3</span><span class=p>,</span> <span class=nv>%arg4</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>In the process of lowering to loops and lower-level constructs, similar requirements are encountered, as are discussed in the <a href=https://llvm.discourse.group/t/introduce-std-inlined-call-op-proposal/282/2>inlined call op proposal</a>. We expect to be able to reuse the common lower-level infrastructure provided it evolves to support both region arguments and captures.</p><h4 id=property-5-may-map-to-an-external-library-calla-nameprop5a>Property 5: May Map To an External Library Call<a name=prop5></a></h4><p>A <code>linalg.generic</code> op may map to an external library call by specifying a <code>SymbolAttr</code>. At this level of abstraction, the important glue is the ability to perform transformations that preserve the structure necessary to <em><strong>call the external library after different transformations have been applied</strong></em>.</p><p>This involves considerations related to preservation of op semantics and integration at the ABI level. Regardless of whether one wants to use external library calls or a custom ISA, the problem for codegen is similar: preservation of a fixed granularity.</p><p>Consider the following example that adds an additional attribute <code>library_call="pointwise_add"</code> that specifies the name of an external library call we intend to use:</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>// File name: example4.mlir </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>#indexing_maps</span> <span class=p>=</span> <span class=p>[</span> </span></span><span class=line><span class=cl> affine_map<span class=p><(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)>,</span> </span></span><span class=line><span class=cl> affine_map<span class=p><(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)>,</span> </span></span><span class=line><span class=cl> affine_map<span class=p><(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)></span> </span></span><span class=line><span class=cl><span class=p>]</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=nv>#attrs</span> <span class=p>=</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>indexing_maps =</span> <span class=nv>#indexing_maps</span><span class=p>,</span> </span></span><span class=line><span class=cl> <span class=nl>iterator_types =</span> <span class=p>[</span><span class=s>"parallel"</span><span class=p>,</span> <span class=s>"parallel"</span><span class=p>],</span> </span></span><span class=line><span class=cl> <span class=nl>library_call =</span> <span class=s>"pointwise_add"</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%A</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=nv>%B</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=nv>%C</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>generic <span class=nv>#attrs</span> </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>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>)</span> </span></span><span class=line><span class=cl> outs<span class=p>(</span><span class=nv>%C</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>^bb0</span><span class=p>(</span><span class=nv>%a</span><span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=nv>%b</span><span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=nv>%c</span><span class=p>:</span> <span class=k>f32</span><span class=p>):</span> </span></span><span class=line><span class=cl> <span class=nv>%d</span> <span class=p>=</span> arith<span class=p>.</span>addf <span class=nv>%a</span><span class=p>,</span> <span class=nv>%b</span> <span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>yield <span class=nv>%d</span> <span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>The property “<em>Map To an External Library Call</em>” is materialized by a lowering into a form that will resemble:</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>// Run: mlir-opt example4.mlir -convert-linalg-to-std </span></span></span><span class=line><span class=cl><span class=c></span> </span></span><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=nv>%arg1</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>,</span> <span class=nv>%arg2</span><span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%0</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>cast <span class=nv>%arg0</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>></span> to <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>></span> </span></span><span class=line><span class=cl> <span class=nv>%1</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>cast <span class=nv>%arg1</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>></span> to <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>></span> </span></span><span class=line><span class=cl> <span class=nv>%2</span> <span class=p>=</span> <span class=kt>memref</span><span class=p>.</span>cast <span class=nv>%arg2</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>></span> to <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>></span> </span></span><span class=line><span class=cl> call <span class=nf>@pointwise_add</span><span class=p>(</span><span class=nv>%0</span><span class=p>,</span> <span class=nv>%1</span><span class=p>,</span> <span class=nv>%2</span><span class=p>)</span> <span class=p>:</span> <span class=p>(</span><span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>>,</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>>,</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>>)</span> <span class=p>-></span> <span class=p>()</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@pointwise_add</span><span class=p>(</span><span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>>,</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>>,</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> strided<span class=p><[</span><span class=err>?</span><span class=p>,</span> <span class=err>?</span><span class=p>],</span> offset<span class=p>:</span> <span class=err>?</span><span class=p>>>)</span> attributes <span class=p>{</span>llvm<span class=p>.</span>emit_c_interface<span class=p>}</span> </span></span></code></pre></div><p>Which, after lowering to LLVM resembles:</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>// Run: mlir-opt example4.mlir -convert-linalg-to-std | mlir-opt -convert-func-to-llvm </span></span></span><span class=line><span class=cl><span class=c>// Some generated code are omitted here. </span></span></span><span class=line><span class=cl><span class=c></span><span class=kt>func</span><span class=p>.</span><span class=kt>func</span> <span class=nf>@example</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>:</span> <span class=p>!</span>llvm<span class=p><</span><span class=s>"float*"</span><span class=p>>,</span> <span class=p>...)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=p>...</span> </span></span><span class=line><span class=cl> llvm<span class=p>.</span>call <span class=nf>@pointwise_add</span><span class=p>(...)</span> <span class=p>:</span> <span class=p>(!</span>llvm<span class=p><</span><span class=s>"float*"</span><span class=p>>,</span> <span class=p>...)</span> <span class=p>-></span> <span class=p>()</span> </span></span><span class=line><span class=cl> <span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl>llvm<span class=p>.</span><span class=kt>func</span> <span class=nf>@pointwise_add</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>:</span> <span class=p>!</span>llvm<span class=p><</span><span class=s>"float*"</span><span class=p>>,</span> <span class=p>...)</span> attributes <span class=p>{</span>llvm<span class=p>.</span>emit_c_interface<span class=p>}</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=p>...</span> </span></span><span class=line><span class=cl> llvm<span class=p>.</span>call <span class=nf>@_mlir_ciface_pointwise_add</span><span class=p>(</span><span class=nv>%9</span><span class=p>,</span> <span class=nv>%19</span><span class=p>,</span> <span class=nv>%29</span><span class=p>)</span> <span class=p>:</span> <span class=p>(!</span>llvm<span class=p>.</span><span class=s>"{ float*, float*, i64, [2 x i64], [2 x i64] }*"</span><span class=p>>,</span> <span class=p>!</span>llvm<span class=p><</span><span class=s>"{ f32*, f32*, i64, [2 x i64], [2 x i64] }*"</span><span class=p>>,</span> <span class=p>!</span>llvm<span class=p><</span><span class=s>"{ float*, float*, i64, [2 x i64], [2 x i64] } </span></span></span><span class=line><span class=cl><span class=s>*"</span><span class=p>>)</span> <span class=p>-></span> <span class=p>()</span> </span></span><span class=line><span class=cl> llvm<span class=p>.</span><span class=kt>return</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl>llvm<span class=p>.</span><span class=kt>func</span> <span class=nf>@_mlir_ciface_pointwise_add</span><span class=p>(!</span>llvm<span class=p>.</span><span class=s>"{ float*, float*, i64, [2 x i64], [2 x i64] }*"</span><span class=p>>,</span> <span class=p>!</span>llvm<span class=p><</span><span class=s>"{ f32*, f32*, i64, [2 x i64], [2 x i64] }*"</span><span class=p>>,</span> <span class=p>!</span>llvm<span class=p><</span><span class=s>"{ f32*, f32*, i64, [2 x i64], [2 x i64] }*"</span><span class=p>>)</span> attributes <span class=p>{</span>llvm<span class=p>.</span>emit_c_interface<span class=p>}</span> </span></span></code></pre></div><h5 id=convention-for-external-library-interoperability>Convention For External Library Interoperability</h5><p>The <code>linalg</code> dialect adopts a convention that is similar to <code>BLAS</code> when offloading operations to fast library implementations: pass a non-owning pointer to input and output data with additional metadata. This convention is also found in libraries such as <code>MKL</code>, <code>OpenBLAS</code>, <code>BLIS</code>, <code>cuBLAS</code>, <code>cuDNN</code>, etc.. and more generally at interface points across language boundaries (e.g. C++ / Python).</p><p>Generally, <code>linalg</code> passes non-owning pointers to View data structures to pre-compiled library calls linked externally.</p><p>There is an <a href=https://llvm.discourse.group/t/lowering-optional-attributes-in-linalg-structuredops-to-standard-dialect/333/3>ongoing discussion</a> on the topic of extending interoperability in the presence of key attributes.</p><h4 id=property-6-perfectly-nested-writes-to-the-whole-output-operandsa-nameprop6a>Property 6: Perfectly Nested Writes To The Whole Output Operands<a name=prop6></a></h4><p>Perfectly nested loops form a particularly important class of structure that enables key loop transformations such as tiling and mapping to library calls. Unfortunately, this type of structure is easily broken by transformations such as partial loop fusion. Tiling and mapping to library calls become more challenging, or even infeasible. Linalg ops adopt perfect-nestedness as a first-class property: the structure cannot be broken and is transported in the IR by construction.</p><p>A <code>linalg.generic</code> op represents a perfectly nested loop nest that writes the entire memory region. This is a structural constraint across regions and loops that has proven to be key in simplifying transformations.</p><p>One particular point to mention is that converting imperfectly nested code into perfectly nested code can often be done with enough loop distribution and embedding of conditionals down to the innermost loop level.</p><p>Previous experience with Tensor Comprehensions gave us the intuition that forcing innermost control-flow nesting is a lot like writing data-parallel code with arrays of boolean values and predication. This type of trick has also been used before in polyhedral compilers to convert non-affine control into affine compute dependencies.</p><p>While it may be possible to automate such rewrites from generic IR, <code>linalg.generic</code> just forces the semantics for now.</p><p>The key implication is that this conversion to deep predication needs to be undone once we are done with Linalg transformations. After iterators and induction variables are materialized (i.e. after lowering out of <code>linalg.generic</code> occurred), the overall performance will be greatly influenced by the quality of canonicalizations, foldings and <em>Loop Independent Code Motion</em> (LICM).</p><p>In the grander scheme, the reliance on late LICM was deemed a necessary risk.</p><h4 id=putting-it-togethera-namesummarya>Putting it Together<a name=summary></a></h4><p>As it stands, the six properties above define the semantics of a <code>linalg.generic</code> op. It is an open question whether all of these semantics are strictly necessary in practice and whether some should or could be derived automatically while still maintaining the <a href=/docs/Rationale/RationaleLinalgDialect/#core-guiding-principlesa-nameguiding_principlesa>core guiding principles</a>.</p><p>For the time being, we have settled on the combination of these properties because of empirical evidence building and working on multiple high-level compilers. As we lay those down and engage more with the community, we expect multiple rounds of discussions and design changes to the original architecture.</p><h3 id=data-representation-viewsa-nameviewsa>Data Representation: Views<a name=views></a></h3><p>The current implementation uses the <a href=https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/MaL8m2nXuio>Strided MemRef (a.k.a View)</a> abstraction. The name <em>View</em> is used interchangeably in <code>linalg</code> to signify <em>Strided MemRef</em>. In the future we expect to use other structured data types and support ragged, mixed-sparse and other types. We expect to draw on the experience from existing LIFT abstractions for <a href=https://www.lift-project.org/publications/2016/harries16sparse.pdf>sparse</a> and <a href=https://www.lift-project.org/publications/2019/pizzuti19positiondependentarrays.pdf>position-dependent arrays</a>.</p><h3 id=metadata-opsa-namemetadata_opsa>Metadata Ops<a name=metadata_ops></a></h3><p>A set of ops that manipulate metadata but do not move memory. These ops take <code>view</code> operands + extra attributes and return new <code>view</code>s. The returned <code>view</code>s generally alias the operand <code>view</code>. At the moment the existing ops are:</p><pre tabindex=0><code>* `memref.view`, * `memref.subview`, * `memref.transpose`. * `linalg.slice`, * `linalg.reshape`, </code></pre><p>Future ops are added on a per-need basis but should include:</p><pre tabindex=0><code>* `linalg.tile`, * `linalg.intersection`, * `linalg.convex_union`, * `linalg.difference` (would need to work on a list of views). </code></pre><p>These additional operations correspond to abstractions that have been known to work in the field of large-scale distributed stencil computations.</p><p>In a longer-term future, the abstractions from <a href=https://legion.stanford.edu/overview/>Legion data-centric programming model</a> seem generally appealing.</p><h3 id=named-payload-carrying-opsa-namenamed_opsa>Named Payload-Carrying Ops<a name=named_ops></a></h3><p>Additionally, <code>linalg</code> provides a small subset of commonly named operations:</p><pre tabindex=0><code>* `linalg.fill`, * `linalg.dot`, * `linalg.matmul`, * `linalg.conv`. </code></pre><p>These named operations adhere to the <code>linalg.generic</code> op interface. Work is in progress to define declarative mechanisms to automatically generate named ops from a description in terms of only the generic op interface.</p><p>This is the main reason there are only a small number of ops today: we expect them to be auto-generated from Tablegen soon.</p><h3 id=named-payload-ops-specification>Named Payload Ops Specification</h3><p>Linalg provides a declarative specification and a generation tool (<code>mlir-linalg-ods-gen</code>) to automatically produce named ops from a notation that is inspired by Einstein notation.</p><p>The syntax and semantics used in <code>mlir-linalg-ods-gen</code> are very much in flight and borrow from Tensor Comprehensions (TC) but differ in a few dimensions, to better adapt to Linalg:</p><ol><li>The input and output tensor parameters are specified as <code>id : type(symbolic-affine-expression-list)</code> (e.g. <code>A : f32(M, N + M)</code>) and each new symbol is discovered eagerly. TC on the other hand does not allow general symbolic affine expressions.</li><li>The output shapes are specified explicitly, in TC they are always derived from the input shapes.</li><li>The operations used to specify computations use EDSC intrinsics so that they can easily be parsed and emitted into a simple region builder without resorting to more general MLIR parsing.</li><li>Reduction dimensions are specified with angle bracket notation on the operation they apply to (e.g. <code>std_add<k></code> specifies that <code>k</code> is a reduction dimension). In TC, the reduction dimensions are inferred. If one of the operand is not used in any expressions, it will be considered a shape-only operand, and the result of the indexing_map will be reduction dimensions.</li><li>The parallel and reduction dimension are ordered by the textual program order. For instance, in the comprehension <code>O(i, j) = std_add<k, l>(...)</code>, <code>i</code> (resp. <code>j</code>) is a parallel iterator encoded by affine dimension of position <code>0</code> (resp. <code>1</code>); <code>k</code> (resp. <code>l</code>) is a reduction iterator encoded by an affine dimension of position <code>2</code> (resp. <code>3</code>).</li><li>A list of attributes can be defined for the op with the format of <code>attr( strides: 2xi32)</code> and referenced in comprehension like <code>strides[0]</code>. These attribute uses will be parsed as affine symbols to generate op definition and implementation. For a concrete op instance, the runtime constant values from the attributes will be used to replace the affine symbols and simplify the indexing maps.</li></ol><p>These decisions and syntax are subject to evolution and change. In particular, op-specific attributes, dynamic ranks, some form of templating, shape calculation function specification, etc. may be added in the future.</p><p>At this time, the following restrictions are imposed on the syntax and semantics:</p><ol><li>Each def may only contain a single comprehension but each comprehension may perform multiple updates.</li><li>Each tensor may only be used with a single indexing expression.</li></ol><p>A <code>"""</code>-wrapped doc string can be attached to the named op. It should contain a oneliner for summary first, followed by lengthy description.</p><p>The following specification may be used to define a named <code>batchmatmul</code> op:</p><pre tabindex=0><code>def batchmatmul(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N)) """Batch matrix-multiply operation. This operation performs batch matrix-multiply over ... """ { C(b, m, n) = std_addf<k>(std_mulf(A(b, m, k), B(k, n))); } </code></pre><p>When <code>mlir-linalg-ods-gen -gen-ods-decl=1</code> is called, the following ODS is produced:</p><pre tabindex=0><code>def batchmatmulOp : LinalgNamedStructured_Op<"batchmatmul", [ NInputs<2>, NOutputs<1>, NamedStructuredOpTrait]> { ... } </code></pre><p>When <code>mlir-linalg-ods-gen -gen-impl=1</code> is called, the following C++ is produced:</p><pre tabindex=0><code>std::optional<SmallVector<StringRef, 8>> batchmatmul::referenceIterators() { return SmallVector<StringRef, 8>{ getParallelIteratorTypeName(), getParallelIteratorTypeName(), getParallelIteratorTypeName(), getReductionIteratorTypeName() }; } std::optional<SmallVector<AffineMap, 8>> batchmatmul::referenceIndexingMaps() { MLIRContext *context = getContext(); AffineExpr d0, d1, d2, d3; bindDims(context, d0, d1, d2, d3); return SmallVector<AffineMap, 8>{ AffineMap::get(4, 0, {d0, d1, d3}), AffineMap::get(4, 0, {d3, d2}), AffineMap::get(4, 0, {d0, d1, d2}) }; } void batchmatmul::regionBuilder(ArrayRef<BlockArgument> args) { using namespace edsc; using namespace intrinsics; Value _0(args[0]), _1(args[1]), _2(args[2]); Value _4 = std_mulf(_0, _1); Value _5 = std_addf(_2, _4); (linalg_yield(ValueRange{ _5 })); } </code></pre><h3 id=yaml-based-named-structured-opsa-nameyaml-gena>YAML Based Named Structured Ops<a name=yaml-gen></a></h3><p>Linalg provides a declarative generation tool (<code>mlir-linalg-ods-yaml-gen</code>) to automatically produce named ops from a YAML-based op description format intended to capture the structure of the named ops. The YAML-based op descriptions are generated from a higher level <a href=/docs/Dialects/Linalg/OpDSL/>DSL</a> and are not meant to be edited directly.</p><p>This facility is currently in flight and is intended to subsume the above when ready. See the C++ class to YAML mapping traits in <code>mlir-linalg-ods-yaml-gen.cpp</code> as the source of truth for the schema.</p><p>Most of the above documentation roughly applies to this path and will be ported as migration continues.</p><h2 id=open-issues-and-design-alternativesa-nameopen_issuesa>Open Issues and Design Alternatives<a name=open_issues></a></h2><p>Multiple open issues and design alternatives are in flight and it is time to lay them out for the community to discuss and pick apart:</p><ol><li>Should <code>linalg.generic</code> support nesting?</li><li>Should <code>linalg.generic</code> regions take views or only scalars?</li><li>Should we try to solve automatic differentiation at this level of abstraction?</li><li>Are all the six properties really necessary?</li><li>Is this relying too much on declarative specification and would we be better off relying more on analyses?</li><li>Is this general enough for the community’s needs? If not how should this be extended, if at all? …</li></ol><p>These key questions (and much more) should be really thought of in the general context of MLIR in which different levels of IR interoperate seamlessly. In practice, it is not necessary (or beneficial) to try and solve all problems in the same IR.</p><h2 id=operations>Operations</h2><p><a href=https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/Linalg/IR/LinalgDoc.td>source</a></p><h3 id=linalgabs-linalgabsop><code>linalg.abs</code> (linalg::AbsOp)</h3><p><em>Applies abs(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgadd-linalgaddop><code>linalg.add</code> (linalg::AddOp)</h3><p><em>Adds two tensors elementwise.</em></p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.add</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-1>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-1>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgbatch_matmul-linalgbatchmatmulop><code>linalg.batch_matmul</code> (linalg::BatchMatmulOp)</h3><p><em>Performs a batched matrix multiplication of two 3D inputs.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><pre><code>Broadcast and Transpose semantics can be appiled by specifying the explicit attribute 'indexing_maps' as shown below. This is a list attribute, so must include maps for all arguments if specified. Example Transpose: ``` linalg.batch_matmul indexing_maps = [ affine_map<(d0, d1, d2, d3) -> (d0, d3, d1)>, // transpose affine_map<(d0, d1, d2, d3) -> (d0, d3, d2)>, affine_map<(d0, d1, d2, d3) -> (d0, d1, d2)> ] ins(%arg0, %arg1 : memref<2x5x3xf32>,memref<2x5x7xf32>) outs(%arg2: memref<2x3x7xf32>) ``` Example Broadcast: ``` linalg.batch_matmul indexing_maps = [ affine_map<(d0, d1, d2, d3) -> (d3)>, // broadcast affine_map<(d0, d1, d2, d3) -> (d0, d3, d2)>, affine_map<(d0, d1, d2, d3) -> (d0, d1, d2)> ] ins(%arg0, %arg1 : memref<5xf32>, memref<2x5x7xf32>) outs(%arg2: memref<2x3x7xf32>) ``` Example Broadcast and Transpose: ``` linalg.batch_matmul indexing_maps = [ affine_map<(d0, d1, d2, d3) -> (d1, d3)>, // broadcast affine_map<(d0, d1, d2, d3) -> (d0, d2, d3)>, // transpose affine_map<(d0, d1, d2, d3) -> (d0, d1, d2)> ] ins(%arg0, %arg1 : memref<3x5xf32>, memref<2x7x5xf32>) outs(%arg2: memref<2x3x7xf32>) ``` </code></pre><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>indexing_maps</code></td><td>::mlir::ArrayAttr</td><td>AffineMap array attribute</td></tr><tr><td><code>cast</code></td><td>::mlir::linalg::TypeFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1</summary><p>Enum cases:</p><ul><li>cast_signed (<code>cast_signed</code>)</li><li>cast_unsigned (<code>cast_unsigned</code>)</li></ul></details></td></tr></table><h4 id=operands-2>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-2>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgbatch_matmul_transpose_a-linalgbatchmatmultransposeaop><code>linalg.batch_matmul_transpose_a</code> (linalg::BatchMatmulTransposeAOp)</h3><p><em>Performs a batched matrix multiplication of two 3D inputs where lhs operand has its non-batch dimensions transposed.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-3>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-3>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgbatch_matmul_transpose_b-linalgbatchmatmultransposebop><code>linalg.batch_matmul_transpose_b</code> (linalg::BatchMatmulTransposeBOp)</h3><p><em>Performs a batched matrix multiplication of two 3D inputs where rhs operand has its non-batch dimensions transposed.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-4>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-4>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgbatch_matvec-linalgbatchmatvecop><code>linalg.batch_matvec</code> (linalg::BatchMatvecOp)</h3><p><em>Performs a batched matrix-vector multiplication.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-5>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-5>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgbatch_mmt4d-linalgbatchmmt4dop><code>linalg.batch_mmt4d</code> (linalg::BatchMmt4DOp)</h3><p><em>Performs a batched matrix-matrix-transpose multiplication of two batched-4D (5D) inputs.</em></p><p>Besides the outermost batch dimension has the same semantic as linalg.batch_matmul, the differences from linalg.batch_matmul in the non-batch dimensions are the same as linalg.mmt4d vs. linalg.matmul. See the description of lingalg.mmt4d.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-6>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-6>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgbatch_reduce_matmul-linalgbatchreducematmulop><code>linalg.batch_reduce_matmul</code> (linalg::BatchReduceMatmulOp)</h3><p><em>Performs a batch-reduce matrix multiplication of two 3D inputs. The partial multiplication results are reduced into a 2D output.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-7>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-7>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgbatch_vecmat-linalgbatchvecmatop><code>linalg.batch_vecmat</code> (linalg::BatchVecmatOp)</h3><p><em>Performs a batched matrix-vector multiplication.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-8>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-8>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgbroadcast-linalgbroadcastop><code>linalg.broadcast</code> (linalg::BroadcastOp)</h3><p><em>Static broadcast operator</em></p><p>Broadcast the input into the given shape by adding <code>dimensions</code>.</p><p>Example:</p><pre tabindex=0><code> %bcast = linalg.broadcast ins(%input:tensor<16xf32>) outs(%init:tensor<16x64xf32>) dimensions = [1] </code></pre><p>Traits: <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>OpAsmOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-1>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>dimensions</code></td><td>::mlir::DenseI64ArrayAttr</td><td>i64 dense array attribute</td></tr></table><h4 id=operands-9>Operands:</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>memref of any type values or ranked tensor of any type values</td></tr><tr><td style=text-align:center><code>init</code></td><td>memref of any type values or ranked tensor of any type values</td></tr></tbody></table><h4 id=results-9>Results:</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>variadic of tensor of any type values</td></tr></tbody></table><h3 id=linalgceil-linalgceilop><code>linalg.ceil</code> (linalg::CeilOp)</h3><p><em>Applies ceil(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-10>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-10>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgcontract-linalgcontractop><code>linalg.contract</code> (linalg::ContractOp)</h3><p><em>Perform a contraction on two inputs, accumulating into the third.</em></p><p>The semantics of contracting inputs <code>A</code> and <code>B</code> on top of <code>C</code> to produce output <code>D</code> is given by</p><p><code>D[H] = (SUM_{(I ∪ J) \ H} A[I] * B[J]) + C[H]</code></p><p>where <code>I</code>, <code>J</code>, and <code>H</code> are tuples of (pairwise distinct) dimension identifiers - meant to range over valid indices - corresponding to the results of the mandatory (projected permutation) <code>indexing_maps</code> for <code>A</code>, <code>B</code> and <code>C</code>. <code>SUM_{dims}</code> means reduce over all valid indices for the dimensions in the set <code>dims</code> (with <code>I</code>, <code>J</code>, and <code>K</code> treated as <em>sets</em> of dim identifiers).</p><p>The iteration space consists of all dimensions in <code>I</code>, <code>J</code> and <code>H</code>, i.e. the domain of each of the <code>affine_map</code>s. Like for einsums, the iteration type of each dim is inferred and is either:</p><ul><li><p>reduction: the dim is used to index into <code>A</code> and <code>B</code> but not <code>C</code>. Per the above semantics, these dims will be contracted, i.e. reduced over.</p></li><li><p>parallel: the dim is used to index into <code>C</code> and at least one of <code>A</code> and <code>B</code>, and - deriving from matmul terminology - is either an “M-like” dim (if used on <code>A</code> and <code>C</code>), an “N-like” dim (if used on <code>B</code> and <code>C</code>) or a “batch”-dim (if used to index into <code>A</code>, <code>B</code>, and <code>C</code>).</p></li></ul><p>For example, batch-matmul is given by <code>I = ⟨ b, m, k ⟩</code>, <code>J = ⟨ b, k, n ⟩</code>, <code>H = ⟨ b, m, n ⟩</code> (with <code>k</code> as a contracting reduction-dimension while <code>m</code>, <code>n</code> and <code>b</code> have parallel iteration-type) and gets represented as:</p><pre tabindex=0><code>%D = linalg.contract indexing_maps = [affine_map<(batch, m, n, k) -> (batch, m, k)>, affine_map<(batch, m, n, k) -> (batch, k, n)>, affine_map<(batch, m, n, k) -> (batch, m, n)>] ins(%A, %B: tensor<?x?x?xf32>, tensor<?x?x?xf32>) outs(%C: tensor<?x?x?xf32>) -> tensor<?x?x?xf32> </code></pre><p>Note that by permuting dims in the <code>affine_map</code>s’ results, accesses to to the inputs and output can be arbitrarily transposed. Similarly, arbitrary broadcasts can be achieved through leaving out dims on either input operand. For example, the following is a variant of batch-matmul with a transposition applied to <code>A</code> while <code>B</code>’s 2D-matrix gets broadcasted along the batch dim:</p><pre tabindex=0><code>linalg.contract indexing_maps = [affine_map<(batch, m, n, k) -> (batch, k, m)>, affine_map<(batch, m, n, k) -> (k, n)>, affine_map<(batch, m, n, k) -> (batch, m, n)>] ins(%A, %B: memref<?x?x?xf32>, memref<?x?xf32>) outs(%C: memref<?x?x?xf32>) </code></pre><p>Numeric casting is performed on the operands to the inner multiplication, promoting/truncating them to the same data type as the accumulator/output.</p><p>TODO: Allow control over the combining/accumulating op and possibly the multiplication op.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-2>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>indexing_maps</code></td><td>::mlir::ArrayAttr</td><td>AffineMap array attribute</td></tr><tr><td><code>cast</code></td><td>::mlir::linalg::TypeFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1</summary><p>Enum cases:</p><ul><li>cast_signed (<code>cast_signed</code>)</li><li>cast_unsigned (<code>cast_unsigned</code>)</li></ul></details></td></tr></table><h4 id=operands-11>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-11>Results:</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_tensors</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h3 id=linalgconv_1d_ncw_fcw-linalgconv1dncwfcwop><code>linalg.conv_1d_ncw_fcw</code> (linalg::Conv1DNcwFcwOp)</h3><p><em>Performs 1-D convolution.</em></p><p>Layout:</p><ul><li>Input: NCW.</li><li>Kernel: FCW.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-3>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-12>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-12>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_1d_nwc_wcf-linalgconv1dnwcwcfop><code>linalg.conv_1d_nwc_wcf</code> (linalg::Conv1DNwcWcfOp)</h3><p><em>Performs 1-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-4>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-13>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-13>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_1d-linalgconv1dop><code>linalg.conv_1d</code> (linalg::Conv1DOp)</h3><p><em>Performs 1-D convolution with no channels.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-14>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-14>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_nchw_fchw-linalgconv2dnchwfchwop><code>linalg.conv_2d_nchw_fchw</code> (linalg::Conv2DNchwFchwOp)</h3><p><em>Performs 2-D convolution.</em></p><p>Layout:</p><ul><li>Input: NCHW.</li><li>Kernel: FCHW.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-5>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-15>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-15>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_nchw_fchw_q-linalgconv2dnchwfchwqop><code>linalg.conv_2d_nchw_fchw_q</code> (linalg::Conv2DNchwFchwQOp)</h3><p><em>Performs 2-D convolution with zero point offsets.</em></p><p>Layout:</p><ul><li>Input: NCHW.</li><li>Kernel: FCHW.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. This includes the zero point offsets common to quantized operations.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-6>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-16>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-16>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_ngchw_fgchw-linalgconv2dngchwfgchwop><code>linalg.conv_2d_ngchw_fgchw</code> (linalg::Conv2DNgchwFgchwOp)</h3><p><em>Performs 2-D grouped convolution.</em></p><p>Layout:</p><ul><li>Input: NGCHW.</li><li>Kernel: FGCHW.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-7>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-17>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-17>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_ngchw_gfchw-linalgconv2dngchwgfchwop><code>linalg.conv_2d_ngchw_gfchw</code> (linalg::Conv2DNgchwGfchwOp)</h3><p><em>Performs 2-D grouped convolution.</em></p><p>Layout:</p><ul><li>Input: NGCHW.</li><li>Kernel: GFCHW.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-8>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-18>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-18>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_ngchw_gfchw_q-linalgconv2dngchwgfchwqop><code>linalg.conv_2d_ngchw_gfchw_q</code> (linalg::Conv2DNgchwGfchwQOp)</h3><p><em>Performs 2-D grouped convolution with zero-point offsets.</em></p><p>Layout:</p><ul><li>Input: NGCHW.</li><li>Kernel: GFCHW.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. This includes the zero point offsets common to quantized operations.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-9>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-19>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-19>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_nhwc_fhwc-linalgconv2dnhwcfhwcop><code>linalg.conv_2d_nhwc_fhwc</code> (linalg::Conv2DNhwcFhwcOp)</h3><p><em>Performs 2-D convolution.</em></p><p>Layout:</p><ul><li>Input: NHWC.</li><li>Kernel: FHWC.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-10>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-20>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-20>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_nhwc_fhwc_q-linalgconv2dnhwcfhwcqop><code>linalg.conv_2d_nhwc_fhwc_q</code> (linalg::Conv2DNhwcFhwcQOp)</h3><p><em>Performs 2-D convolution with zero point offsets.</em></p><p>Layout:</p><ul><li>Input: NHWC.</li><li>Kernel: FHWC.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. This includes the zero point offsets common to quantized operations.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-11>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-21>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-21>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_nhwc_hwcf-linalgconv2dnhwchwcfop><code>linalg.conv_2d_nhwc_hwcf</code> (linalg::Conv2DNhwcHwcfOp)</h3><p><em>Performs 2-D convolution.</em></p><p>Layout:</p><ul><li>Input: NHWC.</li><li>Kernel: HWCF.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-12>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-22>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-22>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_nhwc_hwcf_q-linalgconv2dnhwchwcfqop><code>linalg.conv_2d_nhwc_hwcf_q</code> (linalg::Conv2DNhwcHwcfQOp)</h3><p><em>Performs 2-D convolution with zero point offsets.</em></p><p>Layout:</p><ul><li>Input: NHWC.</li><li>Kernel: HWCF.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. This includes the zero point offsets common to quantized operations.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-13>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-23>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-23>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_nhwgc_gfhwc-linalgconv2dnhwgcgfhwcop><code>linalg.conv_2d_nhwgc_gfhwc</code> (linalg::Conv2DNhwgcGfhwcOp)</h3><p><em>Performs 2-D grouped convolution.</em></p><p>Layout:</p><ul><li>Input: NHWGC.</li><li>Kernel: GFHWC.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-14>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-24>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-24>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d_nhwgc_gfhwc_q-linalgconv2dnhwgcgfhwcqop><code>linalg.conv_2d_nhwgc_gfhwc_q</code> (linalg::Conv2DNhwgcGfhwcQOp)</h3><p><em>Performs 2-D grouped convolution with zero point offsets.</em></p><p>Layout:</p><ul><li>Input: NHWGC.</li><li>Kernel: GFHWC.</li></ul><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. This includes the zero point offsets common to quantized operations.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-15>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-25>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-25>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_2d-linalgconv2dop><code>linalg.conv_2d</code> (linalg::Conv2DOp)</h3><p><em>Performs 2-D convolution with no channels.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-26>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-26>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_3d_ncdhw_fcdhw-linalgconv3dncdhwfcdhwop><code>linalg.conv_3d_ncdhw_fcdhw</code> (linalg::Conv3DNcdhwFcdhwOp)</h3><p><em>Performs 3-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-16>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-27>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-27>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_3d_ndhwc_dhwcf-linalgconv3dndhwcdhwcfop><code>linalg.conv_3d_ndhwc_dhwcf</code> (linalg::Conv3DNdhwcDhwcfOp)</h3><p><em>Performs 3-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-17>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-28>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-28>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_3d_ndhwc_dhwcf_q-linalgconv3dndhwcdhwcfqop><code>linalg.conv_3d_ndhwc_dhwcf_q</code> (linalg::Conv3DNdhwcDhwcfQOp)</h3><p><em>Performs 3-D convolution with zero point offsets.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. This includes the zero point offsets common to quantized operations.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-18>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-29>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-29>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgconv_3d-linalgconv3dop><code>linalg.conv_3d</code> (linalg::Conv3DOp)</h3><p><em>Performs 3-D convolution with no channels.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-30>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-30>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgcopy-linalgcopyop><code>linalg.copy</code> (linalg::CopyOp)</h3><p><em>Copies the tensor elementwise.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-19>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>cast</code></td><td>::mlir::linalg::TypeFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1</summary><p>Enum cases:</p><ul><li>cast_signed (<code>cast_signed</code>)</li><li>cast_unsigned (<code>cast_unsigned</code>)</li></ul></details></td></tr></table><h4 id=operands-31>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-31>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_1d_ncw_cw-linalgdepthwiseconv1dncwcwop><code>linalg.depthwise_conv_1d_ncw_cw</code> (linalg::DepthwiseConv1DNcwCwOp)</h3><p><em>Performs depth-wise 1-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. Multiplier is set to 1 which is a special case for most depthwise convolutions.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-20>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-32>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-32>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_1d_nwc_wc-linalgdepthwiseconv1dnwcwcop><code>linalg.depthwise_conv_1d_nwc_wc</code> (linalg::DepthwiseConv1DNwcWcOp)</h3><p><em>Performs depth-wise 1-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. Multiplier is set to 1 which is a special case for most depthwise convolutions.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-21>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-33>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-33>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_1d_nwc_wcm-linalgdepthwiseconv1dnwcwcmop><code>linalg.depthwise_conv_1d_nwc_wcm</code> (linalg::DepthwiseConv1DNwcWcmOp)</h3><p><em>Performs depth-wise 1-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-22>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-34>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-34>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_2d_nchw_chw-linalgdepthwiseconv2dnchwchwop><code>linalg.depthwise_conv_2d_nchw_chw</code> (linalg::DepthwiseConv2DNchwChwOp)</h3><p><em>Performs depth-wise 2-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. Multiplier is set to 1 which is a special case for most depthwise convolutions.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-23>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-35>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-35>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_2d_nhwc_hwc-linalgdepthwiseconv2dnhwchwcop><code>linalg.depthwise_conv_2d_nhwc_hwc</code> (linalg::DepthwiseConv2DNhwcHwcOp)</h3><p><em>Performs depth-wise 2-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. Multiplier is set to 1 which is a special case for most depthwise convolutions.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-24>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-36>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-36>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_2d_nhwc_hwc_q-linalgdepthwiseconv2dnhwchwcqop><code>linalg.depthwise_conv_2d_nhwc_hwc_q</code> (linalg::DepthwiseConv2DNhwcHwcQOp)</h3><p><em>Performs depth-wise 2-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-25>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-37>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-37>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_2d_nhwc_hwcm-linalgdepthwiseconv2dnhwchwcmop><code>linalg.depthwise_conv_2d_nhwc_hwcm</code> (linalg::DepthwiseConv2DNhwcHwcmOp)</h3><p><em>Performs depth-wise 2-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-26>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-38>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-38>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_2d_nhwc_hwcm_q-linalgdepthwiseconv2dnhwchwcmqop><code>linalg.depthwise_conv_2d_nhwc_hwcm_q</code> (linalg::DepthwiseConv2DNhwcHwcmQOp)</h3><p><em>Performs depth-wise 2-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-27>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-39>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-39>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_3d_ncdhw_cdhw-linalgdepthwiseconv3dncdhwcdhwop><code>linalg.depthwise_conv_3d_ncdhw_cdhw</code> (linalg::DepthwiseConv3DNcdhwCdhwOp)</h3><p><em>Performs depth-wise 3-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. Multiplier is set to 1 which is a special case for most depthwise convolutions.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-28>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-40>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-40>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_3d_ndhwc_dhwc-linalgdepthwiseconv3dndhwcdhwcop><code>linalg.depthwise_conv_3d_ndhwc_dhwc</code> (linalg::DepthwiseConv3DNdhwcDhwcOp)</h3><p><em>Performs depth-wise 3-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. Multiplier is set to 1 which is a special case for most depthwise convolutions.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-29>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-41>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-41>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdepthwise_conv_3d_ndhwc_dhwcm-linalgdepthwiseconv3dndhwcdhwcmop><code>linalg.depthwise_conv_3d_ndhwc_dhwcm</code> (linalg::DepthwiseConv3DNdhwcDhwcmOp)</h3><p><em>Performs depth-wise 3-D convolution.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-30>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-42>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-42>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdiv-linalgdivop><code>linalg.div</code> (linalg::DivOp)</h3><p><em>Divides the first tensor by the second tensor, elementwise.</em></p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.div</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-43>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-43>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdiv_unsigned-linalgdivunsignedop><code>linalg.div_unsigned</code> (linalg::DivUnsignedOp)</h3><p><em>Divides the first tensor by the second tensor, elementwise. For integer types, performs an unsigned division.</em></p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.div</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-44>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-44>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgdot-linalgdotop><code>linalg.dot</code> (linalg::DotOp)</h3><p><em>Performs a dot product of two vectors to a scalar result.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-45>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-45>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgelemwise_binary-linalgelemwisebinaryop><code>linalg.elemwise_binary</code> (linalg::ElemwiseBinaryOp)</h3><p><em>Applies the binary function fun elementwise.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-31>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>fun</code></td><td>::mlir::linalg::BinaryFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9</summary><p>Enum cases:</p><ul><li>add (<code>add</code>)</li><li>sub (<code>sub</code>)</li><li>mul (<code>mul</code>)</li><li>div (<code>div</code>)</li><li>div_unsigned (<code>div_unsigned</code>)</li><li>max_signed (<code>max_signed</code>)</li><li>min_signed (<code>min_signed</code>)</li><li>max_unsigned (<code>max_unsigned</code>)</li><li>min_unsigned (<code>min_unsigned</code>)</li><li>powf (<code>powf</code>)</li></ul></details></td></tr><tr><td><code>cast</code></td><td>::mlir::linalg::TypeFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1</summary><p>Enum cases:</p><ul><li>cast_signed (<code>cast_signed</code>)</li><li>cast_unsigned (<code>cast_unsigned</code>)</li></ul></details></td></tr></table><h4 id=operands-46>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-46>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgelemwise_unary-linalgelemwiseunaryop><code>linalg.elemwise_unary</code> (linalg::ElemwiseUnaryOp)</h3><p><em>Applies the unary function fun elementwise.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-32>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>fun</code></td><td>::mlir::linalg::UnaryFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12</summary><p>Enum cases:</p><ul><li>exp (<code>exp</code>)</li><li>log (<code>log</code>)</li><li>abs (<code>abs</code>)</li><li>ceil (<code>ceil</code>)</li><li>floor (<code>floor</code>)</li><li>negf (<code>negf</code>)</li><li>reciprocal (<code>reciprocal</code>)</li><li>round (<code>round</code>)</li><li>sqrt (<code>sqrt</code>)</li><li>rsqrt (<code>rsqrt</code>)</li><li>square (<code>square</code>)</li><li>tanh (<code>tanh</code>)</li><li>erf (<code>erf</code>)</li></ul></details></td></tr><tr><td><code>cast</code></td><td>::mlir::linalg::TypeFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1</summary><p>Enum cases:</p><ul><li>cast_signed (<code>cast_signed</code>)</li><li>cast_unsigned (<code>cast_unsigned</code>)</li></ul></details></td></tr></table><h4 id=operands-47>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-47>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgerf-linalgerfop><code>linalg.erf</code> (linalg::ErfOp)</h3><p><em>Applies erf(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-48>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-48>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgexp-linalgexpop><code>linalg.exp</code> (linalg::ExpOp)</h3><p><em>Applies exp(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-49>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-49>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgfill-linalgfillop><code>linalg.fill</code> (linalg::FillOp)</h3><p><em>Fills the output tensor with the given value.</em></p><p>Works for arbitrary ranked output tensors since the operation performs scalar accesses only and is thus rank polymorphic. Numeric casting is performed on the value operand, promoting it to the same data type as the output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgFillOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-50>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-50>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgfill_rng_2d-linalgfillrng2dop><code>linalg.fill_rng_2d</code> (linalg::FillRng2DOp)</h3><p><em>Fills the output tensor with pseudo random numbers.</em></p><p>The operation generations pseudo random numbers using a linear congruential generator. It provides no guarantees regarding the distribution of the generated random numbers. Instead of generating the random numbers sequentially, it instantiates one random number generator per data element and runs them in parallel. The seed operand and the indices of the data element seed the random number generation. The min and max operands limit the range of the generated random numbers.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-51>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-51>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgfloor-linalgfloorop><code>linalg.floor</code> (linalg::FloorOp)</h3><p><em>Applies floor(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-52>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-52>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalggeneric-linalggenericop><code>linalg.generic</code> (linalg::GenericOp)</h3><p>Generic Linalg op form where the key properties of the computation are specified as attributes. In pretty form, a <code>linalg.generic</code> op is written as:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>linalg<span class=p>.</span>generic <span class=nv>#trait_attribute</span> </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>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>,</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>)</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>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>)</span> </span></span><span class=line><span class=cl> <span class=nl>attrs =</span> <span class=p>{</span>other<span class=err>-</span>optional<span class=err>-</span>attributes<span class=p>}</span> </span></span><span class=line><span class=cl> <span class=p>{</span>region<span class=p>}</span> </span></span></code></pre></div><p>Where #trait_attributes is an alias of a dictionary attribute containing:</p><ul><li>doc [optional]: a documentation string</li><li>indexing_maps: a list of AffineMapAttr, one AffineMapAttr per each input and output view. Such AffineMapAttr specifies the mapping between the loops and the indexing within each view.</li><li>library_call [optional]: a StringAttr containing the name of an external library function that the linalg.generic operation maps to. The external library is assumed to be dynamically linked and no strong compile-time guarantees are provided. In the absence of such a library call, linalg.generic will always lower to loops.</li><li>iterator_types: an ArrayAttr specifying the type of the enclosing loops. Each element of the list represents and iterator of one of the following types: parallel, reduction, window</li></ul><p>Example: Defining a #matmul_trait attribute in MLIR can be done as follows:</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>#matmul_accesses</span> <span class=p>=</span> <span class=p>[</span> </span></span><span class=line><span class=cl> <span class=p>(</span>m<span class=p>,</span> n<span class=p>,</span> k<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>m<span class=p>,</span> k<span class=p>),</span> </span></span><span class=line><span class=cl> <span class=p>(</span>m<span class=p>,</span> n<span class=p>,</span> k<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>k<span class=p>,</span> n<span class=p>),</span> </span></span><span class=line><span class=cl> <span class=p>(</span>m<span class=p>,</span> n<span class=p>,</span> k<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>m<span class=p>,</span> n<span class=p>)</span> </span></span><span class=line><span class=cl><span class=p>]</span> </span></span><span class=line><span class=cl><span class=nv>#matmul_trait</span> <span class=p>=</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>doc =</span> <span class=s>"C(m, n) += A(m, k) * B(k, n)"</span><span class=p>,</span> </span></span><span class=line><span class=cl> <span class=nl>indexing_maps =</span> <span class=nv>#matmul_accesses</span><span class=p>,</span> </span></span><span class=line><span class=cl> <span class=nl>library_call =</span> <span class=s>"linalg_matmul"</span><span class=p>,</span> </span></span><span class=line><span class=cl> <span class=nl>iterator_types =</span> <span class=p>[</span><span class=s>"parallel"</span><span class=p>,</span> <span class=s>"parallel"</span><span class=p>,</span> <span class=s>"reduction"</span><span class=p>]</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>And can be reused in multiple places as:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>linalg<span class=p>.</span>generic <span class=nv>#matmul_trait</span> </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>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>,</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>)</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>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>)</span> </span></span><span class=line><span class=cl> <span class=p>{</span>other<span class=err>-</span>optional<span class=err>-</span>attributes<span class=p>}</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>^bb0</span><span class=p>(</span><span class=nv>%a</span><span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=nv>%b</span><span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=nv>%c</span><span class=p>:</span> <span class=k>f32</span><span class=p>)</span> <span class=p>:</span> </span></span><span class=line><span class=cl> <span class=nv>%d</span> <span class=p>=</span> arith<span class=p>.</span>mulf <span class=nv>%a</span><span class=p>,</span> <span class=nv>%b</span><span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> <span class=nv>%e</span> <span class=p>=</span> arith<span class=p>.</span>addf <span class=nv>%c</span><span class=p>,</span> <span class=nv>%d</span><span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>yield <span class=nv>%e</span> <span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>This may lower to either:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>call <span class=nf>@linalg_matmul</span><span class=p>(</span><span class=nv>%A</span><span class=p>,</span> <span class=nv>%B</span><span class=p>,</span> <span class=nv>%C</span><span class=p>)</span> <span class=p>:</span> </span></span><span class=line><span class=cl> <span class=p>(</span><span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>,</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>,</span> </span></span><span class=line><span class=cl> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>>)</span> </span></span><span class=line><span class=cl> <span class=p>-></span> <span class=p>()</span> </span></span></code></pre></div><p>or IR resembling:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>scf<span class=p>.</span>for <span class=nv>%m</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%M</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> scf<span class=p>.</span>for <span class=nv>%n</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%N</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> scf<span class=p>.</span>for <span class=nv>%k</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%K</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%a</span> <span class=p>=</span> load <span class=nv>%A</span><span class=p>[</span><span class=nv>%m</span><span class=p>,</span> <span class=nv>%k</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>></span> </span></span><span class=line><span class=cl> <span class=nv>%b</span> <span class=p>=</span> load <span class=nv>%B</span><span class=p>[</span><span class=nv>%k</span><span class=p>,</span> <span class=nv>%n</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>></span> </span></span><span class=line><span class=cl> <span class=nv>%c</span> <span class=p>=</span> load <span class=nv>%C</span><span class=p>[</span><span class=nv>%m</span><span class=p>,</span> <span class=nv>%n</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>></span> </span></span><span class=line><span class=cl> <span class=nv>%d</span> <span class=p>=</span> arith<span class=p>.</span>mulf <span class=nv>%a</span><span class=p>,</span> <span class=nv>%b</span><span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> <span class=nv>%e</span> <span class=p>=</span> arith<span class=p>.</span>addf <span class=nv>%c</span><span class=p>,</span> <span class=nv>%d</span><span class=p>:</span> <span class=k>f32</span> </span></span><span class=line><span class=cl> store <span class=nv>%e</span><span class=p>,</span> <span class=nv>%C</span><span class=p>[</span><span class=nv>%m</span><span class=p>,</span> <span class=nv>%n</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x?x</span><span class=k>f32</span><span class=p>,</span> stride_specification<span class=p>></span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>OpAsmOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-33>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>indexing_maps</code></td><td>::mlir::ArrayAttr</td><td>AffineMap array attribute</td></tr><tr><td><code>iterator_types</code></td><td>::mlir::ArrayAttr</td><td>Iterator type should be an enum.</td></tr><tr><td><code>doc</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr><tr><td><code>library_call</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr></table><h4 id=operands-53>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-53>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgindex-linalgindexop><code>linalg.index</code> (linalg::IndexOp)</h3><p><em>Linalg index operation</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `linalg.index` $dim attr-dict `:` type($result) </code></pre><p>The <code>linalg.index</code> operation returns the iteration index of the immediately enclosing linalg structured operation for the iteration dimension <code>dim</code>. The <code>dim</code> attribute specifies the position of the accessed dimension in the indexing map domain.</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>#map</span> <span class=p>=</span> affine_map<span class=p><(</span>i<span class=p>,</span> j<span class=p>)</span> <span class=p>-></span> <span class=p>(</span>i<span class=p>,</span> j<span class=p>)></span> </span></span><span class=line><span class=cl>linalg<span class=p>.</span>generic <span class=p>{</span><span class=nl>indexing_maps =</span> <span class=p>[</span><span class=nv>#map</span><span class=p>,</span> <span class=nv>#map</span><span class=p>],</span> </span></span><span class=line><span class=cl> <span class=nl>iterator_types =</span> <span class=p>[</span><span class=s>"parallel"</span><span class=p>,</span> <span class=s>"parallel"</span><span class=p>]}</span> </span></span><span class=line><span class=cl> outs<span class=p>(</span><span class=nv>%I</span><span class=p>,</span> <span class=nv>%J</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>index</span><span class=p>>,</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>index</span><span class=p>>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nl>^bb0</span><span class=p>(</span><span class=nv>%arg0</span> <span class=p>:</span> <span class=k>index</span><span class=p>,</span> <span class=nv>%arg1</span> <span class=p>:</span> <span class=k>index</span><span class=p>):</span> </span></span><span class=line><span class=cl> <span class=c>// Access the outer iteration dimension i </span></span></span><span class=line><span class=cl><span class=c></span> <span class=nv>%i</span> <span class=p>=</span> linalg<span class=p>.</span><span class=k>index</span> <span class=m>0</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> <span class=c>// Access the inner iteration dimension j </span></span></span><span class=line><span class=cl><span class=c></span> <span class=nv>%j</span> <span class=p>=</span> linalg<span class=p>.</span><span class=k>index</span> <span class=m>1</span> <span class=p>:</span> <span class=k>index</span> </span></span><span class=line><span class=cl> linalg<span class=p>.</span>yield <span class=nv>%i</span><span class=p>,</span> <span class=nv>%j</span> <span class=p>:</span> <span class=k>index</span><span class=p>,</span> <span class=k>index</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>This may lower to IR resembling:</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> dim <span class=nv>%I</span><span class=p>,</span> <span class=nv>%c0</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>index</span><span class=p>></span> </span></span><span class=line><span class=cl><span class=nv>%1</span> <span class=p>=</span> dim <span class=nv>%I</span><span class=p>,</span> <span class=nv>%c1</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>index</span><span class=p>></span> </span></span><span class=line><span class=cl>scf<span class=p>.</span>for <span class=nv>%i</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%0</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> scf<span class=p>.</span>for <span class=nv>%j</span> <span class=p>=</span> <span class=nv>%c0</span> to <span class=nv>%1</span> step <span class=nv>%c1</span> <span class=p>{</span> </span></span><span class=line><span class=cl> store <span class=nv>%i</span><span class=p>,</span> <span class=nv>%I</span><span class=p>[</span><span class=nv>%i</span><span class=p>,</span> <span class=nv>%j</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>index</span><span class=p>></span> </span></span><span class=line><span class=cl> store <span class=nv>%j</span><span class=p>,</span> <span class=nv>%J</span><span class=p>[</span><span class=nv>%i</span><span class=p>,</span> <span class=nv>%j</span><span class=p>]</span> <span class=p>:</span> <span class=kt>memref</span><span class=p><</span><span class=m>?x?x</span><span class=k>index</span><span class=p>></span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>Traits: <code>AlwaysSpeculatableImplTrait</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>InferTypeOpInterface</code>, <code>NoMemoryEffect (MemoryEffectOpInterface)</code></p><p>Effects: <code>MemoryEffects::Effect{}</code></p><h4 id=attributes-34>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>dim</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute whose minimum value is 0</td></tr></table><h4 id=results-54>Results:</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>index</td></tr></tbody></table><h3 id=linalgsoftmax-linalgsoftmaxop><code>linalg.softmax</code> (linalg::SoftmaxOp)</h3><p><em>Softmax operator</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `linalg.softmax` attr-dict `dimension` `(` $dimension `)` `ins` `(` $input `:` type($input) `)` `outs` `(` $output `:` type($output) `)` (`->` type($result)^)? </code></pre><p>linalg.softmax computes a numerically stable version of softmax.</p><p>For a given input tensor and a specified dimension <code>d</code>, compute:</p><ol><li>the max <code>m</code> along that dimension <code>d</code></li><li>f(x) = exp(x - m)</li><li>sum f(x) along dimension d to get l(x).</li><li>compute the final result f(x) / l(x).</li></ol><p>This is an aggregate linalg operation that further reduces to a small DAG of structured operations.</p><p>Warning: Regarding the tiling capabilities, the implementation doesn’t check that the provided dimensions make sense. This is the responsability of the transformation calling the tiling to ensure that the provided sizes for each dimension make sense with respect to the semantic of softmax.</p><p>Interfaces: <code>AggregatedOpInterface</code>, <code>DestinationStyleOpInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code>, <code>TilingInterface</code></p><h4 id=attributes-35>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>dimension</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute</td></tr></table><h4 id=operands-54>Operands:</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>shaped of any type values</td></tr><tr><td style=text-align:center><code>output</code></td><td>shaped of any type values</td></tr></tbody></table><h4 id=results-55>Results:</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>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgwinograd_filter_transform-linalgwinogradfiltertransformop><code>linalg.winograd_filter_transform</code> (linalg::WinogradFilterTransformOp)</h3><p><em>Winograd filter transform operator</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `linalg.winograd_filter_transform` attr-dict `m` `(` $m `)` `r` `(` $r `)` `ins` `(` $filter `:` type($filter) `)` `outs` `(` $output `:` type($output) `)` `->` type($result) </code></pre><p>Winograd Conv2D algorithm will convert linalg Conv2D operator into batched matrix multiply. Before the matrix multiply, it will convert filter and input into a format suitable for batched matrix multiply. After the matrix multiply, it will convert output to the final result tensor.</p><p>The algorithm F(m x m, r x r) is</p><p>Y = A^T x [(G x g x G^T) @ (B^T x d x B)] x A</p><p>The size of output Y is m x m. The size of filter g is r x r. The size of input d is (m + r - 1) x (m + r - 1). A^T, A, G^T, G, B^T, and B are transformation matrices.</p><p>This operator is defined to represent the high level concept of filter transformation (G x g x G^T) in the Winograd Conv2D algorithm.</p><p>Interfaces: <code>DestinationStyleOpInterface</code>, <code>TilingInterface</code></p><h4 id=attributes-36>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>m</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute</td></tr><tr><td><code>r</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute</td></tr></table><h4 id=operands-55>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>filter</code></td><td>4D tensor of any type values</td></tr><tr><td style=text-align:center><code>output</code></td><td>4D tensor of any type values</td></tr></tbody></table><h4 id=results-56>Results:</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>4D tensor of any type values</td></tr></tbody></table><h3 id=linalgwinograd_input_transform-linalgwinogradinputtransformop><code>linalg.winograd_input_transform</code> (linalg::WinogradInputTransformOp)</h3><p><em>Winograd input transform operator</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `linalg.winograd_input_transform` attr-dict `m` `(` $m `)` `r` `(` $r `)` `ins` `(` $input `:` type($input) `)` `outs` `(` $output `:` type($output) `)` `->` type($result) </code></pre><p>Winograd Conv2D algorithm will convert linalg Conv2D operator into batched matrix multiply. Before the matrix multiply, it will convert filter and input into a format suitable for batched matrix multiply. After the matrix multiply, it will convert output to the final result tensor.</p><p>The algorithm F(m x m, r x r) is</p><p>Y = A^T x [(G x g x G^T) @ (B^T x d x B)] x A</p><p>The size of output Y is m x m. The size of filter g is r x r. The size of input d is (m + r - 1) x (m + r - 1). A^T, A, G^T, G, B^T, and B are transformation matrices.</p><p>This operator is defined to represent the high level concept of input transformation (B^T x d x B) in the Winograd Conv2D algorithm.</p><p>Interfaces: <code>DestinationStyleOpInterface</code>, <code>TilingInterface</code></p><h4 id=attributes-37>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>m</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute</td></tr><tr><td><code>r</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute</td></tr></table><h4 id=operands-56>Operands:</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>4D tensor of any type values</td></tr><tr><td style=text-align:center><code>output</code></td><td>6D tensor of any type values</td></tr></tbody></table><h4 id=results-57>Results:</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>6D tensor of any type values</td></tr></tbody></table><h3 id=linalgwinograd_output_transform-linalgwinogradoutputtransformop><code>linalg.winograd_output_transform</code> (linalg::WinogradOutputTransformOp)</h3><p><em>Winograd output transform operator</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `linalg.winograd_output_transform` attr-dict `m` `(` $m `)` `r` `(` $r `)` `ins` `(` $value `:` type($value) `)` `outs` `(` $output `:` type($output) `)` `->` type($result) </code></pre><p>Winograd Conv2D algorithm will convert linalg Conv2D operator into batched matrix multiply. Before the matrix multiply, it will convert filter and input into a format suitable for batched matrix multiply. After the matrix multiply, it will convert output to the final result tensor.</p><p>The algorithm F(m x m, r x r) is</p><p>Y = A^T x [(G x g x G^T) @ (B^T x d x B)] x A</p><p>The size of output Y is m x m. The size of filter g is r x r. The size of input d is (m + r - 1) x (m + r - 1). A^T, A, G^T, G, B^T, and B are transformation matrices.</p><p>This operator is defined to represent the high level concept of output transformation (A^T x y x A) in the Winograd Conv2D algorithm.</p><p>Interfaces: <code>DestinationStyleOpInterface</code>, <code>TilingInterface</code></p><h4 id=attributes-38>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>m</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute</td></tr><tr><td><code>r</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute</td></tr></table><h4 id=operands-57>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>value</code></td><td>6D tensor of any type values</td></tr><tr><td style=text-align:center><code>output</code></td><td>4D tensor of any type values</td></tr></tbody></table><h4 id=results-58>Results:</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>4D tensor of any type values</td></tr></tbody></table><h3 id=linalgyield-linalgyieldop><code>linalg.yield</code> (linalg::YieldOp)</h3><p><em>Linalg yield operation</em></p><p><code>linalg.yield</code> is a special terminator operation for blocks inside regions in <code>linalg</code> generic ops. It returns values to the immediately enclosing <code>linalg</code> generic op.</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>linalg<span class=p>.</span>yield <span class=nv>%f0</span><span class=p>,</span> <span class=nv>%f1</span> <span class=p>:</span> <span class=k>f32</span><span class=p>,</span> <span class=k>f32</span> </span></span></code></pre></div><p>Traits: <code>AlwaysSpeculatableImplTrait</code>, <code>ReturnLike</code>, <code>Terminator</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>NoMemoryEffect (MemoryEffectOpInterface)</code>, <code>RegionBranchTerminatorOpInterface</code></p><p>Effects: <code>MemoryEffects::Effect{}</code></p><h4 id=operands-58>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>values</code></td><td>variadic of any type</td></tr></tbody></table><h3 id=linalglog-linalglogop><code>linalg.log</code> (linalg::LogOp)</h3><p><em>Applies log(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-59>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-59>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgmap-linalgmapop><code>linalg.map</code> (linalg::MapOp)</h3><p><em>Elementwise operations</em></p><p>Models elementwise operations on tensors in terms of arithmetic operations on the corresponding elements.</p><p>Example:</p><pre tabindex=0><code> %add = linalg.map ins(%lhs, %rhs : tensor<64xf32>, tensor<64xf32>) outs(%init: tensor<64xf32>) (%lhs_elem: f32, %rhs_elem: f32) { %0 = arith.addf %lhs_elem, %rhs_elem: f32 linalg.yield %0: f32 } </code></pre><p>Shortened print form is available. Applies to simple maps with one non-yield operation inside the body.</p><p>The example above will be printed as:</p><pre tabindex=0><code> %add = linalg.map { arith.addf } ins(%lhs, %rhs : tensor<64xf32>, tensor<64xf32>) outs(%init: tensor<64xf32>) </code></pre><p>Traits: <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>OpAsmOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-60>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of memref of any type values or ranked tensor of any type values</td></tr><tr><td style=text-align:center><code>init</code></td><td>memref of any type values or ranked tensor of any type values</td></tr></tbody></table><h4 id=results-60>Results:</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>variadic of tensor of any type values</td></tr></tbody></table><h3 id=linalgmatmul-linalgmatmulop><code>linalg.matmul</code> (linalg::MatmulOp)</h3><p><em>Performs a matrix multiplication of two 2D inputs without broadcast or transpose.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Broadcast and Transpose semantics can be appiled by specifying the explicit attribute ‘indexing_maps’ as shown below.This is a list attribute, so the list must include all the maps if specified.</p><p>Example Transpose:</p><pre tabindex=0><code>linalg.matmul indexing_maps = [ affine_map<(d0, d1, d2) -> (d2, d0)>, // transpose affine_map<(d0, d1, d2) -> (d2, d1)>, affine_map<(d0, d1, d2) -> (d0, d1)> ] ins(%arg0, %arg1 : memref<5x3xf32>,memref<5x7xf32>) outs(%arg2: memref<3x7xf32>) </code></pre><p>Example Broadcast:</p><pre tabindex=0><code>linalg.matmul indexing_maps = [ affine_map<(d0, d1, d2) -> (d2)>, // broadcast affine_map<(d0, d1, d2) -> (d2, d1)>, affine_map<(d0, d1, d2) -> (d0, d1)> ] ins(%arg0, %arg1 : memref<3xf32>, memref<5x7xf32>) outs(%arg2: memref<3x7xf32>) </code></pre><p>Example Broadcast and transpose:</p><pre tabindex=0><code>linalg.matmul indexing_maps = [ affine_map<(d0, d1, d2) -> (d2, d0)>, // transpose affine_map<(d0, d1, d2) -> (d2)>, // broadcast affine_map<(d0, d1, d2) -> (d0, d1)> ] ins(%arg0, %arg1 : memref<5x3xf32>, memref<7xf32>) outs(%arg2: memref<3x7xf32>) </code></pre><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-39>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>indexing_maps</code></td><td>::mlir::ArrayAttr</td><td>AffineMap array attribute</td></tr><tr><td><code>cast</code></td><td>::mlir::linalg::TypeFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1</summary><p>Enum cases:</p><ul><li>cast_signed (<code>cast_signed</code>)</li><li>cast_unsigned (<code>cast_unsigned</code>)</li></ul></details></td></tr></table><h4 id=operands-61>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-61>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgmatmul_transpose_a-linalgmatmultransposeaop><code>linalg.matmul_transpose_a</code> (linalg::MatmulTransposeAOp)</h3><p><em>Performs a matrix multiplication of two 2D inputs with lhs operand transposed.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-40>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>cast</code></td><td>::mlir::linalg::TypeFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1</summary><p>Enum cases:</p><ul><li>cast_signed (<code>cast_signed</code>)</li><li>cast_unsigned (<code>cast_unsigned</code>)</li></ul></details></td></tr></table><h4 id=operands-62>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-62>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgmatmul_transpose_b-linalgmatmultransposebop><code>linalg.matmul_transpose_b</code> (linalg::MatmulTransposeBOp)</h3><p><em>Performs a matrix multiplication of two 2D inputs with rhs operand transposed.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-41>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>cast</code></td><td>::mlir::linalg::TypeFnAttr</td><td><details><summary>allowed 32-bit signless integer cases: 0, 1</summary><p>Enum cases:</p><ul><li>cast_signed (<code>cast_signed</code>)</li><li>cast_unsigned (<code>cast_unsigned</code>)</li></ul></details></td></tr></table><h4 id=operands-63>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-63>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgmatvec-linalgmatvecop><code>linalg.matvec</code> (linalg::MatvecOp)</h3><p><em>Performs a matrix-vector multiplication.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-64>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-64>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgmax-linalgmaxop><code>linalg.max</code> (linalg::MaxOp)</h3><p><em>Takes the max (signed) between two inputs, elementwise.</em></p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.max</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-65>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-65>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgmin-linalgminop><code>linalg.min</code> (linalg::MinOp)</h3><p><em>Takes the min (signed) between two inputs, elementwise.</em></p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.min</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-66>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-66>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgmmt4d-linalgmmt4dop><code>linalg.mmt4d</code> (linalg::Mmt4DOp)</h3><p><em>Performs a matrix-matrix-transpose multiplication of two 4D inputs.</em></p><p>Differences from linalg.matmul:</p><ul><li>The right hand side is transposed, whence the ’t’ in ‘mmt’.</li><li>The input and output tensors have a 4D shape instead of a 2D shape. They are interpreted as 2D matrices with one level of 2D tile subdivision, whence the 2+2=4 dimensions. The inner tile dimensions are identified with ‘0’ suffixes below, for instance the LHS matrix shape (M, K, M0, K0) reads as: MxK tiles, each of shape M0xK0.</li></ul><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-67>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-67>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgmul-linalgmulop><code>linalg.mul</code> (linalg::MulOp)</h3><p><em>Multiplies two tensors elementwise.</em></p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.mul</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-68>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-68>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgnegf-linalgnegfop><code>linalg.negf</code> (linalg::NegFOp)</h3><p><em>Applies negf(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-69>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-69>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nchw_max-linalgpoolingnchwmaxop><code>linalg.pooling_nchw_max</code> (linalg::PoolingNchwMaxOp)</h3><p><em>Performs max pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-42>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-70>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-70>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nchw_sum-linalgpoolingnchwsumop><code>linalg.pooling_nchw_sum</code> (linalg::PoolingNchwSumOp)</h3><p><em>Performs sum pooling.</em></p><p>Layout:</p><ul><li>Input: NCHW.</li><li>Kernel: HW.</li></ul><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-43>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-71>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-71>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_ncw_max-linalgpoolingncwmaxop><code>linalg.pooling_ncw_max</code> (linalg::PoolingNcwMaxOp)</h3><p><em>Performs max pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-44>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-72>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-72>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_ncw_sum-linalgpoolingncwsumop><code>linalg.pooling_ncw_sum</code> (linalg::PoolingNcwSumOp)</h3><p><em>Performs sum pooling.</em></p><p>Layout:</p><ul><li>Input: NCW.</li><li>Kernel: W.</li></ul><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-45>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-73>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-73>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_ndhwc_max-linalgpoolingndhwcmaxop><code>linalg.pooling_ndhwc_max</code> (linalg::PoolingNdhwcMaxOp)</h3><p><em>Performs 3D max pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-46>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-74>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-74>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_ndhwc_min-linalgpoolingndhwcminop><code>linalg.pooling_ndhwc_min</code> (linalg::PoolingNdhwcMinOp)</h3><p><em>Performs 3D min pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-47>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-75>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-75>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_ndhwc_sum-linalgpoolingndhwcsumop><code>linalg.pooling_ndhwc_sum</code> (linalg::PoolingNdhwcSumOp)</h3><p><em>Performs 3D sum pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-48>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [3]</td></tr></table><h4 id=operands-76>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-76>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nhwc_max-linalgpoolingnhwcmaxop><code>linalg.pooling_nhwc_max</code> (linalg::PoolingNhwcMaxOp)</h3><p><em>Performs max pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-49>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-77>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-77>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nhwc_max_unsigned-linalgpoolingnhwcmaxunsignedop><code>linalg.pooling_nhwc_max_unsigned</code> (linalg::PoolingNhwcMaxUnsignedOp)</h3><p><em>Performs unsigned max pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-50>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-78>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-78>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nhwc_min-linalgpoolingnhwcminop><code>linalg.pooling_nhwc_min</code> (linalg::PoolingNhwcMinOp)</h3><p><em>Performs min pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-51>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-79>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-79>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nhwc_min_unsigned-linalgpoolingnhwcminunsignedop><code>linalg.pooling_nhwc_min_unsigned</code> (linalg::PoolingNhwcMinUnsignedOp)</h3><p><em>Performs unsigned min pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-52>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-80>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-80>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nhwc_sum-linalgpoolingnhwcsumop><code>linalg.pooling_nhwc_sum</code> (linalg::PoolingNhwcSumOp)</h3><p><em>Performs sum pooling.</em></p><p>Layout:</p><ul><li>Input: NHWC.</li><li>Kernel: HW.</li></ul><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-53>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [2]</td></tr></table><h4 id=operands-81>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-81>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nwc_max-linalgpoolingnwcmaxop><code>linalg.pooling_nwc_max</code> (linalg::PoolingNwcMaxOp)</h3><p><em>Performs max pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-54>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-82>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-82>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nwc_max_unsigned-linalgpoolingnwcmaxunsignedop><code>linalg.pooling_nwc_max_unsigned</code> (linalg::PoolingNwcMaxUnsignedOp)</h3><p><em>Performs unsigned max pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-55>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-83>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-83>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nwc_min-linalgpoolingnwcminop><code>linalg.pooling_nwc_min</code> (linalg::PoolingNwcMinOp)</h3><p><em>Performs min pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-56>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-84>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-84>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nwc_min_unsigned-linalgpoolingnwcminunsignedop><code>linalg.pooling_nwc_min_unsigned</code> (linalg::PoolingNwcMinUnsignedOp)</h3><p><em>Performs unsigned min pooling.</em></p><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-57>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-85>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-85>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpooling_nwc_sum-linalgpoolingnwcsumop><code>linalg.pooling_nwc_sum</code> (linalg::PoolingNwcSumOp)</h3><p><em>Performs sum pooling.</em></p><p>Layout:</p><ul><li>Input: NWC.</li><li>Kernel: W.</li></ul><p>Numeric casting is performed on the input operand, promoting it to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgConvolutionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-58>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>strides</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr><tr><td><code>dilations</code></td><td>::mlir::DenseIntElementsAttr</td><td>64-bit signless int elements attribute of shape [1]</td></tr></table><h4 id=operands-86>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-86>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgpowf-linalgpowfop><code>linalg.powf</code> (linalg::PowFOp)</h3><p><em>Takes the powf(lhs, rhs) between two inputs, elementwise. For powf(arg, 2) use <code>linalg.square</code>.</em></p><p>Only applies to floating point values.</p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.powf</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-87>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-87>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgquantized_batch_matmul-linalgquantizedbatchmatmulop><code>linalg.quantized_batch_matmul</code> (linalg::QuantizedBatchMatmulOp)</h3><p><em>Performs a batched matrix multiplication of two 3D inputs.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. The quantized variant includes zero-point adjustments for the left and right operands of the matmul.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-88>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-88>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgquantized_matmul-linalgquantizedmatmulop><code>linalg.quantized_matmul</code> (linalg::QuantizedMatmulOp)</h3><p><em>Performs a matrix multiplication of two 2D inputs.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output. The quantized variant includes zero-point adjustments for the left and right operands of the matmul.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-89>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-89>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgreciprocal-linalgreciprocalop><code>linalg.reciprocal</code> (linalg::ReciprocalOp)</h3><p><em>Applies reciprocal(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-90>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-90>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgreduce-linalgreduceop><code>linalg.reduce</code> (linalg::ReduceOp)</h3><p><em>Reduce operator</em></p><p>Executes <code>combiner</code> on the <code>dimensions</code> of <code>inputs</code> and returns the reduced result. The <code>dimensions</code> attribute needs to list the reduction dimensions in increasing order.</p><p>Example:</p><pre tabindex=0><code> %reduce = linalg.reduce ins(%input:tensor<16x32x64xf32>) outs(%init:tensor<16x64xf32>) dimensions = [1] (%in: f32, %out: f32) { %0 = arith.addf %out, %in: f32 linalg.yield %0: f32 } </code></pre><p>Shortened print form is available. Applies to simple (not variadic) reduces with one non-yield operation inside the body. Applies only if the operation takes <code>%out</code> as the first argument.</p><p>The example above will be printed as:</p><pre tabindex=0><code> %reduce = linalg.reduce { arith.addf } ins(%input:tensor<16x32x64xf32>) outs(%init:tensor<16x64xf32>) dimensions = [1] </code></pre><p>Traits: <code>RecursiveMemoryEffects</code>, <code>SameVariadicOperandSize</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>OpAsmOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-59>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>dimensions</code></td><td>::mlir::DenseI64ArrayAttr</td><td>i64 dense array attribute should be in increasing order</td></tr></table><h4 id=operands-91>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of memref of any type values or ranked tensor of any type values</td></tr><tr><td style=text-align:center><code>inits</code></td><td>variadic of memref of any type values or ranked tensor of any type values</td></tr></tbody></table><h4 id=results-91>Results:</h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>«unnamed»</td><td>variadic of tensor of any type values</td></tr></tbody></table><h3 id=linalground-linalgroundop><code>linalg.round</code> (linalg::RoundOp)</h3><p><em>Applies round(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-92>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-92>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgrsqrt-linalgrsqrtop><code>linalg.rsqrt</code> (linalg::RsqrtOp)</h3><p><em>Applies rsqrt(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-93>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-93>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgselect-linalgselectop><code>linalg.select</code> (linalg::SelectOp)</h3><p><em>Chooses one value based on a binary condition supplied as its first operand.</em></p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.select</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-94>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-94>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgsqrt-linalgsqrtop><code>linalg.sqrt</code> (linalg::SqrtOp)</h3><p><em>Applies sqrt(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-95>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-95>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgsquare-linalgsquareop><code>linalg.square</code> (linalg::SquareOp)</h3><p><em>Applies square(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-96>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-96>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgsub-linalgsubop><code>linalg.sub</code> (linalg::SubOp)</h3><p><em>Subtracts two tensors elementwise.</em></p><p>The shapes and element types must be identical. The appropriate casts, broadcasts and reductions should be done previously to calling this op.</p><p>This means reduction/broadcast/element cast semantics is explicit. Further passes can take that into account when lowering this code. For example, a <code>linalg.broadcast</code> + <code>linalg.sub</code> sequence can be lowered to a <code>linalg.generic</code> with different affine maps for the two operands.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-97>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-97>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgtanh-linalgtanhop><code>linalg.tanh</code> (linalg::TanhOp)</h3><p><em>Applies tanh(x) elementwise.</em></p><p>No numeric casting is performed on the input operand.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-98>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-98>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h3 id=linalgtranspose-linalgtransposeop><code>linalg.transpose</code> (linalg::TransposeOp)</h3><p><em>Transpose operator</em></p><p>Permutes the dimensions of <code>input</code> according to the given <code>permutation</code>. <code>dim(result, i) = dim(input, permutation[i])</code></p><p>This op actually moves data, unlike <code>memref.transpose</code> which is a metadata operation only that produces a transposed “view”.</p><p>Example:</p><pre tabindex=0><code> %transpose = linalg.transpose ins(%input:tensor<16x64xf32>) outs(%init:tensor<64x16xf32>) permutation = [1, 0] </code></pre><p>Traits: <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>OpAsmOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=attributes-60>Attributes:</h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>permutation</code></td><td>::mlir::DenseI64ArrayAttr</td><td>i64 dense array attribute</td></tr></table><h4 id=operands-99>Operands:</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>memref of any type values or ranked tensor of any type values</td></tr><tr><td style=text-align:center><code>init</code></td><td>memref of any type values or ranked tensor of any type values</td></tr></tbody></table><h4 id=results-99>Results:</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>variadic of tensor of any type values</td></tr></tbody></table><h3 id=linalgvecmat-linalgvecmatop><code>linalg.vecmat</code> (linalg::VecmatOp)</h3><p><em>Performs a vector-matrix multiplication.</em></p><p>Numeric casting is performed on the operands to the inner multiply, promoting them to the same data type as the accumulator/output.</p><p>Traits: <code>AttrSizedOperandSegments</code>, <code>RecursiveMemoryEffects</code>, <code>SingleBlockImplicitTerminator<YieldOp></code>, <code>SingleBlock</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>DestinationStyleOpInterface</code>, <code>LinalgContractionOpInterface</code>, <code>LinalgStructuredInterface</code>, <code>MemoryEffectOpInterface</code>, <code>ReifyRankedShapedTypeOpInterface</code></p><h4 id=operands-100>Operands:</h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>inputs</code></td><td>variadic of any type</td></tr><tr><td style=text-align:center><code>outputs</code></td><td>variadic of shaped of any type values</td></tr></tbody></table><h4 id=results-100>Results:</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_tensors</code></td><td>variadic of ranked tensor of any type values</td></tr></tbody></table><h2>'linalg' Dialect Docs</h2><ul><li><a href=https://mlir.llvm.org/docs/Dialects/Linalg/OpDSL/>Linalg OpDSL</a></li></ul><div class=edit-meta><br></div><nav class=pagination><a class="nav nav-prev" href=https://mlir.llvm.org/docs/Dialects/IRDL/ title="'irdl' Dialect"><i class="fas fa-arrow-left" aria-hidden=true></i> Prev - 'irdl' Dialect</a> <a class="nav nav-next" href=https://mlir.llvm.org/docs/Dialects/Linalg/OpDSL/ title="Linalg OpDSL">Next - Linalg OpDSL <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/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/Assembly/>Customizing Assembly Behavior</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/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="active 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>