Hardware / NVIDIA Ada Lovelace · AD102
GeForce RTX 4090
The Ada card: sm_86 instructions run under sm_89 launch descriptors and driver contracts.
SM89 · compute capability 8.9
What has run here
Verified · run pending
Coppelius was brought up on this card before the current refactor, and today's Bob and Coppelius executables pass compiler and envelope verification. A fresh train, resume and predict run is waiting for a rented card whose /dev/nvidia-uvm opens (two failed with EIO).
Driver facts
Typed profile
Read at build time from Platform.RunPod.Nvidia.SM89 at 2877a0c1. Systems bind to these values by name; none branches on a card name.
| Fact | Value | Alpha definition |
|---|---|---|
| Product identity | NVIDIA GeForce RTX 4090 | runPodRTX4090ProductIdentity |
| Target identity | runpod-nvidia-geforce-rtx4090-sm89 | runPodRTX4090TargetIdentity |
| Compute capability | 8.9 | runPodRTX4090TargetProfile |
| Total video memory | 25,769,803,776 B (24 GiB) | runPodRTX4090TotalVideoMemory |
| QMD architecture | 0x00000089 | runPodSM89QMDArchitecture |
| Compute class | 0x0000C9C0 | runPodSM89ComputeClass |
| SPA version | 0x00000809 | runPodSM89SPAVersion |
Instruction set · 40 typed instructions
Every GPU instruction Alpha can emit for this device
The typed instruction set is SM86InstructionBody in Accelerator.SM86.Instruction; each name links to the line that defines it, each opcode to the line that encodes it. The SASS column is the mnemonic NVIDIA's tools would print for the same encoding. The RTX 4090 runs these SM86 instruction payloads under its SM89 command-stream contracts. Instructions this device has that Alpha has not yet typed are not listed: Alpha only claims what its compiler can emit and its runtime has executed.
| Alpha name | SASS | Opcode | Meaning | Operands |
|---|---|---|---|---|
SM86MoveConstant | MOV (constant bank) | 0xA02 | destination = c[bank][offset], a 32-bit word from a constant bank. |
|
SM86SpecialToRegister | S2R | 0x919 | destination = a special register (thread or cooperative-thread-array index). |
|
SM86MoveImmediate | MOV (immediate) | 0x802 | destination = a 32-bit immediate. |
|
SM86IntegerMultiplyAddConstant | IMAD (constant bank) | 0xA24 | destination = left * c[bank][offset] + addend, 32-bit integer. |
|
SM86IntegerMultiplyAddImmediate | IMAD (immediate) | 0x824 | destination = left * immediate + addend, 32-bit integer. |
|
SM86IntegerMultiplyAddWideConstant | IMAD.WIDE.U32 | 0x625 | destination pair = left * right + c[bank][offset], a 64-bit product plus a 64-bit constant. |
|
SM86IntegerAddThreeImmediate | IADD3 (immediate) | 0x810 | destination = left + immediate, the three-input adder with one input zero. |
|
SM86IntegerAddThreeRegister | IADD3 (register) | 0x210 | destination = left + right, the three-input adder with one input zero. |
|
SM86ShiftRightImmediate | SHF.R.U32.HI | 0x819 | destination = source logically shifted right by an immediate amount. |
|
SM86LogicThreeInputTruthTable | LOP3.LUT | 0x212 | destination = truthTable(left, right, zero), any bitwise function of the inputs given as an 8-bit lookup table. |
|
SM86IntegerToFloat | I2FP.F32.S32 | 0x245 | destination = the signed 32-bit integer source converted to binary32. |
|
SM86FloatAdd | FADD | 0x221 | destination = left + right, binary32, round to nearest even. |
|
SM86FloatMultiply | FMUL | 0x220 | destination = left * right, binary32, round to nearest even. |
|
SM86FloatFusedMultiplyAdd | FFMA | 0x223 | destination = left * right + addend, binary32 with a single rounding. |
|
SM86MultiFunctionUnitApproximation | MUFU | 0x308 | destination = an approximate transcendental of the source (cosine, sine, exp2, log2, reciprocal, reciprocal square root, square root, tanh) from the multi-function unit. |
|
SM86FloatMinimumOrMaximum | FMNMX | 0x209 | destination = the minimum or the maximum of left and right, binary32. |
|
SM86FloatNegate | FADD (negated source, zero addend) | 0x221 | destination = -source, binary32. |
|
SM86FloatPairToPackedHalfPair | F2FP.PACK_AB | 0x23E | destination = two binary32 sources converted and packed into one register of two binary16 halves. |
|
SM86FloatPairToPackedBFloat16Pair | F2FP.BF16.PACK_AB | — | destination = two binary32 sources rounded to bfloat16 (to nearest, ties to even) and packed into one register. |
|
SM86HalfToFloat | HADD2.F32 | 0x230 | destination = the selected binary16 half of the source widened to binary32. |
|
SM86BFloat16ToFloat | PRMT Rd, Ra, 0x1044 (H0) or 0x3244 (H1), RZ | — | destination = the selected bfloat16 half of the source widened to binary32 (its bits moved to the high half, the low half zero: exact). |
|
SM86TensorCoreHalfMatrixMultiplyAccumulate16x8x16Float32 | HMMA.16816.F32 | 0x23C | destination = fragmentA (16x16, binary16) * fragmentB (16x8, binary16) + accumulator (16x8, binary32) on the tensor cores, one warp-wide 16x8x16 tile. |
|
SM86TensorCoreBFloat16MatrixMultiplyAccumulate16x8x16Float32 | HMMA.16816.F32.BF16 | — | the same tile product with bfloat16 fragments. |
|
SM86LoadGlobal | LDG.E | 0x981 | destination = the 32-bit word at address + offset in global memory. |
|
SM86LoadGlobalWide | LDG.E.128 | 0x981 | destination quad = the 128 bits at address + offset in global memory. |
|
SM86WarpShuffle | SHFL | 0xF89 | destination = the source register of another lane of the warp, selected by index, up, down or butterfly mode. |
|
SM86LoadShared | LDS | 0x984 | destination = the 32-bit word at address + offset in shared memory. |
|
SM86LoadSharedMatrix | LDSM | 0x83B | destination = one, two or four 8x8 binary16 matrices loaded from shared memory into tensor-core fragment layout, optionally transposed. |
|
SM86StoreShared | STS | 0x388 | the 32-bit value stored at address + offset in shared memory. |
|
SM86LoadGlobalToShared | LDGSTS.E.BYPASS.128 (cp.async.cg, 16 bytes) | 0xFAE | the 128 bits at global source + sourceOffset (a register pair; the offset a signed 12-bit immediate) copied to shared memory at address + offset, asynchronously: the copy joins the thread's open group (SM86CommitAsyncGroup closes it), and nothing may read those shared bytes until SM86WaitAsyncGroups has retired the group (and, for other threads, a BAR.SYNC after). Its registers are read after issue: a read barrier guards them. |
|
SM86CommitAsyncGroup | LDGDEPBAR (cp.async.commit_group) | 0x9AF | the thread's open group of asynchronous copies closed; the groups in flight count on scoreboard SB0, which the control's write barrier names. |
|
SM86WaitAsyncGroups | DEPBAR.LE SB0, count (cp.async.wait_group count) | 0x91A | wait until at most `count` (0..63) groups of asynchronous copies are in flight. |
|
SM86BarrierSynchronize | BAR.SYNC | 0xB1D | every thread of the cooperative thread array waits until all have arrived. |
|
SM86StoreGlobal | STG.E | 0x986 | the 32-bit value stored at address + offset in global memory. |
|
SM86StoreGlobalWide | STG.E.128 | 0x986 | the 128-bit value quad stored at address + offset in global memory. |
|
SM86StoreGlobal64 | STG.E.64 | 0x986 | the 64-bit value pair stored at address + offset in global memory. |
|
SM86ReduceGlobalAddFloat32 | RED.E.ADD.F32 | 0x98E | the binary32 value atomically added to the word at address + offset in global memory, no result returned. |
|
SM86PredicateGreaterThanImmediate | ISETP.GT (immediate) | 0x80C | destination predicate = source > immediate, compared as unsigned 32-bit words in this encoding: the RTX 3070 has 0x80000000 > 0 (Checked.IntegerCompareProbe, Proof.CheckedIntegerCompareSilicon). |
|
SM86Branch | BRA | 0x947 | continue at the instruction offset bytes away, relative to the next instruction. |
|
SM86Exit | EXIT | 0x94D | this thread finishes the program. |
|
Operand vocabularies
The named values an instruction's operands range over: special registers, execution guards, shuffle modes, half selectors, shared-matrix shapes, multi-function operations, extremum modes, and the scoreboard barriers and yield modes carried by every instruction's SM86Control word (Stall, Yield, WriteBarrier, ReadBarrier, WaitMask, ReuseMask).
SM86SpecialRegister
| Alpha name | SASS | Meaning |
|---|---|---|
SM86CooperativeThreadArrayIdX | SR_CTAID.X | the cooperative thread array (block) index on x. |
SM86CooperativeThreadArrayIdY | SR_CTAID.Y | the cooperative thread array (block) index on y. |
SM86CooperativeThreadArrayIdZ | SR_CTAID.Z | the cooperative thread array (block) index on z. |
SM86ThreadIdX | SR_TID.X | the thread index on x within its cooperative thread array. |
SM86ClockLow | SR_CLOCKLO | the low word of the SM's cycle counter. |
SM86GlobalTimerLow | SR_GLOBALTIMERLO | the low word of the device's global timer, in nanoseconds -- the clock the semaphore releases stamp. |
SM86GlobalTimerHigh | SR_GLOBALTIMERHI | its high word. |
SM86InstructionGuard
| Alpha name | SASS | Meaning |
|---|---|---|
SM86InstructionAlways | — | no guard: the instruction always executes. |
SM86InstructionWhen | @P | the instruction executes only in threads where the predicate is true. |
SM86InstructionWhenNot | @!P | the instruction executes only in threads where the predicate is false. |
SM86ShuffleMode
| Alpha name | SASS | Meaning |
|---|---|---|
SM86ShuffleIndex | SHFL.IDX | read the lane named by the lane operand. |
SM86ShuffleUp | SHFL.UP | read the lane that is lane places below this one. |
SM86ShuffleDown | SHFL.DOWN | read the lane that is lane places above this one. |
SM86ShuffleButterfly | SHFL.BFLY | read the lane whose index is this lane's index xor the lane operand. |
SM86HalfSelector
| Alpha name | SASS | Meaning |
|---|---|---|
SM86LowHalf | — | the low binary16 half (H0) of a 32-bit register. |
SM86HighHalf | — | the high binary16 half (H1) of a 32-bit register. |
SM86HalfFormat
| Alpha name | SASS | Meaning |
|---|---|---|
SM86Binary16 | — | — |
SM86BFloat16 | — | — |
SM86MultiFunction
| Alpha name | SASS | Meaning |
|---|---|---|
SM86Cosine | MUFU.COS | cosine of the source, radians. |
SM86Sine | MUFU.SIN | sine of the source, radians. |
SM86ExponentialBase2 | MUFU.EX2 | two raised to the source. |
SM86LogarithmBase2 | MUFU.LG2 | the base-2 logarithm of the source. |
SM86Reciprocal | MUFU.RCP | one divided by the source. |
SM86ReciprocalSquareRoot | MUFU.RSQ | one divided by the square root of the source. |
SM86SquareRoot | MUFU.SQRT | the square root of the source. |
SM86HyperbolicTangent | MUFU.TANH | the hyperbolic tangent of the source. |
SM86FloatExtremum
| Alpha name | SASS | Meaning |
|---|---|---|
SM86FloatMinimum | FMNMX with PT | the smaller of the two operands. |
SM86FloatMaximum | FMNMX with !PT | the larger of the two operands. |
SM86Barrier
| Alpha name | SASS | Meaning |
|---|---|---|
SM86Barrier0 | — | — |
SM86Barrier1 | — | — |
SM86Barrier2 | — | — |
SM86Barrier3 | — | — |
SM86Barrier4 | — | — |
SM86Barrier5 | — | — |
SM86Barrier6 | — | — |
SM86BarrierNone | — | — |
SM86WaitBarrier
| Alpha name | SASS | Meaning |
|---|---|---|
SM86WaitBarrier0 | — | — |
SM86WaitBarrier1 | — | — |
SM86WaitBarrier2 | — | — |
SM86WaitBarrier3 | — | — |
SM86WaitBarrier4 | — | — |
SM86WaitBarrier5 | — | — |
SM86YieldMode
| Alpha name | SASS | Meaning |
|---|---|---|
SM86Continue | — | — |
SM86Yield | — | — |
Profile coverage
What has been measured, and what has not
A fully profiled device has three tiers. A tier that is not measured yet lists the fields it will fill, so the gap is explicit.
- 1
Driver facts
LiveWhat the resource manager reports and the typed profile binds: product identity, compute capability, video memory, the QMD architecture, compute class and SPA version the command stream is built for.
- product identity
- compute capability
- total video memory
- QMD architecture
- compute class
- SPA version
- UVM / RM / QMD / pushbuffer / GPFIFO admission bits
- 2
Micro-benchmarks
Not measured yetMeasured instruction and memory behaviour, so the compiler can reason about cost from numbers read on this card rather than assumptions.
- issue rate and latency per typed instruction (FFMA, IMAD, MUFU, LDG, STG, LDSM, HMMA…)
- shared-memory bandwidth and bank behaviour
- global-memory bandwidth by access pattern and width
- tensor-core throughput at 16×8×16
- barrier and warp-shuffle cost
- submission, doorbell and semaphore round-trip cost
- sustained clocks under the training workload
- 3
Model-shaped calibration
Not measured yetThe cost of the exact kernels and launch schedules Alpha emits for each system on this device, so realization choices can be made from measurements.
- per-kernel time for every launch in each system's schedule
- occupancy and register / shared-memory pressure per kernel
- end-to-end step time and its split between host protocol, launches and waits
- memory footprint against the profile's video memory
Sources