B
    )²ô`Få  ã               @   s  d Z ddlmZ ddlmZ ddlm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 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"dd„Z!G dd„ de"ƒZ#d#d d!„Z$dS )$z¾CLI Backend for the Analyzer Part of the Debugger.

The analyzer performs post hoc analysis of dumped intermediate tensors and
graph structure information from debugged Session.run() calls.
é    )Úabsolute_import)Údivision)Úprint_functionN)Úxrange)Ú
cli_config)Ú
cli_shared)Úcommand_parser)Údebugger_cli_common)Ú	evaluator)Ú
ui_factory)Údebug_graphs)Úsource_utilsz|  z   z|- z(%d) z[%s] z(Ctrl) z...Ú	timestampZ	dump_sizeÚop_typeÚtensor_nameTc             C   s  t  ¡ }| t jdd|d¡ |rŒ| t jdd| |d¡ | t jdd| |d¡ | t jdd| |d¡ | t jd	d
| |d¡ nX| t jdddd¡ | t jdddd¡ | t jdddd¡ | t jd	ddd¡ | t  dd¡¡ | t  dd¡¡ || jt j< dS )a2  Generate main menu for the screen output from a command.

  Args:
    output: (debugger_cli_common.RichTextLines) the output object to modify.
    node_name: (str or None) name of the node involved (if any). If None,
      the menu items node_info, list_inputs and list_outputs will be
      automatically disabled, overriding the values of arguments
      enable_node_info, enable_list_inputs and enable_list_outputs.
    enable_list_tensors: (bool) whether the list_tensor menu item will be
      enabled.
    enable_node_info: (bool) whether the node_info item will be enabled.
    enable_print_tensor: (bool) whether the print_tensor item will be enabled.
    enable_list_inputs: (bool) whether the item list_inputs will be enabled.
    enable_list_outputs: (bool) whether the item list_outputs will be enabled.
  Úlist_tensors)ZenabledÚ	node_infoznode_info -a -d -t %sÚprint_tensorzprint_tensor %sÚlist_inputszlist_inputs -c -r %sÚlist_outputszlist_outputs -c -r %sNFZrun_infoÚhelp)r	   ZMenuÚappendÚMenuItemÚannotationsZMAIN_MENU_KEY)ÚoutputÚ	node_nameÚenable_list_tensorsÚenable_node_infoÚenable_print_tensorÚenable_list_inputsÚenable_list_outputsÚmenu© r"   úW/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow/python/debug/cli/analyzer_cli.pyÚ_add_main_menu=   sN    


r$   c               @   s  e Zd ZdZdZdZdZdZdZdd„ Z	d	d
„ Z
dd„ Zdd„ Zdd„ Zd<dd„Zdd„ Zdd„ Zdd„ Zd=dd„Zdd„ Zdd„ Zd>d d!„Zd?d"d#„Zd@d$d%„ZdAd&d'„ZdBd)d*„ZdCd+d,„Zd-d.„ ZdDd/d0„ZdEd2d3„ZdFd4d5„Zd6d7„ Zd8d9„ Z d:d;„ Z!dS )GÚDebugAnalyzerz.Analyzer for debug data from dump directories.zt (ms)zSize (B)zOp typezTensor name)Z_SendZ_RecvZ	_HostSendZ	_HostRecvZ_Retvalc             C   s6   || _ t | j ¡| _i | _|  |¡ | d| j¡ dS )z²DebugAnalyzer constructor.

    Args:
      debug_dump: A DebugDumpDir object.
      config: A `cli_config.CLIConfig` object that carries user-facing
        configurations.
    Úgraph_recursion_depthN)Ú_debug_dumpr
   ZExpressionEvaluatorÚ
_evaluatorÚ_tensor_filtersÚ_build_argument_parsersZset_callback)ÚselfÚ
debug_dumpÚconfigr"   r"   r#   Ú__init__Ž   s    	
zDebugAnalyzer.__init__c             C   s  i | _ tjdtjd}|jdddtddd |jd	d
dtddd |jdddtddd |jdddtddd |jdddttdtttt	f d |jdddddd || j d< tjd tjd}|jd!td"d# |jd$d%d&dd'd |jd(d)d*dd+d |jdd,d-dd.d || j d/< tjd0tjd}|jd!td1d# |jd2d3dd4d5 |jd(d6d7t
| d8¡d9d |jdd:d;dd<d |jdd=dd>d5 || j d?< tjd@tjd}|jd!td1d# |jd2d3dd4d5 |jd(d6d7t
| d8¡dAd |jdd:d;ddBd |jdd=ddCd5 || j dD< t dE¡| j dF< tjdGtjd}|jdHtdId# |jddJdKddLd |jdMdNt
dOdPdQ |jdRdSt
dTdUdQ || j dV< tjdWtjd}|jdXdYtddZdQ |jddtdd[dQ || j d\< tjd]tjd}|jd^td_d# |jd$d`daddbd |jdcddddedf || j dg< dhS )iz¿Build argument parsers for DebugAnalayzer.

    Args:
      config: A `cli_config.CLIConfig` object.

    Returns:
      A dict mapping command handler name to `ArgumentParser` instance.
    z!List dumped intermediate tensors.)ÚdescriptionÚusagez-fz--tensor_filterÚtensor_filterÚ z:List only Tensors passing the filter of the specified name)ÚdestÚtypeÚdefaultr   z-fennz--filter_exclude_node_namesÚfilter_exclude_node_namesz‹When applying the tensor filter, exclude node with names matching the regular expression. Applicable only if --tensor_filter or -f is used.z-nz--node_name_filterÚnode_name_filterzfilter node name by regex.z-tz--op_type_filterÚop_type_filterzfilter op type by regex.z-sz	--sort_byÚsort_byz2the field to sort the data by: (%s | %s | %s | %s)z-rz	--reverseÚreverseÚ
store_truez+sort the data in reverse (descending) order)r3   Úactionr   r   zShow information about a node.r   zdName of the node or an associated tensor, e.g., hidden1/Wx_plus_b/MatMul, hidden1/Wx_plus_b/MatMul:0)r4   r   z-az--attributesÚ
attributesz!Also list attributes of the node.z-dz--dumpsÚdumpsz(Also list dumps available from the node.z--tracebackÚ	tracebackzKAlso include the traceback of the node's creation (if available in Python).r   zShow inputs to a node.znName of the node or an output tensor from the node, e.g., hidden1/Wx_plus_b/MatMul, hidden1/Wx_plus_b/MatMul:0z-cz	--controlzInclude control inputs.)r<   r   z--depthÚdepthr&   z<Maximum depth of recursion used when showing the input tree.z--recursiveÚ	recursivez:Show inputs to the node recursively, i.e., the input tree.z	--op_typezShow op types of input nodes.r   z6Show the nodes that receive the outputs of given node.z=Maximum depth of recursion used when showing the output tree.z?Show recipients of the node recursively, i.e., the output tree.z!Show op types of recipient nodes.r   z#Print the value of a dumped tensor.r   z}Print a Python source file with overlaid debug information, including the nodes (ops) or Tensors created at the source lines.Úsource_file_pathzPath to the source file.z	--tensorsÚtensorsz0Label lines with dumped Tensors, instead of ops.z-mz--max_elements_per_lineé
   zDMaximum number of elements (ops or Tensors) to show per source line.)r4   r5   r   z-bz--line_beginé   z0Print source beginning at line number (1-based.)Úprint_sourcezVList source files responsible for constructing nodes and tensors present in the run().z-pz--path_filterz(Regular expression filter for file path.z(Regular expression filter for node name.Úlist_sourcea  Evaluate an arbitrary expression. Can use tensor values
        from the current debug dump. The debug tensor names should be enclosed
        in pairs of backticks. Expressions with spaces should be enclosed in
        a pair of double quotes or a pair of single quotes. By default, numpy
        is imported as np and can be used in the expressions. E.g.,
          1) eval np.argmax(`Softmax:0`),
          2) eval 'np.sum(`Softmax:0`, axis=1)',
          3) eval "np.matmul((`output/Identity:0`/`Softmax:0`).T, `Softmax:0`)".
        Ú
expressionao  Expression to be evaluated.
        1) in the simplest case, use <node_name>:<output_slot>, e.g.,
          hidden_0/MatMul:0.

        2) if the default debug op "DebugIdentity" is to be overridden, use
          <node_name>:<output_slot>:<debug_op>, e.g.,
          hidden_0/MatMul:0:DebugNumericSummary.

        3) if the tensor of the same name exists on more than one device, use
          <device_name>:<node_name>:<output_slot>[:<debug_op>], e.g.,
          /job:worker/replica:0/task:0/gpu:0:hidden_0/MatMul:0
          /job:worker/replica:0/task:2/cpu:0:hidden_0/MatMul:0:DebugNanCount.

        4) if the tensor is executed multiple times in a given `Session.run`
        call, specify the execution index with a 0-based integer enclose in a
        pair of brackets at the end, e.g.,
          RNN/tanh:0[0]
          /job:worker/replica:0/task:0/gpu:0:RNN/tanh:0[0].z--allÚ	print_allz\Print the tensor in its entirety, i.e., do not use ellipses (may be slow for large results).z-wz--write_pathzLPath of the numpy file to write the evaluation result to, using numpy.save())r5   r   ÚevalN)Ú_arg_parsersÚargparseÚArgumentParserÚSUPPRESSÚadd_argumentÚstrÚSORT_TENSORS_BY_TIMESTAMPÚSORT_TENSORS_BY_DUMP_SIZEÚSORT_TENSORS_BY_OP_TYPEÚSORT_TENSORS_BY_TENSOR_NAMEÚintÚgetr   Zget_print_tensor_argparser)r+   r-   Zapr"   r"   r#   r*   £   s~   










	
z%DebugAnalyzer._build_argument_parsersc             C   s<   t |tƒstdƒ‚|stdƒ‚t|ƒs.tdƒ‚|| j|< dS )a@  Add a tensor filter.

    A tensor filter is a named callable of the signature:
      filter_callable(dump_datum, tensor),

    wherein dump_datum is an instance of debug_data.DebugTensorDatum carrying
    metadata about the dumped tensor, including tensor name, timestamps, etc.
    tensor is the value of the dumped tensor as an numpy.ndarray object.
    The return value of the function is a bool.
    This is the same signature as the input argument to
    debug_data.DebugDumpDir.find().

    Args:
      filter_name: (str) name of the filter. Cannot be empty.
      filter_callable: (callable) a filter function of the signature described
        as above.

    Raises:
      ValueError: If filter_name is an empty str.
      TypeError: If filter_name is not a str.
                 Or if filter_callable is not callable.
    z=Input argument filter_name is expected to be str, but is not.z+Input argument filter_name cannot be empty.zFInput argument filter_callable is expected to be callable, but is not.N)Ú
isinstancerP   Ú	TypeErrorÚ
ValueErrorÚcallabler)   )r+   Úfilter_nameÚfilter_callabler"   r"   r#   Úadd_tensor_filter¤  s    
zDebugAnalyzer.add_tensor_filterc             C   s    || j krtd| ƒ‚| j | S )a  Retrieve filter function by name.

    Args:
      filter_name: Name of the filter set during add_tensor_filter() call.

    Returns:
      The callable associated with the filter name.

    Raises:
      ValueError: If there is no tensor filter of the specified filter name.
    z$There is no tensor filter named "%s")r)   rY   )r+   r[   r"   r"   r#   Úget_tensor_filterÌ  s    
zDebugAnalyzer.get_tensor_filterc             C   s   | j |  ¡ S )N)rK   Úformat_help)r+   Zhandler_namer"   r"   r#   Úget_helpÞ  s    zDebugAnalyzer.get_helpNc          
   C   s   |}| j d  |¡}g }g }|jr@t |j¡}| d|j ¡ nd}|jrht |j¡}| d|j ¡ nd}t |¡}| d¡ |j	rÞy|  
|j	¡}	W n2 tk
rÈ   t d|j	 ¡}t|ddd |S X | jj|	|jd	}
n|jrìtd
ƒ‚| jj}
|  |
¡\}}}|  |
|j|j¡}
| |  ||||¡¡ d}x*|
D ] }|rV| |j¡sVq8|rz| j |j¡}| |¡szq8|j| jj d }t |j¡}d|j|j f }| j |j¡}d| }|d|t!|ƒ  7 }||7 }|d|| t!|ƒ  7 }||7 }|d|| | t!|ƒ  7 }||7 }|j|t!|ƒt!|ƒ t!|ƒt "dd| ¡fgd |d7 }q8W |j	r~| #d||j	f g¡ n| #d| g¡ t|ddd |S )aä  Command handler for list_tensors.

    List tensors dumped during debugged Session.run() call.

    Args:
      args: Command-line arguments, excluding the command prefix, as a list of
        str.
      screen_info: Optional dict input containing screen information such as
        cols.

    Returns:
      Output text lines as a RichTextLines object.

    Raises:
      ValueError: If `--filter_exclude_node_names` is used without `-f` or
        `--tensor_filter` being used.
    r   zOp type regex filter: "%s"NzNode name regex filter: "%s"r2   z%There is no tensor filter named "%s".F)r   r   )Zexclude_node_namesz_The flag --filter_exclude_node_names is valid only when the flag -f or --tensor_filter is used.r   g     @@z%s:%dz[%.3f]ú zpt %s)Úfont_attr_segsrE   z(%d dumped tensor(s) passing filter "%s":z%d dumped tensor(s):)$rK   Ú
parse_argsr8   ÚreÚcompiler   r7   r	   ÚRichTextLinesr1   r^   rY   r   Úerrorr$   r'   Úfindr6   Údumped_tensor_dataÚ"_measure_tensor_list_column_widthsÚ_sort_dump_data_byr9   r:   ÚextendÚ_tensor_list_column_headsÚmatchr   Únode_op_typer   Út0Úbytes_to_readable_strÚdump_size_bytesÚoutput_slotÚlenr   Úprepend)r+   ÚargsÚscreen_infoÚ_Úparsedr   Zfilter_strsZop_type_regexZnode_name_regexr\   Zdata_to_showÚmax_timestamp_widthÚmax_dump_size_widthÚmax_op_type_widthÚ
dump_countÚdumpr   Úrel_timeÚdump_size_strZdumped_tensor_nameÚliner"   r"   r#   r   á  sˆ    



zDebugAnalyzer.list_tensorsc       	      C   sê   d}|r.|d j | jj d }td| ƒd }t|t| jƒd ƒ}d}x4|D ],}t |j¡}t|ƒd |krLt|ƒd }qLW t|t| j	ƒd ƒ}d}x6|D ].}| j 
|j¡}t|ƒd |kršt|ƒd }qšW t|t| jƒd ƒ}|||fS )a  Determine the maximum widths of the timestamp and op-type column.

    This method assumes that data is sorted in the default order, i.e.,
    by ascending timestamps.

    Args:
      data: (list of DebugTensorDaum) the data based on which the maximum
        column widths will be determined.

    Returns:
      (int) maximum width of the timestamp column. 0 if data is empty.
      (int) maximum width of the dump size column. 0 if data is empty.
      (int) maximum width of the op type column. 0 if data is empty.
    r   éÿÿÿÿg     @@z[%.3f] rE   )r   r'   rp   rt   ÚmaxÚ_TIMESTAMP_COLUMN_HEADr   rq   rr   Ú_DUMP_SIZE_COLUMN_HEADro   r   Ú_OP_TYPE_COLUMN_HEAD)	r+   Údatarz   Zmax_rel_time_msr{   r~   r€   r|   r   r"   r"   r#   rj   X  s*    

z0DebugAnalyzer._measure_tensor_list_column_widthsc                s|   |t krt||dd„ dS |tkr4t||dd„ dS |tkrRt||‡ fdd„dS |tkrlt||dd„ dS td| ƒ‚dS )	ao  Sort a list of DebugTensorDatum in specified order.

    Args:
      data: (list of DebugTensorDatum) the data to be sorted.
      sort_by: The field to sort data by.
      reverse: (bool) Whether to use reversed (descending) order.

    Returns:
      (list of DebugTensorDatum) in sorted order.

    Raises:
      ValueError: given an invalid value of sort_by.
    c             S   s   | j S )N)r   )Úxr"   r"   r#   Ú<lambda>”  ó    z2DebugAnalyzer._sort_dump_data_by.<locals>.<lambda>)r:   Úkeyc             S   s   | j S )N)rr   )rˆ   r"   r"   r#   r‰   –  rŠ   c                s   ˆ j  | j¡S )N)r'   ro   r   )rˆ   )r+   r"   r#   r‰   ›  rŠ   c             S   s   d| j | jf S )Nz%s:%d)r   rs   )rˆ   r"   r"   r#   r‰      rŠ   z&Unsupported key to sort tensors by: %sN)rQ   ÚsortedrR   rS   rT   rY   )r+   r‡   r9   r:   r"   )r+   r#   rk     s$    z DebugAnalyzer._sort_dump_data_byc       
      C   s   d}|j r|d|j  7 }|jr,|d|j 7 }|jr@|d|j 7 }dg i}| j}d|tf }|jtkrr|jsr|d7 }|d  dt|ƒt	 
d|¡d	gf¡ |d
|t|ƒ  7 }t|ƒ}	|| j7 }d|tf }|jtkrà|jsà|d7 }|d  |	t|ƒt	 
d|¡d	gf¡ |d
|| t|ƒ  7 }t|ƒ}	|| j7 }d|tf }|jtkrV|jsV|d7 }|d  |	t|ƒt	 
d|¡d	gf¡ |d
|| | t|ƒ  7 }t|ƒ}	|| j7 }d|tf }|jtkrÐ|jsÐ|d7 }|d  |	t|ƒt	 
d|¡d	gf¡ |d
|| | t|ƒ  7 }t	j|g|dS )a™  Generate a line containing the column heads of the tensor list.

    Args:
      parsed: Parsed arguments (by argparse) of the list_tensors command.
      max_timestamp_width: (int) maximum width of the timestamp column.
      max_dump_size_width: (int) maximum width of the dump size column.
      max_op_type_width: (int) maximum width of the op type column.

    Returns:
      A RichTextLines object.
    r   z -f %sz -t %sz -n %sr   z%s -s %sz -rNÚboldra   r2   )rb   )r1   r8   r7   r„   rQ   r9   r:   r   rt   r	   r   r…   rR   r†   rS   Ú_TENSOR_NAME_COLUMN_HEADrT   rf   )
r+   ry   rz   r{   r|   Úbase_commandÚ	attr_segsÚrowÚcommandZprev_lenr"   r"   r#   rm   ¤  sT    


z'DebugAnalyzer._tensor_list_column_headsc             C   sž  |}| j d  |¡}t |j¡\}}| j |¡sVt d| ¡}t	|dddddd |S d| g}dt
|d	 ƒt
|ƒ t
|d	 ƒd
fgi}	| d¡ | d| j |¡ ¡ | d| j |¡ ¡ tj||	d}|  | j |¡¡}
|  | jj|dd¡}| |  d|
|¡¡ |  | j |¡¡}|  | jj|dd¡}| |  d||¡¡ |jr\| |  |¡¡ |jrt| |  |¡¡ |jrŒ| |  |¡¡ t	||dd |S )aQ  Command handler for node_info.

    Query information about a given node.

    Args:
      args: Command-line arguments, excluding the command prefix, as a list of
        str.
      screen_info: Optional dict input containing screen information such as
        cols.

    Returns:
      Output text lines as a RichTextLines object.
    r   z3There is no node named "%s" in the partition graphsNTF)r   r   r   r   r    zNode %sr   r‚   r   r2   z  Op: %sz  Device: %s)rb   )Ú
is_controlÚinputZ	recipient)r   r   )rK   rc   r   Úparse_node_or_tensor_namer   r'   Únode_existsr   rg   r$   rt   r   ro   Znode_devicer	   rf   Ú_exclude_blacklisted_opsÚnode_inputsrl   Ú_format_neighborsÚnode_recipientsr=   Ú_list_node_attributesr>   Ú_list_node_dumpsr?   Ú_render_node_traceback)r+   rv   rw   rx   ry   r   Zunused_slotr   Úlinesrb   ÚinputsÚctrl_inputsZrecsZ	ctrl_recsr"   r"   r#   r   ä  sP    

(

zDebugAnalyzer.node_infoc                s   ‡ fdd„|D ƒS )zÙExclude all nodes whose op types are in _GRAPH_STRUCT_OP_TYPE_BLACKLIST.

    Args:
      node_names: An iterable of node or graph element names.

    Returns:
      A list of node names that are not blacklisted.
    c                s(   g | ] }ˆ j  t |¡¡ˆ jkr|‘qS r"   )r'   ro   r   Úget_node_nameÚ_GRAPH_STRUCT_OP_TYPE_BLACKLIST)Ú.0r   )r+   r"   r#   ú
<listcomp>B  s    
z:DebugAnalyzer._exclude_blacklisted_ops.<locals>.<listcomp>r"   )r+   Z
node_namesr"   )r+   r#   r—   9  s    	z&DebugAnalyzer._exclude_blacklisted_opsc             C   s  t dƒt dƒt ddƒg}y²| j |¡}x t|ƒD ]”\}\}}}}| d||f ¡ |rjt dd||f ¡nd}	t dƒ}
|
t d| |	ƒ7 }
| |
¡ | d	| ¡ | d
|r²d| nd ¡ | d¡ q0W W n< tk
rè   | d¡ Y n  tk
r   | d¡ Y nX t 	|¡S )zßRender traceback of a node's creation in Python, if available.

    Args:
      node_name: (str) name of the node.

    Returns:
      A RichTextLines object containing the stack trace of the node's
      construction.
    r2   zTraceback of node construction:r   z%d: %szps %s -b %dNz  zLine:     %dz  Function: %sz  Text:     z"%s"ÚNonez-(Node unavailable in the loaded Python graph)z5(Unavailable because no Python graph has been loaded))
ÚRLr'   Znode_tracebackÚ	enumerater   r	   r   ÚKeyErrorÚLookupErrorÚ#rich_text_lines_from_rich_line_list)r+   r   rž   Z
node_stackr@   Ú	file_pathr   Zfunction_nameÚtextÚ	attributeZline_number_liner"   r"   r#   r   G  s$    
z$DebugAnalyzer._render_node_tracebackc             C   sR   |}| j d  |¡}| j|j|j|j|j|jdd}t 	|j¡}t
||dd |S )aE  Command handler for inputs.

    Show inputs to a given node.

    Args:
      args: Command-line arguments, excluding the command prefix, as a list of
        str.
      screen_info: Optional dict input containing screen information such as
        cols.

    Returns:
      Output text lines as a RichTextLines object.
    r   F)Ú
do_outputs)r   r   )rK   rc   Ú_list_inputs_or_outputsrA   r   r@   Úcontrolr   r   r¡   r$   )r+   rv   rw   rx   ry   r   r   r"   r"   r#   r   j  s    zDebugAnalyzer.list_inputsc          
   C   sB  | j d  |¡}t |¡}t |j¡}t |j¡\}}t	 
|¡\}}	| j ¡ r|| j |¡s|t d| ¡}
t|
dddd |
S | j |¡}|	dkrtƒ }x$|D ]}| t| d¡d ƒ¡ qžW t|ƒdkrØt|ƒd	 }	n6d
|t|ƒf d| g}t |¡}
t|
|ddd |
S g }x@|D ]8}| j |¡}x$|D ]}|j|	kr.| |¡ q.W qW |snt d|j ¡}
nÐt|ƒdkrà|jd	kr¸tj|d	  ¡ |d	 j||j |||j!|j"d}
nt d|j|jf ¡}
t|
|dd n^|jd	k rÊd|jt|ƒf g}i }x†t#|ƒD ]z\}}|j$| jj% d }| d|||jf ¡ d|j|f }t|d ƒt|jƒ t|d ƒt &d|¡fg|t|ƒd < qW | d¡ | d¡ | d¡ | d|j ¡ tj||d}
nf|jt|ƒkrøt d|jt|ƒ|jf ¡}
n8tj||j  ¡ ||j jd|j  ||j |||j"d}
t|
|dd |
S )aT  Command handler for print_tensor.

    Print value of a given dumped tensor.

    Args:
      args: Command-line arguments, excluding the command prefix, as a list of
        str.
      screen_info: Optional dict input containing screen information such as
        cols.

    Returns:
      Output text lines as a RichTextLines object.
    r   z,Node "%s" does not exist in partition graphsNTF)r   r   r   ú:rE   r   z5Node "%s" generated debug dumps from %s output slots:z%Please specify the output slot: %s:x.z'Tensor "%s" did not generate any dumps.)rI   Útensor_slicingÚhighlight_optionsÚinclude_numeric_summaryÚ
write_pathz<Invalid number (%d) for tensor %s, which generated one dump.)r   r   zTensor "%s" generated %d dumps:g     @@z#%d [%.3f ms] %szprint_tensor %s -n %dr‚   r2   zBYou can use the -n (--number) flag to specify which dump to print.zFor example:z  print_tensor %s -n 0)rb   zNSpecified number (%d) exceeds the number of available dumps (%d) for tensor %sz (dump #%d))rI   r²   r³   rµ   )'rK   rc   r   Ú#numpy_printoptions_from_screen_infoZparse_ranges_highlightÚrangesr   Zparse_tensor_name_with_slicingr   r   r•   r'   Zloaded_partition_graphsr–   rg   r$   Údebug_watch_keysÚsetÚaddrU   Úsplitrt   Úlistr	   rf   Úwatch_key_to_datars   r   ÚnumberÚformat_tensorZ
get_tensorÚ	watch_keyrI   Znumeric_summaryrµ   r§   r   rp   r   )r+   rv   rw   ry   Únp_printoptionsr³   r   r²   r   rs   r   Ú
watch_keysZoutput_slotsrÀ   rž   Zmatching_dataÚdebug_tensor_dataÚdatumrb   Úir   r’   r"   r"   r#   r   Ž  s²    








"


zDebugAnalyzer.print_tensorc             C   sR   |}| j d  |¡}| j|j|j|j|j|jdd}t 	|j¡}t
||dd |S )aE  Command handler for inputs.

    Show inputs to a given node.

    Args:
      args: Command-line arguments, excluding the command prefix, as a list of
        str.
      screen_info: Optional dict input containing screen information such as
        cols.

    Returns:
      Output text lines as a RichTextLines object.
    r   T)r®   F)r   r    )rK   rc   r¯   rA   r   r@   r°   r   r   r¡   r$   )r+   rv   rw   rx   ry   r   r   r"   r"   r#   r     s    zDebugAnalyzer.list_outputsc             C   sH   | j d  |¡}| j |j¡}t |¡}tj|d|j ||jd|j	dS )NrJ   zfrom eval of expression '%s'T)rI   r´   rµ   )
rK   rc   r(   ÚevaluaterH   r   r¶   r¿   rI   rµ   )r+   rv   rw   ry   Zeval_resrÁ   r"   r"   r#   Úevaluate_expression@  s    z!DebugAnalyzer.evaluate_expressionr   c             C   s"   d|j |jrdnd||j| f S )Nzps %s %s -b %d -m %dz-tr2   )rB   rC   Úmax_elements_per_line)r+   ry   Ú
line_beginÚmax_elements_per_line_increaser"   r"   r#   Ú!_reconstruct_print_source_commandO  s    z/DebugAnalyzer._reconstruct_print_source_commandc             C   sº  ~| j d  |¡}tj| j|j|jd}t |j¡\}}g }d}xRt|ƒD ]D\}	}
t	d|	d  t
jƒ}|d|t|ƒ  7 }||
7 }| |¡ |	d |jkrªt|ƒd }|	d |krLt||	d  ƒ}xÊt|ƒD ]¾\}}||jkrBt	dt|ƒ|j t|ƒ|jrdnd	f ƒ}|t	d
t d| j||	d dd¡ƒ7 }| |¡ P t	dƒ}| j t |¡¡rpt dd| ¡}nt
j}|t	||ƒ7 }| |¡ qÐW qLW tj|tj|id}t|dd |S )z#Print the content of a source file.rF   )Zdo_dumped_tensorsr   zL%drE   ra   z"    (... Omitted %d of %d %s ...) z	tensor(s)zop(s)z+5Né   )rÊ   z    r2   zpt %s)r   )r   )rK   rc   r   Zannotate_sourcer'   rB   rC   Úload_sourcer§   r¦   r   ZCOLOR_YELLOWrt   r   rÉ   rŒ   rÈ   r	   r   rË   r¸   r   r¡   Z
COLOR_BLUErª   ZINIT_SCROLL_POS_KEYr$   )r+   rv   rw   ry   Zsource_annotationZsource_linesZline_num_widthZlabeled_source_linesZactual_initial_scroll_targetrÅ   r   Zannotated_lineZsorted_elementsÚkÚelementZomitted_info_lineÚlabelr­   r   r"   r"   r#   rF   W  s\    



zDebugAnalyzer.print_sourcec          	   C   s  d}d}d}d}|r(t j}td|ƒg}nt j}td|ƒg}|sb| tdƒ¡ | tƒ ¡ t |¡S ttdd	„ |D ƒƒt|ƒƒd
 }	ttdd	„ |D ƒƒt|ƒƒd
 }
ttdd	„ |D ƒƒt|ƒƒd
 }t|d|	t|ƒ   |ƒ}|t|d|
t|ƒ   |ƒ7 }|t|d|t|ƒ   |ƒ7 }|t||ƒ7 }| |¡ xÌ|D ]Ä\}}}}}}|g}t	 
|¡rr| t dd||f ¡¡ t||ƒ}|d|	t|ƒ  7 }|tt|ƒd|
tt|ƒƒ   |ƒ7 }|tt|ƒd|tt|ƒƒ   |ƒ7 }|tt|ƒ|ƒ7 }| |¡ q6W | tƒ ¡ t |¡S )aÍ  Make a table summarizing the source files that create nodes and tensors.

    Args:
      source_list: List of source files and related information as a list of
        tuples (file_path, is_tf_library, num_nodes, num_tensors, num_dumps,
        first_line).
      is_tf_py_library: (`bool`) whether this table is for files that belong
        to the TensorFlow Python library.

    Returns:
      The table as a `debugger_cli_common.RichTextLines` object.
    zSource file pathz#(nodes)z
#(tensors)z#(tensor dumps)z"TensorFlow Python library file(s):z*File(s) outside TensorFlow Python library:z[No files.]c             s   s   | ]}t |d  ƒV  qdS )r   N)rt   )r£   Úitemr"   r"   r#   ú	<genexpr>³  s    z3DebugAnalyzer._make_source_table.<locals>.<genexpr>rE   c             s   s   | ]}t t|d  ƒƒV  qdS )é   N)rt   rP   )r£   rÑ   r"   r"   r#   rÒ   µ  s    c             s   s   | ]}t t|d  ƒƒV  qdS )é   N)rt   rP   )r£   rÑ   r"   r"   r#   rÒ   ¸  s    ra   Nzps %s -b %d)r   Z
COLOR_GRAYr¦   ZCOLOR_WHITEr   r	   rª   rƒ   rt   r   Z%is_extension_uncompiled_python_sourcer   rP   )r+   Úsource_listZis_tf_py_libraryZ	path_headZnum_nodes_headZnum_tensors_headZnum_dumps_headÚcolorrž   Zpath_column_widthZnum_nodes_column_widthZnum_tensors_column_widthÚheadr«   rx   Z	num_nodesZnum_tensorsZ	num_dumpsZfirst_line_numZpath_attributesr   r"   r"   r#   Ú_make_source_table’  s^    


z DebugAnalyzer._make_source_tablec             C   sØ   ~| j d  |¡}tj| j|j|jd}tddƒg}|jrN| td|j ƒ¡ |jrh| td|j ƒ¡ | tƒ ¡ t	 
|¡}|s| d¡ |S | |  dd	„ |D ƒd
¡¡ | |  dd	„ |D ƒd¡¡ t|dd |S )z<List Python source files that constructed nodes and tensors.rG   )Zpath_regex_whitelistZnode_name_regex_whitelistz3List of source files that created nodes in this runr   zFile path regex filter: "%s"zNode name regex filter: "%s"z[No source file information.]c             S   s   g | ]}|d  s|‘qS )rE   r"   )r£   rÑ   r"   r"   r#   r¤   ó  s    z-DebugAnalyzer.list_source.<locals>.<listcomp>Fc             S   s   g | ]}|d  r|‘qS )rE   r"   )r£   rÑ   r"   r"   r#   r¤   õ  s    TN)r   )rK   rc   r   Zlist_source_files_against_dumpr'   Zpath_filterr7   r¦   r   r	   rª   rl   rØ   r$   )r+   rv   rw   ry   rÕ   Z	top_linesr   r"   r"   r#   rG   Ú  s0    


zDebugAnalyzer.list_sourceFc             C   s6  |r| j j}d}d}	n| j j}d}d}	g }
i }t |¡\}}| j  |¡sVt d| ¡S |r`|}nd}|rrd|	 }nd}d	||f }t|ƒd t|ƒ t|ƒd d
fg|d< |
 	|d||f  ¡ |rÈdnd}| j
|
||||dg |||d
 |
 	d¡ |
 	d¡ |
 	d¡ |r|
 	d¡ |r(|
 	d¡ tj|
|dS )aù  Helper function used by list_inputs and list_outputs.

    Format a list of lines to display the inputs or output recipients of a
    given node.

    Args:
      recursive: Whether the listing is to be done recursively, as a boolean.
      node_name: The name of the node in question, as a str.
      depth: Maximum recursion depth, applies only if recursive == True, as an
        int.
      control: Whether control inputs or control recipients are included, as a
        boolean.
      op_type: Whether the op types of the nodes are to be included, as a
        boolean.
      do_outputs: Whether recipients, instead of input nodes are to be
        listed, as a boolean.

    Returns:
      Input or recipient tree formatted as a RichTextLines object.
    zRecipients ofZ
recipientsz	Inputs torŸ   z3There is no node named "%s" in the partition graphsrE   z, control %s includedr2   z%s node "%s"r   r   z (Depth limit = %d%s):zlo -c -r %szli -c -r %s)Úcommand_templatezLegend:z  (d): recursion depth = d.z  (Ctrl): Control input.z"  [Op]: Input node has op type Op.)rb   )r'   rš   r˜   r   r•   r–   r   rg   rt   r   Ú_dfs_from_noder	   rf   )r+   rA   r   r@   r°   r   r®   ÚtrackerZtype_strZshort_type_strrž   rb   rx   Ú	max_depthZinclude_ctrls_strr   rÙ   r"   r"   r#   r¯   ù  sT    

(




z%DebugAnalyzer._list_inputs_or_outputsc             C   s   |   t ||dd¡¡}dgt|ƒ }|r^|   t||ddƒ¡}| |¡ | dgt|ƒ ¡ |sx|dkrt| d¡ dS | |¡ d}xDt|ƒD ]8}||d k rÀ|d |kr¶|t7 }qÈ|t7 }q|t	7 }qW |rò||krò| |t
 ¡ | ¡  dS |t| 7 }xüt|ƒD ]ð\}}| j t |¡¡}|| jkr2q|| rBt}nd}d}|	rXt| }|t|ƒd krr| ¡  || | | }| |¡ |
rÆt|ƒt|ƒ t|ƒt d|
| ¡fg|t|ƒd < t |¡\}}| j||||||d |||	|
d
 qW dS )	a™  Perform depth-first search (DFS) traversal of a node's input tree.

    It recursively tracks the inputs (or output recipients) of the node called
    node_name, and append these inputs (or output recipients) to a list of text
    lines (lines) with proper indentation that reflects the recursion depth,
    together with some formatting attributes (to attr_segs). The formatting
    attributes can include command shortcuts, for example.

    Args:
      lines: Text lines to append to, as a list of str.
      attr_segs: (dict) Attribute segments dictionary to append to.
      node_name: Name of the node, as a str. This arg is updated during the
        recursion.
      tracker: A callable that takes one str as the node name input and
        returns a list of str as the inputs/outputs.
        This makes it this function general enough to be used with both
        node-input and node-output tracking.
      max_depth: Maximum recursion depth, as an int.
      depth: Current recursion depth. This arg is updated during the
        recursion.
      unfinished: A stack of unfinished recursion depths, as a list of int.
      include_control: Whether control dependencies are to be included as
        inputs (and marked as such).
      show_op_type: Whether op type of the input nodes are to be displayed
        alongside the nodes' names.
      command_template: (str) Template for command shortcut of the node names.
    F)r“   TrE   z  [None]Nr2   )Úinclude_controlÚshow_op_typerÙ   )r—   Úcopyrt   rŒ   rl   r   r   ÚHANG_UNFINISHEDÚHANG_FINISHEDÚHANG_SUFFIXÚELLIPSISÚpopÚDEPTH_TEMPLATEr§   r'   ro   r   r¡   r¢   Ú
CTRL_LABELÚOP_TYPE_TEMPLATEr	   r   r•   rÚ   )r+   rž   r   r   rÛ   rÜ   r@   Ú
unfinishedrÝ   rÞ   rÙ   Z
all_inputsZis_ctrlr    ZhangrÎ   rÅ   Úinpr   Zctrl_strZop_type_strr   Zinp_node_namerx   r"   r"   r#   rÚ   T  sl    (






 zDebugAnalyzer._dfs_from_nodec       	      C   s:  g }i }|  d¡ |  dt|ƒ|t|ƒ|f ¡ |  dt|ƒ|f ¡ x^|D ]V}d| j |¡|f }|  |¡ t|ƒt|ƒ t|ƒt dd| ¡fg|t|ƒd < qLW |r,|  d¡ |  dt|ƒ|f ¡ x^|D ]V}d| j |¡|f }|  |¡ t|ƒt|ƒ t|ƒt dd| ¡fg|t|ƒd < qÒW tj||d	S )
a  List neighbors (inputs or recipients) of a node.

    Args:
      neighbor_type: ("input" | "recipient")
      non_ctrls: Non-control neighbor node names, as a list of str.
      ctrls: Control neighbor node names, as a list of str.

    Returns:
      A RichTextLines object.
    r2   z  %d %s(s) + %d control %s(s):z    %d %s(s):z      [%s] %sNzni -a -d -t %srE   z    %d control %s(s):)rb   )r   rt   r'   ro   r	   r   rf   )	r+   Zneighbor_typeZ	non_ctrlsZctrlsrž   rb   Znon_ctrlr   Zctrlr"   r"   r#   r™   É  s,    


$


$zDebugAnalyzer._format_neighborsc             C   sz   g }|  d¡ |  d¡ | j |¡}xJ|D ]B}|  d| ¡ t|| ƒ ¡  dd¡}|  d| ¡ |  d¡ q*W t |¡S )z¸List neighbors (inputs or recipients) of a node.

    Args:
      node_name: Name of the node of which the attributes are to be listed.

    Returns:
      A RichTextLines object.
    r2   zNode attributes:z  %s:Ú
ra   z    %s)r   r'   Znode_attributesÚreprÚstripÚreplacer	   rf   )r+   r   rž   ÚattrsZattr_keyZattr_val_strr"   r"   r#   r›   ó  s    



z#DebugAnalyzer._list_node_attributesc             C   sÔ   g }i }| j  |¡}d}xŒ|D ]„}| j  |¡}xr|D ]j}d|j|j|j| j j d f }	| |	¡ d||j|f }
dt|	ƒt	 
d|
¡fg|t|ƒd < |d7 }q4W qW t	j||d}t	 d	| d
g¡}| |¡ |S )z¬List dumped tensor data from a node.

    Args:
      node_name: Name of the node of which the attributes are to be listed.

    Returns:
      A RichTextLines object.
    r   z  Slot %d @ %s @ %.3f msg     @@zpt %s:%d -n %drÓ   NrE   )rb   z%d dumped tensor(s):r2   )r'   r¸   r½   rs   Zdebug_opr   rp   r   rt   r	   r   rf   rl   )r+   r   rž   rb   rÂ   r}   rÀ   rÃ   rÄ   r   r’   r   Zoutput_with_headerr"   r"   r#   rœ   
  s(    



$

zDebugAnalyzer._list_node_dumps)N)N)N)N)N)N)r   )N)N)F)FFN)"Ú__name__Ú
__module__Ú__qualname__Ú__doc__r„   r…   r†   rŽ   r¢   r.   r*   r]   r^   r`   r   rj   rk   rm   r   r—   r   r   r   r   rÇ   rË   rF   rØ   rG   r¯   rÚ   r™   r›   rœ   r"   r"   r"   r#   r%   ‚   sH     (
w)#@
U#
$
 
$


;H
%
]  
k*r%   Úcursesc       
      C   sn  |dkrt  ¡ }t| |d}|r>x|D ]}| ||| ¡ q&W tj|||d}|jd|j| d¡dgd |jd|j	| d¡dgd |jd	|j
| d	¡d
gd |jd|j| d¡dgd |jd|j| d¡dgd |jd|j| d¡dgd |jd|j| d¡dgd |jd|j| d¡dgd g }x&| jD ]}	| d|	j|	jf ¡ q:W | ddg|¡ |S )a2  Create an instance of CursesUI based on a DebugDumpDir object.

  Args:
    debug_dump: (debug_data.DebugDumpDir) The debug dump to use.
    tensor_filters: (dict) A dict mapping tensor filter name (str) to tensor
      filter (Callable).
    ui_type: (str) requested UI type, e.g., "curses", "readline".
    on_ui_exit: (`Callable`) the callback to be called when the UI exits.
    config: A `cli_config.CLIConfig` object.

  Returns:
    (base_ui.BaseUI) A BaseUI subtype object with a set of standard analyzer
      commands and tab-completions registered.
  N)r-   )Ú
on_ui_exitr-   r   Últ)Zprefix_aliasesr   Únir   Úlir   Úlor   ÚptrF   ZpsrG   ZlsrJ   Zevz%s:%d)r   Z	CLIConfigr%   r]   r   Zget_uiZregister_command_handlerr   r`   r   r   r   r   rF   rG   rÇ   ri   r   r   rs   Zregister_tab_comp_context)
r,   Ztensor_filtersZui_typerô   r-   ZanalyzerZtensor_filter_nameÚcliZdumped_tensor_namesrÄ   r"   r"   r#   Úcreate_analyzer_ui.  sj    








rû   )NTTTTT)Nró   NN)%rò   Ú
__future__r   r   r   rL   rß   rd   Z	six.movesr   Ztensorflow.python.debug.clir   r   r   r	   r
   r   Ztensorflow.python.debug.libr   r   ZRichLiner¦   rà   rá   râ   rå   rç   ræ   rã   rQ   rR   rS   rT   r$   Úobjectr%   rû   r"   r"   r"   r#   Ú<module>   sb        
?           8   