o
    i eS5                     @   s   d 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Zddl	m
Z
 ejejejejejejeZejejZdZdZdd Zd	d
 Zdd Zdd Zdd Zdd Zdd Z				dddZ		dddZ				dddZdS )zJClasses and functions that help to inspect Python source w.r.t. TF graphs.    N)app)	profilingz.py)z.pycz.pyoc                 C   s   t jt j| S N)ospathnormpathabspath)	file_path r
   W/var/www/myenv/lib/python3.10/site-packages/tensorflow/python/debug/lib/source_utils.py_norm_abs_path'   s   r   c                 C      t j| \}}| tv S r   )r   r   splitextlowerUNCOMPILED_SOURCE_SUFFIXESr	   _	extensionr
   r
   r   %is_extension_uncompiled_python_source+      r   c                 C   r   r   )r   r   r   r   COMPILED_SOURCE_SUFFIXESr   r
   r
   r   #is_extension_compiled_python_source0   r   r   c                 C   s   | d |  d S )N:)rfind)	watch_keyr
   r
   r   !_convert_watch_key_to_tensor_name5   s   r   c                 C   sT   t | s
t| s
dS t| } | ts| to)| d o)tj	dtj	| vS )a  Guess whether a Python source file is a part of the tensorflow library.

  Special cases:
    1) Returns False for unit-test files in the library (*_test.py),
    2) Returns False for files under python/debug/examples.

  Args:
    py_file_path: full path of the Python source file in question.

  Returns:
    (`bool`) Whether the file is inferred to be a part of the tensorflow
      library.
  Fz_test.pyz tensorflow/python/debug/examples)
r   r   r   
startswith_TENSORFLOW_BASEDIR_ABSL_BASEDIRendswithr   r   r   )py_file_pathr
   r
   r   guess_is_tensorflow_py_library9   s   



r!   c                 C   s   t j| r(t| d}| d}W d   n1 sw   Y  |d}nt| }|du r6td|  t	t
t
t|d }||fS )a  Load the content of a Python source code file.

  This function covers the following case:
    1. source_file_path points to an existing Python (.py) file on the
       file system.
    2. source_file_path is a path within a .par file (i.e., a zip-compressed,
       self-contained Python executable).

  Args:
    source_file_path: Path to the Python source file to read.

  Returns:
    A length-2 tuple:
      - Lines of the source file, as a `list` of `str`s.
      - The width of the string needed to show the line number in the file.
        This is calculated based on the number of lines in the source file.

  Raises:
    IOError: if loading is unsuccessful.
  rbutf-8N
z?Source path neither exists nor can be loaded as a .par file: %s   )r   r   isfileopenreaddecodesplit_try_load_par_sourceIOErrorintnpceillog10len)source_file_pathfsource_textsource_linesline_num_widthr
   r
   r   load_sourceR   s   r7   c              	   C   s   | }	 t j|\}}|sdS t jt jj| |d}|drwt j|rwt|D}dd |	 D }||v rh|
|	 || }| d}|dW  d   W  d   S 1 scw   Y  W d   n1 srw   Y  q)	a[  Try loading the source code inside a .par file.

  A .par file is a zip-compressed, self-contained Python executable.
  It contains the content of individual Python source files that can
  be read only through extracting from the zip file.

  Args:
    source_file_path: The full path to the file inside the .par file. This
      path should include the path to the .par file itself, followed by the
      intra-par path, e.g.,
      "/tmp/my_executable.par/org-tensorflow/tensorflow/python/foo/bar.py".

  Returns:
    If successful, lines of the source file as a `list` of `str`s.
    Else, `None`.
  T)startz.parc                 S   s   g | ]}t j|qS r
   )r   r   r   ).0namer
   r
   r   
<listcomp>   s    z(_try_load_par_source.<locals>.<listcomp>r#   r$   N)r   r   r*   r   relpathr   r&   zipfileZipFilenamelistr'   indexr(   r)   )r2   prefix_pathbasenamesuffix_pathz
norm_nameszfr4   r
   r
   r   r+   w   s*   r+   Fc                 C   s   | j }|s	tdt|}i }| D ]S}t| |jD ]H\}	}
}}|dur+|
|k s3|dur4|
|kr4qt|	|kr;q|rM| |j}tt	t
t|}n|jg}|
|v r]||
 | n|||
< |re nqq|S )a  Annotate a Python source file with a list of ops created at each line.

  (The annotation doesn't change the source file itself.)

  Args:
    dump: (`DebugDumpDir`) A `DebugDumpDir` object of which the Python graph
      has been loaded.
    source_file_path: (`str`) Path to the source file being annotated.
    do_dumped_tensors: (`str`) Whether dumped Tensors, instead of ops are to be
      used to annotate the source file.
    file_stack_top: (`bool`) Whether only the top stack trace in the
      specified source file is to be annotated.
    min_line: (`None` or `int`) The 1-based line to start annotate the source
      file from (inclusive).
    max_line: (`None` or `int`) The 1-based line number to end the annotation
      at (exclusive).

  Returns:
    A `dict` mapping 1-based line number to a list of op name(s) created at
      that line, or tensor names if `do_dumped_tensors` is True.

  Raises:
    ValueError: If the dump object does not have a Python graph set.
  zUCannot perform source annotation due to a lack of set Python graph in the dump objectN)python_graph
ValueErrorr   get_operationsreversednode_tracebackr:   debug_watch_keyslistsetmapr   extend)dumpr2   do_dumped_tensorsfile_stack_topmin_linemax_linepy_graphline_to_op_namesopr	   line_numberr   
watch_keysitems_to_appendr
   r
   r   annotate_source   s4   r\   c                    s  | j }|s	tdtt}tt}i }i  |rt|nd}|r't|nd}t }	| D ]}
|r;||
j	s;q0| 
|
j	D ]v\}}}}t|}||	v s\|rV||r\tj|sb|	| qA|| |
j	 ||v ry|| |krx|||< n|||< |
jD ]}|j	}|| | q| |
j	}|D ]!}|d\}}}d||f }| vrt| |t|| |< qqAq0i }|D ]}t fdd|| D ||< qg }|D ]!}||t|t||i t||i ||d|| f qt|dd	 d
S )a@  Generate a list of source files with information regarding ops and tensors.

  Args:
    dump: (`DebugDumpDir`) A `DebugDumpDir` object of which the Python graph
      has been loaded.
    path_regex_allowlist: A regular-expression filter for source file path.
    node_name_regex_allowlist: A regular-expression filter for node names.

  Returns:
    A list of tuples regarding the Python source files involved in constructing
    the ops and tensors contained in `dump`. Each tuple is:
      (source_file_path, is_tf_library, num_nodes, num_tensors, num_dumps,
       first_line)

      is_tf_library: (`bool`) A guess of whether the file belongs to the
        TensorFlow Python library.
      num_nodes: How many nodes were created by lines of this source file.
        These include nodes with dumps and those without.
      num_tensors: How many Tensors were created by lines of this source file.
        These include Tensors with dumps and those without.
      num_dumps: How many debug Tensor dumps were from nodes (and Tensors)
        that were created by this source file.
      first_line: The first line number (1-based) that created any nodes or
        Tensors in this source file.

    The list is sorted by ascending order of source_file_path.

  Raises:
    ValueError: If the dump object does not have a Python graph set.
  zPCannot generate source list due to a lack of set Python graph in the dump objectNr   z%s:%sc                 3   s    | ]	}  |d V  qdS )r   N)get)r9   tensor_nametensor_name_to_num_dumpsr
   r   	<genexpr>/  s
    

z1list_source_files_against_dump.<locals>.<genexpr>r   c                 S   s   | d S )Nr   r
   )xr
   r
   r   <lambda>=  s    z0list_source_files_against_dump.<locals>.<lambda>)key)rG   rH   collectionsdefaultdictrN   recompilerI   matchr:   rK   r   r   r   r&   addoutputsrL   r*   r1   get_tensorsr-   sumappendr!   r]   sorted)rQ   path_regex_allowlistnode_name_regex_allowlistrV   path_to_node_namespath_to_tensor_namespath_to_first_line
path_regexnode_name_regexto_skip_file_pathsrX   r	   rY   r   output_tensorr^   rZ   r   	node_nameoutput_slotdebug_oppath_to_num_dumpsr   outputr
   r_   r   list_source_files_against_dump   s   "





r~   c           
      C   s   t |}|rt|nd}|rt|nd}i }| D ]J}	|	js qt |	j|kr(q|dur1|	j|k s:|dur;|	j|kr;q|rE||	jjsEq|rN||	jsNq|	j|vr\t	
|	||	j< q||	j |	 q|S )a  Annotate a Python source file with profiling information at each line.

  (The annotation doesn't change the source file itself.)

  Args:
    profile_data: (`list` of `ProfileDatum`) A list of `ProfileDatum`.
    source_file_path: (`str`) Path to the source file being annotated.
    node_name_filter: Regular expression to filter by node name.
    op_type_filter: Regular expression to filter by op type.
    min_line: (`None` or `int`) The 1-based line to start annotate the source
      file from (inclusive).
    max_line: (`None` or `int`) The 1-based line number to end the annotation
      at (exclusive).

  Returns:
    A `dict` mapping 1-based line number to a the namedtuple
      `profiling.LineOrFuncProfileSummary`.
  N)r   rg   rh   r	   rY   ri   node_exec_statsry   op_typer   AggregateProfilerj   )
profile_datar2   node_name_filterop_type_filterrT   rU   rv   op_type_regexline_to_profile_summaryprofile_datumr
   r
   r   annotate_source_against_profile@  s.   

r   )FFNN)NN)NNNN)__doc__re   r   rg   r=   abslr   numpyr.   tensorflow.python.debug.libr   r   dirnamer   r   __file__r   r   r   r   r   r   r   r   r!   r7   r+   r\   r~   r   r
   r
   r
   r   <module>   sH   %#
D
g