
    1Vhr                        d 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
 ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ  ej<                         ZdZ dZ!dZ"dZ#dZ$dZ%dZ&dddddZ'dZ( G d d      Z) G d d      Z*d Z+d  Z,d! Z-d" Z.d# Z/d$ Z0d% Z1 G d& d'ejd                        Z3d( Z4y))zThe Embedding Projector plugin.    N)wrappers)json_format)text_format)context)plugin_asset_util)Respond)tf)base_plugin)metadata)ProjectorConfig)
tb_logging   z/infoz/tensorz	/metadataz/runsz
/bookmarksz/sprite_imagez	image/bmpz	image/gifz
image/jpegz	image/png)bmpgifjpegpngapplication/octet-streamc                   "    e Zd ZdZd Zd Zd Zy)LRUCachez;LRU cache.

    Used for storing the last used tensor.
    c                 d    |dk  rt        d      || _        t        j                         | _        y )Nr   zThe cache size must be >=1)
ValueError_sizecollectionsOrderedDict_dict)selfsizes     ^/home/dcms/DCMS/lib/python3.12/site-packages/tensorboard/plugins/projector/projector_plugin.py__init__zLRUCache.__init__D   s,    !89::
 ,,.
    c                 z    	 | j                   j                  |      }|| j                   |<   |S # t        $ r Y y w xY wN)r   popKeyErrorr   keyvalues      r   getzLRUCache.getJ   s=    	JJNN3'E#DJJsOL 		s   +. 	::c                    |t        d      	 | j                  j                  |       || j                  |<   y # t        $ rA t	        | j                        | j
                  k\  r| j                  j                  d       Y Yw xY w)Nzvalue must be != NoneF)last)r   r   r#   r$   lenr   popitemr%   s      r   setzLRUCache.setR   sr    =455	/JJNN3  

3  	/4::$**,

""".	/s   : ABBN)__name__
__module____qualname____doc__r   r(   r-    r    r   r   r   >   s    
/ r    r   c                       e Zd ZdZd Zd Zy)EmbeddingMetadatazMetadata container for an embedding.

    The metadata holds different columns with values used for
    visualization (color by, label by) in the "Embeddings" tab in
    TensorBoard.
    c                 .    || _         g | _        i | _        y)zConstructs a metadata for an embedding of the specified size.

        Args:
          num_points: Number of points in the embedding.
        N)
num_pointscolumn_namesname_to_values)r   r6   s     r   r   zEmbeddingMetadata.__init__e   s     % r    c                    t        |t              rt        |d   t              rt        d      t        |t        j                        r'|j
                  dk7  rt        d|j
                  z        t        |      | j                  k7  r#t        d| j                  t        |      fz        || j                  v rt        d|z        | j                  j                  |       || j                  |<   y)a  Adds a named column of metadata values.

        Args:
          column_name: Name of the column.
          column_values: 1D array/list/iterable holding the column values. Must be
              of length `num_points`. The i-th value corresponds to the i-th point.

        Raises:
          ValueError: If `column_values` is not 1D array, or of length `num_points`,
              or the `name` is already used.
        r   zS"column_values" must be a flat list, but we detected that its first entry is a listr   z6"column_values" should be of rank 1, but is of rank %dz;"column_values" should be of length %d, but is of length %dz$The column name "%s" is already usedN)
isinstancelistr   npndarrayndimr+   r6   r8   r7   append)r   column_namecolumn_valuess      r   
add_columnzEmbeddingMetadata.add_columno   s     mT*z!d0
 1 
 mRZZ0]5G5G15L$&3&8&89  }0#M0BCD  $---6D  	  -+8K(r    N)r.   r/   r0   r1   r   rB   r2   r    r   r4   r4   ]   s    !%9r    r4   c                 X   t         j                  j                  j                  | d      5 }g }|D ]M  }|j	                  d      }|s|j                  t        t        t        |j                  d                         O 	 d d d        t        j                  d      S # 1 sw Y    xY w)Nr
	float32dtype)r	   iogfileGFilerstripr?   r;   mapfloatsplitr<   array)fpathftensorlines       r   _read_tensor_tsv_filerV      s    			5#	& B! 	BD;;t$Dd3udjj.>#?@A	BB 88F),,B Bs   B 9B  B)c                     t        |      dk7  rt        dj                  |            t        j                  | d      }|j                  |      S )N   zTensor must be 2D, got shape {}rG   rH   )r+   r   formatr<   fromfilereshape)rR   shaperT   s      r   _read_tensor_binary_filer]      sC    
5zQ:AA%HII[[i0F>>%  r    c                    t         j                  j                  t        j                  z   t         j                  j                  z   }|| v ryt         j
                  t         j                  j                  z   t         j
                  z   }t         j                  j                  t         j                  j                  | |            S | S r"   )ospathsepr   PLUGINS_DIRpardirabspathjoin)
assets_dirsub_pathtwo_parents_ups      r   _assets_dir_to_logdirri      sv    ww{{X111BGGKK?H:RWW[[0299<wwrww||JGHHr    c                    |D ]  \  }}|| vrt               }t        j                  j                  |t        j
                        }t        j                  j                  j                  |      r_t        j                  j                  j                  |d      5 }|j                         }ddd       t        j                  |       n| |   }t        |      }t        |      }	|	s|j                   |	k7  s y y# 1 sw Y   RxY w)zEReturns true if the latest checkpoint has changed in any of the runs.rD   NTF)r   r_   r`   re   r   PROJECTOR_FILENAMEr	   rJ   rK   existsrL   readr   Parseri   _find_latest_checkpointmodel_checkpoint_path)
configsrun_path_pairsrun_namerf   configconfig_fpathrS   file_contentlogdir	ckpt_paths
             r   _latest_checkpoints_changedry      s     . *7"$&F77<<
H4O4OPLuu{{!!,/UU[[&&|S9 ,Q#$668L,!!,7X&F 'z2+F3	''94#$ , ,s   C::D	c                     | j                   j                  |      }|sy	 t        |      }|dk  r
t               |S # t        $ r Y yw xY w)zParses and asserts a positive (>0) integer query parameter.

    Args:
      request: The Werkzeug Request object
      param_name: Name of the parameter.

    Returns:
      Param, or None, or -1 if parameter is not a positive integer.
    Nr   )argsr(   intr   )request
param_nameparams      r   _parse_positive_int_paramr      sR     LLZ(EE
A:, s   < 	AAc                     t         j                  j                  |       } t         j                  j                  |       s=t         j                  j	                  t         j                  j                  |      |       S | S r"   )r_   r`   
expanduserisabsre   dirname)rR   ru   s     r   _rel_to_abs_asset_pathr      sM    GGu%E77==ww||BGGOOL95AALr    c                  (    t         j                  dk7  S )zCReturn true if we're not using the fake TF API stub implementation.stub)r	   __version__r2   r    r   	_using_tfr      s    >>V##r    c                      e Zd ZdZej
                  Zd Zd Zd Z	d Z
d Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zej,                  j.                  d        Zej,                  j.                  d        Zej,                  j.                  d        Zej,                  j.                  d        Zej,                  j.                  d        Zej,                  j.                  d        Zej,                  j.                  d        Zy)ProjectorPluginzEmbedding projector.c                     |j                   | _         |j                  | _        i | _        d| _        i | _        d| _        t        t              | _        d| _	        d| _
        y)zInstantiates ProjectorPlugin via TensorBoard core.

        Args:
          context: A base_plugin.TBContext instance.
        NF)data_providerrw   readers
_run_paths_configsconfig_fpathsr   _TENSOR_CACHE_CAPACITYtensor_cache
_is_active!_thread_for_determining_is_active)r   r   s     r   r   zProjectorPlugin.__init__   s[     %22nn!$%;<
   26.r    c                 >   d}t         | j                  t        | j                  t        | j
                  t        | j                  t        | j                  t        | j                  dt        j                  | j                  t        j                   j#                  |d            dt        j                  | j                  t        j                   j#                  |d            dt        j                  | j                  t        j                   j#                  |d            i	S )Ntf_projector_plugin	/index.jszindex.jsz/projector_binary.htmlzprojector_binary.htmlz/projector_binary.jszprojector_binary.js)
RUNS_ROUTE_serve_runsCONFIG_ROUTE_serve_configTENSOR_ROUTE_serve_tensorMETADATA_ROUTE_serve_metadataBOOKMARKS_ROUTE_serve_bookmarksSPRITE_IMAGE_ROUTE_serve_sprite_image	functoolspartial_serve_filer_   r`   re   )r   asset_prefixs     r   get_plugin_appszProjectorPlugin.get_plugin_apps  s    ,(($,,$,,D00T22 8 8**  \:6 %i&7&7  \+BC' #I$5$5  \+@A%
 	
r    c                     | j                   r| j                  sy| j                  ry| j                  r| j                  S t	        j
                  | j                  d      }|| _        |j                          y)a	  Determines whether this plugin is active.

        This plugin is only active if any run has an embedding, and only
        when running against a local log directory.

        Returns:
          Whether any run has embedding data to show in the projector.
        FTProjectorPluginIsActiveThread)targetname)r   rw   r   r   	threadingThread_determine_is_activestart)r   
new_threads     r   	is_activezProjectorPlugin.is_active  sn     !!?? 11 ??"
 %%,,0

 2<.r    c                 0    t        j                  dd      S )Nr   T)es_module_pathdisable_reload)r
   FrontendMetadatar   s    r   frontend_metadataz!ProjectorPlugin.frontend_metadata>  s    ++&
 	
r    c                 X    | j                          | j                  rd| _        d| _        y)zDetermines whether the plugin is active.

        This method is run in a separate thread so that the plugin can
        offer an immediate response to whether it is active and
        determine whether it should be active in a separate thread.
        TN)_update_configsr   r   r   r   s    r   r   z$ProjectorPlugin._determine_is_activeD  s&     	=="DO15.r    c                    | j                   r| j                  r|t        j                         }| j                   j	                  |d      D ci c]A  }|j
                  t        j                  j                  | j                  |j
                        C }}ni }|| j                  k7  }|| _	        t        | j                  j                               }| j                  |       d| j                  vr|j                  d| j                  f       |st        | j                  |      r6i | _        | j#                  |      \  | _        | _        | j'                          yyc c}w )z.Updates `self._configs` and `self._run_paths`. )experiment_id.N)r   rw   r   RequestContext	list_runsrs   r_   r`   re   r   r;   items _append_plugin_asset_directoriesr?   ry   r   r   _read_latest_config_filesr   %_augment_configs_with_checkpoint_info)r   ctxrun	run_pathsrun_paths_changedrr   s         r   r   zProjectorPlugin._update_configsP  s-   $++((*C  --7727N bggll4;;EEI 
 I%8#doo3356--n=
 doo%!!3"45 ;MM>!
 DL040N0N1-DM4- 668!
#s   AEc           	         | j                   j                         D ]5  \  }}|j                  D ]  }|j                  j	                  d      r|j                  d d |_        |j
                  s?t        |j
                  | j                  |         }| j                  j                  ||j                  f      }|4	 t        |      }| j                  j                  ||j                  f|       |j                  r|j                  j                  t!        |      t!        |d         g        | j#                  |      }|s(d }|j                  rC|j                  d   j                  s*|j                  d   }|j                  j%                  |       |j'                         }|j                         D ]  \  }	}
t!        |
      dk7  rd|	v r| j)                  |	|      }|sE|j                  j+                         }|	|_        |r"|j,                  |_        |j.                  |_        |j                  r|j                  j                  |
        8 g }| j                   j                         D ]#  \  }}|j                  r|j1                  |       % |D ]  }| j                   |= | j                  |=  y # t        $ r t        ||j                        }Y w xY w)N:0r   rX   z.OPTIMIZER_SLOT)r   r   
embeddingstensor_nameendswithtensor_pathr   r   r   r(   rV   UnicodeDecodeErrorr]   tensor_shaper-   extendr+   _get_reader_for_runremoveget_variable_to_shape_map_get_embeddingaddmetadata_pathbookmarks_pathr?   )r   r   rt   	embeddingrR   rT   readerspecial_embeddingvar_mapr   r   runs_to_removes               r   r   z5ProjectorPlugin._augment_configs_with_checkpoint_infoo  s   ==..0 6	@KC#.. 	((11$7,5,A,A#2,FI)((2!--t/A/A#/FE "..22C9N9N3OPF~%:5%AF
 ))-- )"7"78& %11!..55 [#fQi.9+2 --c2F $  ):):1)=)I)I$*$5$5a$8!!!(():;668G-4]]_ @)\|$) %3 //VD	  & 1 1 5 5 7I,7I)(-;; "/ .<< "0 !--**11,?'@G6	@r ==..0 	+KC$$%%c*	+ " 	(Cc"""3'	(_  2 %= %y'='=&Fs   :J88KKc                    i }i }|D ]  \  }}t               }t        j                  j                  |t        j
                        }t        j                  j                  j                  |      rYt        j                  j                  j                  |d      5 }|j                         }	ddd       t        j                  	|       d}
|j                  D ]L  }|j                  s|j                   s.t        j                  j#                  |j                        |_        d}
 n |j$                  s%t'        |      }t)        |      }|s|
sF|r||_        |j$                  rbt+               rXt        j                  j                  j-                  |j$                  dz         s"t.        j1                  d|j$                         |||<   |||<    ||fS # 1 sw Y   -xY w)zLReads and returns the projector config files in every run
        directory.rD   NFT*zCheckpoint file "%s" not found)r   r_   r`   re   r   rk   r	   rJ   rK   rl   rL   rm   r   rn   r   r   r   basenamerp   ri   ro   r   globloggerwarning)r   rr   rq   r   rs   rf   rt   ru   rS   rv   has_tensor_filesr   rw   rx   s                 r   r   z)ProjectorPlugin._read_latest_config_files  s    $2 &	3 Hj$&F77<<
H4O4OPLuu{{!!,/UU[[&&|S9 ,Q#$668L,!!,7$#.. 	(($00020@0@%111	- (,$ //.z:3F;	 )93<F0 ,,K(()E)E)KL400  &GH&2M(#M&	3N %%G, ,s   GG	c                 ^   || j                   v r| j                   |   S | j                  |   }d }|j                  r4t               r*	 t        j
                  j                  |j                        }|| j                   |<   |S # t        $ r# t        j                  d|j                         Y <w xY w)NzFailed reading "%s")
r   r   rp   r   r	   trainload_checkpoint	Exceptionr   r   )r   r   rt   r   s       r   r   z#ProjectorPlugin._get_reader_for_run  s    $,,<<$$s#''IK11&2N2NO
 #S  )6+G+Gs   )B   )B,+B,c                 D    | j                  ||      }|r|j                  S y r"   )r   r   r   r   rt   embedding_infos       r   _get_metadata_file_for_tensorz-ProjectorPlugin._get_metadata_file_for_tensor  s&    ,,[&A!///r    c                 D    | j                  ||      }|r|j                  S y r"   )r   r   r   s       r   _get_bookmarks_file_for_tensorz.ProjectorPlugin._get_bookmarks_file_for_tensor  s&    ,,[&A!000r    c                     d|vr|dz   S |S )N:r   r2   )r   r   s     r   _canonical_tensor_namez&ProjectorPlugin._canonical_tensor_name  s    k!%%r    c                     |j                   sy |j                   D ]3  }| j                  |j                        | j                  |      k(  s1|c S  y r"   )r   r   r   )r   r   rt   infos       r   r   zProjectorPlugin._get_embedding  sY      %% 	D**  ,,[9: 		
 r    c                    g }t         j                  }|D ]  \  }}t        j                  ||      }t         j                  |vr/t
        j                  j                  | j                  |   t         j                  |      }|t
        j                  j                  |      f}|j                  |        |j                  |       y r"   )r   PLUGIN_ASSETS_NAMEr   
ListAssetsrk   r_   r`   re   r   rb   rd   r?   r   )	r   rr   extraplugin_assets_namer   rw   assetsrf   assets_path_pairs	            r   r   z0ProjectorPlugin._append_plugin_asset_directories  s    %88) 	+KC&11&:LMF**&8$h&:&:<NJ !$RWW__Z%@ALL)*	+ 	e$r    c                 0   t         j                  j                  t         j                  j                  t              |      }t        |d      5 }t        j                  |      d   }t        ||j                         |      cddd       S # 1 sw Y   yxY w)zReturns a resource file.rbr   )content_typeN)
r_   r`   re   r   __file__open	mimetypes
guess_typer   rm   )r   	file_pathr~   res_path	read_filemimetypes         r   r   zProjectorPlugin._serve_file  sr     77<< 99E(D! 	MY ++I6q9H7INN$48L	M 	M 	Ms   4BBc                 ~    | j                          t        |t        | j                  j	                               d      S )z,Returns a list of runs that have embeddings.application/json)r   r   r;   r   keys)r   r~   s     r   r   zProjectorPlugin._serve_runs!  s2     	wT]]%7%7%9 :<NOOr    c                    |j                   j                  d      }|t        |ddd      S | j                          | j                  j                  |      }|t        |d|z  dd      S t        |t        j                  |      d      S )Nr   !query parameter "run" is required
text/plain  Unknown run: "%s"r
  )r|   r(   r   r   r   r   MessageToJson)r   r~   r   rt   s       r   r   zProjectorPlugin._serve_config'  s    llu%;<lC  	""3'>,s2L#  [..v68J
 	
r    c                    |j                   j                  d      }|t        |ddd      S |j                   j                  d      }|t        |ddd      S t        |d      }|dk(  rt        |d	dd      S | j	                          | j
                  j                  |      }|t        |d
|z  dd      S | j                  ||      }|s"t        |d|d| j                  |   ddd      S t        || j                  |         }t        j                  j                  j                  |      r)t        j                  j                  j                  |      rt        |d|z  dd      S d}t        j                  j                  j                  |d      5 }g }	|D ]@  }
|	j                  |
       t!        |	      dk(  r	d|	d   v rd}|s.t!        |	      ||z   k\  s@ n d d d        t        |dj#                  	      d      S # 1 sw Y   %xY w)Nr   r  r  r  r   "query parameter "name" is requirednum_rowsr{   ,query parameter num_rows must be integer > 0r  z#No metadata file found for tensor "" in the config file "" "%s" not found, or is not a filer   rD   r   rF   r   )r|   r(   r   r   r   r   r   r   r   r	   rJ   rK   rl   isdirrL   r?   r+   re   )r   r~   r   r   r  rt   rR   num_header_rowsrS   linesrU   s              r   r   zProjectorPlugin._serve_metadata8  s   llu%;<lC  ||'<=|S  -WjAr>>	  	""3'>,s2L#  224@++C02  'ud.@.@.EFuu{{!!%(BEEKK,=,=e,D2U:	  UU[[uc* 		aE  T"u:?tuQx'7&'OE
h.H H			 w==		 		s   2G>G>G>>Hc                    |j                   j                  d      }|t        |ddd      S |j                   j                  d      }|t        |ddd      S t        |d      }|dk(  rt        |d	dd      S | j	                          | j
                  j                  |      }|t        |d
|z  dd      S | j                  j                  ||f      }|| j                  ||      }|rv|j                  rjt        |j                  | j                  |         }t        j                  j                  j                  |      st        |d|z  dd      S 	 t        |      }nU| j'                  |      }	|	r|	j)                  |      st        |d|d|j*                  ddd      S 	 |	j-                  |      }| j                  j5                  ||f|       |r|d | }|j6                  dk7  r|j9                  dd      }|j;                         }t        ||d      S # t         $ r t#        ||j$                        }Y w xY w# t        j.                  j0                  $ r!}
t        |t3        |
      dd      cY d }
~
S d }
~
ww xY w)Nr   r  r  r  r   r  r  r{   r  r  zTensor file "%s" does not existzTensor "z" not found in checkpoint dir "r  rG   F)rI   copyr   )r|   r(   r   r   r   r   r   r   r   r   r   r	   rJ   rK   rl   rV   r   r]   r   r   
has_tensorrp   
get_tensorerrorsInvalidArgumentErrorstrr-   rI   astypetobytes)r   r~   r   r   r  rt   rT   r   rR   r   e
data_bytess               r   r   zProjectorPlugin._serve_tensort  s   llu%;<lC  ||'<=|S  -WjAr>>	  	""3'>,s2L#  ""&&T{3>++D&9IY22.))4+=+=c+B uu{{))%0"9EA$	 259F 11#6V%6%6t%<"!=!=?$ G#..t4F !!3+v6IX&F<<9$]]]?F^^%
w
,FGG5 * 5y55F  yy55 G"7CFL#FFGs0   H !H; H87H8;I9I4.I94I9c                 J   |j                   j                  d      }|st        |ddd      S |j                   j                  d      }|t        |ddd      S | j                          | j                  j                  |      }|t        |d|z  dd      S | j                  ||      }|s"t        |d|d	| j                  |   d
dd      S t        || j                  |         }t        j                  j                  j                  |      r)t        j                  j                  j                  |      rt        |d|z  dd      S d }t        j                  j                  j                  |d      5 }|j                         }d d d        t        ||d      S # 1 sw Y   xY w)Nr   r  r  r  r   r  r  z$No bookmarks file found for tensor "r  r  r  r   r
  )r|   r(   r   r   r   r   r   r   r	   rJ   rK   rl   r  rL   rm   )r   r~   r   r   rt   rR   bookmarks_jsonrS   s           r   r   z ProjectorPlugin._serve_bookmarks  s   llu%<lC  ||'<=|S  	""3'>,s2L#  33D&A++C02  'ud.@.@.EFuu{{!!%(BEEKK,=,=e,D2U:	  UU[[ud+ 	&qVVXN	&w0BCC	& 	&s   3FF"c                 .   |j                   j                  d      }|st        |ddd      S |j                   j                  d      }|t        |ddd      S | j                          | j                  j                  |      }|t        |d|z  dd      S | j                  ||      }|r|j                  j                  s"t        |d|d	| j                  |   d
dd      S t        j                  j                  |j                  j                        }t        || j                  |         }t        j                  j                  j!                  |      r)t        j                  j                  j#                  |      rt        |d|z  dd      S t        j                  j                  j%                  |d      }|j'                         }|j)                          t+        j,                  d |      }	t.        j                  |	t0              }
t        |||
      S )Nr   r  r  r  r   r  r  z'No sprite image file found for tensor "r  r  z#"%s" does not exist or is directoryr   )r|   r(   r   r   r   r   sprite
image_pathr   r_   r`   r   r   r	   rJ   rK   rl   r  rL   rm   closeimghdrwhat_IMGHDR_TO_MIMETYPE_DEFAULT_IMAGE_MIMETYPE)r   r~   r   r   rt   r   rR   rS   encoded_image_string
image_type	mime_types              r   r   z#ProjectorPlugin._serve_sprite_image  s   llu%<lC  ||'<=|S  	""3'>,s2L#  ,,T6:^%:%:%E%E++C02  "">#8#8#C#CD&ud.@.@.EFuu{{!!%(BEEKK,=,=e,D5=	  EEKKeT* vvx		[[';<
'++J8OP	w 4i@@r    N)r.   r/   r0   r1   r   PLUGIN_NAMEplugin_namer   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Requestapplicationr   r   r   r   r   r   r   r2   r    r   r   r      sI   &&K6.
. D

69>@(D,&\ % !!M "M !!P "P
 !!
 "
  !!9> "9>v !!HH "HHT !!(D "(DT !!,A ",Ar    r   c                 <   t               sy 	 t        j                  j                  |       }|sKt        j                  j                  t        j
                  j                  | t        j                              }|S # t        j                  j                  $ r Y y w xY wr"   )
r   r	   r   latest_checkpointr_   r`   re   rc   r   NotFoundError)dir_pathrx   s     r   ro   ro     st    ;	HH..x8	22Xryy1I 99"" s   A-A; ;BB)5r1   r   r   r-  r  r_   r   numpyr<   werkzeugr   google.protobufr   r   tensorboardr   $tensorboard.backend.event_processingr   tensorboard.backend.http_utilr   tensorboard.compatr	   tensorboard.pluginsr
   tensorboard.plugins.projectorr   2tensorboard.plugins.projector.projector_config_pb2r   tensorboard.utilr   
get_loggerr   r   r   r   r   r   r   r   r/  r0  r   r4   rV   r]   ri   ry   r   r   r   TBPluginr   ro   r2   r    r   <module>rI     s    &     	    ' '  B 1 ! + 2 N '				    
$  	  5    >79 79t-!.,$
nAk** nAbr    