/** * ruRE CUDA launch plan, part 1 (ADR-501): theoretical occupancy from what the static reader found. Given an architecture's limits and a * kernel's registers, static shared memory and a block size, how many blocks fit on one multiprocessor and which resource stops the next one. * Pure arithmetic over a table: no device, no driver, nothing is run. The model is the one CUDA's occupancy calculator uses (warp, block, * register and shared-memory limits, each with its allocation granularity); it was written here from that model and is checked, over the whole * grid of resource combinations, against NVIDIA's own `cuda_occupancy.h` (rure-cuda-occupancy-oracle.test.ts) and on real devices. * Theoretical occupancy bounds how many warps can be resident. It is not a performance number. */ export type Limiter = 'warps' | 'registers' | 'sharedMemory' | 'blocks' | 'barriers'; /** Where a table row's numbers come from: read off a device by the CUDA runtime, or taken from NVIDIA's documentation. */ export type Provenance = 'device-checked' | 'documentation'; export interface ArchLimits { /** `sm_NN`, as the fatbin names it. */ arch: string; major: number; minor: number; maxThreadsPerSM: number; maxBlocksPerSM: number; maxThreadsPerBlock: number; regsPerSM: number; regsPerBlock: number; maxRegsPerThread: number; sharedPerSM: number; sharedPerBlock: number; sharedPerBlockOptin: number; /** Shared memory the driver reserves in every block (counted against the block's allocation). */ sharedReservedPerBlock: number; /** * Whether a kernel's `.nv.shared.` section already includes that reservation. From sm_90 it does (the compiler adds it, the driver reports * the size without it, and the occupancy calculation adds it back), so the figure to use is the section size less the reservation. */ cubinSharedIncludesReserve: boolean; /** The shared-memory sizes an SM can be configured to, ascending; the SM's allocation rounds up to one of them. */ carveouts: readonly number[]; provenance: Provenance; } /** Architectures with a table. Anything else gets no occupancy figure rather than a guess. */ export declare const ARCH_LIMITS: Readonly>; export declare const limitsFor: (arch: string | null) => ArchLimits | null; export interface Kernel { registers: number; staticSharedBytes: number; dynamicSharedBytes: number; blockSize: number; } export interface Occupancy { /** Blocks resident on one multiprocessor; 0 means the block cannot be launched at all. */ blocks: number; /** Every resource that sets that number (ties are all listed). */ limiters: Limiter[]; /** What each resource alone would allow. */ limits: Record; warpsPerBlock: number; activeWarps: number; /** activeWarps over the multiprocessor's warp capacity, 0 to 1. */ occupancy: number; } export declare function occupancy(l: ArchLimits, k: Kernel): Occupancy; //# sourceMappingURL=cuda-occupancy.d.ts.map