
    ^j,                       d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlmZmZ d dlmZ d dlmZmZ d dlmZmZmZmZmZ ddlmZmZmZ d dlZd d	lmZ d dl Z dd
l!m"Z" ddl#m$Z$m%Z% dZ&e"Z'ddZ(ddZ)d Z*d Z+ G d de jX                  jZ                  j\                        Z.d Z/d dZ0e G d d             Z1d Z2d Z3 G d d      Z4 G d d      Z5	 d!dZ6y)"    )annotationsN)	dataclassfield)Path)cached_propertypartial)DictTupleListOptionalAny   )_bench_cuda_graph_l2_rotate_clone_l2_rotate_inputs_pick_l2_rotate_count)Tensor)__version__)make_epilogue_source_markerserialize_worker_valuetorch_vendor_quackc                r    t        | t        t        f      ryt        |       }t        | t              rd|v ryy)aZ  Return True for failures that should invalidate one config only.

    Autotune candidates can be structurally invalid for a particular epilogue
    and shape (for example, a fragment layout that cannot represent a requested
    local-reduce group). Those should get an infinite timing while unexpected
    programming errors still propagate.
    Tz%expected reshaped size to be the sameF)
isinstanceRuntimeErrorMemoryErrorstr
ValueError)emsgs     h/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/torch/_vendor/quack/autotuner.py$_is_expected_autotune_config_failurer    &   s8     !lK01
a&C!Z %LPS%S    c                    t         j                  j                         rt         j                  j                         syt         j                  j	                         } t
        j                  j                  d      }|@|j                  d      D cg c]  }|j                          }}| t        |      k  r||    S yt        |       S c c}w )a  Return the physical CUDA device identifier for the current process.

    Maps the logical ``torch.cuda.current_device()`` index through
    ``CUDA_VISIBLE_DEVICES`` (if set) so the result is valid as a
    standalone ``CUDA_VISIBLE_DEVICES`` value (handles integer IDs,
    GPU UUIDs, and MIG IDs).

    Returns ``None`` if CUDA is not initialized or the device cannot
    be determined.
    NCUDA_VISIBLE_DEVICES,)torchcudais_availableis_initializedcurrent_deviceosenvirongetsplitstriplenr   )logical_deviceparent_visibledvisible_devicess       r   _get_current_cuda_devicer4   6   s     JJ##%%***C*C*EZZ..0NZZ^^$:;N!.<.B.B3.GH1779HHC00">22~	 Is   Cc                 |    t        j                  t        j                          dt	        j
                               S )N_HOME)r*   getenvPACKAGE_NAMEupperr   home r!   r   get_home_dirr<   M   s*    99**,-U3TYY[AAr!   c                 b    t         j                  j                  t               dt         d      S )N.cache)r*   pathjoinr<   r8   r;   r!   r   default_cache_dirrB   Q   s"    77<<!L>(:GDDr!   c                       e Zd Z fdZ xZS )FileCacheManagerc                   t         |   |       t        j                  t        j                          dd      j                         xs
 t               | _        | j                  rt        j                  j                  | j                  | j                        | _        t        j                  j                  | j                  d      | _        t        j                  | j                  d       y t        d      )N
_CACHE_DIR lockT)exist_okz$Could not create or locate cache dir)super__init__r*   r7   r8   r9   r.   rB   	cache_dirr@   rA   key	lock_pathmakedirsr   )selfrM   	__class__s     r   rK   zFileCacheManager.__init__V   s    II++-.j92>DDF]J[J] 	 >>WW\\$..$((CDNWW\\$..&ADNKK6EFFr!   )__name__
__module____qualname__rK   __classcell__)rQ   s   @r   rD   rD   U   s    
G 
Gr!   rD   c                    t        j                  t        j                  |             j	                  d      j                  d      S )Nutf-8=)base64	b32encodebytesfromhexdecoderstriprM   s    r   _base32r`   c   s2    EMM#./66w?FFsKKr!   c                   t        j                  dddt         j                        }t         j                  j	                          | dz  }t        j
                         }t        j
                         |z
  |k  rOt        d      D ]  }||z  }	 t         j                  j	                          t        j
                         |z
  |k  rNyy)zSaturate the GPU to reach thermal steady-state before benchmarking.

    Without this, the first autotuning config gets artificially good numbers
    because the GPU hasn't been power-throttled yet.
    i   r&   )devicedtypei  d   N)r%   randnbfloat16r&   synchronizetimerange)duration_msatargett0_s        r   _gpu_warmupro   h   s     	D$vU^^DA	JJ4F	B
))+
V
#s 	AAA	

  ))+
V
#r!   c                      e Zd ZU dZ ee      Zded<    ee      Zded<    ee	      Z
ded<    ee	      Zd	ed
<    eej                        Zded<   dddZddZddZy)_PrecompileHandlea&  Per-config completion handle returned by :meth:`Autotuner._precompile`.

    Empty / no-op when the subprocess pool was skipped (cache hit, disabled,
    only 1 config). Calling ``wait_for(i)`` on a missing index returns
    immediately as a no-op, so the bench loop can iterate uniformly.
    )default_factoryzDict[int, threading.Event]eventszDict[int, str]failures	List[Any]_workerszList[threading.Thread]_reader_threadszthreading.Lock_lockNc                d    | j                   j                  |      }||j                  |       yy)a  Block until ``config_idx``'s compile completes (or failed).

        No-op for indices that were never registered (e.g. the entire handle
        is empty because precompile was skipped). The bench loop relies on
        this to call ``wait_for`` unconditionally.
        Ntimeout)rs   r,   wait)rP   
config_idxr{   evts       r   wait_forz_PrecompileHandle.wait_for   s.     kkooj)?HHWH% r!   c                b    | j                   5  || j                  v cddd       S # 1 sw Y   yxY w)a/  True if the subprocess pool failed to compile this config.

        Use after :meth:`wait_for` returns. Failed configs need an in-process
        jit_cache warm before benchmarking to avoid contaminating the timing
        measurement with compile cost (see :meth:`Autotuner._bench_with_warm`).
        N)rx   rt   )rP   r}   s     r   	is_failedz_PrecompileHandle.is_failed   s,     ZZ 	/.	/ 	/ 	/s   %.c                   | j                   D ]9  }	 |j                         &|j                  |j                  j                          ; | j                   D ]  }	 |j                  d        | j                  D ]  }|j                  d        y# t        t
        f$ r Y w xY w# t        j                  $ r@ |j                          	 |j                  d       n# t        j                  $ r Y nw xY wY w xY w)zClose stdins, wait for workers and reader threads to exit.

        Idempotent. Safe to call even if ``__init__`` failed midway through
        spawning workers.
        Ng      @rz         ?)rv   pollstdincloseBrokenPipeErrorOSErrorr|   
subprocessTimeoutExpiredkillrw   rA   )rP   wts      r   shutdownz_PrecompileHandle.shutdown   s      	A668#(;GGMMO	  	As#	 %% 	 AFF3F	  $W- 
 ,, FF3F'!00 	sG   6BB&B#"B#&#C9
CC9C30C92C33C98C9N)r}   intr{   zOptional[float]returnNone)r}   r   r   bool)r   r   )rR   rS   rT   __doc__r   dictrs   __annotations__rt   listrv   rw   	threadingLockrx   r   r   r   r;   r!   r   rq   rq      si     */t)DF&D$T:Hn:5Hi5.3D.IO+I!)..AE>A	&/ r!   rq   c                
   t        |      D ]  \  }}	 t        |j                        }| j                  5  |N||d D ];  }| j                  j                  |d       | j                  |   j                          = 	 ddd        yt        |t              r |j                  d      r|| j                  |<   | j                  |   j                          ddd        y# t        t        t
        f$ r d}Y w xY w# 1 sw Y   xY w)a  Drain replies from one worker's stdout and signal per-config events.

    Replies arrive in dispatch order (length-prefixed pickled strings:
    ``"OK"`` or ``"ERR:..."``). On EOF (= worker crashed), every config
    this worker still had pending is marked failed and its event set so
    waiters don't deadlock.

    Runs in its own daemon thread so the bench loop can interleave waiting
    with kernel launches.
    Nzworker crashed during compilezERR:)	enumerate_recv_from_workerstdoutr   EOFErrorConnectionResetErrorrx   rt   
setdefaultrs   setr   r   
startswith)handleworkerconfig_indicesposr}   rremaining_idxs          r   _reader_thread_mainr      s     %^4 ,Z	!&--0A \\ 	,y &4CD%9 7MOO..}>]^MM-04467 	, 	, !S!all6&:./
+MM*%))+	, 	,,  +?@ 	A		, 	,s$   CAC9AC9C65C69D	c                    ddl }ddl}| j                  d      }t        |      dk  ry|j	                  d|      d   }|dk(  ry| j                  |      }t        |      |k  ry|j                  |      S )u   Read a length-prefixed pickled message. Returns None on EOF or partial body.

    Mirrors ``_compile_worker._recv`` so the parent and worker speak the
    same protocol. Kept private to this module rather than re-imported from
    the worker because the worker module isn't safe to import in the parent
    (it pushes ``_COMPILE_ONLY_DEPTH`` at module load).

    Returns ``None`` on both:

    * clean EOF (header shorter than 4 bytes — pipe write side closed before
      writing the header);
    * truncated body (header read OK, but the body read returns fewer bytes
      than the declared length — the worker was SIGKILL'd by its parent-death
      watchdog, or by OOM-killer, *between* writing the header and writing
      the body).

    Without the truncated-body check, ``pickle.loads`` raises ``UnpicklingError``
    on a short body. That exception would propagate out of the reader thread,
    leaving the per-config events unset and deadlocking every ``wait_for(i)``
    waiter in :meth:`Autotuner.__call__`'s ``benchmark()`` closure.
    r   N   <I)picklestructreadr/   unpackloads)streamr   r   headerlengthbodys         r   r   r      sr    , [[^F
6{Q]]4(+F{;;vD
4y6 <<r!   c                      e Zd Z	 	 	 	 d	 ddZed        Zd Zed        ZddZ	d Z
ej                  j                  d        Zd	 Zdd
Zy)	AutotunerNc                0    |st               g _        n| _        t        j                  |      }| _        i  _        t        |j                  j	                                _        |xs. t        j                  t        j                          dd      dk(   _        g  _        |t        |       _        t         j                        dkD  r fd}	|	 _        nd _        t         j                        dkD  r fd}
|
 _        nd _        d _        d _        d _        |rc|j+                  d j$                         _        |j+                  d	 j&                         _        |j+                  d
 j(                         _        | _        | _        y)a  
        :param prune_configs_by: a dict of functions that are used to prune configs, fields:
            'perf_model': performance model used to predicate running time with different configs, returns running time
            'top_k': number of configs to bench
            'prune_num_stages_by'(optional): a function used to prune num_stages. It takes configs:List[Config] as its input, and returns pruned configs.
        _CACHE_AUTOTUNINGN1r   c                r    j                   D ci c]  }|| |   j                          c}_        y c c}w r   )restore_valueclonerestore_copies)kwargsnamerP   s     r   	_pre_hookz%Autotuner.__init__.<locals>._pre_hook9  s1    NRN`N`&adtVD\-?-?-A'A&a#&as   4c                x    j                   D ]#  }| |   j                  j                  |          % i _        y r   )r   copy_r   )r   	exceptionr   rP   s      r   
_post_hookz&Autotuner.__init__.<locals>._post_hookB  s?     .. BD4L&&t':':4'@AB&(#r!   r   
perf_modeltop_kearly_config_prune)AutotuneConfigconfigsinspect	signaturekeysr?   r   
parameters	arg_namesr*   r7   r8   r9   cache_resultsr   r/   pre_hook	post_hookr   configs_top_kr   r,   fn	_do_bench)rP   r   rM   r   r   prune_configs_bydo_benchr   r   r   r   s   `          r   rK   zAutotuner.__init__  sr     *,-DL"DL%%b)		24
i22779:_RYY,*<*<*>)??P'QSWX\__ 	  $!%m!4Dt!!"Q&b &DM DMt!!"Q&)
 (DN!DN "&.22<QDO!1!5!5gt?Q?Q!RD&6&:&:$d&=&='D# !r!   c                   t        | t              rd }| j                  dk(  r| j                  j                  sk| j                         j                         j                         j                         j                         }t        j                  |      j                         }dt        | j                        t        d | j                         D              t!        | j                        |fS t        | t              rt        d | D              S t        | t"              r#| D cg c]  }t$        j'                  |       c}S t        | t(              r)t        t+        d | j-                         D                    S | S c c}w )Nr   r   c              3  ,   K   | ]  }|d v r|nd  yw)   r   r      Nr;   ).0ss     r   	<genexpr>z%Autotuner._key_arg.<locals>.<genexpr>b  s     F!1;aA-Fs   c              3  F   K   | ]  }t         j                  |        y wr   r   _key_arg)r   vs     r   r   z%Autotuner._key_arg.<locals>.<genexpr>g  s     >1++A.>s   !c              3  P   K   | ]  \  }}|t         j                  |      f   y wr   r   )r   kr   s      r   r   z%Autotuner._key_arg.<locals>.<genexpr>k  s$     Utq!I$6$6q$9 :Us   $&)r   r   ndimrc   is_floating_pointdetachcpu
contiguousnumpytobyteshashlibsha256	hexdigesttupleshapestrider   r   r   r   r   sorteditems)value	value_keyvalue_bytesr   s       r   r   zAutotuner._key_argX  s   eV$IzzQu{{'D'D#lln002==?EEGOOQ#NN;7AAC	ekk"Fu||~FFEKK   eU#>>>>eT"389aI&&q)99eT"Uu{{}UUVV :s   $E>c           
     h   |j                         D ci c]  \  }}|| j                  v s|| }}}| j                  D cg c]$  }||v st        | j	                  ||               & }}|j                         D ]  \  }}t        |t              s|j                  t        |j                               |j                  t        |j                         D 	cg c]
  }	|	dv r|	nd c}	             |j                  t        |j                                t        |      S c c}}w c c}w c c}	w )Nr   r   )r   r   r   r   r   r   r   appendr   r   rc   r   )
rP   all_argsr   r   _argsr   rM   rn   argr   s
             r   _make_cache_keyzAutotuner._make_cache_keyn  s    $,NN$4L&1aT^^8KALL;?99V4PUs4==t-.VVkkm 	+FAs#v&

3syy>*

3NAQ&[a 7NOP

3syy>*		+
 Sz MV  Os   D$D$	D*D*D/c                ~    | j                   &t        t        j                  j                  dd      S | j                   S )N      )warmuprep)r   r   tritontestingr   rP   s    r   r   zAutotuner.do_benchx  s/    >>!6>>221"EE~~r!   c          
     t   ddl m} |s
t               S t        t	        |      t        t        j                  dd                  }|dk  r
t               S t        j                         }	 t        |fi |d   j                         } | j                  |i | t        j                         |z
  dk  r
t               S t        j                  t        j                          dd      d	k(  }|rt        d
t	        |       d| d       ddlddlfd}	|D 
cg c]  }
t%        |
       }}
| j                  j&                  }| j                  j(                  }|j+                  d      }|j+                  d      }t%        t        |            }||t-        |j.                  |      |d<   t        j0                  j3                         }t5               }|||d<   t7        t        j8                               |d<   g }t;        |      D ]  }t=        j>                  t@        jB                  ddgt<        jD                  t<        jD                  |st<        jF                  nd|      }tI        |jJ                        }|dk7  r|jM                          |jO                  |        |s
t               S t               }||_(        |D cg c]  }g  }}tS        |      D ]s  \  }}|t	        |      z  }	  |	||   jT                  |||||j                         d       ||   jO                  |       t[        j\                         |j^                  |<   u tS        |      D ]\  \  }}||   st[        jd                  tf        d| ||||   fd      }|ji                          |jj                  jO                  |       ^ |S # t        $ r Y /w xY wc c}
w c c}w # tV        tX        f$ rQ t[        j\                         |j^                  |<   |j^                  |   ja                          d|jb                  |<   Y [w xY w)u  Pre-compile all configs in parallel subprocesses to populate .o cache.

        cute.compile() is not thread-safe (MLIR thread-local state) and fork after
        CUDA init causes segfaults. So we spawn persistent subprocess workers: each
        has its own CUDA context, creates FakeTensors matching the parent's tensor
        metadata, and compiles with COMPILE_ONLY=True. Workers stay alive to amortize
        import overhead across multiple configs. The parent then loads instantly from
        the .o cache during benchmarking.

        Returns a :class:`_PrecompileHandle` whose ``wait_for(i)`` blocks until
        config ``i``'s compile completes; the bench loop interleaves
        ``wait_for`` + benchmark to overlap the remaining compiles with GPU
        work. Workers are equipped with a parent-death watchdog
        (:func:`quack._compile_worker._install_parent_watchdog`) so an
        orphaned worker self-terminates within ~60 s instead of lingering on
        long-lived self-hosted CI runners.

        The returned handle is also valid (empty but functional) when
        precompilation is skipped — cache disabled, only 1 config, the
        first-config warm-cache shortcut hit. Callers always call
        ``wait_for`` + ``shutdown``; the no-op handle makes both fast.
        r   )CACHE_ENABLEDQUACK_COMPILE_WORKERS8r         ?_PRINT_AUTOTUNINGNr   zPre-compiling z configs with z workersc                    j                  |      }| j                  j                  dt        |                   | j                  |       | j	                          y )Nr   )dumpswritepackr/   flush)r   r   datar   r   s      r   _sendz$Autotuner._precompile.<locals>._send  sA    <<$DLLT3t956LLLLNr!   tensor_epilogue_fntensor_epilogue_sourcer#   QUACK_COMPILE_WORKER_PARENT_PIDz-mz#torch._vendor.quack._compile_worker)r   r   stderrenvREADY)	fn_modulefn_qualnameargsr   config_kwargszworker died before dispatchzquack-precompile-reader-T)rl   r   r  daemon)6r?   r  rq   minr/   r   r*   r7   rh   r   
all_kwargsr   	Exceptionr8   r9   printr   r   r   rS   rT   r,   r   rR   r+   copyr4   r   getpidri   r   Popensys
executablePIPEDEVNULLr   r   r   r   rv   r   r   r   r   r   Eventrs   r   rt   Threadr   startrw   ) rP   r   r  r   r  max_workerst_checkcurrentverboser  r   serialized_argsr  r  epilogue_fnepilogue_sourceworker_kwargs
worker_envr)   workersrn   preadyr   assignmentsiconfigwir   r   r   r   s                                  @@r   _precompilezAutotuner._precompile~  s   . 	)$&&#g,BII6Ms,S(TU!$&& ))+	6=WQZ%:%:%<=GDGGT%W% 99; 3&$&&))|11344EFMQTTN3w<.{m8TU	 CGG31#6GGGG&&	gg**jj!56 **%=>.tF|<&;+B2M$$o3M./ ZZ__&
13%1?J-.8;BIIK8H
45 {# 	A  'LM oo!18z))dA &ahh/ENN1	 $&& #$!4;'<q'<'<"7+ 	1IAvS\!BBK%%%.'2 /"/)/):):)<	" O""1%(0FMM!+	16 w' 
	-EBr?  */t4aR1	A GGI""))!,
	- W  		$ Hb (= $W-  $-??#4a a $$&%B"s1   +/N= O	O0*O=	O
	O
AP76P7c          	     R    t         j                  j                  t        j	                          dd       dk(  }|r%t        d j                  j                   d|        |j                         |j                  j                         z  }|rt        ddj                  |       d      t        |fi |j                         i  j                  t         dd       t         d	d        j                   d uxs  j"                  d u} j$                  d u xr d uxr	 d uxr | }|r	 t        j&                  t        j	                          d
d      }|dv rt)        t        j&                  t        j	                          dd            }	t)        t        j&                  t        j	                          dd            }
ddi|j                          fd}|dk(  rt+        |
      D ]	  } |         t,        j.                  j1                          t,        j.                  j3                         }t,        j.                  j5                  |      5   |        d d d        t,        j.                  j1                          t+        |
      D ]  }|j7                           t,        j.                  j1                          t,        j.                  j9                  d      }t,        j.                  j9                  d      }|j;                          t+        |	      D ]  }|j7                           |j;                          t,        j.                  j1                          |j=                  |      |	z  }nddlm } t+        |
      D ]	  } |         t,        j.                  j1                          |jC                  ||	|
dd      }tE        t-        jF                  t-        jH                  |            jK                               }dD cg c]  }| c}S tE        t        j&                  t        j	                          dd            }t)        t        j&                  t        j	                          dd            }tM         j                  |j                         ||d      S  fd"}	  j[                  |d#      S # 1 sw Y   gxY wc c}w # tN        $ rs}tQ        |tR        tT        f      r tW        |      s |r$t        dtY        |      j                   d |        tE        d!      tE        d!      tE        d!      gcY d }~S d }~ww xY w# tN        $ r:}|rt        d|        tE        d!      tE        d!      tE        d!      gcY d }~S d }~ww xY w)$Nr
  r   zAutotuning kernel z with config zConflicting meta-parameters: , z8. Make sure that you don't re-define auto-tuned symbols._l2_cold_arg_sets_l2_cold_kwarg_sets_AUTOTUNE_BENCH_MODE	l2_rotate)torch_profiletorch_cudagraph_AUTOTUNE_TORCH_ITERS100_AUTOTUNE_TORCH_WARMUP20r8  r   c                 v    d   t              z  } dxx   dz  cc<    j                  |    i |     y )Nr8  r   )r/   r   )idxextra_kwargsl2_cold_arg_setsl2_cold_kwarg_setsrP   states    r   rotating_callz'Autotuner._bench.<locals>.rotating_callB  sQ    #Cj3/?+@@c
a
-c205 +r!   rC  T)enable_timing)benchmarkerall)benchmark_itersmemory_warmup_itersreturn_modeis_vetted_benchmarking)r	  g?g?_AUTOTUNE_WARMUP_MS200_AUTOTUNE_TIMED_CALLS)rJ  warmup_target_msn_timed_calls	quantileszAutotuning failed with : infc                 (   j                   j                         	  j                  j                  i  j                  j	                  d        y y # t        $ r+} 	 j                  j	                  |         #  xY wd } ~ ww xY w)N)r   )r   r   __call__r  r   )r   r  r-  
full_nargsrP   s    r   kernel_callz%Autotuner._bench.<locals>.kernel_call  s    }}(j)    ~~)zT: *  ~~1zQ? Es)   A 	B'BBB		BB)r[  ).r*   r+   r,   r8   r9   r   r   rR   r   r   r   rA   r   r  nargsgetattrr   r   r   r7   r   ri   r%   r&   rg   	CUDAGraphgraphreplayr(  recordelapsed_time$torch._inductor.runtime.benchmarkingrP  benchmark_gpufloatmediantensoritemr   r  r   KeyboardInterrupt
SystemExitr    typer   )rP   r9  r  metar.  	conflicts	has_hooksuse_l2_cold
bench_mode	num_iterswarmup_itersrN  rn   re  r*  endmsrP  
samples_msrY  rZ  r   ra  r-  rJ  r`  rK  rL  rM  s   ` `                    @@@@@@r   _benchzAutotuner._bench  s   **..L$6$6$8#99J!KTRVYY&tww'7'7&8fXNO IIK&--"4"4"66	/		)0D/E FJ J 
 t3v0023.

.g.
 #4)<dC$T+@$GMM-Kt1K	NNd"  ,"$. 	 	 TBYY#))+,,@A;
 !EE #		\%7%7%9$::O"PRWX!I $'		\%7%7%9$::P"QSWX$L !!HE#)#4#4#6L  "%66!&|!4 ,A)O,

..0 %

 4 4 6"ZZ--e4 ,)O,

..0!&|!4 +A!LLN+

..0 %

 0 0t 0 D#jj..T.B!&y!1 +A!LLN+



..0"//4y@T!&|!4 ,A)O,

..0%0%>%>),50<(-37 &? &
 #5<<Z0H#I#N#N#PQ(781B88#(II!3!3!5 66IJER$  !$II!3!3!5 66KLeT! 3GG$&!'!2!2!4%5"/- 4	;&	>===HHe, ,8 9"  B
 a"3Z!@A;A>3DG4D4D3ERsKLeeElE%LAABL  	>/s34%L%,e==	>sj   8D-S$ %S-F+S$ 	S!S$ $BS$ ?U# SS$ $	U -A(UU U #	V&,/V!V&!V&c                   |s |        y | j                   }|D cg c]  }t        |       }}t        |      t        t        |            k(  sJ d       t        t        |      g|z   }t        j                  dj                  |      j                  d            j                         }t        t        |            }|j                  d d  d}	|j                  |	      }
|
rt        j                  j!                  t"        j%                          dd      st'        ||      D ci c]  \  }}||
 }}}t)        |
d      5 }t+        j,                  |      d	   }|D ci c]  \  }}||   | }}}t/        j0                  ||j                   
      | j2                  |<   || _        d| _        d d d        y  |        |j9                  t+        j:                  || j4                  j=                         D cg c]  \  }}t        |      |f c}}d      |	d       y c c}w c c}}w c c}}w # 1 sw Y   y xY wc c}}w )NzConfig strings must be unique-rW      z.autotune.json_FORCE_CACHE_UPDATEFr   configs_timingsr_   r   )rM   r  )binary)r   r   r/   r   VERSIONr   r   rA   encoder   rD   r`   rR   get_filer*   r+   r,   r8   r9   zipopenjsonloadbuiltinsr  r?   r  
bench_timeputr  r   )rP   
tuning_keyr   bench_fnr   cconfig_str_list	cache_keyr?   	file_namer@   r   
str2configcached_configstimingsr9  timings                    r   check_disk_cachezAutotuner.check_disk_cache  s   JWW+23a3q633?#s3+?'@@aBaa@c*o.@	NN388I#6#=#=g#FGQQS	 !34{{4C()8	~~i(

,*<*<*>)??R'SUZ[+.+HI41a!Q$IJIdC $N))N34EFLST.&&:f-v5TT)1g7;;)O

:&'.$"#$ 
		JJ%FJFZFZF`F`Fb(3B67Vg.(  	 	
' 4 J U$ (s/   H"(H'H3"H-2?H39H?-H33H<c           
     @    t        t         j                               _        d}t	         j
                        dkD  r j                  i  j                         j                  vr`d} j                        t        j                  j                   fd       } j                  r j                  |       n |         j                     }n j
                  d   }| _        t        j                   t"        j%                          dd       dk(  rF|sDt'        t"         d j(                  j*                   d	 j,                  d
d j                   d         j(                  j.                  i |j1                         }d  _        |S )NTr   Fc                     j                   di} t        j                         }t        j                  t        j                          dd       dk(  }t        j                  t        j                          dd       dk(  }j                  d uxs j                  d u}i }i }i }i }	 t                j                  .|s,	 t              }	t        |	      \  }
}|
_        |_        nd _        d _        t!              D ]c  \  }}t        j                         }| j#                  |       t        j                         |z
  ||<   | j%                  |      r||rt'        d| d| j(                  |    d       t        j                         }	 t+        fi |j-                         } j.                  i | t        j                         |z
  ||<   t        j                         } j2                  d|i||<   t        j                         |z
  ||<   |st'        d	| d
|j5                  |d      dd|j5                  |d      dd||   dd||   d   dd       f 	 d _        d _        | j7                          t        j                         }|r.|j9                         D ]  \  }}t'        d| d|d   dd        |r|rt'        dt;        |       dt=        |j?                               ddt=        |j?                               ddt=        |j?                               ddt        j                         |z
  dd       t=        d |j?                         D              }|rYt'        d| dt;        |       dj.                  j@                    dt        j                          d 
tB        jD                  !       ||z
  _#        tI        jJ                  ||j4                  "      jL                  <   |_'        y # t        t        f$ r d _        d _        Y 6w xY w# t0        $ r Y w xY w# d _        d _        | j7                          w xY w)#Nr   r
  r   _AUTOTUNE_WALL_DEBUGz[autotune] config z subprocess compile failed (z9); falling back to in-process compile before benchmarkingr9  z[autotune-wall] config z: wait=g        z.3fzs warm=zs bench=z	s median=r   z.6frz  [z] -> z [autotune-wall-summary] configs=z wait_total=zs warm_total=zs bench_total=zs wall_total=r   c              3  D   K   | ]  }|d    t        d      k(  sd  yw)r   r]  r   N)rk  )r   r   s     r   r   z8Autotuner.__call__.<locals>.benchmark.<locals>.<genexpr>I  s      "W!A$%PU,BV1"Ws     zquack autotune: /z configs failed for z; set z_PRINT_AUTOTUNING=1 for details)filer_   )(r;  rh   r*   r7   r8   r9   r   r   ro   r   r   r   r>  r?  r   r   r   r   r   r   rt   r   r  r   r  r|  r,   r   r   r/   sumvaluesrR   r$  r  r  r  r  r?   r  )r   bench_startr.  
wall_debugrt  r  
wait_times
warm_timesbench_wall_times	n_buffersarg_sets
kwarg_setsr8  r9  
wait_start
warm_startr-  bench_wall_start	bench_endtime_n_failedr  rM   r   pruned_configsrP   s                        r   	benchmarkz%Autotuner.__call__.<locals>.benchmark  s    .T--tV^VvVF"&))+K ii<+=+=+?*@@Q(RTXY]``G!#l.@.@.B-CCW+XZ^!_cf!fJ $T 9 WT^^SW=WI G!#J!#J')$I*#  >>1)@,A$,O	7N$(&)8" 4* :B 6;E 8 6:D27;D4)2>)B )"IAv
 *.J"OOA.,0IIK*,DJqM  &//2#*$)*<QC @;;A??1;M:N O>)?%& .2YY[
!).26.QV=N=N=P.QG$+DGGT$=W$=
 15		j0H
1/3yy{,.9dkk4.Y.YRX.YGFO26))+@P2P,Q/) %&=aS A,,6NN1c,B3+G H,,6NN1c,B3+G H--=a-@,E F..5foa.@-ER	%I!"G)"Z 26.370 ) $		I-4]]_ EMFE!AfXU58C."CDE!g''*7|n 5**-j.?.?.A*B3)G H**-j.?.?.A*B3)G H++./?/F/F/H+I#*N O**.))+*CC)HK  #"Wgnn.>"WWH.xj#g, H**.''*:*:);C5 A##/#5#5#7"88WY "%	 '0+&=DO&.ll7&LDJJsO+2D(i %1+#> @ :> 6;? 8	@F (1 !) %)!)& 26.370 )s]   -Q	 *P 0B&Q	 ,P9A!Q	 &AQ	 P62Q	 5P66Q	 9	QQ	 QQ	 	 Q)r   r
  r   z autotuning for function z finished after z.2fzs; best config selected: ;)r   r  r   rb  r/   r   r   r?   prune_configsr%   compilerdisabler   r  best_configr*   r7   r8   r9   r   r   rR   r  r_  r  )	rP   r  r   used_cached_resultr  r9  retrM   r  s	   ```    @@r   r_  zAutotuner.__call__  s   #dnnd34
!t||q &&'?$**'?'?@C$**$%*"!%!3!3F!;''z3 (z3x %%))#~yIKZZ_F\\!_F!II++-..?@$G3N&. 9$'':J:J9KK[??3''@AQAQ@RRSU dgg

 !

 

r!   c           
     *   | j                   }| j                  r( | j                  | j                   | j                  fi |}t        j                  t
        j                          d      }|r	 t        dt        |            }|d | }| j                  r| j                  }t        |t              r'|dk  r"t        t        | j                         |z        }nt        |t              st        d      t        |      |kD  r^|D ci c]1  }| | j                  di | j                  ||j!                         3 c}t#        j%                         fd      d | }|S # t        $ r# t        t
        j                          d|      w xY wc c}w )	N_AUTOTUNE_MAX_CONFIGSr   z._AUTOTUNE_MAX_CONFIGS must be an integer, got r   zPError while pruning configs, top_k must be either 1) a float <= 1.0 or 2) an intc                    |    S r   r;   )x
est_timings    r   <lambda>z)Autotuner.prune_configs.<locals>.<lambda>  s    TU r!   r_   r;   )r   r   rb  r*   r7   r8   r9   maxr   r   r   r   r   rk  r/   	TypeErrorr  r   r   )rP   r   r  max_configs_envmax_configsr   r9  r  s          @r   r  zAutotuner.prune_configsn  s   ""4T44T\\4::XQWXN))|'9'9';&<<Q$RS!!S%9: ,L[9N??&&E%'ESLC-56s+f  >"U* #1  ODOO **  !++- 
 "(
(9?V!WX^Y^!_5   #))+, -*-/ "s   /E! 6F!,F)NNNF)r   zOptional[Dict])r   rq   )r   r	   r   ru   )rR   rS   rT   rK   staticmethodr   r   r   r   r;  r|  r%   r  r  r  r_  r  r;   r!   r   r   r     s     +/?" )?"B  *  
QfU>n ^^$
 $
L]~"r!   r   c                  4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	r   z
    An object that represents a possible kernel configuration for the auto-tuner to try.

    :ivar kwargs: a dictionary of meta-parameters to pass to the kernel as keyword arguments.
    :type kwargs: dict[Str, Any]
    c                    || _         y r   r   )rP   r   s     r   rK   zAutotuneConfig.__init__  s	    r!   c                2    |j                  di       | _        y )Nr   )r,   r   )rP   rM  s     r   __setstate__zAutotuneConfig.__setstate__  s    ii"-r!   c                    | j                   S r   r  r  s    r   r  zAutotuneConfig.all_kwargs  s    {{r!   c                    g }| j                   j                         D ]  \  }}|j                  | d|         dj                  |      S )Nr\  r=  )r   r   r   rA   )rP   resr   r   s       r   __str__zAutotuneConfig.__str__  sK    KK%%' 	$DAqJJ!Bqc{#	$yy~r!   c                b    t        t        | j                         j                                     S r   )hashr   r  r   r  s    r   __hash__zAutotuneConfig.__hash__  s"    E$//+113455r!   c                    t        | j                         j                               }t        |j                         j                               }||k(  S r   )r   r  r   )rP   other
self_tupleother_tuples       r   __eq__zAutotuneConfig.__eq__  sC    4??,2245
E,,.4467[((r!   N)
rR   rS   rT   r   rK   r  r  r  r  r  r;   r!   r   r   r     s%    .6)r!   r   c                ^     dt         j                          d g  fd}|S )Nzw
    Decorator for auto-tuning a function function.

    .. highlight:: python

    If the environment variable :code:`a  _PRINT_AUTOTUNING` is set to
    :code:`"1"`, we will print a message to stdout after autotuning each
    kernel, including the time spent autotuning and the best configuration.

    :param configs: a list of :code:`AutotuneConfig` objects
    :type configs: list[AutotuneConfig]
    :param key: a list of argument names whose change in value will trigger the evaluation of all provided configs.
    :type key: list[str]
    :param prune_configs_by: a dict of functions that are used to prune configs, fields:
        'perf_model': performance model used to predicate running time with different configs, returns running time
        'top_k': number of configs to bench
        'early_config_prune'(optional): a function used to do early prune (eg, num_stages). It takes configs:List[Config] as its input, and returns pruned configs.
    :param restore_value: a list of argument names whose value will be restored after evaluating any configs.
    :type restore_value: list[str]
    :param do_bench: a benchmark function to measure the time of each run.
    :type do_bench: lambda fn, quantiles
    :param cache_results: whether to cache autotune timings to disk.  Defaults to False.
    "type cache_results: bool
    c           	     (    t        |       S )N)r   r   r   r   )r   )r   r   r   r   rM   r   r   s    r   	decoratorzautotune.<locals>.decorator  s%    '-'
 	
r!   )r8   r9   )r   rM   r   r   r   r   r  s   `````` r   autotuner    sA    	(
 )5(:(:(<'= >2 {	
 	
 r!   )r   r  r   r   )r   z
str | None)   )NNNNT)7
__future__r   r  r*   r   r$  r   rh   r   rY   r   r  dataclassesr   r   pathlibr   	functoolsr   r   typingr	   r
   r   r   r   bench.bench_utilsr   r   r   r%   r   r  rG   r   _compile_payloadr   r   r8   r  r    r4   r<   rB   runtimer?   rD   r`   ro   rq   r   r   r   r   r  r;   r!   r   <module>r     s    #  	  
       (  . 3 3      Q $
 .BEGv~~++<< GL
!V 9  9  9 x,<%Pz	 z	z) )B `d*r!   