
    Mja"                     	   d Z ddlZddlZddlZddlZ ej                         j                  d      xr dej
                  v Z ej                         dk(  Z
 ej                         dk(  Z ed ej                          d ej                                  ed	e        d
ZdZ	 ddlZer ed       d
Zn<	  ej                          Z eed      rej&                  rdZdZ ed       n ed       e
r
es ed        G d d      Zedk(  rC ed        ed        ed        e       Z ed       ej4                  j7                  d       ej4                  j9                  dd      j;                  ej<                        Zej4                  j9                  dd      j;                  ej<                        Z ee z  Z!ejE                  ee       Z# ejH                   ejJ                  e#e!z
              Z& ede&d       e&dk  s
J d e&         ed!        ed"       ej4                  j9                  d#d$      j;                  ej<                        Zej4                  j9                  d$d      j;                  ej<                        Z ee z  Z!ejE                  ee       Z# ejH                   ejJ                  e#e!z
              Z& ede&d       e&dk  s
J d e&         ed!        ed%       ejE                  ee       Z' ejH                   ejJ                  e'e!z
              Z( ede(d        ed&ejS                                  ed'       ddl*Z* e*jT                         Z+ e,d(      D ]~  Z-ej4                  j9                  d#d#      j;                  ej<                        Zej4                  j9                  d#d#      j;                  ej<                        Z ejE                  ee       Z#  e*jT                         e+z
  Z. ed)e.d*d+e.d(z  d,z  d-d.        ed/ejS                                  ed0        ed1        ed       yy# e$ rZ ede d       Y dZ[wdZ[ww xY w# e$ r  ed       Y w xY w)2u   
vgpu_cache.py — Universal VGPU persistent kernel cache.
Works on all platforms: RPi5 (numpy), Linux/macOS/Windows (OpenGL/Metal).

Author: Per Lindholm
License: MIT

Run: python vgpu_cache.py
    NarmlinuxDarwinWindowsz[VGPU] Platform:  z[VGPU] Raspberry Pi: Fz/[VGPU] RPi5 detected: using CPU (numpy) backendcompute_shaderTmodernglu#   [VGPU] ✅ GPU available (moderngl)u,   [VGPU] ⚠️  No compute shaders; using CPUu   [VGPU] ❌ GPU init failed: z; using CPUz0[VGPU] moderngl not installed; using CPU (numpy)zA[VGPU] macOS detected: consider installing Metal support (future)c                   P    e Zd Zd Zdej
                  fdZd Zd Zde	fdZ
d Zy)		VGPUCachec                 L   i | _         dddddd| _        t        | _        t        | _        | j                  r*| j
                  dk(  r	 t        j                         | _        nd | _        t        d| j                  rdnd d	       y #  d| _        d | _        t        d       Y ;xY w)
Nr   )compiles
cache_hits
dispatches	cpu_calls	gpu_callsr	   Fz-[VGPU] GPU context creation failed; using CPUz[VGPU] Using GPUCPUz backend)
_kernels_statsGPU_AVAILABLEgpu_availableGPU_BACKENDgpu_backendr	   create_standalone_contextctxprintselfs    4/home/per/Documents/Emulate_CUDA/MNIST/vgpu_cache.py__init__zVGPUCache.__init__?   s    
 +&$"2"2j"@G#==? DHt'9'9euEXNOG%*"#' EFs   B B#returnc                    |j                   \  }}|j                   \  }}||k(  sJ d| d|        |j                  t        j                        }|j                  t        j                        }|||f}|| j                  v r| j
                  dxx   dz  cc<   n&d| j                  |<   | j
                  dxx   dz  cc<   | j                  rS| j                  dk(  rD	 | j                  |||      }| j
                  dxx   dz  cc<   | j
                  d	xx   dz  cc<   |S | j
                  dxx   dz  cc<   | j
                  d	xx   dz  cc<   ||z  S # t        $ r }	t        d
|	 d       d| _        Y d}	~	Wd}	~	ww xY w)z!A @ B. Cached on (M, K, N) shape.zInner dimensions must match: z vs r      Nr   r	   r   r   z[VGPU] GPU matmul failed: z; falling back to CPUFr   )shapeastypenpfloat32r   r   r   r   _matmul_gpu	Exceptionr   )
r   ABMKK2Nkeyresultes
             r   matmulzVGPUCache.matmulX   so   ww1ABwC7s$rdCCwHHRZZ HHRZZ !Qi $--KK%*%!%DMM#KK
#q(# $"2"2j"@+))!Q4K(A-(L)Q.) 	K A% L!Q&!1u  +21#5JKL%*""+s   AE 	E;E66E;c                     | j                   |   | j                  |      | j                   |<   | j                   |   } |||      S )z)GPU matmul using moderngl (desktop only).)r   _compile_kernel)r   r*   r+   r0   kernels        r   r(   zVGPUCache._matmul_gpuy   sF     ==%!%!5!5c!:DMM#s#a|    c           	         |\  }}}d| d| d| d}| j                   j                  |      }| j                   j                  ||z  dz        }| j                   j                  ||z  dz        }| j                   j                  ||z  dz        }	t        d|dz   d	z        }
t        d|dz   d	z        } G d
 d      }t	        d| d| d|         || j                   ||||	|
|      S )z,Compile GLSL compute shader for given shape.a  
#version 430 core
layout(local_size_x = 16, local_size_y = 16) 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[]; };
uniform int M = z;
uniform int K = z;
uniform int N = a7  ;
void main() {
    uint row = gl_GlobalInvocationID.y;
    uint col = gl_GlobalInvocationID.x;
    if (row >= uint(M) || col >= uint(N)) return;
    float sum = 0.0;
    for (uint k = 0u; k < uint(K); k++) {
        sum += A[row * uint(K) + k] * B[k * uint(N) + col];
    }
    C[row * uint(N) + col] = sum;
}
   )reserver#         c                       e Zd Zd Zd Zy),VGPUCache._compile_kernel.<locals>.GPUKernelc                 f    || _         || _        || _        || _        || _        || _        || _        y )N)r   programA_bufB_bufC_bufgxgy)r   r   r@   rA   rB   rC   rD   rE   s           r   r    z5VGPUCache._compile_kernel.<locals>.GPUKernel.__init__   s3    &"
"
"
r7   c                    | j                   j                  |j                                | j                  j                  |j                                | j                   j	                  d       | j                  j	                  d       | j
                  j	                  d       | j                  j                  | j                  | j                  d       t        j                  | j
                  j                         t        j                        j                  |j                  d   |j                  d         j!                         S )Nr   r#      )dtype)rA   writetobytesrB   bind_to_storage_bufferrC   r@   runrD   rE   r&   
frombufferreadr'   reshaper$   copy)r   r*   r+   s      r   __call__z5VGPUCache._compile_kernel.<locals>.GPUKernel.__call__   s    

  -

  -

11!4

11!4

11!4  $''15}}TZZ__%6bjjIQQRSRYRYZ[R\^_^e^efg^hinnppr7   N)__name__
__module____qualname__r    rQ    r7   r   	GPUKernelr>      s    qr7   rV   u   [VGPU] ✅ Compiled kernel for x)r   r   buffermaxr   )r   r0   r,   r-   r/   
shader_srcr@   rA   rB   rC   rD   rE   rV   s                r   r5   zVGPUCache._compile_kernel   s   1a    
* (())*5A	2A	2A	2QVN#QVN#	q 	q& 	/s!A3as;<7E5%RHHr7   c                     | j                   rdnd}d| d| j                  d    d| j                  d    d| j                  d	    d
| j                  d    d| j                  d    dS )Nr   r   zVGPUCache [z]: r   z compiles, r   z cache hits, r   z dispatches, r   z CPU, r   z GPU)r   r   )r   backends     r   reportzVGPUCache.report   sy    --%5gYc;;z*+;;;|,-];;|,-];;{+,F;;{+,D2 	3r7   c                 8    | j                   j                          y)zClear all cached kernels.N)r   clearr   s    r   r_   zVGPUCache.clear   s    r7   N)rR   rS   rT   r    r&   ndarrayr3   r(   r5   strr]   r_   rU   r7   r   r   r   >   s6    P2bjj B6Ip3 3r7   r   __main__zF======================================================================zVGPU Universal Cache Testz"
[1] Testing small matmul (16x16):*   r<   z  Max diff: z.2eg-C6?zMatmul failed: diff=u     ✓ Verifiedz0
[2] Testing rectangular matmul (32x64 @ 64x16):    @   z 
[3] Testing cache (should hit):z  Cache stats: z
[4] Benchmarking 100 matmuls:d   z  100 matmuls in z.3fzs (i  z.1fzms each)z  Final cache stats: zG
======================================================================u   ✅ All tests passed!)/__doc__numpyr&   ossysplatformmachine
startswithIS_RASPBERRY_PIsystemIS_MACOS
IS_WINDOWSr   r   r   r	   r   r   hasattrr   r)   r2   ImportErrorr   rR   cacherandomseedrandnr%   r'   r*   r+   expectedr3   CrY   absdiffC2diff2r]   timestartrange_elapsedrU   r7   r   <module>r      su    	 
 
 #(""$//6R7cll;R8??(X__)+
 /(//+,A.>h.>.>.@-AB C o./ 0
 >?@		A4(446Cs,-#2D2D $(;<DE M	
MN
G GZ z	(O	
%&	(OKE 

/0IINN2
		B&&rzz2A
		B&&rzz2A1uHQA266&"&&X&'D	Lc

#$$;5.tf55;	
 

=>
		B&&rzz2A
		B&&rzz2A1uHQA266&"&&X&'D	Lc

#$$;5.tf55;	
 

-.	a	BBFF6266"x-()E	Ls
$%	OELLN+
,- 

+,DIIKE3Z IIOOB#**2::6IIOOB#**2::6LLA diikE!G	gc]#gck$.>s-C8
LM	!%,,.!1
23	/	
!"	(Ok u  	A0;?@@	A  >	
<=>s6   'Q3 9;Q Q0Q+%Q3 +Q00Q3 3RR