
    ΅iB                     2   S SK r S SKrS SKJrJr  S SKrS SKrS SKrS SKJ	r	  S SK
r
S SKJrJr  S SKrS SKr\R                   " \5      rS rS r\" 5       rS r\\\\" S5      \\4rSrS	 r " S
 S\5      r SSS.S jr!S r"S r#S r$S r%Sr&Sr'S r(S r)S r*g)    N)Any
NamedTuple)NamedTemporaryFile)_frames_fmt_block_extrac                    ^ ^^ SmSU4S jjn[         R                  " U5        SUU 4S jjm[        R                  R	                  T5        SU4S jjnU$ )NTc                  
   > Sm g )NF )enableds   Q/home/james-whalen/.local/lib/python3.13/site-packages/torch/utils/viz/_cycles.pydisable observe_garbage.<locals>.disable   s
         c                    >^^^ T(       d  g U S:X  a%  [         R                  " [         R                  5        g U S:X  a9  [        R                  " 5       mS/mUUUUU4S jn[        R
                  " U5        g g )NstartstopFc                  ,  > TS   (       d  STS'   O[         R                  " T5        Sm TS   S:w  a  [        R                  " 5         T" [        R                  5        [        R                  R                  5         [        R                  " S5        [        R                  R                  5       n[        R                  " 5         [        R                  R                  5       nX#:w  a  [        R                  SX#-
  5        SmTb  T" U 0 UD6$ g ! Smf = f)Nr   TF
generation   z.CUDA Memory changed during GC, %d bytes freed.)sys
setprofilegccollectgarbageclear	set_debugtorchcudamemory_allocatedloggerwarning)	argskwargsbeforeafterr   infoobserver
orig_traceself_returns	       r   
do_collect8observe_garbage.<locals>.gc_callback.<locals>.do_collect#   s    "1~%)KNNN:.#G'  -2JJL ,

((* Q!&!<!<!>

 %

 ; ; =!?"NN+[]c]kl"&)%t6v66 * #'s   CD D)r   r   DEBUG_SAVEALLr   
getprofiler   )phaser&   r*   r(   r)   r   r'   s    ` @@r   gc_callback$observe_garbage.<locals>.gc_callback   s[    GLL))*f_)J 'K7 7: NN:&C r   c                  D   > [         R                  R                  T 5        g N)r   	callbacksremove)r/   s   r   r4   observe_garbage.<locals>.removeE   s    
K(r   returnN)atexitregisterr   r3   append)r'   r   r4   r   r/   s   `  @@r   observe_garbager;      sD    G
 OOG'' ''R LL$)Mr   c                  F    SS jn [        U " 5       R                  S   5      $ )Nc                    ^  U 4S j$ )Nc                     > T $ r2   r
   xs   r   <lambda>+_get_cell_type.<locals>.f.<locals>.<lambda>Z   s    qr   r
   r?   s   `r   f_get_cell_type.<locals>.fY   s	    r   r   r2   )type__closure__)rC   s    r   _get_cell_typerG   X   s    "##r   c                 `  ^ ^^^ 0 mSU4S jjmSUU 4S jjmSU4S jjnSU4S jjnSUU 4S jjnSUU 4S jjnSUU 4S jjnSU4S jjnSUU 4S	 jjnSUUU 4S
 jjnSU4S jjn	[         U[        U[        U[        U[        U[
        R                  U[
        R                  U[        U[
        R                  U[        R                  U[
        R                  U	0n
[        T 5      R                   H  nX;   d  M
  X   " 5         M     T" SS5        [        T [        5      (       a  T" S5        T$ )a  
Return known information about references held by the given object.

Returns a mapping from referents to lists of descriptions.  Note that there
may be more than one edge leading to any particular referent; hence the
need for a list.  Descriptions are currently strings.

c                 Z   > TR                  [        U5      / 5      R                  U 5        g r2   )
setdefaultidr:   )nameobj
referencess     r   add_reference+annotated_references.<locals>.add_referencej   s"    bgr*11$7r   c                  d   > U  H)  n[        TU5      (       d  M  T" U[        TU5      5        M+     g r2   )hasattrgetattr)attrsattrrO   rM   s     r   	add_attrs'annotated_references.<locals>.add_attrsm   s+    DsD!!dGC$67 r   c                  8   >  T " S5        g ! [          a     g f = f)Ncell_contents)
ValueErrorrV   s   r   add_cell_references1annotated_references.<locals>.add_cell_referencesr   s$    	o& 	
 	s    
c                  &   > T " SSSSSSSSS	5	        g )
N__defaults__rF   __globals____code____name__
__module____doc____qualname____annotations____kwdefaults__r
   r[   s   r   add_function_references5annotated_references.<locals>.add_function_references|   s'    .!#"		$r   c                  H   > [        T5       H  u  pT" SU  S3U5        M     g )N[])	enumerate)positionitemrO   rM   s     r   add_sequence_references5annotated_references.<locals>.add_sequence_references   s%    'nNHAhZq/40 -r   c                  v   > TR                  5        H$  u  pT" SU 5        T" S[        U 5       S3U5        M&     g )Nkeyrj   rk   )itemsrepr)rr   valuerO   rM   s     r   add_dict_references1annotated_references.<locals>.add_dict_references   s6    ))+JC%%Ad3i[*E2 &r   c                  *   > T H  n T" SU 5        M     g )Nelementr
   )eltrO   rM   s    r   add_set_references0annotated_references.<locals>.add_set_references   s    C)S) r   c                     > T " SSS5        g )N__self____func__im_classr
   r[   s   r   add_bound_method_references9annotated_references.<locals>.add_bound_method_references   s    *j*5r   c                     > [        T5      [        R                  L a5  [        R                  " T5      n [        U 5      S:X  a  U S   nT" SU5        g g g )N   r   __callback__)rE   weakrefrefr   get_referentslen)	referentstargetrO   rM   s     r   add_weakref_references4annotated_references.<locals>.add_weakref_references   sN     9#((-I9~""1nf5 # $r   c                     > TR                   n T" SSSSSS5        [        U 5      [        L a0  TR                   R                  5        H  u  pT" SU 3U5        M     g g )Nf_backf_code
f_builtins	f_globalsf_tracef_localszlocal )r   rE   dictrs   )r   rL   localrV   rO   rM   s      r   add_frame_references2annotated_references.<locals>.add_frame_references   sZ    <<(HlKJW >T!"||113tfou5  4 "r   c                     > T " SSS5        g )N__objclass__rb   __doc__r
   r[   s   r    add_getset_descriptor_references>annotated_references.<locals>.add_getset_descriptor_references   s    .*i8r   __dict__	__class____mro__r6   )tuplelistr   set	frozensettypesFunctionType	FrameTypeCellType
MethodTyper   r   GetSetDescriptorTyperE   r   
isinstance)rM   r\   rg   ro   rv   r{   r   r   r   r   type_based_referencestype_rV   rO   rN   s   `           @@@r   annotated_referencesr   _   s    (*J88 8

$1 13 3
* *66 66 69 	&%!%3-%5+""$D c"")!(* # j+&#t)r       c                    S n[        U [        5      (       a  [        U 5      $ [        U 5      R                  S:X  a  SU R                   3$ [        U [
        R                  5      (       a   U R                  R                  nSU 3$ [        U [        5      (       a  SU" U 5       S3$ [        U [        5      (       a  SU" U 5       S	3$ [        U [        5      (       a  S
[        U 5       S3$ [        U [
        R                  5      (       a  SU R                   3$ [        U [        5      (       a  SU R                   3$ [        U [        R                   5      (       a  U " 5       nUc  gS[#        U5      S 3$ [        U [
        R$                  5      (       aK  U R&                  R(                  n[        U5      [*        :  a  SU[*        S-
  * S -   nSU SU R,                   3$ [/        U 5      (       a<  S[        U 5      R0                   S[        U 5      R                   SU R2                   S	3$ S[        U 5      R0                   S[        U 5      R                   3$ ! [         a    Sn GNf = f)zl
Return a string to be used for Graphviz nodes.

The string should be short but as informative as possible.
c                     SR                  S U S S  5       5      n[        U 5      S:  a  U S[        U 5      S-
   3nU$ )N,c              3      #    U  H:  n[        U[        5      (       a  [        U5      O[        U5      R                  v   M<     g 7fr2   )r   
BASE_TYPESrt   rE   rb   ).0r@   s     r   	<genexpr>=object_annotation.<locals>.format_sequence.<locals>.<genexpr>   s2     d\cWX:a#<#<Q$q'BRBRR\cs   AA   z, ...)joinr   )rM   bodys     r   format_sequence*object_annotation.<locals>.format_sequence   sH    xxd\_`bab\cdds8a<V5SA/Dr   functionz	function
z<anonymous>zinstancemethod
rj   rk   ()zdict[zmodule
ztype
Nzweakref (dead referent)zweakref to id 0xr@   z...   zframe
:zobject
.z ()r   r   rt   rE   rb   r   r   r   __qualname__AttributeErrorr   r   r   r   
ModuleTyper   r   rK   r   r   co_filenameFRAME_FILENAME_LIMITf_linenois_cuda_tensorrc   shape)rM   r   	func_namereferentfilenames        r   object_annotationr      s3    #z""CyCyZ'CLL>**	C))	*	*	&11I ")--	C		?3'(**	C		?3'(**	C		s3xj""	C))	*	*#,,((	C		~&&	C	%	%5,%bl1%566	C	)	)::))x=//x*>*B(C(DEEH
!CLL>22			$s)../qc1C1C0DBsyykQRSS$s)../qc1C1C0DEE7  	&%I	&s   ,I I,+I,c                   T    \ rS rSr% \\S'   \S-  \S'   \\S'   \\\\	4      \S'   Sr
g)Nodei  labelNcontextroot
referrentsr
   )rb   rc   r   __firstlineno__strre   boolr   r   int__static_attributes__r
   r   r   r   r     s)    J4Z
JU38_%%r   r   )r   filterc          
      6   Uc
  [        5       nUc  [        nU  Vs/ s H&  n[        U[        R                  5      (       a  M$  UPM(     n nU  Vs/ s H&  n[        [        U5      U" U5      U" U5      / 5      PM(     nnU  Vs/ s H  n/ PM     nn[        U 5       VVs0 s H  u  pc[        U5      U_M     nnnU  H  nU[        U5         nXH   n	[        U5      n
[        R                  " U5       Ho  n[        U5      nUR                  U5      nUc  M$  U
R                  US/5      nX]   R                  U5        U H  nU	R                  R                  X45        M!     Mq     M     [        U5       VVs/ s H  u  nnUR                  (       d  M  UPM     nnn[!        5       nU(       aH  UR#                  5       nUU;   a  M  UR%                  U5        UU   nUR'                  U5        U(       a  MH  0 n/ n[        U5       H-  u  nnUU;   d  M  [)        U5      UU'   UR                  U5        M/     U H?  nUR                   VVs/ s H  u  nnUU;   d  M  UUU   4PM     snnUR                  S S & MA     U$ s  snf s  snf s  snf s  snnf s  snnf s  snnf )N?)cuda_allocation_contextr   r   r   
ProxyTypesr   r   rl   rK   r   r   r   getr:   r   r   r   popaddextendr   )objectsr   r   rM   nodesnode_referrersi
id_to_nodefidxrC   rN   	referrentridtidxlabelsr   n	to_searchto_keepidx	referrersid_to_filtered_idfiltereds                          r   create_graphr   	  sg   )+~%QgsZW=O=O-PsgGQT[\T[ST#C('#,sRHT[E\5<&=WcrWN&=+4W+=>+="S'1*+=J>"S'"K)#.
))#.IY-C>>#&D|^^C#/F ''-##UM2   /	   )/:/tq!166/I:eG
mmo'>C"3'	# ) )+H% 1<#&'8#9a OOA ! /0||8/;|s!%66 ;E#4S#9:/;8Q  OM R\&=> ; 8s5   #I:I:-I?JJ	5JJJJc                 .    [         R                  " U 5      $ r2   )jsondumps)r   s    r   escaper   7  s    ::a=r   c                     [        U [        R                  5      =(       aI    U R                  R                  S:H  =(       a)    [        U [        R
                  R                  5      (       + $ )Nr   )r   r   TensordevicerE   _subclasses
FakeTensor)rM   s    r   r   r   ;  sH    3% 	:

6!	:sE--8899r   c                     ^ [         R                  R                  R                  5       n 0 mU S    H6  nUS   nUS    H%  nUS   S:X  a  [	        U5      u  pEUTU'   X#S   -  nM'     M8     U4S jnU$ )Nsegmentsaddressblocksstateactive_allocatedsizec                    > [        U 5      (       aK  U R                  5       R                  5       nTR                  U5      nUb  SR	                  [        USS95      $ g )N
T)full_filename)r   untyped_storagedata_ptrr   r   r   )rM   addrframesaddr_to_frames      r   object_context/cuda_allocation_context.<locals>.object_contextM  sT    #&&(113D"&&t,F!yyV4!HIIr   )r   r   memory	_snapshotr   )snapshotsegr
  blkr  
_real_sizer  r  s          @r   r   r   B  s    zz  **,HM
#9~x=C7|11%1#%6"&,d#KD	 ! $ r   c                    / SQn[        U 5       HE  u  p#UR                  U S[        UR                  5       SUR                  (       a  SOS S35        MG     [        U 5       H=  u  p$UR
                   H(  u  pVUR                  U SU S[        U5       S	35        M*     M?     UR                  S
5        SR                  U5      $ )N)zdigraph GraphName {znode [shape=rect];zrankdir=LR;z [label=z, color=redblackz];z -> z
 [label = rk   z}
r  )rl   r:   r   r   r   r   r   )r   linesr   r   rC   r   js          r   to_dotr  V  s    HE% s(6!''?"38QVVEQX;YY[\] ! % HELLA3d1#Zua@A % ! 
LL99Ur   a  
<!DOCTYPE html>
<html>
<head>
  <style>
    body {
      margin: 0;
      padding: 0;
      overflow: hidden;
    }

    #container {
      display: flex;
      flex-direction: column;
      height: 100vh;
    }

    #main {
      flex: 2;
      height: 60vh;
      overflow: clip;
    }

    #preContainer {
      flex: 1;
      height: 40vh;
      overflow: auto;
    }

    pre {
      margin: 0;
      padding: 10px;
    }
  </style>
</head>
<body>
  <div id="container">
    <div id="main">
    </div>
    <div id="preContainer">
      <pre id="stacktrace">Mouse over tensor objects to see where they were allocated.</pre>
    </div>
  </div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/viz.js/1.8.0/viz-lite.js'></script>
<script>
let dot = $DOT
let image = Viz(dot, {format: 'svg', 'totalMemory': 1024*1024*1024});
let main = document.getElementById('main')
main.innerHTML = image
let svg = main.firstElementChild
// Panning and zooming logic
let isPanning = false;
let startX, startY;
let viewBox = { x: 0, y: 0, width: parseFloat(svg.getAttribute('width')), height: parseFloat(svg.getAttribute('height')) };
svg.removeAttribute('width');
svg.removeAttribute('height');
function updateViewBox() {
    svg.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`);
}
updateViewBox()
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
svg.addEventListener('mousedown', function(e) {
    isPanning = true;
    startX = e.clientX;
    startY = e.clientY;
});
svg.addEventListener('mousemove', function(e) {
    if (!isPanning) return;
    const dx = (e.clientX - startX) * (viewBox.width / svg.clientWidth);
    const dy = (e.clientY - startY) * (viewBox.height / svg.clientHeight);
    viewBox.x -= dx;
    viewBox.y -= dy;
    startX = e.clientX;
    startY = e.clientY;
    updateViewBox();
});
svg.addEventListener('mouseup', function() {
    isPanning = false;
});
svg.addEventListener('mouseleave', function() {
    isPanning = false;
});
svg.addEventListener('wheel', function(e) {
    e.preventDefault();
    const zoomFactor = 0.1;
    const zoomAmount = e.deltaY > 0 ? 1 + zoomFactor : 1 - zoomFactor;
    // Calculate mouse position relative to the SVG
    const rect = svg.getBoundingClientRect();
    const mouseX = e.clientX - rect.left;
    const mouseY = e.clientY - rect.top;
    const mouseXRel = mouseX / svg.clientWidth;
    const mouseYRel = mouseY / svg.clientHeight;
    // Adjust viewBox to zoom around the mouse position
    const newWidth = viewBox.width * zoomAmount;
    const newHeight = viewBox.height * zoomAmount;
    viewBox.x += (viewBox.width - newWidth) * mouseXRel;
    viewBox.y += (viewBox.height - newHeight) * mouseYRel;
    viewBox.width = newWidth;
    viewBox.height = newHeight;
    updateViewBox();
});
$LISTENERS
</script>
</body>
</html>
z
document.getElementById('node{id}').addEventListener('mouseover', function(event) {{
  document.getElementById("stacktrace").textContent = {stack}
}})
c           	         / n[        U 5       Hg  u  p#UR                  c  M  [        R                  [	        US-   5      [        UR                   SUR                   35      S9nUR                  U5        Mi     [        U 5      n[        R                  S[        U5      5      R                  SSR                  U5      5      $ )Nr   z:
)rK   stackz$DOTz
$LISTENERSr  )rl   r   _listener_templateformatr   r   r   r:   r  	_templatereplacert   r   )r   	listenersr   r   sdots         r   to_htmlr$    s    I% 99%%QU6QWWISQRQZQZP[B\;]%^ ! -CVT#Y/77diiPYFZ[[r   c                 x   ^  [         R                  R                  R                  SS9  SU 4S jjn[	        U5      $ )Ni )max_entriesc                    > U (       aH  [        S U  5       5      (       d  [        R                  S5        g T" [        [	        U 5      5      5        g g )Nc              3   8   #    U  H  n[        U5      v   M     g 7fr2   )r   )r   rM   s     r   r   :observe_tensor_cycles.<locals>.observer.<locals>.<genexpr>  s     >gs~c**gs   z No CUDA Tensors found in garbage)anyr    r&   r$  r   )r   callbacks    r   r'   'observe_tensor_cycles.<locals>.observer  s>    >g>>>>?W\'234	 r   r6   )r   r   r  _record_memory_historyr;   )r+  r'   s   ` r   observe_tensor_cyclesr.    s0    	JJ,,,@5 8$$r   c                  L    [         R                  S5        SS jn [        U 5      $ )af  
Install a warning that reports whenever a cycle that is holding CUDA memory is observed.

The warning produces an .html file that visualizes the cycle,
and links it to the stack frame that allocated the CUDA tensor.

Reference cycles are freed by the cycle collector rather than being cleaned up
when the objects in the cycle first become unreachable. If a cycle points to a tensor,
the CUDA memory for that tensor will not be freed until garbage collection runs.
Accumulation of CUDA allocations can lead to out of memory errors (OOMs), as well as
non-deterministic allocation behavior which is harder to debug.
z2Watching Python reference cycles for CUDA Tensors.c                     [        SSS9 nUR                  U 5        [        R                  SUR                  5        S S S 5        g ! , (       d  f       g = f)Nwz.html)suffixzDReference cycle includes a CUDA Tensor see visualization of cycle %s)r   writer    r!   rL   )htmlrC   s     r   write_and_log)warn_tensor_cycles.<locals>.write_and_log  s;    G4GGDMNNacdcicij 544s   2A
Ar6   )r    r&   r.  )r5  s    r   warn_tensor_cyclesr7    s$     KKDEk !//r   )+r   r   typingr   r   r   r   r   tempfiler   r   torch.cuda._memory_vizr   r   r8   logging	getLoggerrb   r    r;   rG   r   r   r   floatcomplexrE   r   bytesr   r   r   r   r   r   r   r   r  r  r  r$  r.  r7  r
   r   r   <module>r@     s    	 
 "    '  <  			8	$8R$
 gZ 5'4:sE:
 0Fh&: & &*$ ,\(	i	T 
	\	%0r   