Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SM Version Codes & Scheduler Generations

Addresses apply to ptxas v13.0.88 (CUDA 13.0). VA base 0x400000 (non-PIE); file offset = VA − 0x400000.

ptxas maps a target architecture through three small .rodata tables: a version-code table (the packed sm_NN identifier), a supported-SM enumeration (the list of compute capabilities it accepts), and a scheduler-generation seed table (which internal scheduling model a target uses). All three are keyed by an internal arch index, not the SM number directly.

Version-code table

At VMA 0x2020620, a 128 × u16 array. The code packs the compute capability into three fields:

bits[15:12] = major × 10      bits[11:8] = minor      bits[7:0] = variant
e.g.  0x8000 → major 8, minor 0, variant 0   (sm_80)
      0x7003 → major 7, minor 0, variant 3   (the third gen-7 chip)
      0x9004 → major 9, minor 0, variant 4   (the fourth gen-9 chip)

The reader is sub_60FBF0: version_code = word_2020620[internal_arch_id − 20], clamped to index ≤ 0x65 (101) — entries at index ≥ 102 are adjacent-table bleed, not version codes. The reader stores word_2020620[arch_enum − 20] opaquely (sub_60FBF0:871); it never extracts a letter or decomposes the variant byte.

The variant byte is a per-generation chip ordinal, not a suffix selector

The low byte is a per-generation chip ordinal index — the N-th chip introduced inside that compute-major generation — not a selector that maps a number to a suffix letter. There is no runtime code anywhere in ptxas that turns a variant number into an a/c/f character.

The ordinal run is proven by the contiguous compute_86/compute_87/compute_88/compute_89 strings at VA 0x201F4D6 / 0x201F4E1 / 0x201F4F2 / 0x201F503, and by the profile constructors that stamp the code into profile+0x15c:

Generationvariant 0variant 1variant 2variant 3variant 4variant 5
gen-7 (major 8)sm_80sm_86sm_87sm_88sm_89
gen-9 (major 9)sm_100sm_101 / sm_110(unused, 0)sm_103sm_120sm_121

So variant 2 = sm_86 (gen-7; the gen-9 0x9002 slot is zero/unused), and variant 4 = sm_88 (gen-7) or sm_120 (gen-9). Both are real, user-selectable -arch targets — not internal-only, and never a suffix character. "variant 3" is sm_87 (gen-7) or sm_103 (gen-9), never a c suffix. Representative constructors:

0x60AC30   movl $0x7002, …(profile+0x15c)     ; sm_86  (gen-7, variant 2)
0x60AB30   movl $0x7004, …(profile+0x15c)     ; sm_88  (gen-7, variant 4)
0x608DF0   … = 0x9004                          ; sm_120 (gen-9, variant 4)

Suffix letters are an orthogonal naming property

The a and f suffixes (sm_90a, sm_120f, …) are a separate, hardcoded name-registration property, orthogonal to the variant byte. sm_120, sm_120a, and sm_120f all collapse to the same internal code 0x9004 once the profile is built — the suffix character is discarded after registration and never re-derived from the code. The string inventory confirms this: only a (15×) and f (14×) suffix strings exist, all in gen-9; there is no b/c/d/e. The apparent sm_9f token is a disassembler artifact of the hardcoded sm_90a deprecation-message builder, not a real target. The earlier variant 1→a, 3→c, 5→f reading of this table was wrong: it confused two independent mechanisms.

The raw table contents (with the variant column understood as a chip ordinal) are in Version-Code Table & Suffix Map.

Supported-SM enumeration

A cleaner arch-index → SM map at VMA 0x1CE7F80, 28 × u32, read by sub_442710: sm_id = dword_1CE7F80[internal_arch_index − 7] for index 7..34. Contents (26 active + 2 NULL separators that split the datacenter batch from the consumer batch):

sm_30 32 35 37 50 52 53 60 61 62 70 72 73 75 80 · [null] · 86 87 88 89 90 100 101 110 · [null] · 103 120 121

Scheduler-generation seeds

At VMA 0x1D16148, 50 × {u32 sm_id, u32 gen_code, u32 variant}. gen_code is an internal scheduler-model generation index, not the marketing architecture name — an earlier extraction legend that read it as "1=Fermi … 9=Thor" was a mislabel. The binary-derived groupings:

gensm_ids(marketing)
110, 11, 12, 13Tesla
220, 21Fermi
330, 35Kepler
432, 37, 50, 52, 53late-Kepler + Maxwell (one model)
560, 61, 62Pascal
670, 72, 75, 82Volta + Turing (shared)
780, 86, 87, 88, 89, 90Ampere / Ada (+ sm_90 as "A")
890, 100, 101, 103, 120, 121Hopper + Blackwell
9110Thor

sm_90 appears in both gen 7 and gen 8 — two scheduling models selected by context, which is the same split seen in the per-SM dependency tables (sm_90 disables 6 WGMMA/async classes that sm_90a keeps). The seed table's own variant column is the chip ordinal described above (e.g. sm_86 variant 1, sm_88 variant 3, sm_120 variant 7 in the gen-8 segment), not a suffix.

The full per-index tables are in the repo at decoded/ptxas-targets/ (sm_version_codes.tsv, sm_id_enumeration.tsv, sm_scheduling_seeds.tsv, supported_targets.tsv).

Cross-References