
    Mja                      $    d Z ddlZd ZddZd Zy)u  
Replacement for `_tiled_matmul_src` and `_TiledKernel` in `vgpu_tiled.py`.

Bug: shader exposed `M_dim`/`N_dim`/`K_dim` as `uniform int` but the
host never assigned them, so they defaulted to 0, every bound check
failed, the inner loop ran zero iterations, and C was never written
— leaving uninitialised float32 garbage in the readback.

Fix: bake M, K, N into the source as #define so the compiler sees
constants and the runtime-undefined-uniform trap is gone. Also zero
the output buffer once at allocation as a belt-and-braces defence.
    Nc                     |d   }|d   }|d   }|d   }|d   }|d   }	|d   }
||z  |	|
z  z  }||z  |	|
z  z  }d| d	| d
| d| d| d|	 d|
 d| d| d|  d| d| dS )NTS_KTSMTSNWPTMWPTNRTSMRTSNuT   #version 430 core
// Tile geometry for this kernel — compile-time.
#define TS_K   z
#define TSM    z
#define TSN    z
#define WPTM   z
#define WPTN   z
#define RTSM   z
#define RTSN   z
#define LPTA   z
#define LPTB   u   

// Shader-shape constants — BAKE, do not use uniforms.
// Prevents the "uniform defaults to 0" trap that you just hit.
#define MDIM   z
#define NDIM   z
#define KDIM   u  

layout(local_size_x = RTSM, local_size_y = RTSN) in;
layout(std430, binding = 0) readonly buffer A_buf { float A[]; };
layout(std430, binding = 1) readonly buffer B_buf { float B[]; };
layout(std430, binding = 2) writeonly buffer C_buf { float C[]; };

// A is stored transposed so the inner-loop read pattern
// `Asub[k][tidm + wm*RTSM]` is bank-coalesced on Intel/AMD after the
// first tile.
shared float Asub[TS_K][TSM];
// The +2 column pad prevents 32-way bank conflicts on Intel.
shared float Bsub[TSN][TS_K + 2];

void main() {
    uint tidm = gl_LocalInvocationID.x;          // 0..RTSM-1
    uint tidn = gl_LocalInvocationID.y;          // 0..RTSN-1
    uint offM = TSM * gl_WorkGroupID.x;
    uint offN = TSN * gl_WorkGroupID.y;

    float acc[WPTM][WPTN];
    for (uint i = 0u; i < WPTM; ++i)
        for (uint j = 0u; j < WPTN; ++j)
            acc[i][j] = 0.0;

    uint nTiles = (KDIM + TS_K - 1u) / TS_K;

    for (uint t = 0u; t < nTiles; ++t) {
        uint kBase = t * TS_K;

        // ─── Load A tile into shared (transposed) ─────────────────────
        for (uint la = 0u; la < LPTA; ++la) {
            uint lin   = la * (RTSM * RTSN) + tidn * RTSM + tidm;
            uint row   = lin % TSM;
            uint col   = lin / TSM;
            uint gRow  = offM + row;
            uint gK    = kBase + col;
            Asub[col][row] =
                (gRow < MDIM && gK < KDIM)
                    ? A[gRow * KDIM + gK]
                    : 0.0;
        }

        // ─── Load B tile into shared (column-padded) ──────────────────
        for (uint lb = 0u; lb < LPTB; ++lb) {
            uint lin   = lb * (RTSM * RTSN) + tidn * RTSM + tidm;
            uint row   = lin % TSN;
            uint col   = lin / TSN;
            uint gCol  = offN + row;
            uint gK    = kBase + col;
            Bsub[row][col] =
                (gCol < NDIM && gK < KDIM)
                    ? B[gK * NDIM + gCol]
                    : 0.0;
        }

        barrier();

        // Inner loop within tile.
        // Last (possibly partial) tile: bound K so we never read past KDIM.
        uint tileK = min(TS_K, KDIM - kBase);
        for (uint k = 0u; k < tileK; ++k) {
            float Areg;
            for (uint wm = 0u; wm < WPTM; ++wm) {
                Areg = Asub[k][tidm + wm * RTSM];
                for (uint wn = 0u; wn < WPTN; ++wn) {
                    float Breg = Bsub[tidn + wn * RTSN][k];
                    acc[wm][wn] += Areg * Breg;
                }
            }
        }

        barrier();
    }

    for (uint wm = 0u; wm < WPTM; ++wm) {
        uint gRow = offM + tidm + wm * RTSM;
        if (gRow >= MDIM) continue;
        for (uint wn = 0u; wn < WPTN; ++wn) {
            uint gCol = offN + tidn + wn * RTSN;
            if (gCol >= NDIM) continue;
            // Row-major write matches `np.frombuffer().reshape(M, N)`.
            C[gRow * NDIM + gCol] = acc[wm][wn];
        }
    }
}
 )MKNgeor   r   r   r   r   r	   r
   LPTALPTBs                0/home/per/Documents/VGPU/tiled_matmul_fix_bak.py_tiled_matmul_srcr      s    v;Dc%jE
#v;Ds6{v;Ds6{$JD4K(D$JD4K(Dv u u v v v v v v  s s s V!f f    c                    	
 t         vr"t        t         j                         fd      t            }t        |      } j                  j                  |       j                  j                  z  dz         j                  j                  z  dz        	 j                  j                  z  dz        
t        d|d   z   dz
  |d   z        t        d|d   z   dz
  |d   z         G 	
 fdd	      }t        d
 d d d d d d|d    d|d            |       S )Nc                      t        | z
        S )N)abs)xks    r   <lambda>z'_compile_tiled_matmul.<locals>.<lambda>   s    c!a%j r   )key   )reserve   r   r   c            
       >    e Zd ZdZ 	f
dZ
fdZy)+_compile_tiled_matmul.<locals>._TiledKernelprogABCgxgyr   r   r   tile_kclearedc                    
 
| _         c| _        | _        | _        c| _        | _        c| _        | _        | _        	| _	        d| _
        y )NFr!   )selfA_bufB_bufC_bufr   r   r   r&   r'   r   r"   s    r   __init__z4_compile_tiled_matmul.<locals>._TiledKernel.__init__   sT    DI%*E5"DFDFDF!2DGTW%&1"DFDFDFDK DLr   c                 R   | j                   j                  |j                                | j                  j                  |j                                | j                   j	                  d       | j                  j	                  d       | j
                  j	                  d       | j                  j                  | j                  | j                  d       	j                  j                          | j
                  j                         }t        j                  |t        j                        j!                         }| j"                  s^t%        |dk7  j'                               t)        |j*                  d      z  }|dk  rt-        d d d dd|z
  d	z  d
d	      d| _        |S )Nr   r      )dtypeg{Gz?z[VGPU] tiled matmul r   z: C buffer is d   z.1fuT   % zeros — shader produced no output. Likely a bug in the shader, not in this call.T)r#   writetobytesr$   bind_to_storage_bufferr%   r"   runr&   r'   ctxfinishreadnp
frombufferfloat32copyr)   floatsummaxsizeRuntimeError)
r+   A_arrB_arrbufoutnz_ratior   r   r   
self_outers
         r   __call__z4_compile_tiled_matmul.<locals>._TiledKernel.__call__   s?   FFLL)FFLL)FF))!,FF))!,FF))!,IIMM$''477A.NN!!#
 &&++-C--2::6;;=C<< !#(!12S15EEd?&.qc1#QqchJ+C0 1%&' '
  $Jr   N)__name__
__module____qualname__	__slots__r/   rJ   )r,   r-   r.   r   r   r   r&   r'   r   r"   rI   s   r   _TiledKernelr       s    9		! 	!	 	r   rO   u#   [VGPU] ✅ compiled tiled matmul M=z K=z N=z  k=z @ workgroup    ×u    × r	   r
   )	TILE_GEOMETRIESminkeysr   r8   compute_shaderbufferrA   print)rI   r   r   r   r   r   srcrO   r,   r-   r.   r&   r'   r"   s   `````   @@@@@@r   _compile_tiled_matmulrX      s\   $$&,@A
!
C
Aq!S
)C>>((-DNN!!!a%!)!4ENN!!!a%!)!4ENN!!!a%!)!4E	QSZ!#E
2	3B	QSZ!#E
2	3B% % %N 
 cQCs1#T! %Brd$s6{m2c&k]D E >r   c                      dddd}|| _         y)z=Adds `cache.verify_matmul(M, K, N, k=16)`. Use after install.gMbP?)atolc                L   | j                   | j                  st        d       yt        j                  j                  ||      j                  t        j                        }t        j                  j                  ||      j                  t        j                        }||z  }| j                  |||      j                  ||      }	t        t        j                  t        j                  |	|z
                    }
|
|k  }t        d| d| d| d| d|
dd	|rd
ndz          |S )z;Run a small ground-truth check before trusting a benchmark.u4   [verify] CPU backend — skipped (nothing to verify)T)r   z[verify] matmul(,z, k=z)  err=z.2ez  u   ✓u   ✗  ABOVE TOLERANCE)r8   gpu_availablerV   r;   randomrandnastyper=   matmulreshaper?   rA   r   )r+   r   r   r   r   rZ   XWrefrG   erroks               r   verify_matmulz%install_verify.<locals>.verify_matmul   s    884#5#5HIIIOOAq!((4IIOOAq!((4!ekk!Q!k$,,Q2BFF266#),-.Dj 1QCq4s'#c"E"8: 	;	r   N)@   ri   ri      )rh   )clsrh   s     r   install_verifyrl      s    D  &Cr   )rj   )__doc__numpyr;   r   rX   rl   r   r   r   <module>ro      s!    
md8|&r   