brintos

brintos / llvm-project-archived public Read only

0
0
Text · 173.3 KiB · 5f7fb00 Raw
3838 lines · plain
1=============================2User Guide for NVPTX Back-end3=============================4 5.. contents::6   :local:7   :depth: 38 9 10Introduction11============12 13To support GPU programming, the NVPTX back-end supports a subset of LLVM IR14along with a defined set of conventions used to represent GPU programming15concepts. This document provides an overview of the general usage of the back-16end, including a description of the conventions used and the set of accepted17LLVM IR.18 19.. note::20 21   This document assumes a basic familiarity with CUDA and the PTX22   assembly language. Information about the CUDA Driver API and the PTX assembly23   language can be found in the `CUDA documentation24   <http://docs.nvidia.com/cuda/index.html>`_.25 26 27 28Conventions29===========30 31Marking Functions as Kernels32----------------------------33 34In PTX, there are two types of functions: *device functions*, which are only35callable by device code, and *kernel functions*, which are callable by host36code. By default, the back-end will emit device functions. The ``ptx_kernel``37calling convention is used to declare a function as a kernel function.38 39The following example shows a kernel function calling a device function in LLVM40IR. The function ``@my_kernel`` is callable from host code, but ``@my_fmad`` is41not.42 43.. code-block:: llvm44 45    define float @my_fmad(float %x, float %y, float %z) {46      %mul = fmul float %x, %y47      %add = fadd float %mul, %z48      ret float %add49    }50 51    define ptx_kernel void @my_kernel(ptr %ptr) {52      %val = load float, ptr %ptr53      %ret = call float @my_fmad(float %val, float %val, float %val)54      store float %ret, ptr %ptr55      ret void56    }57 58When compiled, the PTX kernel functions are callable by host-side code.59 60 61Parameter Attributes62--------------------63 64``"nvvm.grid_constant"``65    This attribute may be attached to a ``byval`` parameter of a kernel function66    to indicate that the parameter should be lowered as a direct reference to67    the grid-constant memory of the parameter, as opposed to a copy of the68    parameter in local memory. Writing to a grid-constant parameter is69    undefined behavior. Unlike a normal ``byval`` parameter, the address of a70    grid-constant parameter is not unique to a given function invocation but71    instead is shared by all kernels in the grid.72 73.. _nvptx_fnattrs:74 75Function Attributes76-------------------77 78``"nvvm.maxclusterrank"="<n>"``79    This attribute specifies the maximum number of blocks per cluster. Must be 80    non-zero. Only supported for Hopper+.81 82``"nvvm.minctasm"="<n>"``83    This indicates a hint/directive to the compiler/driver, asking it to put at84    least these many CTAs on an SM.85 86``"nvvm.maxnreg"="<n>"``87    This attribute indicates the maximum number of registers to be used for the88    kernel function.89 90``"nvvm.maxntid"="<x>[,<y>[,<z>]]"``91    This attribute declares the maximum number of threads in the thread block92    (CTA). The maximum number of threads is the product of the maximum extent in93    each dimension. Exceeding the maximum number of threads results in a runtime94    error or kernel launch failure.95 96``"nvvm.reqntid"="<x>[,<y>[,<z>]]"``97    This attribute declares the exact number of threads in the thread block98    (CTA). The number of threads is the product of the value in each dimension.99    Specifying a different CTA dimension at launch will result in a runtime 100    error or kernel launch failure.101 102``"nvvm.cluster_dim"="<x>[,<y>[,<z>]]"``103    This attribute declares the number of thread blocks (CTAs) in the cluster.104    The total number of CTAs is the product of the number of CTAs in each 105    dimension. Specifying a different cluster dimension at launch will result in106    a runtime error or kernel launch failure. Only supported for Hopper+.107 108``"nvvm.blocksareclusters"``109    This attribute implies that the grid launch configuration for the corresponding110    kernel function is specifying the number of clusters instead of the number of thread111    blocks. This attribute is only allowed for kernel functions and requires112    ``nvvm.reqntid`` and ``nvvm.cluster_dim`` attributes.113 114.. _address_spaces:115 116Address Spaces117--------------118 119The NVPTX back-end uses the following address space mapping:120 121   ============= ======================122   Address Space Memory Space123   ============= ======================124   0             Generic125   1             Global126   2             Internal Use127   3             Shared128   4             Constant129   5             Local130   7             Shared Cluster131   ============= ======================132 133Every global variable and pointer type is assigned to one of these address134spaces, with 0 being the default address space. Intrinsics are provided which135can be used to convert pointers between the generic and non-generic address136spaces.137 138As an example, the following IR will define an array ``@g`` that resides in139global device memory.140 141.. code-block:: llvm142 143    @g = internal addrspace(1) global [4 x i32] [ i32 0, i32 1, i32 2, i32 3 ]144 145LLVM IR functions can read and write to this array, and host-side code can146copy data to it by name with the CUDA Driver API.147 148Note that since address space 0 is the generic space, it is illegal to have149global variables in address space 0.  Address space 0 is the default address150space in LLVM, so the ``addrspace(N)`` annotation is *required* for global151variables.152 153 154Triples155-------156 157The NVPTX target uses the module triple to select between 32/64-bit code158generation and the driver-compiler interface to use. The triple architecture159can be one of ``nvptx`` (32-bit PTX) or ``nvptx64`` (64-bit PTX). The160operating system should be one of ``cuda`` or ``nvcl``, which determines the161interface used by the generated code to communicate with the driver.  Most162users will want to use ``cuda`` as the operating system, which makes the163generated PTX compatible with the CUDA Driver API.164 165Example: 32-bit PTX for CUDA Driver API: ``nvptx-nvidia-cuda``166 167Example: 64-bit PTX for CUDA Driver API: ``nvptx64-nvidia-cuda``168 169.. _nvptx_arch_hierarchy:170 171NVPTX Architecture Hierarchy and Ordering172=========================================173 174GPU architectures: sm_2Y/sm_3Y/sm_5Y/sm_6Y/sm_7Y/sm_8Y/sm_9Y/sm_10Y/sm_12Y175('Y' represents version within the architecture)176The architectures have name of form ``sm_XYz`` where ``X`` represent the generation177number, ``Y`` represents the version within the architecture, and ``z`` represents178the optional feature suffix.179If ``X1Y1 <= X2Y2``, then GPU capabilities of ``sm_X1Y1`` are included in ``sm_X2Y2``.180For example, take ``sm_90`` (9 represents ``X``, 0 represents ``Y``, and no feature181suffix) and ``sm_103`` architectures (10 represents ``X``, 3 represents ``Y``, and no182feature suffix). Since 90 <= 103, ``sm_90`` is compatible with ``sm_103``.183 184The family-specific variants have ``f`` feature suffix and they follow185following order:186``sm_X{Y2}f > sm_X{Y1}f`` iff ``Y2 > Y1``187``sm_XY{f} > sm_{XY}{}``188 189For example, take ``sm_100f`` (10 represents ``X``, 0 represents ``Y``, and ``f``190represents ``z``) and ``sm_103f`` (10 represents ``X``, 3 represents ``Y``, and ``f``191represents ``z``) architecture variants. Since ``Y1 < Y2``, ``sm_100f`` is compatible with192``sm_103f``. Similarly based on the second rule, ``sm_90`` is compatible with ``sm_103f``.193 194Some counter examples, take ``sm_100f`` and ``sm_120f`` (12 represents ``X``, 0195represents ``Y``, and ``f`` represents ``z``) architecture variants. Since both196belongs to different family i.e. ``X1 != X2``, ``sm_100f`` is not compatible with197``sm_120f``.198 199The architecture-specific variants have ``a`` feature suffix and they follow200following order:201``sm_XY{a} > sm_XY{f} > sm_{XY}{}``202 203For example, take ``sm_103a`` (10 represents ``X``, 3 represents ``Y``, and ``a``204represents ``z``), ``sm_103f``, and ``sm_103`` architecture variants. The ``sm_103`` is205compatible with ``sm_103a`` and ``sm_103f``, and ``sm_103f`` is compatible with ``sm_103a``.206 207Encoding := Arch * 10 + 2 (for 'f') + 1 (for 'a')208Arch := X * 10 + Y209 210For example, ``sm_103f`` is encoded as 1032 (103 * 10 + 2) and ``sm_103a`` is211encoded as 1033 (103 * 10 + 2 + 1).212 213This encoding allows simple partial ordering of the architectures.214 215* Compare Family and Arch by dividing FullSMVersion by 100 and 10216  respectively before the comparison.217* Compare within the family by comparing FullSMVersion, given both belongs to218  the same family.219* Detect ``a`` variants by checking FullSMVersion & 1.220 221.. _nvptx_intrinsics:222 223NVPTX Intrinsics224================225 226Reading PTX Special Registers227-----------------------------228 229'``llvm.nvvm.read.ptx.sreg.*``'230^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^231 232Syntax:233"""""""234 235.. code-block:: llvm236 237    declare i32 @llvm.nvvm.read.ptx.sreg.tid.x()238    declare i32 @llvm.nvvm.read.ptx.sreg.tid.y()239    declare i32 @llvm.nvvm.read.ptx.sreg.tid.z()240    declare i32 @llvm.nvvm.read.ptx.sreg.ntid.x()241    declare i32 @llvm.nvvm.read.ptx.sreg.ntid.y()242    declare i32 @llvm.nvvm.read.ptx.sreg.ntid.z()243    declare i32 @llvm.nvvm.read.ptx.sreg.ctaid.x()244    declare i32 @llvm.nvvm.read.ptx.sreg.ctaid.y()245    declare i32 @llvm.nvvm.read.ptx.sreg.ctaid.z()246    declare i32 @llvm.nvvm.read.ptx.sreg.nctaid.x()247    declare i32 @llvm.nvvm.read.ptx.sreg.nctaid.y()248    declare i32 @llvm.nvvm.read.ptx.sreg.nctaid.z()249    declare i32 @llvm.nvvm.read.ptx.sreg.warpsize()250 251Overview:252"""""""""253 254The '``@llvm.nvvm.read.ptx.sreg.*``' intrinsics provide access to the PTX255special registers, in particular the kernel launch bounds.  These registers256map in the following way to CUDA builtins:257 258   ============ =====================================259   CUDA Builtin PTX Special Register Intrinsic260   ============ =====================================261   ``threadId`` ``@llvm.nvvm.read.ptx.sreg.tid.*``262   ``blockIdx`` ``@llvm.nvvm.read.ptx.sreg.ctaid.*``263   ``blockDim`` ``@llvm.nvvm.read.ptx.sreg.ntid.*``264   ``gridDim``  ``@llvm.nvvm.read.ptx.sreg.nctaid.*``265   ============ =====================================266 267 268Barriers269--------270 271'``llvm.nvvm.barrier.cta.*``'272^^^^^^^^^^^^^^^^^^^^^^^^^^^^^273 274Syntax:275"""""""276 277.. code-block:: llvm278 279  declare void @llvm.nvvm.barrier.cta.sync.count(i32 %id, i32 %n)280  declare void @llvm.nvvm.barrier.cta.sync.all(i32 %id)281  declare void @llvm.nvvm.barrier.cta.arrive.count(i32 %id, i32 %n)282 283  declare void @llvm.nvvm.barrier.cta.sync.aligned.count(i32 %id, i32 %n)284  declare void @llvm.nvvm.barrier.cta.sync.aligned.all(i32 %id)285  declare void @llvm.nvvm.barrier.cta.arrive.aligned.count(i32 %id, i32 %n)286 287Overview:288"""""""""289 290The '``@llvm.nvvm.barrier.cta.*``' family of intrinsics perform barrier291synchronization and communication within a CTA. They can be used by the threads292within the CTA for synchronization and communication.293 294Semantics:295""""""""""296 297Operand %id specifies a logical barrier resource and must fall within the range2980 through 15. When present, operand %n specifies the number of threads299participating in the barrier. When specifying a thread count, the value must be300a multiple of the warp size. With the '``@llvm.nvvm.barrier.cta.sync.*``'301variants, the '``.all``' suffix indicates that all threads in the CTA should302participate in the barrier while the '``.count``' suffix indicates that only303the threads specified by the %n operand should participate in the barrier.304 305All forms of the '``@llvm.nvvm.barrier.cta.*``' intrinsic cause the executing306thread to wait for all non-exited threads from its warp and then marks the307warp's arrival at the barrier. In addition to signaling its arrival at the 308barrier, the '``@llvm.nvvm.barrier.cta.sync.*``' intrinsics cause the executing309thread to wait for non-exited threads of all other warps participating in the310barrier to arrive. On the other hand, the '``@llvm.nvvm.barrier.cta.arrive.*``'311intrinsic does not cause the executing thread to wait for threads of other312participating warps.313 314When a barrier completes, the waiting threads are restarted without delay,315and the barrier is reinitialized so that it can be immediately reused.316 317The '``@llvm.nvvm.barrier.cta.*``' intrinsic has an optional '``.aligned``'318modifier to indicate textual alignment of the barrier. When specified, it319indicates that all threads in the CTA will execute the same320'``@llvm.nvvm.barrier.cta.*``' instruction. In conditionally executed code, an321aligned '``@llvm.nvvm.barrier.cta.*``' instruction should only be used if it is322known that all threads in the CTA evaluate the condition identically, otherwise323behavior is undefined.324 325MBarrier family of Intrinsics326-----------------------------327 328Overview:329^^^^^^^^^330 331An ``mbarrier`` is a barrier created in shared memory that supports:332 333* Synchronizing any subset of threads within a CTA.334* One-way synchronization of threads across CTAs of a cluster.335  Threads can perform only ``arrive`` operations but not ``*_wait`` on an336  mbarrier located in shared::cluster space.337* Waiting for completion of asynchronous memory operations initiated by a338  thread and making them visible to other threads.339 340Unlike ``bar{.cta}/barrier{.cta}`` instructions which can access a limited341number of barriers per CTA, ``mbarrier`` objects are user-defined and are342only limited by the total shared memory size available.343 344An mbarrier object is an opaque object in shared memory with an345alignment of 8-bytes. It keeps track of:346 347* Current phase of the mbarrier object348* Count of pending arrivals for the current phase of the mbarrier object349* Count of expected arrivals for the next phase of the mbarrier object350* Count of pending asynchronous memory operations (or transactions)351  tracked by the current phase of the mbarrier object. This is also352  referred to as ``tx-count``. The unit of ``tx-count`` is specified353  by the asynchronous memory operation (for example,354  ``llvm.nvvm.cp.async.bulk.tensor.g2s.*``).355 356The ``phase`` of an mbarrier object is the number of times the mbarrier357object has been used to synchronize threads/track async operations.358In each phase, threads perform:359 360* arrive/expect-tx/complete-tx operations to progress the current phase.361* test_wait/try_wait operations to check for completion of the current phase.362 363An mbarrier object completes the current phase when:364 365* The count of the pending arrivals has reached zero AND366* The tx-count has reached zero.367 368When an mbarrier object completes the current phase, below369actions are performed ``atomically``:370 371* The mbarrier object transitions to the next phase.372* The pending arrival count is reinitialized to the expected arrival count.373 374For more information, refer PTX ISA375`<https://docs.nvidia.com/cuda/parallel-thread-execution/#parallel-synchronization-and-communication-instructions-mbarrier>`_.376 377'``llvm.nvvm.mbarrier.init``'378^^^^^^^^^^^^^^^^^^^^^^^^^^^^^379 380Syntax:381"""""""382 383.. code-block:: llvm384 385  declare void @llvm.nvvm.mbarrier.init(ptr %addr, i32 %count)386  declare void @llvm.nvvm.mbarrier.init.shared(ptr addrspace(3) %addr, i32 %count)387 388Overview:389"""""""""390 391The '``@llvm.nvvm.mbarrier.init.*``' intrinsics are used to initialize392an mbarrier object located at ``addr`` with the value ``count``.393``count`` is a 32-bit unsigned integer value and must be within394the range [1...2^20-1]. During initialization:395 396* The tx-count and the current phase of the mbarrier object are set to 0.397* The expected and pending arrival counts are set to ``count``.398 399Semantics:400""""""""""401 402The ``.shared`` variant explicitly uses shared memory address space for403the ``addr`` operand. If the ``addr`` does not fall within the404shared::cta space, then the behavior of this intrinsic is undefined.405Performing ``mbarrier.init`` on a valid mbarrier object is undefined;406use ``mbarrier.inval`` before reusing the memory for another mbarrier407or any other purpose.408 409'``llvm.nvvm.mbarrier.inval``'410^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^411 412Syntax:413"""""""414 415.. code-block:: llvm416 417  declare void @llvm.nvvm.mbarrier.inval(ptr %addr)418  declare void @llvm.nvvm.mbarrier.inval.shared(ptr addrspace(3) %addr)419 420Overview:421"""""""""422 423The '``@llvm.nvvm.mbarrier.inval.*``' intrinsics invalidate the mbarrier424object at the address specified by ``addr``.425 426Semantics:427""""""""""428 429The ``.shared`` variant explicitly uses shared memory address space for430the ``addr`` operand. If the ``addr`` does not fall within the431shared::cta space, then the behavior of this intrinsic is undefined.432It is expected that ``addr`` was previously initialized using433``mbarrier.init``; otherwise, the behavior is undefined.434 435'``llvm.nvvm.mbarrier.expect.tx``'436^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^437 438Syntax:439"""""""440 441.. code-block:: llvm442 443  declare void @llvm.nvvm.mbarrier.expect.tx.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %tx_count)444  declare void @llvm.nvvm.mbarrier.expect.tx.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %tx_count)445  declare void @llvm.nvvm.mbarrier.expect.tx.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)446  declare void @llvm.nvvm.mbarrier.expect.tx.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)447 448Overview:449"""""""""450 451The '``@llvm.nvvm.mbarrier.expect.tx.*``' intrinsics increase the transaction452count of the mbarrier object at ``%addr`` by ``%tx_count``. The ``%tx_count``453is a 32-bit unsigned integer value.454 455Semantics:456""""""""""457 458The ``.space.{cta/cluster}`` indicates the address space where the mbarrier459object resides.460 461The ``.scope.{cta/cluster}`` denotes the set of threads that can directly462observe the synchronizing effect of the mbarrier operation. When scope is463"cta", all threads executing in the same CTA (as the current thread) can464directly observe the effect of the ``expect.tx`` operation. Similarly,465when scope is "cluster", all threads executing in the same Cluster466(as the current thread) can directly observe the effect of the operation.467 468If the ``addr`` does not fall within shared::cta or shared::cluster space,469then the behavior of this intrinsic is undefined. This intrinsic has470``relaxed`` semantics and hence does not provide any memory ordering471or visibility guarantees.472 473'``llvm.nvvm.mbarrier.complete.tx``'474^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^475 476Syntax:477"""""""478 479.. code-block:: llvm480 481  declare void @llvm.nvvm.mbarrier.complete.tx.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %tx_count)482  declare void @llvm.nvvm.mbarrier.complete.tx.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %tx_count)483  declare void @llvm.nvvm.mbarrier.complete.tx.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)484  declare void @llvm.nvvm.mbarrier.complete.tx.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)485 486Overview:487"""""""""488 489The '``@llvm.nvvm.mbarrier.complete.tx.*``' intrinsics decrease the transaction490count of the mbarrier object at ``%addr`` by ``%tx_count``. The ``%tx_count``491is a 32-bit unsigned integer value. As a result of this decrement,492the mbarrier can potentially complete its current phase and transition493to the next phase.494 495Semantics:496""""""""""497 498The semantics of these intrinsics are identical to those of the499``llvm.nvvm.mbarrier.expect.tx.*`` intrinsics described above.500 501'``llvm.nvvm.mbarrier.arrive``'502^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^503 504Syntax:505"""""""506 507.. code-block:: llvm508 509  declare i64  @llvm.nvvm.mbarrier.arrive.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %count)510  declare i64  @llvm.nvvm.mbarrier.arrive.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %count)511  declare void @llvm.nvvm.mbarrier.arrive.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %count)512  declare void @llvm.nvvm.mbarrier.arrive.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %count)513 514  declare i64  @llvm.nvvm.mbarrier.arrive.relaxed.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %count)515  declare i64  @llvm.nvvm.mbarrier.arrive.relaxed.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %count)516  declare void @llvm.nvvm.mbarrier.arrive.relaxed.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %count)517  declare void @llvm.nvvm.mbarrier.arrive.relaxed.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %count)518 519Overview:520"""""""""521 522The ``@llvm.nvvm.mbarrier.arrive.*`` intrinsics signal the arrival of the523executing thread or completion of an asynchronous instruction associated with524an arrive operation on the mbarrier object at ``%addr``. This operation525decrements the pending arrival count by ``%count``, a 32-bit unsigned integer,526potentially completing the current phase and triggering a transition to the527next phase.528 529Semantics:530""""""""""531 532The ``.space.{cta/cluster}`` indicates the address space where the mbarrier533object resides. When the mbarrier is in shared::cta space, the intrinsics534return an opaque 64-bit value capturing the phase of the mbarrier object535_prior_ to this arrive operation. This value can be used with a try_wait536or test_wait operation to check for the completion of the mbarrier.537 538The ``.scope.{cta/cluster}`` denotes the set of threads that can directly539observe the synchronizing effect of the mbarrier operation. When scope is540"cta", all threads executing in the same CTA (as the current thread) can541directly observe the effect of the ``arrive`` operation. Similarly,542when scope is "cluster", all threads executing in the same Cluster543(as the current thread) can directly observe the effect of the operation.544 545If the ``addr`` does not fall within shared::cta or shared::cluster space,546then the behavior of this intrinsic is undefined.547 548These intrinsics have ``release`` semantics by default. The release semantics549ensure ordering of operations that occur in program order _before_ this arrive550instruction, making their effects visible to subsequent operations in other551threads of the CTA (or cluster, depending on scope). Threads performing552corresponding acquire operations (such as mbarrier.test.wait) synchronize553with this release. The ``relaxed`` variants of these intrinsics do not554provide any memory ordering or visibility guarantees.555 556'``llvm.nvvm.mbarrier.arrive.expect.tx``'557^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^558 559Syntax:560"""""""561 562.. code-block:: llvm563 564  declare i64  @llvm.nvvm.mbarrier.arrive.expect.tx.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %tx_count)565  declare i64  @llvm.nvvm.mbarrier.arrive.expect.tx.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %tx_count)566  declare void @llvm.nvvm.mbarrier.arrive.expect.tx.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)567  declare void @llvm.nvvm.mbarrier.arrive.expect.tx.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)568 569  declare i64  @llvm.nvvm.mbarrier.arrive.expect.tx.relaxed.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %tx_count)570  declare i64  @llvm.nvvm.mbarrier.arrive.expect.tx.relaxed.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %tx_count)571  declare void @llvm.nvvm.mbarrier.arrive.expect.tx.relaxed.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)572  declare void @llvm.nvvm.mbarrier.arrive.expect.tx.relaxed.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)573 574Overview:575"""""""""576 577The ``@llvm.nvvm.mbarrier.arrive.expect.tx.*`` intrinsics are similar to578the ``@llvm.nvvm.mbarrier.arrive`` intrinsics except that they also579perform an ``expect-tx`` operation _prior_ to the ``arrive`` operation.580The ``%tx_count`` specifies the transaction count for the ``expect-tx``581operation and the count for the ``arrive`` operation is assumed to be 1.582 583Semantics:584""""""""""585 586The semantics of these intrinsics are identical to those of the587``llvm.nvvm.mbarrier.arrive.*`` intrinsics described above.588 589'``llvm.nvvm.mbarrier.arrive.drop``'590^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^591 592Syntax:593"""""""594 595.. code-block:: llvm596 597  declare i64  @llvm.nvvm.mbarrier.arrive.drop.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %count)598  declare i64  @llvm.nvvm.mbarrier.arrive.drop.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %count)599  declare void @llvm.nvvm.mbarrier.arrive.drop.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %count)600  declare void @llvm.nvvm.mbarrier.arrive.drop.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %count)601 602  declare i64  @llvm.nvvm.mbarrier.arrive.drop.relaxed.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %count)603  declare i64  @llvm.nvvm.mbarrier.arrive.drop.relaxed.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %count)604  declare void @llvm.nvvm.mbarrier.arrive.drop.relaxed.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %count)605  declare void @llvm.nvvm.mbarrier.arrive.drop.relaxed.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %count)606 607Overview:608"""""""""609 610The ``@llvm.nvvm.mbarrier.arrive.drop.*`` intrinsics decrement the611expected arrival count of the mbarrier object at ``%addr`` by612``%count`` and then perform an ``arrive`` operation with ``%count``.613The ``%count`` is a 32-bit integer.614 615Semantics:616""""""""""617 618The semantics of these intrinsics are identical to those of the619``llvm.nvvm.mbarrier.arrive.*`` intrinsics described above.620 621'``llvm.nvvm.mbarrier.arrive.drop.expect.tx``'622^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^623 624Syntax:625"""""""626 627.. code-block:: llvm628 629  declare i64  @llvm.nvvm.mbarrier.arrive.drop.expect.tx.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %tx_count)630  declare i64  @llvm.nvvm.mbarrier.arrive.drop.expect.tx.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %tx_count)631  declare void @llvm.nvvm.mbarrier.arrive.drop.expect.tx.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)632  declare void @llvm.nvvm.mbarrier.arrive.drop.expect.tx.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)633 634  declare i64  @llvm.nvvm.mbarrier.arrive.drop.expect.tx.relaxed.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %tx_count)635  declare i64  @llvm.nvvm.mbarrier.arrive.drop.expect.tx.relaxed.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %tx_count)636  declare void @llvm.nvvm.mbarrier.arrive.drop.expect.tx.relaxed.scope.cta.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)637  declare void @llvm.nvvm.mbarrier.arrive.drop.expect.tx.relaxed.scope.cluster.space.cluster(ptr addrspace(7) %addr, i32 %tx_count)638 639Overview:640"""""""""641 642The ``@llvm.nvvm.mbarrier.arrive.drop.expect.tx.*`` intrinsics perform643the below operations on the mbarrier located at ``%addr``.644 645* Perform an ``expect-tx`` operation i.e. increase the transaction count646  of the mbarrier by ``%tx_count``, a 32-bit unsigned integer value.647* Decrement the expected arrival count of the mbarrier by 1.648* Perform an ``arrive`` operation on the mbarrier with a value of 1.649 650Semantics:651""""""""""652 653The semantics of these intrinsics are identical to those of the654``llvm.nvvm.mbarrier.arrive.*`` intrinsics described above.655 656'``llvm.nvvm.mbarrier.test.wait``'657^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^658 659Syntax:660"""""""661 662.. code-block:: llvm663 664  declare i1 @llvm.nvvm.mbarrier.test.wait.scope.cta.space.cta(ptr addrspace(3) %addr, i64 %state)665  declare i1 @llvm.nvvm.mbarrier.test.wait.scope.cluster.space.cta(ptr addrspace(3) %addr, i64 %state)666  declare i1 @llvm.nvvm.mbarrier.test.wait.parity.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %phase)667  declare i1 @llvm.nvvm.mbarrier.test.wait.parity.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %phase)668 669  declare i1 @llvm.nvvm.mbarrier.test.wait.relaxed.scope.cta.space.cta(ptr addrspace(3) %addr, i64 %state)670  declare i1 @llvm.nvvm.mbarrier.test.wait.relaxed.scope.cluster.space.cta(ptr addrspace(3) %addr, i64 %state)671  declare i1 @llvm.nvvm.mbarrier.test.wait.parity.relaxed.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %phase)672  declare i1 @llvm.nvvm.mbarrier.test.wait.parity.relaxed.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %phase)673 674Overview:675"""""""""676 677The ``@llvm.nvvm.mbarrier.test.wait.*`` intrinsics test for the completion678of the current or the immediately preceding phase of an mbarrier object at679``%addr``. The test for completion can be done with either the ``state`` or680the ``phase-parity`` of the mbarrier object.681 682* When done through the ``i64 %state`` operand, the state must be683  returned by an ``llvm.nvvm.mbarrier.arrive.*`` on the _same_684  mbarrier object.685* The ``.parity`` variant of these intrinsics test for completion686  of the phase indicated by the operand ``i32 %phase``, which is687  the integer parity of either the current phase or the immediately688  preceding phase of the mbarrier object. An even phase has integer689  parity 0 and an odd phase has integer parity of 1. So the valid690  values for phase-parity are 0 and 1.691 692Semantics:693""""""""""694 695The ``.scope.{cta/cluster}`` denotes the set of threads that the696test_wait operation can directly synchronize with.697 698If the ``addr`` does not fall within shared::cta space, then the699the behavior of this intrinsic is undefined.700 701These intrinsics have ``acquire`` semantics by default. This acquire702pattern establishes memory ordering for operations occurring in program703order after this ``test_wait`` instruction by making operations from704other threads in the CTA (or cluster, depending on scope) visible to705subsequent operations in the current thread. When this wait completes,706it synchronizes with the corresponding release pattern from the707``mbarrier.arrive`` operation. The ``relaxed`` variants of these intrinsics708do not provide any memory ordering or visibility guarantees.709 710This ``test.wait`` intrinsic is non-blocking and immediately returns711the completion status without suspending the executing thread.712 713The boolean return value indicates:714 715* True: The immediately preceding phase has completed716* False: The current phase is still incomplete717 718When this wait returns true, the following ordering guarantees hold:719 720* All memory accesses (except async operations) requested prior to721  ``mbarrier.arrive`` having release semantics by participating722  threads of a CTA (or cluster, depending on scope) are visible to723  the executing thread.724* All ``cp.async`` operations requested prior to ``cp.async.mbarrier.arrive``725  by participating threads of a CTA are visible to the executing thread.726* All ``cp.async.bulk`` operations using the same mbarrier object requested727  prior to ``mbarrier.arrive`` having release semantics by participating CTA728  threads are visible to the executing thread.729* Memory accesses requested after this wait are not visible to memory730  accesses performed prior to ``mbarrier.arrive`` by other participating731  threads.732* No ordering guarantee exists for memory accesses by the same thread733  between an ``mbarrier.arrive`` and this wait.734 735'``llvm.nvvm.mbarrier.try.wait``'736^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^737 738Syntax:739"""""""740 741.. code-block:: llvm742 743  declare i1 @llvm.nvvm.mbarrier.try.wait{.relaxed}.scope.cta.space.cta(ptr addrspace(3) %addr, i64 %state)744  declare i1 @llvm.nvvm.mbarrier.try.wait{.relaxed}.scope.cluster.space.cta(ptr addrspace(3) %addr, i64 %state)745 746  declare i1 @llvm.nvvm.mbarrier.try.wait.parity{.relaxed}.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %phase)747  declare i1 @llvm.nvvm.mbarrier.try.wait.parity{.relaxed}.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %phase)748 749  declare i1 @llvm.nvvm.mbarrier.try.wait.tl{.relaxed}.scope.cta.space.cta(ptr addrspace(3) %addr, i64 %state, i32 %timelimit)750  declare i1 @llvm.nvvm.mbarrier.try.wait.tl{.relaxed}.scope.cluster.space.cta(ptr addrspace(3) %addr, i64 %state, i32 %timelimit)751 752  declare i1 @llvm.nvvm.mbarrier.try.wait.parity.tl{.relaxed}.scope.cta.space.cta(ptr addrspace(3) %addr, i32 %phase, i32 %timelimit)753  declare i1 @llvm.nvvm.mbarrier.try.wait.parity.tl{.relaxed}.scope.cluster.space.cta(ptr addrspace(3) %addr, i32 %phase, i32 %timelimit)754 755Overview:756"""""""""757 758The ``@llvm.nvvm.mbarrier.try.wait.*`` intrinsics test for the completion of759the current or immediately preceding phase of an mbarrier object at ``%addr``.760Unlike the ``test.wait`` intrinsics, which perform a non-blocking test, these761intrinsics may block the executing thread until the specified phase completes762or a system-dependent time limit expires. Suspended threads resume execution763when the phase completes or the time limit elapses. This time limit is764configurable through the ``.tl`` variants of these intrinsics, where the765``%timelimit`` operand (an unsigned integer) specifies the limit in766nanoseconds. Other semantics are identical to those of the ``test.wait``767intrinsics described above.768 769Electing a thread770-----------------771 772'``llvm.nvvm.elect.sync``'773^^^^^^^^^^^^^^^^^^^^^^^^^^774 775Syntax:776"""""""777 778.. code-block:: llvm779 780  declare {i32, i1} @llvm.nvvm.elect.sync(i32 %membermask)781 782Overview:783"""""""""784 785The '``@llvm.nvvm.elect.sync``' intrinsic generates the ``elect.sync``786PTX instruction, which elects one predicated active leader thread from787a set of threads specified by ``membermask``. The behavior is undefined788if the executing thread is not in ``membermask``. The laneid of the789elected thread is captured in the i32 return value. The i1 return790value is set to ``True`` for the leader thread and ``False`` for all791the other threads. Election of a leader thread happens deterministically,792i.e. the same leader thread is elected for the same ``membermask``793every time. For more information, refer PTX ISA794`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-elect-sync>`_.795 796Membar/Fences797-------------798 799'``llvm.nvvm.fence.acquire/release.sync_restrict.*``'800^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^801 802Syntax:803"""""""804 805.. code-block:: llvm806 807  declare void @llvm.nvvm.fence.acquire.sync_restrict.space.cluster.scope.cluster()808  declare void @llvm.nvvm.fence.release.sync_restrict.space.cta.scope.cluster()809 810Overview:811"""""""""812 813The `nvvm.fence.{semantics}.sync_restrict.*` restrict the class of memory814operations for which the fence instruction provides the memory ordering guarantees.815When `.sync_restrict` is restricted to `shared_cta`, then memory semantics must816be `release` and the effect of the fence operation only applies to operations817performed on objects in `shared_cta` space. Likewise, when `sync_restrict` is818restricted to `shared_cluster`, then memory semantics must be `acquire` and the819effect of the fence operation only applies to operations performed on objects in820`shared_cluster` memory space. The scope for both operations is `cluster`. For more details,821please refer the `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-membar>`__822 823'``llvm.nvvm.fence.mbarrier_init.release.cluster``'824^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^825 826Syntax:827"""""""828 829.. code-block:: llvm830 831  declare void @llvm.nvvm.fence.mbarrier_init.release.cluster()832 833Overview:834"""""""""835 836`nvvm.fence.mbarrier_init.release.cluster` intrinsic restrict the class of837memory operations for which the fence instruction provides the memory ordering838guarantees. The `mbarrier_init` modifiers restricts the synchronizing effect to839the prior `mbarrier_init` operation executed by the same thread on mbarrier objects840in `shared_cta` memory space. For more details, please refer the `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-membar>`__841 842'``llvm.nvvm.fence.proxy.async_generic.acquire/release.sync_restrict``'843^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^844 845Syntax:846"""""""847 848.. code-block:: llvm849 850  declare void @llvm.nvvm.fence.proxy.async.generic.acquire.sync_restrict.space.cluster.scope.cluster()851  declare void @llvm.nvvm.fence.proxy.async.generic.release.sync_restrict.space.cta.scope.cluster()852 853Overview:854"""""""""855 856`nvvm.fence.proxy.async_generic.{semantics}.sync_restrict` are used to establish857ordering between a prior memory access performed via the `async proxy<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#proxies>__`858and a subsequent memory access performed via the generic proxy.859``nvvm.fence.proxy.async_generic.release.sync_restrict`` can form a release860sequence that synchronizes with an acquire sequence that contains the861``nvvm.fence.proxy.async_generic.acquire.sync_restrict`` proxy fence. When862`.sync_restrict` is restricted to `shared_cta`, then memory semantics must863be `release` and the effect of the fence operation only applies to operations864performed on objects in `shared_cta` space. Likewise, when `sync_restrict` is865restricted to `shared_cluster`, then memory semantics must be `acquire` and the866effect of the fence operation only applies to operations performed on objects in867`shared_cluster` memory space. The scope for both operations is `cluster`.868For more details, please refer the `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-membar>`__869 870'``llvm.nvvm.fence.proxy.<proxykind>``'871^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^872 873Syntax:874"""""""875 876.. code-block:: llvm877 878  declare void @llvm.nvvm.fence.proxy.alias()879  declare void @llvm.nvvm.fence.proxy.async()880  declare void @llvm.nvvm.fence.proxy.async.global()881  declare void @llvm.nvvm.fence.proxy.async.shared_cluster()882  declare void @llvm.nvvm.fence.proxy.async.shared_cta()883 884Overview:885"""""""""886 887`nvvm.fence.proxy.{proxykind}` intrinsics represent a fence with bi-directional888proxy ordering that is established between the memory accesses done between the889`generic proxy<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#proxies>__`890and the proxy specified by `proxykind`. A `bi-directional proxy` ordering between891two proxykinds establishes two `uni-directional` proxy orderings: one from the892first proxykind to the second proxykind and the other from the second proxykind893to the first proxykind.894 895`alias` proxykind refers to memory accesses performed using virtually aliased896addresses to the same memory location897 898`async` proxykind specifies that the memory ordering is established between the899`async proxy` and the `generic proxy`. The memory ordering is limited only to900operations performed on objects in the state space specified (`generic`, `global`,901`shared_cluster`, `shared_cta`). If no state space is specified, then the memory902ordering applies on all state spaces. For more details, please refer the903`PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-membar>`__904 905'``llvm.nvvm.fence.proxy.tensormap_generic.*``'906^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^907 908Syntax:909"""""""910 911.. code-block:: llvm912 913  declare void @llvm.nvvm.fence.proxy.tensormap_generic.release.cta()914  declare void @llvm.nvvm.fence.proxy.tensormap_generic.release.cluster()915  declare void @llvm.nvvm.fence.proxy.tensormap_generic.release.gpu()916  declare void @llvm.nvvm.fence.proxy.tensormap_generic.release.sys()917 918  declare void @llvm.nvvm.fence.proxy.tensormap_generic.acquire.cta(ptr %addr, i32 %size)919  declare void @llvm.nvvm.fence.proxy.tensormap_generic.acquire.cluster(ptr %addr, i32 %size)920  declare void @llvm.nvvm.fence.proxy.tensormap_generic.acquire.gpu(ptr %addr, i32 %size)921  declare void @llvm.nvvm.fence.proxy.tensormap_generic.acquire.sys(ptr %addr, i32 %size)922 923Overview:924"""""""""925 926The ``@llvm.nvvm.fence.proxy.tensormap_generic.*`` is a uni-directional fence used to establish ordering between a prior memory access performed via the generic `proxy<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#proxies>_` and a subsequent memory access performed via the tensormap proxy. ``nvvm.fence.proxy.tensormap_generic.release`` can form a release sequence that synchronizes with an acquire sequence that contains the ``nvvm.fence.proxy.tensormap_generic.acquire`` proxy fence. The following table describes the mapping between LLVM Intrinsic and the PTX instruction:927 928  ====================================================== =========================================================929  NVVM Intrinsic                                         PTX Instruction930  ====================================================== =========================================================931  ``@llvm.nvvm.fence.proxy.tensormap_generic.release.*`` ``fence.proxy.tensormap::generic.release.*``932  ``@llvm.nvvm.fence.proxy.tensormap_generic.acquire.*`` ``fence.proxy.tensormap::generic.acquire.* [addr], size``933  ====================================================== =========================================================934 935The address operand ``addr`` and the operand ``size`` together specify the memory range ``[addr, addr+size)`` on which the ordering guarantees on the memory accesses across the proxies is to be provided. The only supported value for the ``size`` operand is ``128`` and must be an immediate. Generic Addressing is used unconditionally, and the address specified by the operand addr must fall within the ``.global`` state space. Otherwise, the behavior is undefined. For more information, see `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#parallel-synchronization-and-communication-instructions-membar>`_.936 937Address Space Intrinsics938------------------------939 940'``llvm.nvvm.isspacep.*``' Intrinsics941^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^942 943Syntax:944"""""""945 946.. code-block:: llvm947 948    declare i1 @llvm.nvvm.isspacep.const(ptr %p)949    declare i1 @llvm.nvvm.isspacep.global(ptr %p)950    declare i1 @llvm.nvvm.isspacep.local(ptr %p)951    declare i1 @llvm.nvvm.isspacep.shared(ptr %p)952    declare i1 @llvm.nvvm.isspacep.shared.cluster(ptr %p)953 954Overview:955"""""""""956 957The '``llvm.nvvm.isspacep.*``' intrinsics determine whether the provided generic958pointer references memory which falls within a particular address space.959 960Semantics:961""""""""""962 963If the given pointer in the generic address space refers to memory which falls964within the state space of the intrinsic (and therefore could be safely address965space casted to this space), 1 is returned, otherwise 0 is returned.966 967'``llvm.nvvm.mapa.*``' Intrinsics968^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^969 970Syntax:971"""""""972 973.. code-block:: llvm974 975    declare ptr @llvm.nvvm.mapa(ptr %p, i32 %rank)976    declare ptr addrspace(7) @llvm.nvvm.mapa.shared.cluster(ptr addrspace(3) %p, i32 %rank)977 978Overview:979"""""""""980 981The '``llvm.nvvm.mapa.*``' intrinsics map a shared memory pointer ``p`` of another CTA with ``%rank`` to the current CTA.982The ``llvm.nvvm.mapa`` form expects a generic pointer to shared memory and returns a generic pointer to shared cluster memory.983The ``llvm.nvvm.mapa.shared.cluster`` form expects a pointer to shared memory and returns a pointer to shared cluster memory.984They corresponds directly to the ``mapa`` and ``mapa.shared.cluster`` PTX instructions.985 986Semantics:987""""""""""988 989If the given pointer in the generic address space refers to memory which falls990within the state space of the intrinsic (and therefore could be safely address991space casted to this space), 1 is returned, otherwise 0 is returned.992 993Arithmetic Intrinsics994---------------------995 996'``llvm.nvvm.fabs.*``' Intrinsic997^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^998 999Syntax:1000"""""""1001 1002.. code-block:: llvm1003 1004    declare float @llvm.nvvm.fabs.f32(float %a)1005    declare double @llvm.nvvm.fabs.f64(double %a)1006    declare half @llvm.nvvm.fabs.f16(half %a)1007    declare <2 x half> @llvm.nvvm.fabs.v2f16(<2 x half> %a)1008    declare bfloat @llvm.nvvm.fabs.bf16(bfloat %a)1009    declare <2 x bfloat> @llvm.nvvm.fabs.v2bf16(<2 x bfloat> %a)1010 1011Overview:1012"""""""""1013 1014The '``llvm.nvvm.fabs.*``' intrinsics return the absolute value of the operand.1015 1016Semantics:1017""""""""""1018 1019Unlike, '``llvm.fabs.*``', these intrinsics do not perfectly preserve NaN1020values. Instead, a NaN input yields an unspecified NaN output.1021 1022 1023'``llvm.nvvm.fabs.ftz.*``' Intrinsic1024^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1025 1026Syntax:1027"""""""1028 1029.. code-block:: llvm1030 1031    declare float @llvm.nvvm.fabs.ftz.f32(float %a)1032    declare half @llvm.nvvm.fabs.ftz.f16(half %a)1033    declare <2 x half> @llvm.nvvm.fabs.ftz.v2f16(<2 x half> %a)1034 1035Overview:1036"""""""""1037 1038The '``llvm.nvvm.fabs.ftz.*``' intrinsics return the absolute value of the1039operand, flushing subnormals to sign preserving zero.1040 1041Semantics:1042""""""""""1043 1044Before the absolute value is taken, the input is flushed to sign preserving1045zero if it is a subnormal. In addition, unlike '``llvm.fabs.*``', a NaN input1046yields an unspecified NaN output.1047 1048 1049'``llvm.nvvm.idp2a.[us].[us]``' Intrinsics1050^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1051 1052Syntax:1053"""""""1054 1055.. code-block:: llvm1056 1057    declare i32 @llvm.nvvm.idp2a.s.s(i32 %a, i32 %b, i1 immarg %is.hi, i32 %c)1058    declare i32 @llvm.nvvm.idp2a.s.u(i32 %a, i32 %b, i1 immarg %is.hi, i32 %c)1059    declare i32 @llvm.nvvm.idp2a.u.s(i32 %a, i32 %b, i1 immarg %is.hi, i32 %c)1060    declare i32 @llvm.nvvm.idp2a.u.u(i32 %a, i32 %b, i1 immarg %is.hi, i32 %c)1061 1062 1063Overview:1064"""""""""1065 1066The '``llvm.nvvm.idp2a.[us].[us]``' intrinsics performs a 2-element vector dot1067product followed by addition. They corresponds directly to the ``dp2a`` PTX 1068instruction.1069 1070Semantics:1071""""""""""1072 1073The 32-bit value in ``%a`` is broken into 2 16-bit values which are extended to107432 bits. For the '``llvm.nvvm.idp2a.u.[us]``' variants zero-extension is used,1075while for the '``llvm.nvvm.idp2a.s.[us]``' sign-extension is used. Two bytes are1076selected from ``%b``, if ``%is.hi`` is true, the most significant bytes are1077selected, otherwise the least significant bytes are selected. These bytes are1078then extended to 32-bits. For the '``llvm.nvvm.idp2a.[us].u``' variants1079zero-extension is used, while for the '``llvm.nvvm.idp2a.[us].s``'1080sign-extension is used. The dot product of these 2-element vectors is added to1081``%c`` to produce the return.1082 1083 1084'``llvm.nvvm.idp4a.[us].[us]``' Intrinsics1085^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1086 1087Syntax:1088"""""""1089 1090.. code-block:: llvm1091 1092    declare i32 @llvm.nvvm.idp4a.s.s(i32 %a, i32 %b, i32 %c)1093    declare i32 @llvm.nvvm.idp4a.s.u(i32 %a, i32 %b, i32 %c)1094    declare i32 @llvm.nvvm.idp4a.u.s(i32 %a, i32 %b, i32 %c)1095    declare i32 @llvm.nvvm.idp4a.u.u(i32 %a, i32 %b, i32 %c)1096 1097Overview:1098"""""""""1099 1100The '``llvm.nvvm.idp4a.[us].[us]``' intrinsics perform a 4-element vector dot1101product followed by addition. They corresponds directly to the ``dp4a`` PTX1102instruction.1103 1104Semantics:1105""""""""""1106 1107Each of the 4 bytes in both ``%a`` and ``%b`` are extended to 32-bit integers1108forming 2 ``<4 x i32>``. For ``%a``, zero-extension is used in the1109'``llvm.nvvm.idp4a.u.[us]``' variants, while sign-extension is used with1110'``llvm.nvvm.idp4a.s.[us]``' variants. Similarly, for ``%b``, zero-extension is1111used in the '``llvm.nvvm.idp4a.[us].u``' variants, while sign-extension is used1112with '``llvm.nvvm.idp4a.[us].s``' variants. The dot product of these 4-element1113vectors is added to ``%c`` to produce the return.1114 1115Bit Manipulation Intrinsics1116---------------------------1117 1118'``llvm.nvvm.fshl.clamp.*``' Intrinsic1119^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1120 1121Syntax:1122"""""""1123 1124.. code-block:: llvm1125 1126    declare i32 @llvm.nvvm.fshl.clamp.i32(i32 %hi, i32 %lo, i32 %n)1127 1128Overview:1129"""""""""1130 1131The '``llvm.nvvm.fshl.clamp``' family of intrinsics performs a clamped funnel1132shift left. These intrinsics are very similar to '``llvm.fshl``', except the1133shift amount is clamped at the integer width (instead of modulo it). Currently,1134only ``i32`` is supported.1135 1136Semantics:1137""""""""""1138 1139The '``llvm.nvvm.fshl.clamp``' family of intrinsic functions performs a clamped1140funnel shift left: the first two values are concatenated as { %hi : %lo } (%hi1141is the most significant bits of the wide value), the combined value is shifted1142left, and the most significant bits are extracted to produce a result that is1143the same size as the original arguments. The shift amount is the minimum of the1144value of %n and the bit width of the integer type.1145 1146'``llvm.nvvm.fshr.clamp.*``' Intrinsic1147^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1148 1149Syntax:1150"""""""1151 1152.. code-block:: llvm1153 1154    declare i32 @llvm.nvvm.fshr.clamp.i32(i32 %hi, i32 %lo, i32 %n)1155 1156Overview:1157"""""""""1158 1159The '``llvm.nvvm.fshr.clamp``' family of intrinsics perform a clamped funnel1160shift right. These intrinsics are very similar to '``llvm.fshr``', except the1161shift amount is clamped at the integer width (instead of modulo it). Currently,1162only ``i32`` is supported.1163 1164Semantics:1165""""""""""1166 1167The '``llvm.nvvm.fshr.clamp``' family of intrinsic functions performs a clamped1168funnel shift right: the first two values are concatenated as { %hi : %lo } (%hi1169is the most significant bits of the wide value), the combined value is shifted1170right, and the least significant bits are extracted to produce a result that is1171the same size as the original arguments. The shift amount is the minimum of the1172value of %n and the bit width of the integer type.1173 1174'``llvm.nvvm.flo.u.*``' Intrinsic1175^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1176 1177Syntax:1178"""""""1179 1180.. code-block:: llvm1181 1182    declare i32 @llvm.nvvm.flo.u.i32(i32 %a, i1 %shiftamt)1183    declare i32 @llvm.nvvm.flo.u.i64(i64 %a, i1 %shiftamt)1184 1185Overview:1186"""""""""1187 1188The '``llvm.nvvm.flo.u``' family of intrinsics identifies the bit position of the1189leading one, returning either it's offset from the most or least significant bit.1190 1191Semantics:1192""""""""""1193 1194The '``llvm.nvvm.flo.u``' family of intrinsics returns the bit position of the1195most significant 1. If %shiftamt is true, The result is the shift amount needed1196to left-shift the found bit into the most-significant bit position, otherwise1197the result is the shift amount needed to right-shift the found bit into the1198least-significant bit position. 0xffffffff is returned if no 1 bit is found.1199 1200'``llvm.nvvm.flo.s.*``' Intrinsic1201^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1202 1203Syntax:1204"""""""1205 1206.. code-block:: llvm1207 1208    declare i32 @llvm.nvvm.flo.s.i32(i32 %a, i1 %shiftamt)1209    declare i32 @llvm.nvvm.flo.s.i64(i64 %a, i1 %shiftamt)1210 1211Overview:1212"""""""""1213 1214The '``llvm.nvvm.flo.s``' family of intrinsics identifies the bit position of the1215leading non-sign bit, returning either it's offset from the most or least1216significant bit.1217 1218Semantics:1219""""""""""1220 1221The '``llvm.nvvm.flo.s``' family of intrinsics returns the bit position of the1222most significant 0 for negative inputs and the most significant 1 for 1223non-negative inputs. If %shiftamt is true, The result is the shift amount needed1224to left-shift the found bit into the most-significant bit position, otherwise1225the result is the shift amount needed to right-shift the found bit into the1226least-significant bit position. 0xffffffff is returned if no 1 bit is found.1227 1228'``llvm.nvvm.{zext,sext}.{wrap,clamp}``' Intrinsics1229^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1230 1231Syntax:1232"""""""1233 1234.. code-block:: llvm1235 1236    declare i32 @llvm.nvvm.zext.wrap(i32 %a, i32 %b)1237    declare i32 @llvm.nvvm.zext.clamp(i32 %a, i32 %b)1238    declare i32 @llvm.nvvm.sext.wrap(i32 %a, i32 %b)1239    declare i32 @llvm.nvvm.sext.clamp(i32 %a, i32 %b)1240 1241Overview:1242"""""""""1243 1244The '``llvm.nvvm.{zext,sext}.{wrap,clamp}``' family of intrinsics extracts the1245low bits of the input value, and zero- or sign-extends them back to the original1246width.1247 1248Semantics:1249""""""""""1250 1251The '``llvm.nvvm.{zext,sext}.{wrap,clamp}``' family of intrinsics returns1252extension of N lowest bits of operand %a. For the '``wrap``' variants, N is the1253value of operand %b modulo 32. For the '``clamp``' variants, N is the value of1254operand %b clamped to the range [0, 32]. The N lowest bits are then1255zero-extended the case of the '``zext``' variants, or sign-extended the case of1256the '``sext``' variants. If N is 0, the result is 0.1257 1258'``llvm.nvvm.bmsk.{wrap,clamp}``' Intrinsic1259^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1260 1261Syntax:1262"""""""1263 1264.. code-block:: llvm1265 1266    declare i32 @llvm.nvvm.bmsk.wrap(i32 %a, i32 %b)1267    declare i32 @llvm.nvvm.bmsk.clamp(i32 %a, i32 %b)1268 1269Overview:1270"""""""""1271 1272The '``llvm.nvvm.bmsk.{wrap,clamp}``' family of intrinsics creates a bit mask1273given a starting bit position and a bit width.1274 1275Semantics:1276""""""""""1277 1278The '``llvm.nvvm.bmsk.{wrap,clamp}``' family of intrinsics returns a value with1279all bits set to 0 except for %b bits starting at bit position %a. For the1280'``wrap``' variants, the values of %a and %b modulo 32 are used. For the1281'``clamp``' variants, the values of %a and %b are clamped to the range [0, 32],1282which in practice is equivalent to using them as is.1283 1284'``llvm.nvvm.prmt``' Intrinsic1285^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1286 1287Syntax:1288"""""""1289 1290.. code-block:: llvm1291 1292    declare i32 @llvm.nvvm.prmt(i32 %lo, i32 %hi, i32 %selector)1293 1294Overview:1295"""""""""1296 1297The '``llvm.nvvm.prmt``' constructs a permutation of the bytes of the first two1298operands, selecting based on the third operand.1299 1300Semantics:1301""""""""""1302 1303The bytes in the first two source operands are numbered from 0 to 7:1304{%hi, %lo} = {{b7, b6, b5, b4}, {b3, b2, b1, b0}}. For each byte in the target1305register, a 4-bit selection value is defined.1306 1307The 3 lsbs of the selection value specify which of the 8 source bytes should be1308moved into the target position. The msb defines if the byte value should be1309copied, or if the sign (msb of the byte) should be replicated over all 8 bits1310of the target position (sign extend of the byte value); msb=0 means copy the1311literal value; msb=1 means replicate the sign.1312 1313These 4-bit selection values are pulled from the lower 16-bits of the %selector1314operand, with the least significant selection value corresponding to the least1315significant byte of the destination.1316 1317 1318'``llvm.nvvm.prmt.*``' Intrinsics1319^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1320 1321Syntax:1322"""""""1323 1324.. code-block:: llvm1325 1326    declare i32 @llvm.nvvm.prmt.f4e(i32 %lo, i32 %hi, i32 %selector)1327    declare i32 @llvm.nvvm.prmt.b4e(i32 %lo, i32 %hi, i32 %selector)1328 1329    declare i32 @llvm.nvvm.prmt.rc8(i32 %lo, i32 %selector)1330    declare i32 @llvm.nvvm.prmt.ecl(i32 %lo, i32 %selector)1331    declare i32 @llvm.nvvm.prmt.ecr(i32 %lo, i32 %selector)1332    declare i32 @llvm.nvvm.prmt.rc16(i32 %lo, i32 %selector)1333 1334Overview:1335"""""""""1336 1337The '``llvm.nvvm.prmt.*``' family of intrinsics constructs a permutation of the1338bytes of the first one or two operands, selecting based on the 2 least1339significant bits of the final operand.1340 1341Semantics:1342""""""""""1343 1344As with the generic '``llvm.nvvm.prmt``' intrinsic, the bytes in the first one1345or two source operands are numbered. The first source operand (%lo) is numbered1346{b3, b2, b1, b0}, in the case of the '``f4e``' and '``b4e``' variants, the1347second source operand (%hi) is numbered {b7, b6, b5, b4}.1348 1349Depending on the 2 least significant bits of the %selector operand, the result1350of the permutation is defined as follows:1351 1352+------------+----------------+--------------+1353|    Mode    | %selector[1:0] |    Output    |1354+------------+----------------+--------------+1355| '``f4e``'  | 0              | {3, 2, 1, 0} |1356|            +----------------+--------------+1357|            | 1              | {4, 3, 2, 1} |1358|            +----------------+--------------+1359|            | 2              | {5, 4, 3, 2} |1360|            +----------------+--------------+1361|            | 3              | {6, 5, 4, 3} |1362+------------+----------------+--------------+1363| '``b4e``'  | 0              | {5, 6, 7, 0} |1364|            +----------------+--------------+1365|            | 1              | {6, 7, 0, 1} |1366|            +----------------+--------------+1367|            | 2              | {7, 0, 1, 2} |1368|            +----------------+--------------+1369|            | 3              | {0, 1, 2, 3} |1370+------------+----------------+--------------+1371| '``rc8``'  | 0              | {0, 0, 0, 0} |1372|            +----------------+--------------+1373|            | 1              | {1, 1, 1, 1} |1374|            +----------------+--------------+1375|            | 2              | {2, 2, 2, 2} |1376|            +----------------+--------------+1377|            | 3              | {3, 3, 3, 3} |1378+------------+----------------+--------------+1379| '``ecl``'  | 0              | {3, 2, 1, 0} |1380|            +----------------+--------------+1381|            | 1              | {3, 2, 1, 1} |1382|            +----------------+--------------+1383|            | 2              | {3, 2, 2, 2} |1384|            +----------------+--------------+1385|            | 3              | {3, 3, 3, 3} |1386+------------+----------------+--------------+1387| '``ecr``'  | 0              | {0, 0, 0, 0} |1388|            +----------------+--------------+1389|            | 1              | {1, 1, 1, 0} |1390|            +----------------+--------------+1391|            | 2              | {2, 2, 1, 0} |1392|            +----------------+--------------+1393|            | 3              | {3, 2, 1, 0} |1394+------------+----------------+--------------+1395| '``rc16``' | 0              | {1, 0, 1, 0} |1396|            +----------------+--------------+1397|            | 1              | {3, 2, 3, 2} |1398|            +----------------+--------------+1399|            | 2              | {1, 0, 1, 0} |1400|            +----------------+--------------+1401|            | 3              | {3, 2, 3, 2} |1402+------------+----------------+--------------+1403 1404TMA family of Intrinsics1405------------------------1406 1407'``llvm.nvvm.cp.async.bulk.global.to.shared.cluster``'1408^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1409 1410Syntax:1411"""""""1412 1413.. code-block:: llvm1414 1415  declare void @llvm.nvvm.cp.async.bulk.global.to.shared.cluster(ptr addrspace(7) %dst, ptr addrspace(3) %mbar, ptr addrspace(1) %src, i32 %size, i16 %mc, i64 %ch, i1 %flag_mc, i1 %flag_ch)1416 1417Overview:1418"""""""""1419 1420The '``@llvm.nvvm.cp.async.bulk.global.to.shared.cluster``' intrinsic1421corresponds to the ``cp.async.bulk.shared::cluster.global.*`` family1422of PTX instructions. These instructions initiate an asynchronous1423copy of bulk data from global memory to shared::cluster memory.1424The 32-bit operand ``%size`` specifies the amount of memory to be1425copied and it must be a multiple of 16.1426 1427* The last two arguments to these intrinsics are boolean flags1428  indicating support for cache_hint and/or multicast modifiers.1429  These flag arguments must be compile-time constants. The backend1430  looks through these flags and lowers the intrinsics appropriately.1431 1432* The Nth argument (denoted by ``i1 %flag_ch``) when set, indicates1433  a valid cache_hint (``i64 %ch``) and generates the ``.L2::cache_hint``1434  variant of the PTX instruction.1435 1436* The [N-1]th argument (denoted by ``i1 %flag_mc``) when set, indicates1437  the presence of a multicast mask (``i16 %mc``) and generates the PTX1438  instruction with the ``.multicast::cluster`` modifier.1439 1440For more information, refer PTX ISA1441`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk>`_.1442 1443'``llvm.nvvm.cp.async.bulk.global.to.shared.cta``'1444^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1445 1446Syntax:1447"""""""1448 1449.. code-block:: llvm1450 1451  declare void @llvm.nvvm.cp.async.bulk.global.to.shared.cta(ptr addrspace(3) %dst, ptr addrspace(3) %mbar, ptr addrspace(1) %src, i32 %size, i64 %ch, i1 %flag_ch)1452 1453Overview:1454"""""""""1455 1456The '``@llvm.nvvm.cp.async.bulk.global.to.shared.cta``' intrinsic1457corresponds to the ``cp.async.bulk.shared::cta.global.*`` family1458of PTX instructions. These instructions initiate an asynchronous1459copy of bulk data from global memory to shared::cta memory.1460The 32-bit operand ``%size`` specifies the amount of memory to be1461copied and it must be a multiple of 16. The last argument1462(denoted by ``i1 %flag_ch``) is a compile-time constant. When set,1463it indicates a valid cache_hint (``i64 %ch``) and generates the1464``.L2::cache_hint`` variant of the PTX instruction.1465 1466For more information, refer PTX ISA1467`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk>`_.1468 1469'``llvm.nvvm.cp.async.bulk.shared.cta.to.global``'1470^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1471 1472Syntax:1473"""""""1474 1475.. code-block:: llvm1476 1477  declare void @llvm.nvvm.cp.async.bulk.shared.cta.to.global(ptr addrspace(1) %dst, ptr addrspace(3) %src, i32 %size, i64 %ch, i1 %flag_ch)1478  declare void @llvm.nvvm.cp.async.bulk.shared.cta.to.global.bytemask(..., i32 %size, i64 %ch, i1 %flag_ch, i16 %mask)1479 1480Overview:1481"""""""""1482 1483The '``@llvm.nvvm.cp.async.bulk.shared.cta.to.global``' intrinsic1484corresponds to the ``cp.async.bulk.global.shared::cta.*`` set of PTX1485instructions. These instructions initiate an asynchronous copy from1486shared::cta to global memory. The 32-bit operand ``%size`` specifies1487the amount of memory to be copied (in bytes) and it must be a multiple1488of 16. For the ``.bytemask`` variant, the 16-bit wide mask operand1489specifies whether the i-th byte of each 16-byte wide chunk of source1490data is copied to the destination.1491 1492* The ``i1 %flag_ch`` argument to these intrinsics is a boolean1493  flag indicating support for cache_hint. This flag argument must1494  be a compile-time constant. When set, it indicates a valid1495  cache_hint (``i64 %ch``) and generates the ``.L2::cache_hint``1496  variant of the PTX instruction.1497 1498For more information, refer PTX ISA1499`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk>`_.1500 1501'``llvm.nvvm.cp.async.bulk.shared.cta.to.cluster``'1502^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1503 1504Syntax:1505"""""""1506 1507.. code-block:: llvm1508 1509  declare void @llvm.nvvm.cp.async.bulk.shared.cta.to.cluster(ptr addrspace(7) %dst, ptr addrspace(3) %mbar, ptr addrspace(3) %src, i32 %size)1510 1511Overview:1512"""""""""1513 1514The '``@llvm.nvvm.cp.async.bulk.shared.cta.to.cluster``' intrinsic1515corresponds to the ``cp.async.bulk.shared::cluster.shared::cta.*``1516PTX instruction. This instruction initiates an asynchronous copy from1517shared::cta to shared::cluster memory. The destination has to be in1518the shared memory of a different CTA within the cluster. The 32-bit1519operand ``%size`` specifies the amount of memory to be copied and1520it must be a multiple of 16.1521 1522For more information, refer PTX ISA1523`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk>`_.1524 1525'``llvm.nvvm.cp.async.bulk.prefetch.L2``'1526^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1527 1528Syntax:1529"""""""1530 1531.. code-block:: llvm1532 1533  declare void @llvm.nvvm.cp.async.bulk.prefetch.L2(ptr addrspace(1) %src, i32 %size, i64 %ch, i1 %flag_ch)1534 1535Overview:1536"""""""""1537 1538The '``@llvm.nvvm.cp.async.bulk.prefetch.L2``' intrinsic1539corresponds to the ``cp.async.bulk.prefetch.L2.*`` family1540of PTX instructions. These instructions initiate an asynchronous1541prefetch of bulk data from global memory to the L2 cache.1542The 32-bit operand ``%size`` specifies the amount of memory to be1543prefetched in terms of bytes and it must be a multiple of 16.1544 1545* The last argument to these intrinsics is boolean flag indicating1546  support for cache_hint. These flag argument must be compile-time1547  constant. When set, it indicates a valid cache_hint (``i64 %ch``)1548  and generates the ``.L2::cache_hint`` variant of the PTX instruction.1549 1550For more information, refer PTX ISA1551`<https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-cp-async-bulk-prefetch>`_.1552 1553'``llvm.nvvm.prefetch.*``'1554^^^^^^^^^^^^^^^^^^^^^^^^^^1555 1556Syntax:1557"""""""1558 1559.. code-block:: llvm1560 1561  declare void  @llvm.nvvm.prefetch.global.L1(ptr addrspace(1) %global_ptr)1562  declare void  @llvm.nvvm.prefetch.global.L2(ptr addrspace(1) %global_ptr)1563  declare void  @llvm.nvvm.prefetch.local.L1(ptr addrspace(5) %local_ptr)1564  declare void  @llvm.nvvm.prefetch.local.L2(ptr addrspace(5) %local_ptr)1565  1566  declare void  @llvm.nvvm.prefetch.L1(ptr %ptr)1567  declare void  @llvm.nvvm.prefetch.L2(ptr %ptr)1568  1569  declare void  @llvm.nvvm.prefetch.tensormap.p0(ptr %ptr)1570  declare void  @llvm.nvvm.prefetch.tensormap.p4(ptr addrspace(4) %const_ptr)1571  declare void  @llvm.nvvm.prefetch.tensormap.p101(ptr addrspace(101) %param_ptr)  1572  1573  declare void  @llvm.nvvm.prefetch.global.L2.evict.normal(ptr addrspace(1) %global_ptr)1574  declare void  @llvm.nvvm.prefetch.global.L2.evict.last(ptr addrspace(1) %global_ptr)1575 1576  declare void  @llvm.nvvm.prefetchu.L1(ptr %ptr)1577 1578Overview:1579"""""""""1580 1581The '``@llvm.nvvm.prefetch.*``' and '``@llvm.nvvm.prefetchu.*``' intrinsic1582correspond to the '``prefetch.*``;' and '``prefetchu.*``' family of PTX instructions. 1583The '``prefetch.*``' instructions bring the cache line containing the1584specified address in global or local memory address space into the 1585specified cache level (L1 or L2). If the '``.tensormap``' qualifier is specified then the 1586prefetch instruction brings the cache line containing the specified address in the 1587'``.const``' or '``.param memory``' state space for subsequent use by the '``cp.async.bulk.tensor``' 1588instruction. The '`prefetchu.*``' instruction brings the cache line 1589containing the specified generic address into the specified uniform cache level.1590If no address space is specified, it is assumed to be generic address. The intrinsic 1591uses and eviction priority which can be accessed by the '``.level::eviction_priority``' modifier.1592 1593* A prefetch to a shared memory location performs no operation.1594* A prefetch into the uniform cache requires a generic address, 1595  and no operation occurs if the address maps to a const, local, or shared memory location.1596 1597For more information, refer to the PTX ISA1598`<https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-prefetch-prefetchu>`_.1599 1600'``llvm.nvvm.applypriority.*``'1601^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1602 1603Syntax:1604"""""""1605 1606.. code-block:: llvm1607 1608  declare void  @llvm.nvvm.applypriority.global.L2.evict.normal(ptr addrspace(1) %global_ptr, i64 %size)1609  declare void  @llvm.nvvm.applypriority.L2.evict.normal(ptr %ptr, i64 %size)1610 1611Overview:1612"""""""""1613 1614The '``@llvm.nvvm.applypriority.*``'  applies the cache eviction priority specified by the1615.level::eviction_priority qualifier to the address range [a..a+size) in the specified cache 1616level. If no state space is specified then Generic Addressing is used. If the specified address 1617does not fall within the address window of .global state space then the behavior is undefined.1618The operand size is an integer constant that specifies the amount of data, in bytes, in the specified cache1619level on which the priority is to be applied. The only supported value for the size operand is 128.1620 1621For more information, refer to the PTX ISA1622`<https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-applypriority>`_.1623 1624``llvm.nvvm.discard.*``'1625^^^^^^^^^^^^^^^^^^^^^^^^1626 1627Syntax:1628"""""""1629 1630.. code-block:: llvm1631 1632  declare void  @llvm.nvvm.discard.global.L2(ptr addrspace(1) %global_ptr, i64 immarg)1633  declare void  @llvm.nvvm.discard.L2(ptr %ptr, i64 immarg)1634 1635Overview:1636"""""""""1637 1638The *effects* of the ``@llvm.nvvm.discard.L2*`` intrinsics are those of a non-atomic 1639non-volatile ``llvm.memset`` that writes ``undef`` to the destination 1640address range ``[%ptr, %ptr + immarg)``. The ``%ptr`` must be aligned by 128 bytes.1641Subsequent reads from the address range may read ``undef`` until the memory is overwritten 1642with a different value.1643These operations *hint* the implementation that data in the L2 cache can be destructively 1644discarded without writing it back to memory. 1645The operand ``immarg`` is an integer constant that specifies the length in bytes of the 1646address range ``[%ptr, %ptr + immarg)`` to write ``undef`` into. 1647The only supported value for the ``immarg`` operand is ``128``. 1648If generic addressing is used and the specified address does not fall within the 1649address window of global memory (``addrspace(1)``) the behavior is undefined.1650 1651.. code-block:: llvm1652 1653   call void @llvm.nvvm.discard.L2(ptr %p, i64 128)  ;; writes `undef` to [p, p+128)1654   %a = load i64, ptr %p. ;; loads 8 bytes containing undef1655   %b = load i64, ptr %p  ;; loads 8 bytes containing undef1656   ;; comparing %a and %b compares `undef` values!1657   %fa = freeze i64 %a  ;; freezes undef to stable bit-pattern1658   %fb = freeze i64 %b  ;; freezes undef to stable bit-pattern1659   ;; %fa may compare different to %fb!1660   1661For more information, refer to the  `CUDA C++ discard documentation <https://nvidia.github.io/cccl/libcudacxx/extended_api/memory_access_properties/discard_memory.html>`__ and to the `PTX ISA discard documentation <https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-discard>`__ .1662 1663'``llvm.nvvm.cp.async.bulk.tensor.g2s.tile.[1-5]d``'1664^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1665 1666Syntax:1667"""""""1668 1669.. code-block:: llvm1670 1671  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.tile.1d(ptr addrspace(7) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %d0, i16 %mc, i64 %ch, i1 %flag_mc, i1 %flag_ch, i32 %flag_cta_group)1672  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.tile.2d(..., i32 %d0, i32 %d1, ...)1673  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.tile.3d(..., i32 %d0, i32 %d1, i32 %d2, ...)1674  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.tile.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1675  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.tile.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1676 1677  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.tile.gather4.2d(ptr addrspace(7) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %x0, i32 %y0, i32 %y1, i32 %y2, i32 %y3, i16 %mc, i64 %ch, i1 %flag_mc, i1 %flag_ch, i32 %flag_cta_group)1678 1679Overview:1680"""""""""1681 1682The '``@llvm.nvvm.cp.async.bulk.tensor.g2s.tile.[1-5]d``' intrinsics1683correspond to the ``cp.async.bulk.tensor.[1-5]d.*`` set of PTX instructions.1684These instructions initiate an asynchronous copy of tensor data from1685global memory to shared::cluster memory (indicated by the ``g2s`` prefix)1686in ``tile`` mode. In tile mode, the multi-dimensional layout of the1687source tensor is preserved at the destination. The dimension of the1688tensor data ranges from 1d to 5d with the coordinates specified1689by the ``i32 %d0 ... i32 %d4`` arguments. In ``tile.gather4`` mode,1690four rows in a 2D tensor are combined to form a single 2D destination1691tensor. The first coordinate ``i32 %x0`` denotes the column index1692followed by four coordinates indicating the four row-indices.1693So, this mode takes a total of 5 coordinates as input arguments.1694For more information on ``gather4`` mode, refer PTX ISA1695`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-tiled-scatter4-gather4-modes>`_.1696 1697* The last three arguments to these intrinsics are flags1698  indicating support for multicast, cache_hint and cta_group::1/21699  modifiers. These flag arguments must be compile-time constants.1700  The backend looks through these flags and lowers the intrinsics1701  appropriately.1702 1703* The argument denoted by ``i1 %flag_ch`` when set, indicates1704  a valid cache_hint (``i64 %ch``) and generates the ``.L2::cache_hint``1705  variant of the PTX instruction.1706 1707* The argument denoted by ``i1 %flag_mc`` when set, indicates1708  the presence of a multicast mask (``i16 %mc``) and generates1709  the PTX instruction with the ``.multicast::cluster`` modifier.1710 1711* The argument denoted by ``i32 %flag_cta_group`` takes values within1712  the range [0, 3) i.e. {0,1,2}. When the value of ``%flag_cta_group``1713  is not within the range, it may raise an error from the Verifier.1714  The default value is '0' with no cta_group modifier in the1715  instruction. The values of '1' and '2' lower to ``cta_group::1``1716  and ``cta_group::2`` variants of the PTX instruction respectively.1717 1718For more information, refer PTX ISA1719`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk-tensor>`_.1720 1721'``llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.[3-5]d``'1722^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1723 1724Syntax:1725"""""""1726 1727.. code-block:: llvm1728 1729  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.3d(ptr addrspace(7) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %im2col0, i16 %mc, i64 %ch, i1 %flag_mc, i1 %flag_ch, i32 %flag_cta_group)1730  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i16 %im2col0, i16 %im2col1, ...)1731  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, i16 %im2col0, i16 %im2col1, i16 %im2col2, ...)1732 1733  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.w.3d(ptr addrspace(7) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %wHalo, i16 %wOffset, i16 %mc, i64 %ch, i1 %flag_mc, i1 %flag_ch, i32 %flag_cta_group)1734  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.w.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1735  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.w.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1736 1737  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.w.128.3d(ptr addrspace(7) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %wHalo, i16 %wOffset, i16 %mc, i64 %ch, i1 %flag_mc, i1 %flag_ch, i32 %flag_cta_group)1738  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.w.128.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1739  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.w.128.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1740 1741Overview:1742"""""""""1743 1744The '``@llvm.nvvm.cp.async.bulk.tensor.g2s.im2col.[3-5]d``' intrinsics1745correspond to the ``cp.async.bulk.tensor.[1-5]d.*`` set of PTX instructions.1746These instructions initiate an asynchronous copy of tensor data from1747global memory to shared::cluster memory (indicated by the ``g2s`` prefix)1748in ``im2col`` mode. In im2col mode, some dimensions of the source tensor1749are unrolled into a single dimensional column at the destination. In this1750mode, the tensor has to be at least three-dimensional. Along with the tensor1751coordinates, im2col offsets are also specified (denoted by1752``i16 im2col0...i16 %im2col2``). For the ``im2col`` mode, the number of offsets1753is two less than the number of dimensions of the tensor operation. For the1754``im2col.w`` and ``im2col.w.128`` mode, the number of offsets is always 2,1755denoted by ``i16 %wHalo`` and ``i16 %wOffset`` arguments. For more information1756on ``im2col.w`` and ``im2col.w.128`` modes, refer PTX ISA1757`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-im2col-w-w128-modes>`_.1758 1759The last three arguments to these intrinsics are flags, with the same functionality1760as described in the ``tile`` mode intrinsics above.1761 1762For more information, refer PTX ISA1763`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk-tensor>`_.1764 1765'``llvm.nvvm.cp.async.bulk.tensor.g2s.cta.tile.[1-5]d``'1766^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1767 1768Syntax:1769"""""""1770 1771.. code-block:: llvm1772 1773  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.tile.1d(ptr addrspace(3) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)1774  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.tile.2d(..., i32 %d0, i32 %d1, ...)1775  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.tile.3d(..., i32 %d0, i32 %d1, i32 %d2, ...)1776  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.tile.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1777  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.tile.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1778 1779  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.tile.gather4.2d(ptr addrspace(3) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %x0, i32 %y0, i32 %y1, i32 %y2, i32 %y3, i64 %ch, i1 %flag_ch)1780 1781Overview:1782"""""""""1783 1784The '``@llvm.nvvm.cp.async.bulk.tensor.g2s.cta.tile.[1-5]d``' intrinsics1785correspond to the ``cp.async.bulk.tensor.[1-5]d.shared::cta.global.*``1786set of PTX instructions. These instructions initiate an asynchronous1787copy of tensor data from global memory to shared::cta memory in1788``tile`` mode. In tile mode, the multi-dimensional layout of the1789source tensor is preserved at the destination. The dimension of the1790tensor data ranges from 1d to 5d with the coordinates specified1791by the ``i32 %d0 ... i32 %d4`` arguments. In ``tile.gather4`` mode,1792four rows in a 2D tensor are combined to form a single 2D destination1793tensor. The first coordinate ``i32 %x0`` denotes the column index1794followed by four coordinates indicating the four row-indices.1795So, this mode takes a total of 5 coordinates as input arguments.1796For more information on ``gather4`` mode, refer PTX ISA1797`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-tiled-scatter4-gather4-modes>`_.1798 1799* The last argument to these intrinsics is a boolean flag1800  indicating support for cache_hint. This flag argument must1801  be a compile-time constant. When set, it indicates a valid1802  cache_hint (``i64 %ch``) and generates the ``.L2::cache_hint``1803  variant of the PTX instruction.1804 1805For more information, refer PTX ISA1806`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk-tensor>`_.1807 1808'``llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.[3-5]d``'1809^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1810 1811Syntax:1812"""""""1813 1814.. code-block:: llvm1815 1816  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.3d(ptr addrspace(3) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %im2col0, i64 %ch, i1 %flag_ch)1817  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i16 %im2col0, i16 %im2col1, ...)1818  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, i16 %im2col0, i16 %im2col1, i16 %im2col2, ...)1819 1820  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.w.3d(ptr addrspace(3) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %wHalo, i16 %wOffset, i64 %ch, i1 %flag_ch)1821  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.w.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1822  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.w.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1823 1824  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.w.128.3d(ptr addrspace(3) %dst, ptr addrspace(3) %bar, ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %wHalo, i16 %wOffset, i64 %ch, i1 %flag_ch)1825  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.w.128.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1826  declare void @llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.w.128.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1827 1828Overview:1829"""""""""1830 1831The '``@llvm.nvvm.cp.async.bulk.tensor.g2s.cta.im2col.[3-5]d``' intrinsics1832correspond to the ``cp.async.bulk.tensor.[1-5]d.shared::cta.global.*``1833set of PTX instructions. These instructions initiate an asynchronous copy1834of tensor data from global memory to shared::cta memory in ``im2col`` mode.1835In im2col mode, some dimensions of the source tensor are unrolled into a1836single dimensional column at the destination. In this mode, the tensor has1837to be at least three-dimensional. Along with the tensor coordinates, im2col1838offsets are also specified (denoted by ``i16 im2col0...i16 %im2col2``).1839For the ``im2col`` mode, the number of offsets is two less than the number1840of dimensions of the tensor operation. For the ``im2col.w`` and ``im2col.w.128``1841mode, the number of offsets is always 2, denoted by ``i16 %wHalo`` and1842``i16 %wOffset`` arguments. For more information on ``im2col.w`` and1843``im2col.w.128`` modes, refer PTX ISA1844`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-im2col-w-w128-modes>`_.1845 1846* The last argument to these intrinsics is a boolean flag1847  indicating support for cache_hint. This flag argument must1848  be a compile-time constant. When set, it indicates a valid1849  cache_hint (``i64 %ch``) and generates the ``.L2::cache_hint``1850  variant of the PTX instruction.1851 1852For more information, refer PTX ISA1853`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk-tensor>`_.1854 1855'``llvm.nvvm.cp.async.bulk.tensor.s2g.tile.[1-5]d``'1856^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1857 1858Syntax:1859"""""""1860 1861.. code-block:: llvm1862 1863  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)1864  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.tile.2d(..., i32 %d0, i32 %d1, ...)1865  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.tile.3d(..., i32 %d0, i32 %d1, i32 %d2, ...)1866  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.tile.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1867  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.tile.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1868 1869  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.tile.scatter4.2d(ptr addrspace(3) %src, ptr %tensor_map, i32 %x0, i32 %y0, i32 %y1, i32 %y2, i32 %y3, i64 %ch, i1 %flag_ch)1870 1871Overview:1872"""""""""1873 1874The '``@llvm.nvvm.cp.async.bulk.tensor.s2g.tile.[1-5]d``' intrinsics1875correspond to the ``cp.async.bulk.tensor.[1-5]d.*`` set of PTX instructions.1876These instructions initiate an asynchronous copy of tensor data from1877shared::cta to global memory (indicated by the ``s2g`` prefix)1878in ``tile`` mode. The dimension of the tensor data ranges from 1d to 5d1879with the coordinates specified by the ``i32 %d0 ... i32 %d4`` arguments.1880In ``tile.scatter4`` mode, a single 2D source tensor is divided into1881four rows in the 2D destination tensor. The first coordinate ``i32 %x0``1882denotes the column index followed by four coordinates indicating the1883four row-indices. So, this mode takes a total of 5 coordinates as input arguments.1884For more information on ``scatter4`` mode, refer PTX ISA1885`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-tiled-scatter4-gather4-modes>`_.1886 1887* The last argument to these intrinsics is a boolean flag1888  indicating support for cache_hint. This flag argument must1889  be a compile-time constant. When set, it indicates a valid1890  cache_hint (``i64 %ch``) and generates the ``.L2::cache_hint``1891  variant of the PTX instruction.1892 1893For more information, refer PTX ISA1894`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk-tensor>`_.1895 1896'``llvm.nvvm.cp.async.bulk.tensor.s2g.im2col.[3-5]d``'1897^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1898 1899Syntax:1900"""""""1901 1902.. code-block:: llvm1903 1904  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.im2col.3d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i64 %ch, i1 %flag_ch)1905  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.im2col.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1906  declare void @llvm.nvvm.cp.async.bulk.tensor.s2g.im2col.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1907 1908Overview:1909"""""""""1910 1911The '``@llvm.nvvm.cp.async.bulk.tensor.s2g.im2col.[1-5]d``' intrinsics1912correspond to the ``cp.async.bulk.tensor.[1-5]d.*`` set of PTX instructions.1913These instructions initiate an asynchronous copy of tensor data from1914shared::cta to global memory (indicated by the ``s2g`` prefix)1915in ``im2col`` mode. In this mode, the tensor has to be at least1916three-dimensional. Unlike the ``g2s`` variants, there are no1917im2col_offsets for these intrinsics. The last argument to these1918intrinsics is a boolean flag, with the same functionality as1919described in the ``s2g.tile`` mode intrinsics above.1920 1921For more information, refer PTX ISA1922`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-async-bulk-tensor>`_.1923 1924'``llvm.nvvm.cp.async.bulk.tensor.prefetch.tile.[1-5]d``'1925^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1926 1927Syntax:1928"""""""1929 1930.. code-block:: llvm1931 1932  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.tile.1d(ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)1933  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.tile.2d(..., i32 %d0, i32 %d1, ...)1934  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.tile.3d(..., i32 %d0, i32 %d1, i32 %d2, ...)1935  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.tile.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1936  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.tile.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1937 1938  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.tile.gather4.2d(ptr %tensor_map, i32 %x0, i32 %y0, i32 %y1, i32 %y2, i32 %y3, i64 %ch, i1 %flag_ch)1939 1940Overview:1941"""""""""1942 1943The '``@llvm.nvvm.cp.async.bulk.tensor.prefetch.tile.[1-5]d``' intrinsics1944correspond to the ``cp.async.bulk.prefetch.tensor.[1-5]d.L2.global*`` set1945of PTX instructions. These instructions initiate an asynchronous prefetch1946of tensor data from global memory to the L2 cache. In tile mode, the1947multi-dimensional layout of the source tensor is preserved at the destination.1948The dimension of the tensor data ranges from 1d to 5d with the coordinates1949specified by the ``i32 %d0 ... i32 %d4`` arguments.1950 1951In ``tile.gather4`` mode, four rows in the 2-dimnesional source tensor are1952fetched to the L2 cache. The first coordinate ``i32 %x0`` denotes the column index1953followed by four coordinates indicating the four row-indices. So, this mode takes1954a total of 5 coordinates as input arguments.1955For more information on ``gather4`` mode, refer PTX ISA1956`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-tiled-scatter4-gather4-modes>`_.1957 1958* The last argument to these intrinsics is a boolean flag1959  indicating support for cache_hint. This flag argument must1960  be a compile-time constant. When set, it indicates a valid1961  cache_hint (``i64 %ch``) and generates the ``.L2::cache_hint``1962  variant of the PTX instruction.1963 1964For more information, refer PTX ISA1965`<https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-cp-async-bulk-prefetch-tensor>`_.1966 1967'``llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.[3-5]d``'1968^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^1969 1970Syntax:1971"""""""1972 1973.. code-block:: llvm1974 1975  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.3d(ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %im2col0, i64 %ch, i1 %flag_ch)1976  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i16 %im2col0, i16 %im2col1, ...)1977  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, i16 %im2col0, i16 %im2col1, i16 %im2col2, ...)1978 1979  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.w.3d(ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %wHalo, i16 %wOffset, i64 %ch, i1 %flag_ch)1980  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.w.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1981  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.w.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1982 1983  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.w.128.3d(ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i16 %wHalo, i16 %wOffset, i64 %ch, i1 %flag_ch)1984  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.w.128.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)1985  declare void @llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.w.128.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)1986 1987Overview:1988"""""""""1989 1990The '``@llvm.nvvm.cp.async.bulk.tensor.prefetch.im2col.[3-5]d``' intrinsics1991correspond to the ``cp.async.bulk.prefetch.tensor.[1-5]d.L2.global*`` set1992of PTX instructions. These instructions initiate an asynchronous prefetch1993of tensor data from global memory to the L2 cache. In im2col mode, some1994dimensions of the source tensor are unrolled into a single dimensional1995column at the destination. In this mode, the tensor has to be at least1996three-dimensional. Along with the tensor coordinates, im2col offsets are1997also specified (denoted by ``i16 im2col0...i16 %im2col2``). For ``im2col``1998mode, the number of offsets is two less than the number of dimensions of1999the tensor operation. For the ``im2col.w`` and ``im2col.w.128`` modes,2000the number of offsets is always 2, denoted by ``i16 %wHalo`` and2001``i16 %wOffset`` arguments. For more information on ``im2col.w`` and2002``im2col.w.128`` modes, refer PTX ISA2003`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-im2col-w-w128-modes>`_.2004 2005 2006The last argument to these intrinsics is a boolean flag, with2007the same functionality as described in the ``tile`` mode intrinsics above.2008 2009For more information, refer PTX ISA2010`<https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-cp-async-bulk-prefetch-tensor>`_.2011 2012'``llvm.nvvm.cp.async.bulk.tensor.reduce.[red_op].tile.[1-5]d``'2013^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2014 2015Syntax:2016"""""""2017 2018.. code-block:: llvm2019 2020  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.add.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)2021  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.min.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)2022  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.max.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)2023  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.inc.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)2024  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.dec.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)2025  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.and.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)2026  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.or.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)2027  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.xor.tile.1d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i64 %ch, i1 %flag_ch)2028 2029  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.tile.2d(..., i32 %d0, i32 %d1, ...)2030  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.tile.3d(..., i32 %d0, i32 %d1, i32 %d2, ...)2031  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.tile.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)2032  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.tile.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)2033 2034Overview:2035"""""""""2036 2037The '``@llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.tile.[1-5]d``' intrinsics2038correspond to the ``cp.reduce.async.bulk.tensor.[1-5]d.*`` set of PTX instructions.2039These instructions initiate an asynchronous reduction operation of tensor data2040in global memory with the tensor data in shared{::cta} memory, using ``tile`` mode.2041The dimension of the tensor data ranges from 1d to 5d with the coordinates2042specified by the ``i32 %d0 ... i32 %d4`` arguments. The supported reduction2043operations are {add, min, max, inc, dec, and, or, xor} as described in the2044``tile.1d`` intrinsics.2045 2046* The last argument to these intrinsics is a boolean flag2047  indicating support for cache_hint. This flag argument must2048  be a compile-time constant. When set, it indicates a valid2049  cache_hint (``i64 %ch``) and generates the ``.L2::cache_hint``2050  variant of the PTX instruction.2051 2052For more information, refer PTX ISA2053`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-reduce-async-bulk-tensor>`_.2054 2055'``llvm.nvvm.cp.async.bulk.tensor.reduce.[red_op].im2col.[3-5]d``'2056^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2057 2058Syntax:2059"""""""2060 2061.. code-block:: llvm2062 2063  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.im2col.3d(ptr addrspace(3) %src, ptr %tensor_map, i32 %d0, i32 %d1, i32 %d2, i64 %ch, i1 %flag_ch)2064  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.im2col.4d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, ...)2065  declare void @llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.im2col.5d(..., i32 %d0, i32 %d1, i32 %d2, i32 %d3, i32 %d4, ...)2066 2067Overview:2068"""""""""2069 2070The '``@llvm.nvvm.cp.async.bulk.tensor.reduce.<red_op>.im2col.[3-5]d``' intrinsics2071correspond to the ``cp.reduce.async.bulk.tensor.[3-5]d.*`` set of PTX instructions.2072These instructions initiate an asynchronous reduction operation of tensor data2073in global memory with the tensor data in shared{::cta} memory, using ``im2col`` mode.2074In this mode, the tensor has to be at least three-dimensional. The supported reduction2075operations supported are the same as the ones in the tile mode. The last argument to2076these intrinsics is a boolean flag, with the same functionality as described in the2077``tile`` mode intrinsics above.2078 2079For more information, refer PTX ISA2080`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#data-movement-and-conversion-instructions-cp-reduce-async-bulk-tensor>`_.2081 2082Warp Group Intrinsics2083---------------------2084 2085'``llvm.nvvm.wgmma.fence.sync.aligned``'2086^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2087 2088Syntax:2089"""""""2090 2091.. code-block:: llvm2092 2093  declare void @llvm.nvvm.wgmma.fence.sync.aligned()2094 2095Overview:2096"""""""""2097 2098The '``@llvm.nvvm.wgmma.fence.sync.aligned``' intrinsic generates the2099``wgmma.fence.sync.aligned`` PTX instruction, which establishes an ordering2100between prior accesses to any warpgroup registers and subsequent accesses to2101the same registers by a ``wgmma.mma_async`` instruction.2102 2103The ``wgmma.fence`` instruction must be issued by all warps of the warpgroup in2104the following locations:2105 2106* Before the first ``wgmma.mma_async`` operation in a warpgroup.2107* Between a register access by a thread in the warpgroup and any2108  ``wgmma.mma_async`` instruction that accesses the same registers, except when2109  these are accumulator register accesses across multiple ``wgmma.mma_async``2110  instructions of the same shape in which case an ordering guarantee is2111  provided by default.2112 2113For more information, refer PTX ISA2114`<https://docs.nvidia.com/cuda/parallel-thread-execution/#asynchronous-warpgroup-level-matrix-instructions-wgmma-fence>`_.2115 2116'``llvm.nvvm.wgmma.commit_group.sync.aligned``'2117^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2118 2119Syntax:2120"""""""2121 2122.. code-block:: llvm2123 2124  declare void @llvm.nvvm.wgmma.commit_group.sync.aligned()2125 2126Overview:2127"""""""""2128 2129The '``@llvm.nvvm.wgmma.commit_group.sync.aligned``' intrinsic generates the2130``wgmma.commit_group.sync.aligned`` PTX instruction, which creates a new2131wgmma-group per warpgroup and batches all prior ``wgmma.mma_async``2132instructions initiated by the executing warp but not committed to any2133wgmma-group into the new wgmma-group. If there are no uncommitted ``wgmma2134mma_async`` instructions then, ``wgmma.commit_group`` results in an empty2135wgmma-group.2136 2137An executing thread can wait for the completion of all ``wgmma.mma_async``2138operations in a wgmma-group by using ``wgmma.wait_group``.2139 2140For more information, refer PTX ISA2141`<https://docs.nvidia.com/cuda/parallel-thread-execution/#asynchronous-warpgroup-level-matrix-instructions-wgmma-commit-group>`_.2142 2143'``llvm.nvvm.wgmma.wait_group.sync.aligned``'2144^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2145 2146Syntax:2147"""""""2148 2149.. code-block:: llvm2150 2151  declare void @llvm.nvvm.wgmma.wait_group.sync.aligned(i64 immarg N)2152 2153Overview:2154"""""""""2155 2156The '``@llvm.nvvm.wgmma.wait_group.sync.aligned``' intrinsic generates the2157``wgmma.commit_group.sync.aligned N`` PTX instruction, which will cause the2158executing thread to wait until only ``N`` or fewer of the most recent2159wgmma-groups are pending and all the prior wgmma-groups committed by the2160executing threads are complete. For example, when ``N`` is 0, the executing2161thread waits on all the prior wgmma-groups to complete. Operand ``N`` is an2162integer constant.2163 2164Accessing the accumulator register or the input register containing the2165fragments of matrix A of a ``wgmma.mma_async`` instruction without first2166performing a ``wgmma.wait_group`` instruction that waits on a wgmma-group2167including that ``wgmma.mma_async`` instruction is undefined behavior.2168 2169For more information, refer PTX ISA2170`<https://docs.nvidia.com/cuda/parallel-thread-execution/#asynchronous-warpgroup-level-matrix-instructions-wgmma-wait-group>`_.2171 2172'``llvm.nvvm.griddepcontrol.*``'2173^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2174 2175Syntax:2176"""""""2177 2178.. code-block:: llvm2179 2180  declare void @llvm.nvvm.griddepcontrol.launch_dependents()2181  declare void @llvm.nvvm.griddepcontrol.wait()2182 2183Overview:2184"""""""""2185 2186The ``griddepcontrol`` intrinsics allows the dependent grids and prerequisite grids as defined by the runtime, to control execution in the following way:2187 2188``griddepcontrol.launch_dependents`` intrinsic signals that the dependents can be scheduled, before the current grid completes. The intrinsic can be invoked by multiple threads in the current CTA and repeated invocations of the intrinsic will have no additional side effects past that of the first invocation.2189 2190``griddepcontrol.wait`` intrinsic causes the executing thread to wait until all prerequisite grids in flight have completed and all the memory operations from the prerequisite grids are performed and made visible to the current grid.2191 2192For more information, refer 2193`PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#parallel-synchronization-and-communication-instructions-griddepcontrol>`__.2194 2195TCGEN05 family of Intrinsics2196----------------------------2197 2198The llvm.nvvm.tcgen05.* intrinsics model the TCGEN05 family of instructions2199exposed by PTX. These intrinsics use 'Tensor Memory' (henceforth ``tmem``).2200NVPTX represents this memory using ``addrspace(6)`` and is always 32-bits.2201 2202For more information, refer to the PTX ISA2203`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-memory>`_.2204 2205The tensor-memory pointers may only be used with the tcgen05 intrinsics.2206There are specialized load/store instructions provided (tcgen05.ld/st) to2207work with tensor-memory.2208 2209See the PTX ISA for more information on tensor-memory load/store instructions2210`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-memory-and-register-load-store-instructions>`_.2211 2212'``llvm.nvvm.tcgen05.alloc``'2213^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2214 2215Syntax:2216"""""""2217 2218.. code-block:: llvm2219 2220  declare void @llvm.nvvm.tcgen05.alloc.cg1(ptr %dst, i32 %ncols)2221  declare void @llvm.nvvm.tcgen05.alloc.cg2(ptr %dst, i32 %ncols)2222  declare void @llvm.nvvm.tcgen05.alloc.shared.cg1(ptr addrspace(3) %dst, i32 %ncols)2223  declare void @llvm.nvvm.tcgen05.alloc.shared.cg2(ptr addrspace(3) %dst, i32 %ncols)2224 2225Overview:2226"""""""""2227 2228The '``@llvm.nvvm.tcgen05.alloc.*``' intrinsics correspond to the2229``tcgen05.alloc.cta_group*.sync.aligned.b32`` family of PTX instructions.2230The ``tcgen05.alloc`` is a potentially blocking instruction which dynamically2231allocates the specified number of columns in the Tensor Memory and writes2232the address of the allocated Tensor Memory into shared memory at the2233location specified by ``%dst``. The 32-bit operand ``%ncols`` specifies2234the number of columns to be allocated and it must be a power-of-two.2235The ``.shared`` variant explicitly uses shared memory address space for2236the ``%dst`` operand. The ``.cg1`` and ``.cg2`` variants generate2237``cta_group::1`` and ``cta_group::2`` variants of the instruction respectively.2238 2239For more information, refer to the PTX ISA2240`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-memory-allocation-and-management-instructions>`_.2241 2242'``llvm.nvvm.tcgen05.dealloc``'2243^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2244 2245Syntax:2246"""""""2247 2248.. code-block:: llvm2249 2250  declare void @llvm.nvvm.tcgen05.dealloc.cg1(ptr addrspace(6) %tmem_addr, i32 %ncols)2251  declare void @llvm.nvvm.tcgen05.dealloc.cg2(ptr addrspace(6) %tmem_addr, i32 %ncols)2252 2253Overview:2254"""""""""2255 2256The '``@llvm.nvvm.tcgen05.dealloc.*``' intrinsics correspond to the2257``tcgen05.dealloc.*`` set of PTX instructions. The ``tcgen05.dealloc``2258instructions deallocates the Tensor Memory specified by the Tensor Memory2259address ``%tmem_addr``. The operand ``%tmem_addr`` must point to a previous2260Tensor Memory allocation. The 32-bit operand ``%ncols`` specifies the number2261of columns to be de-allocated. The ``.cg1`` and ``.cg2`` variants generate2262``cta_group::1`` and ``cta_group::2`` variants of the instruction respectively.2263 2264For more information, refer to the PTX ISA2265`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-memory-allocation-and-management-instructions>`_.2266 2267'``llvm.nvvm.tcgen05.relinq.alloc.permit``'2268^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2269 2270Syntax:2271"""""""2272 2273.. code-block:: llvm2274 2275  declare void @llvm.nvvm.tcgen05.relinq.alloc.permit.cg1()2276  declare void @llvm.nvvm.tcgen05.relinq.alloc.permit.cg2()2277 2278Overview:2279"""""""""2280 2281The '``@llvm.nvvm.tcgen05.relinq.alloc.permit.*``' intrinsics correspond2282to the ``tcgen05.relinquish_alloc_permit.*`` set of PTX instructions.2283This instruction specifies that the CTA of the executing thread is2284relinquishing the right to allocate Tensor Memory. So, it is illegal2285for a CTA to perform ``tcgen05.alloc`` after any of its constituent2286threads execute ``tcgen05.relinquish_alloc_permit``. The ``.cg1``2287and ``.cg2`` variants generate ``cta_group::1`` and ``cta_group::2``2288flavors of the instruction respectively.2289 2290For more information, refer to the PTX ISA2291`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensor-memory-allocation-and-management-instructions>`_.2292 2293'``llvm.nvvm.tcgen05.commit``'2294^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2295 2296Syntax:2297"""""""2298 2299.. code-block:: llvm2300 2301  declare void @llvm.nvvm.tcgen05.commit.{cg1,cg2}(ptr %mbar)2302  declare void @llvm.nvvm.tcgen05.commit.shared.{cg1,cg2}(ptr addrspace(3) %mbar)2303  declare void @llvm.nvvm.tcgen05.commit.mc.{cg1,cg2}(ptr %mbar, i16 %mc)2304  declare void @llvm.nvvm.tcgen05.commit.mc.shared.{cg1,cg2}(ptr addrspace(3) %mbar, i16 %mc)2305 2306Overview:2307"""""""""2308 2309The '``@llvm.nvvm.tcgen05.commit.*``' intrinsics correspond to the2310``tcgen05.commit.{cg1/cg2}.mbarrier::arrive::one.*`` set of PTX instructions.2311The ``tcgen05.commit`` is an asynchronous instruction which makes the mbarrier2312object (``%mbar``) track the completion of all prior asynchronous tcgen05 operations.2313The ``.mc`` variants allow signaling on the mbarrier objects of multiple CTAs2314(specified by ``%mc``) in the cluster. The ``.cg1`` and ``.cg2`` variants generate2315``cta_group::1`` and ``cta_group::2`` flavors of the instruction respectively.2316 2317For more information, refer to the PTX ISA2318`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen-async-sync-operations-commit>`_.2319 2320'``llvm.nvvm.tcgen05.wait``'2321^^^^^^^^^^^^^^^^^^^^^^^^^^^^2322 2323Syntax:2324"""""""2325 2326.. code-block:: llvm2327 2328  declare void @llvm.nvvm.tcgen05.wait.ld()2329  declare void @llvm.nvvm.tcgen05.wait.st()2330 2331Overview:2332"""""""""2333 2334The '``@llvm.nvvm.tcgen05.wait.ld/st``' intrinsics correspond to2335the ``tcgen05.wait::{ld/st}.sync.aligned`` pair of PTX instructions.2336The ``tcgen05.wait::ld`` causes the executing thread to block until2337all prior ``tcgen05.ld`` operations issued by the executing thread2338have completed. The ``tcgen05.wait::st`` causes the executing thread2339to block until all prior ``tcgen05.st`` operations issued by the2340executing thread have completed.2341 2342For more information, refer to the PTX ISA2343`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instructions-tcgen05-wait>`_.2344 2345'``llvm.nvvm.tcgen05.fence``'2346^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2347 2348Syntax:2349"""""""2350 2351.. code-block:: llvm2352 2353  declare void @llvm.nvvm.tcgen05.fence.before.thread.sync()2354  declare void @llvm.nvvm.tcgen05.fence.after.thread.sync()2355 2356Overview:2357"""""""""2358 2359The '``@llvm.nvvm.tcgen05.fence.*``' intrinsics correspond to2360the ``tcgen05.fence::{before/after}_thread_sync`` pair of PTX instructions.2361These instructions act as code motion fences for asynchronous tcgen052362operations.2363 2364For more information, refer to the PTX ISA2365`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tensorcore-5th-generation-instructions-tcgen05-fence>`_.2366 2367'``llvm.nvvm.tcgen05.shift``'2368^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2369 2370Syntax:2371"""""""2372 2373.. code-block:: llvm2374 2375  declare void @llvm.nvvm.tcgen05.shift.down.cg1(ptr addrspace(6) %tmem_addr)2376  declare void @llvm.nvvm.tcgen05.shift.down.cg2(ptr addrspace(6) %tmem_addr)2377 2378Overview:2379"""""""""2380 2381The '``@llvm.nvvm.tcgen05.shift.{cg1/cg2}``' intrinsics correspond to2382the ``tcgen05.shift.{cg1/cg2}`` PTX instructions. The ``tcgen05.shift``2383is an asynchronous instruction which initiates the shifting of 32-byte2384elements downwards across all the rows, except the last, by one row.2385The address operand ``%tmem_addr`` specifies the base address of the2386matrix in the Tensor Memory whose rows must be down shifted.2387 2388For more information, refer to the PTX ISA2389`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instructions-tcgen05-shift>`_.2390 2391'``llvm.nvvm.tcgen05.cp``'2392^^^^^^^^^^^^^^^^^^^^^^^^^^2393 2394Syntax:2395"""""""2396 2397.. code-block:: llvm2398 2399  declare void @llvm.nvvm.tcgen05.cp.4x256b.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2400  declare void @llvm.nvvm.tcgen05.cp.128x256b.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2401  declare void @llvm.nvvm.tcgen05.cp.128x128b.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2402  declare void @llvm.nvvm.tcgen05.cp.32x128b_warpx4.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2403  declare void @llvm.nvvm.tcgen05.cp.64x128b_warpx2_02_13.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2404  declare void @llvm.nvvm.tcgen05.cp.64x128b_warpx2_01_23.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2405 2406  declare void @llvm.nvvm.tcgen05.cp.4x256b.b6x16_p32.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2407  declare void @llvm.nvvm.tcgen05.cp.128x256b.b6x16_p32.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2408  declare void @llvm.nvvm.tcgen05.cp.128x128b.b6x16_p32.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2409  declare void @llvm.nvvm.tcgen05.cp.32x128b_warpx4.b6x16_p32.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2410  declare void @llvm.nvvm.tcgen05.cp.64x128b_warpx2_02_13.b6x16_p32.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2411  declare void @llvm.nvvm.tcgen05.cp.64x128b_warpx2_01_23.b6x16_p32.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2412 2413  declare void @llvm.nvvm.tcgen05.cp.4x256b.b4x16_p64.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2414  declare void @llvm.nvvm.tcgen05.cp.128x256b.b4x16_p64.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2415  declare void @llvm.nvvm.tcgen05.cp.128x128b.b4x16_p64.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2416  declare void @llvm.nvvm.tcgen05.cp.32x128b_warpx4.b4x16_p64.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2417  declare void @llvm.nvvm.tcgen05.cp.64x128b_warpx2_02_13.b4x16_p64.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2418  declare void @llvm.nvvm.tcgen05.cp.64x128b_warpx2_01_23.b4x16_p64.{cg1,cg2}(ptr addrspace(6) %tmem_addr, i64 %sdesc)2419 2420Overview:2421"""""""""2422 2423The '``@llvm.nvvm.tcgen05.cp.{shape}.{src_fmt}.{cg1/cg2}``' intrinsics2424correspond to the ``tcgen05.cp.*`` family of PTX instructions.2425The ``tcgen05.cp`` instruction initiates an asynchronous copy operation from2426shared memory to the location specified by ``%tmem_addr`` in Tensor Memory.2427The 64-bit register operand ``%sdesc`` is the matrix descriptor representing2428the source matrix in shared memory that needs to be copied.2429 2430The valid shapes for the copy operation are:2431{128x256b, 4x256b, 128x128b, 64x128b_warpx2_02_13, 64x128b_warpx2_01_23, 32x128b_warpx4}.2432 2433Shapes ``64x128b`` and ``32x128b`` require dedicated multicast qualifiers,2434which are appended to the corresponding intrinsic names.2435 2436Optionally, the data can be decompressed from the source format in the shared memory2437to the destination format in Tensor Memory during the copy operation. Currently,2438only ``.b8x16`` is supported as destination format. The valid source formats are2439``.b6x16_p32`` and ``.b4x16_p64``.2440 2441When the source format is ``.b6x16_p32``, a contiguous set of 16 elements of 6-bits2442each followed by four bytes of padding (``_p32``) in shared memory is decompressed2443into 16 elements of 8-bits (``.b8x16``) each in the Tensor Memory.2444 2445When the source format is ``.b4x16_p64``, a contiguous set of 16 elements of 4-bits2446each followed by eight bytes of padding (``_p64``) in shared memory is decompressed2447into 16 elements of 8-bits (``.b8x16``) each in the Tensor Memory.2448 2449For more information on the decompression schemes, refer to the PTX ISA2450`<https://docs.nvidia.com/cuda/parallel-thread-execution/#optional-decompression>`_.2451 2452For more information on the tcgen05.cp instruction, refer to the PTX ISA2453`<https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instructions-tcgen05-cp>`_.2454 2455'``llvm.nvvm.tcgen05.ld.*``'2456^^^^^^^^^^^^^^^^^^^^^^^^^^^^2457 2458Syntax:2459"""""""2460 2461.. code-block:: llvm2462 2463  declare <n x i32> @llvm.nvvm.tcgen05.ld.<shape>.<num>(ptr addrspace(6) %tmem_addr, i1 %pack)2464 2465  declare <n x i32> @llvm.nvvm.tcgen05.ld.16x32bx2.<num>(ptr addrspace(6) %tmem_addr, i64 %offset, i1 %pack)2466 2467Overview:2468"""""""""2469 2470This group of intrinsics asynchronously load data from the Tensor Memory at the location specified2471by the 32-bit address operand `tmem_addr` into the destination registers, collectively across all threads2472of the warps.2473 2474All the threads in the warp must specify the same value of `tmem_addr`, which must be the base address2475of the collective load operation. Otherwise, the behavior is undefined.2476 2477The `shape` qualifier and the `num` qualifier together determines the total dimension of the data ('n') which2478is loaded from the Tensor Memory. The `shape` qualifier indicates the base dimension of data. The `num` qualifier2479indicates the repeat factor on the base dimension resulting in the total dimension of the data that is accessed.2480 2481Allowed values for the 'num' are `x1, x2, x4, x8, x16, x32, x64, x128`.2482 2483Allowed values for the 'shape' in the first intrinsic are `16x64b, 16x128b, 16x256b, 32x32b`.2484 2485Allowed value for the 'shape' in the second intrinsic is `16x32bx2`.2486 2487The result of the intrinsic is a vector consisting of one or more 32-bit registers derived from `shape` and2488`num` as shown below.2489 2490=========== =========================  ==========  ==========2491 num/shape     16x32bx2/16x64b/32x32b    16x128b    16x256b2492=========== =========================  ==========  ==========2493 x1                 1                      2           42494 x2                 2                      4           82495 x4                 4                      8           162496 x8                 8                      16          322497 x16                16                     32          642498 x32                32                     64          1282499 x64                64                     128         NA2500 x128               128                    NA          NA2501=========== =========================  ==========  ==========2502 2503The last argument `i1 %pack` is a compile-time constant which when set, indicates that the adjacent columns are packed into a single 32-bit element during the load2504 2505For more information, refer to the2506`PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instructions-tcgen05-ld>`__.2507 2508 2509'``llvm.nvvm.tcgen05.st.*``'2510^^^^^^^^^^^^^^^^^^^^^^^^^^^^2511 2512Syntax:2513"""""""2514 2515.. code-block:: llvm2516 2517  declare void @llvm.nvvm.tcgen05.st.<shape>.<num>(ptr addrspace(6) %tmem_addr, <n x i32> %args, i1 %unpack)2518 2519  declare void @llvm.nvvm.tcgen05.st.16x32bx2.<num>(ptr addrspace(6) %tmem_addr, <n x i32> %args, i64 %offset, i1 %unpack)2520 2521Overview:2522"""""""""2523 2524This group of intrinsics asynchronously store data from the source vector into the Tensor Memory at the location2525specified by the 32-bit address operand 'tmem_addr` collectively across all threads of the warps.2526 2527All the threads in the warp must specify the same value of `tmem_addr`, which must be the base address of the2528collective load operation. Otherwise, the behavior is undefined.2529 2530The `shape` qualifier and the `num` qualifier together determines the total dimension of the data ('n') which2531is loaded from the Tensor Memory. The `shape` qualifier indicates the base dimension of data. The `num` qualifier2532indicates the repeat factor on the base dimension resulting in the total dimension of the data that is accessed.2533 2534Allowed values for the 'num' are `x1, x2, x4, x8, x16, x32, x64, x128`.2535 2536Allowed values for the 'shape' in the first intrinsic are `16x64b, 16x128b, 16x256b, 32x32b`.2537 2538Allowed value for the 'shape' in the second intrinsic is `16x32bx2`.2539 2540`args` argument is a vector consisting of one or more 32-bit registers derived from `shape` and2541`num` as listed in the table listed in the `tcgen05.ld` section.2542 2543Each shape support an `unpack` mode to allow a 32-bit element in the register to be unpacked into two 16-bit elements and store them in adjacent columns. `unpack` mode can be enabled by setting the `%unpack` operand to 1 and can be disabled by setting it to 0.2544 2545The last argument `i1 %unpack` is a compile-time constant which when set, indicates that a 32-bit element in the register to be unpacked into two 16-bit elements and store them in adjacent columns.2546 2547For more information, refer to the2548`PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instructions-tcgen05-st>`__.2549 2550tcgen05.mma Intrinsics2551----------------------2552 2553Overview2554^^^^^^^^2555 2556`tcgen05.mma` operation of shape `M x N x K` perform matrix multiplication and2557accumulation of the form: `D =  A * B + D` where:2558 2559  - the `A` matrix has shape `M x K`, in either `Tensor Memory` or `Shared Memory`2560  - the `B` matrix has shape `K x N`, in `Shared Memory` of the current CTA and, optionally in peer CTA2561  - the `D` matrix is of the shape `M x N`, in `Tensor Memory`2562 2563Optionally an input predicate can be used to disable the input (`%enable_inp_d`)2564from the accumulator matrix and the following operation can be performed as `D = A * B`2565 2566The matrix multiplication and accumulation operations are categorized into various2567kinds based on input types and the throughput of the multiplication operation.2568The following table shows the different kinds of MMA operations that are supported:2569 2570+------------+--------------------------------------------+2571| .kind      | Supported Input Types                      |2572+============+============================================+2573| f16        | F16 and BF16                               |2574+------------+--------------------------------------------+2575| tf32       | TF32                                       |2576+------------+--------------------------------------------+2577| f8f6f4     | All combinations of F8, F6, and F4         |2578+------------+--------------------------------------------+2579| i8         | Signed and Unsigned 8-bit Integers         |2580+------------+--------------------------------------------+2581| mxf8f6f4   | MX-floating point formats                  |2582+------------+--------------------------------------------+2583| mxf4       | MX-floating point formats (FP4)            |2584+------------+--------------------------------------------+2585| mxf4nvf4   | MXF4 + custom NVIDIA 4-bit floating point  |2586|            | (with common scaling factor)               |2587+------------+--------------------------------------------+2588 2589`tcgen05.mma.sp` supports sparse variant of `A` with shape `M x K` stored in packed2590form as `M X (K / 2)` in memory. The `%spmetadata` specifies the mapping of the2591`K / 2` non-zero elements to the `K` elements before performing the MMA operation.2592 2593`tcgen05.mma.block_scale` perform matrix multiplication with block scaling2594`D = (A * scale_A)  * (B * scale_B) + D` where scaling of input matrices from2595memory to form the matrix `A` and matrix `B` before performing the MMA operation.2596Scale factors for `A` and `B` matrices need to be duplicated to all 32 lane partitions2597of tensor memory. The shape of `%scale_a` and `%scale_b` matrices depend on the2598`.scale_vectorsize` described in `here <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-mma-scale-valid-comb>`__2599 2600The sparsity metadata (`%spmetadata`) as well as the block-scale inputs for `A / B`2601matrices (`%scale_a` and `%scale_b`) reside in Tensor Memory.2602 2603To facilitate opportunistic re-use of `A / B` matrix data across a sequence of MMA2604operations, the `A/B` matrices are loaded into a collector buffer2605(`%collector_usage_a_op_flag`, `%collector_usage_b_buffer_flag`, and `%collector_usage_b_op_flag`).2606The flag value of the collector_usage flag in the intrinsic specifies the nature of the re-use2607 2608There are three kinds of matrix descriptors used by the tcgen05 family of instructions:2609 2610+----------------------------+-----------------------------------------------------------------------------------------------------------+-------------+2611| Descriptor                 | Description                                                                                               | Size (bits) |2612+============================+===========================================================================================================+=============+2613| Shared Memory Descriptor   | Describes properties of multiplicand matrix                                                               |             |2614|                            | in shared memory, including its location                                                                  |             |2615|                            | within the CTA's shared memory.                                                                           |     64      |2616|                            | `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-shared-memory-descriptor>`__    |             |2617+----------------------------+-----------------------------------------------+-------------+---------------------------------------------+-------------+2618| Instruction Descriptor     | Describes shapes, types, and details of                                                                   |             |2619|                            | all matrices and the MMA operation.                                                                       |     32      |2620|                            | `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-zero-column-mask-descriptor>`__ |             |2621+----------------------------+-----------------------------------------------+-------------+---------------------------------------------+-------------+2622| Zero-Column Mask Descriptor| Generates a mask specifying which columns of                                                              |             |2623|                            | B matrix are zeroed in the MMA operation,                                                                 |             |2624|                            | regardless of values in shared memory.                                                                    |     64      |2625|                            | Total mask size = N bits                                                                                  |             |2626|                            | `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instruction-descriptor>`__      |             |2627+----------------------------+-----------------------------------------------+-------------+---------------------------------------------+-------------+2628 2629`tcgen05.mma` can be used for general matrix multiplication or for convolution operations.2630In case of convolutions, the `activations` can be stored in either matrix `A` or matrix `B`2631while the `weights` will be stored in the other matrix2632 2633`tcgen05.mma` has an optional collector qualifier to specify when an `A` or `B` matrix2634is new to the sequence and should be loaded, unchanged within the sequence and,2635should be reused, or the last use in the sequence and should be discarded.2636The collector qualifier is used to give the TensorCore permission to reuse a2637previously loaded `A` or `B` matrix; however reuse is opportunistic in that the2638TensorCore may reload a matrix even when it has permission to reuse that matrix.2639Thus, the source memory of an A or B matrix must not be modified while the MMA2640instruction using those matrices has not completed - regardless of collector2641qualifier permissions.2642 2643The `cta_group::1` specifies that the operation is performed on the Tensor Memory2644of the executing thread’s CTA only. The `cta_group::2` specifies that the MMA2645operation is performed on the Tensor Memory of the executing thread’s CTA and its peer CTA.2646 2647The vector operand `%disable_output_lane` specifies the lane(s) in the Tensor Memory2648that should be not be updated with the resultant matrix D. Elements of the vector operand2649disable-output-lane forms a mask where each bit corresponds to a lane of the Tensor Memory,2650with least significant bit of the first element of the vector (leftmost in syntax)2651corresponding to the lane 0 of the Tensor Memory. If a bit in the mask is 1, then2652the corresponding lane in the Tensor Memory for the resultant matrix D will not be2653updated2654 2655Intrinsic Design:2656^^^^^^^^^^^^^^^^^2657 2658Given the broad feature set of `tcgen05.mma` instruction modeling these2659through intrinsics is highly complex, and the following table outlines the large2660number of intrinsics required to fully support the `tcgen05.mma` instruction set.2661 2662+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2663| variant                            | Configuration                                                                                     | Total Variants |2664+====================================+===================================================================================================+================+2665| tcgen05.mma.shared                 | 2 (space) x 2 (sp) x 4 (kind) x 2 (cta_group) x 4 (collector_usage)                               | 128            |2666+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2667| tcgen05.mma.tensor.ashift          | 2 (sp) x 4 (kind) x 2 (cta_group) x 2 (collector_usage)                                           | 32             |2668+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2669| tcgen05.mma.scale_d                | 2 (space) x 2 (sp) x 2 (kind) x 2 (cta_group) x 4 (collector_usage)                               | 128            |2670+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2671| tcgen05.mma.scale_d.tensor.ashift  | 2 (sp) x 2 (kind) x 2 (cta_group) x 2 (collector_usage)                                           | 16             |2672+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2673| tcgen05.mma.disable_output_lane    | 2 (space) x 2 (sp) x 4 (kind) x 2 (cta_group) x 4 (collector_usage)                               | 128            |2674+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2675| tcgen05.mma.disable_output_lane... | 2 (sp) x 4 (kind) x 2 (cta_group) x 2 (collector_usage)                                           | 32             |2676+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2677| tcgen05.mma.block_scale            | 2 (space) x 1 (mxf4nvf4) x 2 (cta_group) x 2 (scale_vec_size) x 4 (collector_usage)               | 32             |2678+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2679| tcgen05.mma.block_scale            | 2 (space) x 1 (mxf4) x 2 (cta_group) x 2 (scale_vec_size) x 4 (collector_usage)                   | 32             |2680+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2681| tcgen05.mma.block_scale            | 2 (space) x 1 (mxf8f6f4) x 2 (cta_group) x 2 (scale_vec_size) x 4 (collector_usage)               | 32             |2682+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2683| tcgen05.mma.ws                     | 2 (space) x 2 (sp) x 4 (kind) x 2 (zero_col_mask) x 4 (collector_usage_op) x 4 (collector_buffer) | 256            |2684+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2685| Total                              |                                                                                                   | 816            |2686+------------------------------------+---------------------------------------------------------------------------------------------------+----------------+2687 2688 2689To reduce the number of possible intrinsic variations, we've modeled the `tcgen05.mma`2690instructions using flag operands. We've added range checks to these flags to prevent2691invalid values. We also expanded some flags back into intrinsic modifiers to avoid2692supporting invalid combinations of features.2693 2694 2695'``llvm.nvvm.tcgen05.mma.*``'2696^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2697 2698Syntax:2699"""""""2700 2701.. code-block:: llvm2702 2703  declare void @llvm.nvvm.tcgen05.mma.shared(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i32 %kind_flag, i32 %cta_group_flag, i32 %collector_usage_a_op_flag)2704  declare void @llvm.nvvm.tcgen05.mma.tensor<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i32 %kind_flag, i32 %cta_group_flag, i32 %collector_usage_a_op_flag)2705 2706  ; .sp variants2707  declare void @llvm.nvvm.tcgen05.mma.sp.shared(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, i32 %kind_flag, i32 %cta_group_flag, i32 %collector_usage_op_flag)2708  declare void @llvm.nvvm.tcgen05.mma.sp.tensor<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, i32 %kind_flag, i32 %cta_group_flag, i32 %collector_usage_a_op_flag)2709 2710  ; .scale_d variants2711  declare void @llvm.nvvm.tcgen05.mma.shared.scale_d(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %scale_d_imm, i32 %cta_group_flag, i32 %kind_flag, i32 %collector_usage_a_op_flag)2712  declare void @llvm.nvvm.tcgen05.mma.tensor.scale_d<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %scale_d_imm, i32 %cta_group_flag, i32 %kind_flag, i32 %collector_usage_a_op_flag)2713 2714  ; sp.scale_d variants2715  declare void @llvm.nvvm.tcgen05.mma.sp.shared.scale_d(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, i64 %scale_d_imm, i32 %cta_group_flag, i32 %collector_usage_op_flag)2716  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.scale_d<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, i64 %scale_d_imm, i32 %cta_group, i32 %collector_usage_a_op_flag)2717 2718Overview:2719"""""""""2720 2721`nvvm.tcgen05.mma` is an asynchronous intrinsic which initiates an `M x N x K` matrix2722multiply and accumulate operation, `D = A * B + D` where the `A` matrix is `M x K`,2723the `B` matrix is `K x N`, and the `D` matrix is `M x N`. The operation of the form2724`D = A*B` is issued when the input predicate argument `%enable_inp_d` is false.2725The optional immediate argument `%scale_d_imm` can be specified to scale the input2726matrix `D` as follows: `D = A * B + D * (2 ^ - %scale_d_imm)`. The valid range of2727values for argument `%scale_d_imm` is `[0, 15]`. The 32-bit register operand idesc2728is the instruction descriptor as described in `Instruction descriptor <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instruction-descriptor>`__2729 2730`nvvm.tcgen05.mma` has single thread semantics, unlike the collective instructions2731`nvvm.mma.sync` or the PTX `wgmma.mma_async` instruction. So, a single thread issuing2732the `nvvm.tcgen05.mma` will result in the initiation of the whole matrix and accumulate2733operation2734 2735When `.sp` is specifed, the dimension of A matrix is `M x (K/2)` and requires2736specifying an additional `%spmetadata` argument2737 2738`.ashift` shifts the rows of the A matrix down by one row, except for the last row2739in the Tensor Memory. `.ashift` is only allowed with M = 128 or M = 256.2740 2741The `%collector_usage_a_op_flag` flag specifies the usage of collector buffer for2742matrix `A`. It is illegal to specify either of `USE` or `FILL` for `%collector_usage_a_op_flag`2743along with `.ashift`2744 2745For more information, refer to the2746`PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-mma-instructions-mma>`__2747 2748The following tables describe the possible values of the flag arguments2749 2750`%kind_flag` flag:2751 2752============= ==========2753  `kind_flag`   value2754============= ==========2755     F16          02756     TF32         12757     F8F6F4       22758     I8           32759============= ==========2760 2761`%cta_group_flag` flag:2762 2763================= ==========2764 `cta_group_flag`    value2765================= ==========2766     CG1               12767     CG2               22768================= ==========2769 2770`%collector_usage_a_op_flag` flag:2771 2772============================= ==========2773 `collector_usage_a_op_flag`    value2774============================= ==========2775           DISCARD                 02776           LASTUSE                 12777           USE                     22778           FILL                    32779============================= ==========2780 2781'``llvm.nvvm.tcgen05.mma.block_scale*``'2782^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2783 2784Syntax:2785"""""""2786 2787.. code-block:: llvm2788 2789  ; mxf8f6f42790  declare void @llvm.nvvm.tcgen05.mma.shared.mxf8f6f4.block_scale(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2791  declare void @llvm.nvvm.tcgen05.mma.tensor.mxf8f6f4.block_scale(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2792  declare void @llvm.nvvm.tcgen05.mma.shared.mxf8f6f4.block_scale.block32(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2793  declare void @llvm.nvvm.tcgen05.mma.tensor.mxf8f6f4.block_scale.block32(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2794  declare void @llvm.nvvm.tcgen05.mma.sp.shared.mxf8f6f4.block_scale(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2795  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.mxf8f6f4.block_scale(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2796  declare void @llvm.nvvm.tcgen05.mma.sp.shared.mxf8f6f4.block_scale.block32(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2797  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.mxf8f6f4.block_scale.block32(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2798 2799  ; mxf42800  declare void @llvm.nvvm.tcgen05.mma.shared.mxf4.block_scale(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2801  declare void @llvm.nvvm.tcgen05.mma.tensor.mxf4.block_scale(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2802  declare void @llvm.nvvm.tcgen05.mma.shared.mxf4.block_scale.block32(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2803  declare void @llvm.nvvm.tcgen05.mma.tensor.mxf4.block_scale.block32(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2804  declare void @llvm.nvvm.tcgen05.mma.sp.shared.mxf4.block_scale(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2805  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.mxf4.block_scale(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2806  declare void @llvm.nvvm.tcgen05.mma.sp.shared.mxf4.block_scale.block32(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2807  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.mxf4.block_scale.block32(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2808 2809  ; mxf4nvf42810  declare void @llvm.nvvm.tcgen05.mma.shared.mxf4nvf4.block_scale.block16(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2811  declare void @llvm.nvvm.tcgen05.mma.tensor.mxf4nvf4.block_scale.block16(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2812  declare void @llvm.nvvm.tcgen05.mma.shared.mxf4nvf4.block_scale.block32(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2813  declare void @llvm.nvvm.tcgen05.mma.tensor.mxf4nvf4.block_scale.block32(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2814  declare void @llvm.nvvm.tcgen05.mma.sp.shared.mxf4nvf4.block_scale.block16(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2815  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.mxf4nvf4.block_scale.block16(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2816  declare void @llvm.nvvm.tcgen05.mma.sp.shared.mxf4nvf4.block_scale.block32(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2817  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.mxf4nvf4.block_scale.block32(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, ptr addrspace(6) %scale_a, ptr addrspace(6) %scale_b, i32 cta_group_flag, i32 %collector_usage_a_op_flag)2818 2819Overview:2820"""""""""2821`nvvm.tcgen05.mma.block_scale` is an asynchronous intrinsic which initiates an `M x N x K` matrix multiply and accumulate operation, `D = (A * scale_a)  * (B * scale_b) + D` where the `A` matrix is `M x K`, the `B` matrix is `K x N`, and the `D` matrix is `M x N`. The matrices `A` and `B` are scaled with `%scale_A` and `%scale_B` matrices respectively before performing the matrix multiply and accumulate operation. The operation of the form `D = A*B` is issued when the input predicate argument `%enable_inp_d` is false. The 32-bit register operand idesc is the instruction descriptor as described in `Instruction descriptor <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instruction-descriptor>`__2822 2823`nvvm.tcgen05.mma.block_scale` has single thread semantics, unlike the collective instructions `nvvm.mma.sync` or the PTX `wgmma.mma_async` instruction. So, a single thread issuing the `nvvm.tcgen05.mma.block_scale` will result in the initiation of the whole matrix multiply and accumulate operation2824 2825When `.sp` is specified, the dimension of A matrix is `M x (K / 2)` and requires specifying an additional `%spmetadata` argument2826 2827The `%collector_usage_a_op_flag` flag specifies the usage of collector buffer for matrix `A`2828 2829For more information, refer to the2830`PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-mma-instructions-mma>`__2831 2832The following tables describe the possible values of the flag arguments2833 2834`%cta_group`:2835 2836============= ==========2837 `cta_group`    value2838============= ==========2839     CG1          12840     CG2          22841============= ==========2842 2843`%collector_usage_a_op_flag`:2844 2845============================= ==========2846 `collector_usage_a_op_flag`    value2847============================= ==========2848     DISCARD                      02849     LASTUSE                      12850     USE                          22851     FILL                         32852============================= ==========2853 2854'``llvm.nvvm.tcgen05.mma.disable_output_lane*``'2855^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2856 2857Syntax:2858"""""""2859 2860.. code-block:: llvm2861 2862  declare void @llvm.nvvm.tcgen05.mma.shared.disable_output_lane.cg1(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, <4 x i32> %disable_output_lane_v4, i32 %kind_flag, i32 %collector_usage_a_op_flag)2863  declare void @llvm.nvvm.tcgen05.mma.shared.disable_output_lane.cg2(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, <8 x i32> %disable_output_lane_v8, i32 %kind_flag, i32 %collector_usage_a_op_flag)2864  declare void @llvm.nvvm.tcgen05.mma.tensor.disable_output_lane.cg1<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, <4 x i32> %disable_output_lane_v4, i32 %kind_flag, i32 %collector_usage_a_op_flag)2865  declare void @llvm.nvvm.tcgen05.mma.tensor.disable_output_lane.cg2<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, <8 x i32> %disable_output_lane_v8, i32 %kind_flag, i32 %collector_usage_a_op_flag)2866 2867  ; .sp variants2868  declare void @llvm.nvvm.tcgen05.mma.sp.shared.disable_output_lane.cg1(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, <4 x i32> %disable_output_lane_v4, i32 %kind_flag, i32 %collector_usage_op_flag)2869  declare void @llvm.nvvm.tcgen05.mma.sp.shared.disable_output_lane.cg2(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, <8 x i32> %disable_output_lane_v8, i32 %kind_flag, i32 %collector_usage_op_flag)2870  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.disable_output_lane.cg1<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, <4 x i32> %disable_output_lane_v4, i32 %kind_flag, i32 %collector_usage_a_op_flag)2871  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.disable_output_lane.cg2<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, <8 x i32> %disable_output_lane_v8, i32 %kind_flag, i32 %collector_usage_a_op_flag)2872 2873  ; .scale_d variants2874  declare void @llvm.nvvm.tcgen05.mma.shared.scale_d.disable_output_lane.cg1(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %scale_d_imm, <4 x i32> %disable_output_lane_v4, i32 %kind_flag, i32 %collector_usage_a_op_flag)2875  declare void @llvm.nvvm.tcgen05.mma.shared.scale_d.disable_output_lane.cg2(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %scale_d_imm, <8 x i32> %disable_output_lane_v8, i32 %kind_flag, i32 %collector_usage_a_op_flag)2876  declare void @llvm.nvvm.tcgen05.mma.tensor.scale_d.disable_output_lane.cg1<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %scale_d_imm, <4 x i32> %disable_output_lane_v4, i32 %kind_flag, i32 %collector_usage_a_op_flag)2877  declare void @llvm.nvvm.tcgen05.mma.tensor.scale_d.disable_output_lane.cg2<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %scale_d_imm, <8 x i32> %disable_output_lane_v8, i32 %kind_flag, i32 %collector_usage_a_op_flag)2878 2879  ; .sp.scale_d variants2880  declare void @llvm.nvvm.tcgen05.mma.sp.shared.scale_d.disable_output_lane.cg1(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, i64 %scale_d_imm, <4 x i32> %disable_output_lane_v4, i32 %kind_flag, i32 %collector_usage_op_flag)2881  declare void @llvm.nvvm.tcgen05.mma.sp.shared.scale_d.disable_output_lane.cg2(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, i64 %scale_d_imm, <8 x i32> %disable_output_lane_v8, i32 %kind_flag, i32 %collector_usage_op_flag)2882  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.scale_d.disable_output_lane.cg1<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, i64 %scale_d_imm, <4 x i32> %disable_output_lane_v4, i32 %kind_flag, i32 %collector_usage_a_op_flag)2883  declare void @llvm.nvvm.tcgen05.mma.sp.tensor.scale_d.disable_output_lane.cg2<.ashift>(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, ptr addrspace(6) %spmetadata, i1 %enable_inp_d, i64 %scale_d_imm, <8 x i32> %disable_output_lane_v8, i32 %kind_flag, i32 %collector_usage_a_op_flag)2884 2885Overview:2886"""""""""2887 2888`nvvm.tcgen05.mma.disable_output_lane` is an asynchronous intrinsic which initiates an `M x N x K` matrix multiply and accumulate operation, `D = A * B + D` where the `A` matrix is `M x K`, the `B` matrix is `K x N`, and the `D` matrix is `M x N`. The operation of the form `D = A*B` is issued when the input predicate argument `%enable_inp_d` is false. The optional immediate argument `%scale_d_imm` can be specified to scale the input matrix `D` as follows: `D = A*B+D * (2 ^ - %scale_d_imm)`. The valid range of values for argument `%scale_d_imm` is `[0, 15]`. The 32-bit register operand idesc is the instruction descriptor as described in `Instruction descriptor <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instruction-descriptor>`__2889 2890The vector operand `%disable_output_lane` specifies the lane(s) in the Tensor Memory that should be not be updated with the resultant matrix `D`. Elements of the vector operand `%disable_output_lane` forms a mask where each bit corresponds to a lane of the Tensor Memory, with least significant bit of the first element of the vector corresponding to the `lane 0` of the Tensor Memory. If a bit in the mask is 1, then the corresponding lane in the Tensor Memory for the resultant matrix `D` will not be updated2891 2892`nvvm.tcgen05.mma.disable_output_lane` has single thread semantics, unlike the collective instructions `nvvm.mma.sync` or the PTX `wgmma.mma_async` instruction. So, a single thread issuing the `nvvm.tcgen05.mma.disable_output_lane` will result in the initiation of the whole matrix multiply and accumulate operation2893 2894When `.sp` is specifed, the dimension of A matrix is `M x (K / 2)` and requires specifiying an additional `%spmetadata` argument2895 2896`.ashift` shifts the rows of the A matrix down by one row, except for the last row in the Tensor Memory. `.ashift` is only allowed with M = 128 or M = 256.2897 2898The `%collector_usage_a_op_flag` flag specifies the usage of collector buffer for matrix `A`. It is illegal to specify either of `USE` or `FILL` for `%collector_usage_a_op_flag` along with `.ashift`2899 2900For more information, refer to the `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-mma-instructions-mma>`__2901 2902The following tables describes the possible values of the flag arguments2903 2904`%kind_flag`:2905 2906============= ==========2907 `kind_flag`    value2908============= ==========2909     F16          02910     TF32         12911     F8F6F4       22912     I8           32913============= ==========2914 2915`%cta_group_flag`:2916 2917================= ==========2918 `cta_group_flag`    value2919================= ==========2920        CG1           12921        CG2           22922================= ==========2923 2924`%collector_usage_a_op_flag`:2925 2926============================= ==========2927 `collector_usage_a_op_flag`    value2928============================= ==========2929     DISCARD                      02930     LASTUSE                      12931     USE                          22932     FILL                         32933============================= ==========2934 2935 2936'``llvm.nvvm.tcgen05.mma.ws*``'2937^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^2938 2939Syntax:2940"""""""2941 2942.. code-block:: llvm2943 2944  // tcgen05.mma.ws2945  declare void @llvm.nvvm.tcgen05.mma.ws.shared(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2946  declare void @llvm.nvvm.tcgen05.mma.ws.tensor(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2947  declare void @llvm.nvvm.tcgen05.mma.ws.shared.zero_col_mask(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %zero_col_mask, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2948  declare void @llvm.nvvm.tcgen05.mma.ws.shared.zero_col_mask(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %zero_col_mask, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2949  declare void @llvm.nvvm.tcgen05.mma.ws.tensor.zero_col_mask(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, i64 %zero_col_mask, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2950 2951  ; .sp variants2952  declare void @llvm.nvvm.tcgen05.mma.ws.sp.shared(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2953  declare void @llvm.nvvm.tcgen05.mma.ws.sp.tensor(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2954  declare void @llvm.nvvm.tcgen05.mma.ws.sp.shared.zero_col_mask(ptr addrspace(6) %d, i64 %adesc, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, i64 %zero_col_mask, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2955  declare void @llvm.nvvm.tcgen05.mma.ws.sp.tensor.zero_col_mask(ptr addrspace(6) %d, ptr addrspace(6) %atensor, i64 %bdesc, i32 %idesc, i1 %enable_inp_d, ptr addrspace(6) %spmetadata, i64 %zero_col_mask, i32 %kind_flag, i32 %collector_usage_b_buffer_flag, i32 %collector_usage_b_op_flag)2956 2957Overview:2958"""""""""2959 2960`nvvm.tcgen05.mma.ws` is an asynchronous intrinsic which initiates an `M x N x K` weight stationary convolution matrix multiply and accumulate operation, `D = A * B + D` where the `A` matrix is `M x K`, the `B` matrix is `K x N`, and the `D` matrix is `M x N`. The operation of the form `D = A*B` is issued when the input predicate argument `%enable_inp_d` is false. The optional immediate argument `%scale_d_imm` can be specified to scale the input matrix `D` as follows: `D = A*B+D * (2 ^ - %scale_d_imm)`. The valid range of values for argument `%scale_d_imm` is `[0, 15]`. The 32-bit register operand idesc is the instruction descriptor as described in `Instruction descriptor <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-instruction-descriptor>`__2961 2962`nvvm.tcgen05.mma` has single thread semantics, unlike the collective instructions `nvvm.mma.sync` or the PTX `wgmma.mma_async` instruction. So, a single thread issuing the `nvvm.tcgen05.mma` will result in the initiation of the whole matrix multiply and accumulate operation2963 2964When `.sp` is specifed, the dimension of A matrix is `M x (K / 2)` and requires specifiying an additional `%spmetadata` argument2965 2966The operand `%zero_col_mask` is a 64-bit register which specifies the `Zero-Column Mask Descriptor <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-zero-column-mask-descriptor>`__. The zero-column mask descriptor is used to generate a mask that specifies which columns of `B` matrix will have zero value for the matrix multiply and accumulate operation regardless of the values present in the shared memory.2967 2968The `%collector_usage_b_buffer_flag` and `%collector_usage_b_op_flag` together flag specifies the usage of collector buffer for Matrix `B`2969 2970For more information, refer to the2971`PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#tcgen05-mma-instructions-mma-ws>`__2972 2973The following tables describes the possible values of the flag arguments2974 2975`%kind_flag`:2976 2977============= ==========2978 `kind_flag`    value2979============= ==========2980     F16          02981     TF32         12982     F8F6F4       22983     I8           32984============= ==========2985 2986`%collector_usage_b_buffer_flag`:2987 2988================================ ==========2989 `collector_usage_b_buffer_flag`   value2990================================ ==========2991              B0                     02992              B1                     12993              B2                     22994              B3                     32995================================ ==========2996 2997`%collector_usage_b_op_flag`:2998 2999============================= ==========3000 `collector_usage_b_op_flag`    value3001============================= ==========3002     DISCARD                      03003     LASTUSE                      13004     USE                          23005     FILL                         33006============================= ==========3007 3008Store Intrinsics3009----------------3010 3011'``llvm.nvvm.st.bulk.*``'3012^^^^^^^^^^^^^^^^^^^^^^^^^3013 3014Syntax:3015"""""""3016 3017.. code-block:: llvm3018 3019  declare void @llvm.nvvm.st.bulk(ptr addrspace(1) %dst, i64 %size, i64 immarg %initval)3020  declare void @llvm.nvvm.st.bulk.shared.cta(ptr addrspace(3) %dst, i64 %size, i64 immarg %initval)3021 3022Overview:3023"""""""""3024 3025The '``@llvm.nvvm.st.bulk.*``' intrinsics initialize a region of shared memory 3026starting from the location specified by the destination address operand `%dst`.3027 3028The integer operand `%size` specifies the amount of memory to be initialized in 3029terms of number of bytes and must be a multiple of 8. Otherwise, the behavior 3030is undefined.3031 3032The integer immediate operand `%initval` specifies the initialization value for 3033the memory locations. The only numeric value allowed is 0.3034 3035The ``@llvm.nvvm.st.bulk.shared.cta`` and ``@llvm.nvvm.st.bulk`` intrinsics are 3036similar but the latter uses generic addressing (see `Generic Addressing <https://docs.nvidia.com/cuda/parallel-thread-execution/#generic-addressing>`__).3037 3038For more information, refer `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/#data-movement-and-conversion-instructions-st-bulk>`__.3039 3040 3041clusterlaunchcontrol Intrinsics3042-------------------------------3043 3044'``llvm.nvvm.clusterlaunchcontrol.try_cancel*``' Intrinsics3045^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^3046 3047Syntax:3048"""""""3049 3050.. code-block:: llvm3051 3052  declare void @llvm.nvvm.clusterlaunchcontrol.try_cancel.async.shared(ptr addrspace(3) %addr, ptr addrspace(3) %mbar)3053  declare void @llvm.nvvm.clusterlaunchcontrol.try_cancel.async.multicast.shared(ptr addrspace(3) %addr, ptr addrspace(3) %mbar)3054 3055Overview:3056"""""""""3057 3058The ``clusterlaunchcontrol.try_cancel`` intrinsics requests atomically cancelling3059the launch of a cluster that has not started running yet. It asynchronously non-atomically writes3060a 16-byte opaque response to shared memory, pointed to by 16-byte-aligned ``addr`` indicating whether the3061operation succeeded or failed. ``addr`` and 8-byte-aligned ``mbar`` must refer to ``shared::cta``3062otherwise the behavior is undefined. The completion of the asynchronous operation3063is tracked using the mbarrier completion mechanism at ``.cluster`` scope referenced3064by the shared memory pointer, ``mbar``. On success, the opaque response contains3065the CTA id of the first CTA of the canceled cluster; no other successful response3066from other ``clusterlaunchcontrol.try_cancel`` operations from the same grid will3067contain that id.3068 3069The ``multicast`` variant specifies that the response is asynchronously non-atomically written to3070the corresponding shared memory location of each CTA in the requesting cluster.3071The completion of the write of each local response is tracked by independent3072mbarriers at the corresponding shared memory location of each CTA in the3073cluster.3074 3075For more information, refer `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/?a#parallel-synchronization-and-communication-instructions-clusterlaunchcontrol-try-cancel>`__.3076 3077'``llvm.nvvm.clusterlaunchcontrol.query_cancel.is_canceled``' Intrinsic3078^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^3079 3080Syntax:3081"""""""3082 3083.. code-block:: llvm3084 3085  declare i1 @llvm.nvvm.clusterlaunchcontrol.query_cancel.is_canceled(i128 %try_cancel_response)3086 3087Overview:3088"""""""""3089 3090The ``llvm.nvvm.clusterlaunchcontrol.query_cancel.is_canceled`` intrinsic decodes the opaque response written by the3091``llvm.nvvm.clusterlaunchcontrol.try_cancel`` operation.3092 3093The intrinsic returns ``0`` (false) if the request failed. If the request succeeded,3094it returns ``1`` (true). A true result indicates that:3095 3096- the thread block cluster whose first CTA id matches that of the response3097  handle will not run, and3098- no other successful response of another ``try_cancel`` request in the grid will contain3099  the first CTA id of that cluster3100 3101For more information, refer `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/?a#parallel-synchronization-and-communication-instructions-clusterlaunchcontrol-query-cancel>`__.3102 3103 3104'``llvm.nvvm.clusterlaunchcontrol.query_cancel.get_first_ctaid.*``' Intrinsics3105^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^3106 3107Syntax:3108"""""""3109 3110.. code-block:: llvm3111 3112  declare i32 @llvm.nvvm.clusterlaunchcontrol.query_cancel.get_first_ctaid.x(i128 %try_cancel_response)3113  declare i32 @llvm.nvvm.clusterlaunchcontrol.query_cancel.get_first_ctaid.y(i128 %try_cancel_response)3114  declare i32 @llvm.nvvm.clusterlaunchcontrol.query_cancel.get_first_ctaid.z(i128 %try_cancel_response)3115 3116Overview:3117"""""""""3118 3119The ``clusterlaunchcontrol.query_cancel.get_first_ctaid.*`` intrinsic can be3120used to decode the successful opaque response written by the3121``llvm.nvvm.clusterlaunchcontrol.try_cancel`` operation.3122 3123If the request succeeded:3124 3125- ``llvm.nvvm.clusterlaunchcontrol.query_cancel.get_first_ctaid.{x,y,z}`` returns3126  the coordinate of the first CTA in the canceled cluster, either x, y, or z.3127 3128If the request failed, the behavior of these intrinsics is undefined.3129 3130For more information, refer `PTX ISA <https://docs.nvidia.com/cuda/parallel-thread-execution/?a#parallel-synchronization-and-communication-instructions-clusterlaunchcontrol-query-cancel>`__.3131 3132Perf Monitor Event Intrinsics3133-----------------------------3134 3135'``llvm.nvvm.pm.event.mask``' Intrinsic3136^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^3137 3138Syntax:3139"""""""3140 3141.. code-block:: llvm3142 3143    declare void @llvm.nvvm.pm.event.mask(i16 immarg %mask_val)3144 3145Overview:3146"""""""""3147 3148The '``llvm.nvvm.pm.event.mask``' intrinsic triggers one or more3149performance monitor events. Each bit in the 16-bit immediate operand3150``%mask_val`` controls an event.3151 3152For more information on the pmevent instructions, refer to the PTX ISA3153`<https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#miscellaneous-instructions-pmevent>`_.3154 3155Other Intrinsics3156----------------3157 3158For the full set of NVPTX intrinsics, please see the3159``include/llvm/IR/IntrinsicsNVVM.td`` file in the LLVM source tree.3160 3161 3162.. _libdevice:3163 3164Linking with Libdevice3165======================3166 3167The CUDA Toolkit comes with an LLVM bitcode library called ``libdevice`` that3168implements many common mathematical functions. This library can be used as a3169high-performance math library for any compilers using the LLVM NVPTX target.3170The library can be found under ``nvvm/libdevice/`` in the CUDA Toolkit and3171there is a separate version for each compute architecture.3172 3173For a list of all math functions implemented in libdevice, see3174`libdevice Users Guide <http://docs.nvidia.com/cuda/libdevice-users-guide/index.html>`_.3175 3176To accommodate various math-related compiler flags that can affect code3177generation of libdevice code, the library code depends on a special LLVM IR3178pass (``NVVMReflect``) to handle conditional compilation within LLVM IR. This3179pass looks for calls to the ``@__nvvm_reflect`` function and replaces them3180with constants based on the defined reflection parameters. Such conditional3181code often follows a pattern:3182 3183.. code-block:: c++3184 3185  float my_function(float a) {3186    if (__nvvm_reflect("FASTMATH"))3187      return my_function_fast(a);3188    else3189      return my_function_precise(a);3190  }3191 3192The default value for all unspecified reflection parameters is zero.3193 3194The ``NVVMReflect`` pass should be executed early in the optimization3195pipeline, immediately after the link stage. The ``internalize`` pass is also3196recommended to remove unused math functions from the resulting PTX. For an3197input IR module ``module.bc``, the following compilation flow is recommended:3198 3199The ``NVVMReflect`` pass will attempt to remove dead code even without3200optimizations. This allows potentially incompatible instructions to be avoided3201at all optimizations levels by using the ``__CUDA_ARCH`` argument.3202 32031. Save list of external functions in ``module.bc``32042. Link ``module.bc`` with ``libdevice.compute_XX.YY.bc``32053. Internalize all functions not in list from (1)32064. Eliminate all unused internal functions32075. Run ``NVVMReflect`` pass32086. Run standard optimization pipeline3209 3210.. note::3211 3212  ``linkonce`` and ``linkonce_odr`` linkage types are not suitable for the3213  libdevice functions. It is possible to link two IR modules that have been3214  linked against libdevice using different reflection variables.3215 3216Since the ``NVVMReflect`` pass replaces conditionals with constants, it will3217often leave behind dead code of the form:3218 3219.. code-block:: llvm3220 3221  entry:3222    ..3223    br i1 true, label %foo, label %bar3224  foo:3225    ..3226  bar:3227    ; Dead code3228    ..3229 3230Therefore, it is recommended that ``NVVMReflect`` is executed early in the3231optimization pipeline before dead-code elimination.3232 3233The NVPTX TargetMachine knows how to schedule ``NVVMReflect`` at the beginning3234of your pass manager; just use the following code when setting up your pass3235manager and the PassBuilder will use ``registerPassBuilderCallbacks`` to let3236NVPTXTargetMachine::registerPassBuilderCallbacks add the pass to the3237pass manager:3238 3239.. code-block:: c++3240 3241    std::unique_ptr<TargetMachine> TM = ...;3242    PassBuilder PB(TM);3243    ModulePassManager MPM;3244    PB.parsePassPipeline(MPM, ...);3245 3246Reflection Parameters3247---------------------3248 3249The libdevice library currently uses the following reflection parameters to3250control code generation:3251 3252==================== ======================================================3253Flag                 Description3254==================== ======================================================3255``__CUDA_FTZ=[0,1]`` Use optimized code paths that flush subnormals to zero3256==================== ======================================================3257 3258The value of this flag is determined by the "nvvm-reflect-ftz" module flag.3259The following sets the ftz flag to 1.3260 3261.. code-block:: llvm3262 3263    !llvm.module.flags = !{!0}3264    !0 = !{i32 4, !"nvvm-reflect-ftz", i32 1}3265 3266(``i32 4`` indicates that the value set here overrides the value in another3267module we link with.  See the `LangRef <LangRef.html#module-flags-metadata>`3268for details.)3269 3270Executing PTX3271=============3272 3273The most common way to execute PTX assembly on a GPU device is to use the CUDA3274Driver API. This API is a low-level interface to the GPU driver and allows for3275JIT compilation of PTX code to native GPU machine code.3276 3277Initializing the Driver API:3278 3279.. code-block:: c++3280 3281    CUdevice device;3282    CUcontext context;3283 3284    // Initialize the driver API3285    cuInit(0);3286    // Get a handle to the first compute device3287    cuDeviceGet(&device, 0);3288    // Create a compute device context3289    cuCtxCreate(&context, 0, device);3290 3291JIT compiling a PTX string to a device binary:3292 3293.. code-block:: c++3294 3295    CUmodule module;3296    CUfunction function;3297 3298    // JIT compile a null-terminated PTX string3299    cuModuleLoadData(&module, (void*)PTXString);3300 3301    // Get a handle to the "myfunction" kernel function3302    cuModuleGetFunction(&function, module, "myfunction");3303 3304For full examples of executing PTX assembly, please see the `CUDA Samples3305<https://developer.nvidia.com/cuda-downloads>`_ distribution.3306 3307 3308Common Issues3309=============3310 3311ptxas complains of undefined function: __nvvm_reflect3312-----------------------------------------------------3313 3314When linking with libdevice, the ``NVVMReflect`` pass must be used. See3315:ref:`libdevice` for more information.3316 3317 3318Tutorial: A Simple Compute Kernel3319=================================3320 3321To start, let us take a look at a simple compute kernel written directly in3322LLVM IR. The kernel implements vector addition, where each thread computes one3323element of the output vector C from the input vectors A and B.  To make this3324easier, we also assume that only a single CTA (thread block) will be launched,3325and that it will be one dimensional.3326 3327 3328The Kernel3329----------3330 3331.. code-block:: llvm3332 3333  target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"3334  target triple = "nvptx64-nvidia-cuda"3335 3336  ; Intrinsic to read X component of thread ID3337  declare i32 @llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind3338 3339  define ptx_kernel void @kernel(ptr addrspace(1) %A,3340                                 ptr addrspace(1) %B,3341                                 ptr addrspace(1) %C) {3342  entry:3343    ; What is my ID?3344    %id = tail call i32 @llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind3345 3346    ; Compute pointers into A, B, and C3347    %ptrA = getelementptr float, ptr addrspace(1) %A, i32 %id3348    %ptrB = getelementptr float, ptr addrspace(1) %B, i32 %id3349    %ptrC = getelementptr float, ptr addrspace(1) %C, i32 %id3350 3351    ; Read A, B3352    %valA = load float, ptr addrspace(1) %ptrA, align 43353    %valB = load float, ptr addrspace(1) %ptrB, align 43354 3355    ; Compute C = A + B3356    %valC = fadd float %valA, %valB3357 3358    ; Store back to C3359    store float %valC, ptr addrspace(1) %ptrC, align 43360 3361    ret void3362  }3363 3364 3365We can use the LLVM ``llc`` tool to directly run the NVPTX code generator:3366 3367.. code-block:: text3368 3369  # llc -mcpu=sm_20 kernel.ll -o kernel.ptx3370 3371 3372.. note::3373 3374  If you want to generate 32-bit code, change ``p:64:64:64`` to ``p:32:32:32``3375  in the module data layout string and use ``nvptx-nvidia-cuda`` as the3376  target triple.3377 3378 3379The output we get from ``llc`` (as of LLVM 3.4):3380 3381.. code-block:: text3382 3383  //3384  // Generated by LLVM NVPTX Back-End3385  //3386 3387  .version 3.13388  .target sm_203389  .address_size 643390 3391    // .globl kernel3392                                          // @kernel3393  .visible .entry kernel(3394    .param .u64 kernel_param_0,3395    .param .u64 kernel_param_1,3396    .param .u64 kernel_param_23397  )3398  {3399    .reg .f32   %f<4>;3400    .reg .s32   %r<2>;3401    .reg .s64   %rl<8>;3402 3403  // %bb.0:                                // %entry3404    ld.param.u64    %rl1, [kernel_param_0];3405    mov.u32         %r1, %tid.x;3406    mul.wide.s32    %rl2, %r1, 4;3407    add.s64         %rl3, %rl1, %rl2;3408    ld.param.u64    %rl4, [kernel_param_1];3409    add.s64         %rl5, %rl4, %rl2;3410    ld.param.u64    %rl6, [kernel_param_2];3411    add.s64         %rl7, %rl6, %rl2;3412    ld.global.f32   %f1, [%rl3];3413    ld.global.f32   %f2, [%rl5];3414    add.f32         %f3, %f1, %f2;3415    st.global.f32   [%rl7], %f3;3416    ret;3417  }3418 3419 3420Dissecting the Kernel3421---------------------3422 3423Now let us dissect the LLVM IR that makes up this kernel.3424 3425Data Layout3426^^^^^^^^^^^3427 3428The data layout string determines the size in bits of common data types, their3429ABI alignment, and their storage size.  For NVPTX, you should use one of the3430following:3431 343232-bit PTX:3433 3434.. code-block:: llvm3435 3436  target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"3437 343864-bit PTX:3439 3440.. code-block:: llvm3441 3442  target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"3443 3444 3445Target Intrinsics3446^^^^^^^^^^^^^^^^^3447 3448In this example, we use the ``@llvm.nvvm.read.ptx.sreg.tid.x`` intrinsic to3449read the X component of the current thread's ID, which corresponds to a read3450of register ``%tid.x`` in PTX. The NVPTX back-end supports a large set of3451intrinsics.  A short list is shown below; please see3452``include/llvm/IR/IntrinsicsNVVM.td`` for the full list.3453 3454 3455================================================ ====================3456Intrinsic                                        CUDA Equivalent3457================================================ ====================3458``i32 @llvm.nvvm.read.ptx.sreg.tid.{x,y,z}``     threadIdx.{x,y,z}3459``i32 @llvm.nvvm.read.ptx.sreg.ctaid.{x,y,z}``   blockIdx.{x,y,z}3460``i32 @llvm.nvvm.read.ptx.sreg.ntid.{x,y,z}``    blockDim.{x,y,z}3461``i32 @llvm.nvvm.read.ptx.sreg.nctaid.{x,y,z}``  gridDim.{x,y,z}3462``void @llvm.nvvm.barrier0()``                   __syncthreads()3463================================================ ====================3464 3465 3466Address Spaces3467^^^^^^^^^^^^^^3468 3469You may have noticed that all of the pointer types in the LLVM IR example had3470an explicit address space specifier. What is address space 1? NVIDIA GPU3471devices (generally) have four types of memory:3472 3473- Global: Large, off-chip memory3474- Shared: Small, on-chip memory shared among all threads in a CTA3475- Local: Per-thread, private memory3476- Constant: Read-only memory shared across all threads3477 3478These different types of memory are represented in LLVM IR as address spaces.3479There is also a fifth address space used by the NVPTX code generator that3480corresponds to the "generic" address space.  This address space can represent3481addresses in any other address space (with a few exceptions).  This allows3482users to write IR functions that can load/store memory using the same3483instructions. Intrinsics are provided to convert pointers between the generic3484and non-generic address spaces.3485 3486See :ref:`address_spaces` and :ref:`nvptx_intrinsics` for more information.3487 3488 3489Running the Kernel3490------------------3491 3492Generating PTX from LLVM IR is all well and good, but how do we execute it on3493a real GPU device? The CUDA Driver API provides a convenient mechanism for3494loading and JIT compiling PTX to a native GPU device, and launching a kernel.3495The API is similar to OpenCL.  A simple example showing how to load and3496execute our vector addition code is shown below. Note that for brevity this3497code does not perform much error checking!3498 3499.. note::3500 3501  You can also use the ``ptxas`` tool provided by the CUDA Toolkit to offline3502  compile PTX to machine code (SASS) for a specific GPU architecture. Such3503  binaries can be loaded by the CUDA Driver API in the same way as PTX. This3504  can be useful for reducing startup time by precompiling the PTX kernels.3505 3506 3507.. code-block:: c++3508 3509  #include <iostream>3510  #include <fstream>3511  #include <cassert>3512  #include "cuda.h"3513 3514 3515  void checkCudaErrors(CUresult err) {3516    assert(err == CUDA_SUCCESS);3517  }3518 3519  /// main - Program entry point3520  int main(int argc, char **argv) {3521    CUdevice    device;3522    CUmodule    cudaModule;3523    CUcontext   context;3524    CUfunction  function;3525    CUlinkState linker;3526    int         devCount;3527 3528    // CUDA initialization3529    checkCudaErrors(cuInit(0));3530    checkCudaErrors(cuDeviceGetCount(&devCount));3531    checkCudaErrors(cuDeviceGet(&device, 0));3532 3533    char name[128];3534    checkCudaErrors(cuDeviceGetName(name, 128, device));3535    std::cout << "Using CUDA Device [0]: " << name << "\n";3536 3537    int devMajor, devMinor;3538    checkCudaErrors(cuDeviceComputeCapability(&devMajor, &devMinor, device));3539    std::cout << "Device Compute Capability: "3540              << devMajor << "." << devMinor << "\n";3541    if (devMajor < 2) {3542      std::cerr << "ERROR: Device 0 is not SM 2.0 or greater\n";3543      return 1;3544    }3545 3546    std::ifstream t("kernel.ptx");3547    if (!t.is_open()) {3548      std::cerr << "kernel.ptx not found\n";3549      return 1;3550    }3551    std::string str((std::istreambuf_iterator<char>(t)),3552                      std::istreambuf_iterator<char>());3553 3554    // Create driver context3555    checkCudaErrors(cuCtxCreate(&context, 0, device));3556 3557    // Create module for object3558    checkCudaErrors(cuModuleLoadDataEx(&cudaModule, str.c_str(), 0, 0, 0));3559 3560    // Get kernel function3561    checkCudaErrors(cuModuleGetFunction(&function, cudaModule, "kernel"));3562 3563    // Device data3564    CUdeviceptr devBufferA;3565    CUdeviceptr devBufferB;3566    CUdeviceptr devBufferC;3567 3568    checkCudaErrors(cuMemAlloc(&devBufferA, sizeof(float)*16));3569    checkCudaErrors(cuMemAlloc(&devBufferB, sizeof(float)*16));3570    checkCudaErrors(cuMemAlloc(&devBufferC, sizeof(float)*16));3571 3572    float* hostA = new float[16];3573    float* hostB = new float[16];3574    float* hostC = new float[16];3575 3576    // Populate input3577    for (unsigned i = 0; i != 16; ++i) {3578      hostA[i] = (float)i;3579      hostB[i] = (float)(2*i);3580      hostC[i] = 0.0f;3581    }3582 3583    checkCudaErrors(cuMemcpyHtoD(devBufferA, &hostA[0], sizeof(float)*16));3584    checkCudaErrors(cuMemcpyHtoD(devBufferB, &hostB[0], sizeof(float)*16));3585 3586 3587    unsigned blockSizeX = 16;3588    unsigned blockSizeY = 1;3589    unsigned blockSizeZ = 1;3590    unsigned gridSizeX  = 1;3591    unsigned gridSizeY  = 1;3592    unsigned gridSizeZ  = 1;3593 3594    // Kernel parameters3595    void *KernelParams[] = { &devBufferA, &devBufferB, &devBufferC };3596 3597    std::cout << "Launching kernel\n";3598 3599    // Kernel launch3600    checkCudaErrors(cuLaunchKernel(function, gridSizeX, gridSizeY, gridSizeZ,3601                                   blockSizeX, blockSizeY, blockSizeZ,3602                                   0, NULL, KernelParams, NULL));3603 3604    // Retrieve device data3605    checkCudaErrors(cuMemcpyDtoH(&hostC[0], devBufferC, sizeof(float)*16));3606 3607 3608    std::cout << "Results:\n";3609    for (unsigned i = 0; i != 16; ++i) {3610      std::cout << hostA[i] << " + " << hostB[i] << " = " << hostC[i] << "\n";3611    }3612 3613 3614    // Clean up after ourselves3615    delete [] hostA;3616    delete [] hostB;3617    delete [] hostC;3618 3619    // Clean-up3620    checkCudaErrors(cuMemFree(devBufferA));3621    checkCudaErrors(cuMemFree(devBufferB));3622    checkCudaErrors(cuMemFree(devBufferC));3623    checkCudaErrors(cuModuleUnload(cudaModule));3624    checkCudaErrors(cuCtxDestroy(context));3625 3626    return 0;3627  }3628 3629 3630You will need to link with the CUDA driver and specify the path to cuda.h.3631 3632.. code-block:: text3633 3634  # clang++ sample.cpp -o sample -O2 -g -I/usr/local/cuda-5.5/include -lcuda3635 3636We don't need to specify a path to ``libcuda.so`` since this is installed in a3637system location by the driver, not the CUDA toolkit.3638 3639If everything goes as planned, you should see the following output when3640running the compiled program:3641 3642.. code-block:: text3643 3644  Using CUDA Device [0]: GeForce GTX 6803645  Device Compute Capability: 3.03646  Launching kernel3647  Results:3648  0 + 0 = 03649  1 + 2 = 33650  2 + 4 = 63651  3 + 6 = 93652  4 + 8 = 123653  5 + 10 = 153654  6 + 12 = 183655  7 + 14 = 213656  8 + 16 = 243657  9 + 18 = 273658  10 + 20 = 303659  11 + 22 = 333660  12 + 24 = 363661  13 + 26 = 393662  14 + 28 = 423663  15 + 30 = 453664 3665.. note::3666 3667  You will likely see a different device identifier based on your hardware3668 3669 3670Tutorial: Linking with Libdevice3671================================3672 3673In this tutorial, we show a simple example of linking LLVM IR with the3674libdevice library. We will use the same kernel as the previous tutorial,3675except that we will compute ``C = pow(A, B)`` instead of ``C = A + B``.3676Libdevice provides an ``__nv_powf`` function that we will use.3677 3678.. code-block:: llvm3679 3680  target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"3681  target triple = "nvptx64-nvidia-cuda"3682 3683  ; Intrinsic to read X component of thread ID3684  declare i32 @llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind3685  ; libdevice function3686  declare float @__nv_powf(float, float)3687 3688  define ptx_kernel void @kernel(ptr addrspace(1) %A,3689                                 ptr addrspace(1) %B,3690                                 ptr addrspace(1) %C) {3691  entry:3692    ; What is my ID?3693    %id = tail call i32 @llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind3694 3695    ; Compute pointers into A, B, and C3696    %ptrA = getelementptr float, ptr addrspace(1) %A, i32 %id3697    %ptrB = getelementptr float, ptr addrspace(1) %B, i32 %id3698    %ptrC = getelementptr float, ptr addrspace(1) %C, i32 %id3699 3700    ; Read A, B3701    %valA = load float, ptr addrspace(1) %ptrA, align 43702    %valB = load float, ptr addrspace(1) %ptrB, align 43703 3704    ; Compute C = pow(A, B)3705    %valC = call float @__nv_powf(float %valA, float %valB)3706 3707    ; Store back to C3708    store float %valC, ptr addrspace(1) %ptrC, align 43709 3710    ret void3711  }3712 3713 3714To compile this kernel, we perform the following steps:3715 37161. Link with libdevice37172. Internalize all but the public kernel function37183. Run ``NVVMReflect`` and set ``__CUDA_FTZ`` to 037194. Optimize the linked module37205. Codegen the module3721 3722 3723These steps can be performed by the LLVM ``llvm-link``, ``opt``, and ``llc``3724tools. In a complete compiler, these steps can also be performed entirely3725programmatically by setting up an appropriate pass configuration (see3726:ref:`libdevice`).3727 3728.. code-block:: text3729 3730  # llvm-link t2.bc libdevice.compute_20.10.bc -o t2.linked.bc3731  # opt -internalize -internalize-public-api-list=kernel -nvvm-reflect-list=__CUDA_FTZ=0 -nvvm-reflect -O3 t2.linked.bc -o t2.opt.bc3732  # llc -mcpu=sm_20 t2.opt.bc -o t2.ptx3733 3734.. note::3735 3736  The ``-nvvm-reflect-list=_CUDA_FTZ=0`` is not strictly required, as any3737  undefined variables will default to zero. It is shown here for evaluation3738  purposes.3739 3740 3741This gives us the following PTX (excerpt):3742 3743.. code-block:: text3744 3745  //3746  // Generated by LLVM NVPTX Back-End3747  //3748 3749  .version 3.13750  .target sm_203751  .address_size 643752 3753    // .globl kernel3754                                          // @kernel3755  .visible .entry kernel(3756    .param .u64 kernel_param_0,3757    .param .u64 kernel_param_1,3758    .param .u64 kernel_param_23759  )3760  {3761    .reg .pred  %p<30>;3762    .reg .f32   %f<111>;3763    .reg .s32   %r<21>;3764    .reg .s64   %rl<8>;3765 3766  // %bb.0:                                // %entry3767    ld.param.u64  %rl2, [kernel_param_0];3768    mov.u32   %r3, %tid.x;3769    ld.param.u64  %rl3, [kernel_param_1];3770    mul.wide.s32  %rl4, %r3, 4;3771    add.s64   %rl5, %rl2, %rl4;3772    ld.param.u64  %rl6, [kernel_param_2];3773    add.s64   %rl7, %rl3, %rl4;3774    add.s64   %rl1, %rl6, %rl4;3775    ld.global.f32   %f1, [%rl5];3776    ld.global.f32   %f2, [%rl7];3777    setp.eq.f32 %p1, %f1, 0f3F800000;3778    setp.eq.f32 %p2, %f2, 0f00000000;3779    or.pred   %p3, %p1, %p2;3780    @%p3 bra  BB0_1;3781    bra.uni   BB0_2;3782  BB0_1:3783    mov.f32   %f110, 0f3F800000;3784    st.global.f32   [%rl1], %f110;3785    ret;3786  BB0_2:                                  // %__nv_isnanf.exit.i3787    abs.f32   %f4, %f1;3788    setp.gtu.f32  %p4, %f4, 0f7F800000;3789    @%p4 bra  BB0_4;3790  // %bb.3:                                // %__nv_isnanf.exit5.i3791    abs.f32   %f5, %f2;3792    setp.le.f32 %p5, %f5, 0f7F800000;3793    @%p5 bra  BB0_5;3794  BB0_4:                                  // %.critedge1.i3795    add.f32   %f110, %f1, %f2;3796    st.global.f32   [%rl1], %f110;3797    ret;3798  BB0_5:                                  // %__nv_isinff.exit.i3799 3800    ...3801 3802  BB0_26:                                 // %__nv_truncf.exit.i.i.i.i.i3803    mul.f32   %f90, %f107, 0f3FB8AA3B;3804    cvt.rzi.f32.f32 %f91, %f90;3805    mov.f32   %f92, 0fBF317200;3806    fma.rn.f32  %f93, %f91, %f92, %f107;3807    mov.f32   %f94, 0fB5BFBE8E;3808    fma.rn.f32  %f95, %f91, %f94, %f93;3809    mul.f32   %f89, %f95, 0f3FB8AA3B;3810    // inline asm3811    ex2.approx.ftz.f32 %f88,%f89;3812    // inline asm3813    add.f32   %f96, %f91, 0f00000000;3814    ex2.approx.f32  %f97, %f96;3815    mul.f32   %f98, %f88, %f97;3816    setp.lt.f32 %p15, %f107, 0fC2D20000;3817    selp.f32  %f99, 0f00000000, %f98, %p15;3818    setp.gt.f32 %p16, %f107, 0f42D20000;3819    selp.f32  %f110, 0f7F800000, %f99, %p16;3820    setp.eq.f32 %p17, %f110, 0f7F800000;3821    @%p17 bra   BB0_28;3822  // %bb.27:3823    fma.rn.f32  %f110, %f110, %f108, %f110;3824  BB0_28:                                 // %__internal_accurate_powf.exit.i3825    setp.lt.f32 %p18, %f1, 0f00000000;3826    setp.eq.f32 %p19, %f3, 0f3F800000;3827    and.pred    %p20, %p18, %p19;3828    @!%p20 bra  BB0_30;3829    bra.uni   BB0_29;3830  BB0_29:3831    mov.b32    %r9, %f110;3832    xor.b32   %r10, %r9, -2147483648;3833    mov.b32    %f110, %r10;3834  BB0_30:                                 // %__nv_powf.exit3835    st.global.f32   [%rl1], %f110;3836    ret;3837  }3838