B
    )`s                 @   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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G dd deZd!ddZdd Z G dd deZ!d"dd Z"dS )#z+Formats and displays profiling information.    )absolute_import)division)print_functionN)
cli_shared)command_parser)debugger_cli_common)
ui_factory)	profiling)source_utilsnodeop_typeop_time	exec_time
start_timelinedevice_name_filternode_name_filterop_type_filterc               @   sH   e Zd ZdZejfddZdddZdd Zd	d
 Z	dd Z
dd ZdS )ProfileDataTableViewzTable View of profiling data.c                sn   || _ dd |D | _ fdd|D | _ fdd|D | _dddd  d	  d
g| _ttttt	t
g| _dS )zConstructor.

    Args:
      profile_datum_list: List of `ProfileDatum` objects.
      time_unit: must be in cli_shared.TIME_UNITS.
    c             S   s   g | ]
}|j qS  )r   ).0datumr   r   _/home/dcms/DCMS/lib/python3.7/site-packages/tensorflow/python/debug/cli/profile_analyzer_cli.py
<listcomp><   s    z1ProfileDataTableView.__init__.<locals>.<listcomp>c                s   g | ]}t j|j d qS ))force_time_unit)r   time_to_readable_strr   )r   r   )	time_unitr   r   r   >   s   c                s   g | ]}t j|jj d qS ))r   )r   r   node_exec_statsall_end_rel_micros)r   r   )r   r   r   r   B   s   NodezOp TypezStart Time (us)zOp Time (%s)zExec Time (%s)zFilename:Lineno(function)N)_profile_datum_listformatted_start_timeformatted_op_timeformatted_exec_time_column_namesSORT_OPS_BY_OP_NAMESORT_OPS_BY_OP_TYPESORT_OPS_BY_START_TIMESORT_OPS_BY_OP_TIMESORT_OPS_BY_EXEC_TIMESORT_OPS_BY_LINE_column_sort_ids)selfprofile_datum_listr   r   )r   r   __init__3   s    



zProfileDataTableView.__init__Nc       	      C   s  d}|dkr| j | jj}n|dkr2| j | j}n|dkrJt| j| }n|dkrbt| j| }n|dkrzt| j| }n|dkrd}|r|d	t|f 7 }|r|d	t	|f 7 }|r|d	t
|f 7 }|d
| j | j| j | jf 7 }td|}| j | j}ntd| t||dS )a  Get the content of a cell of the table.

    Args:
      row: (int) row index.
      col: (int) column index.
      device_name_filter: Regular expression to filter by device name.
      node_name_filter: Regular expression to filter by node name.
      op_type_filter: Regular expression to filter by op type.

    Returns:
      A debuggre_cli_common.RichLine object representing the content of the
      cell, potentially with a clickable MenuItem.

    Raises:
      IndexError: if row index is out of range.
    Nr                  psz --%s %sz %s --init_line %dzInvalid column index %d.)	font_attr)r    r   	node_namer   strr!   r"   r#   _DEVICE_NAME_FILTER_FLAG_NODE_NAME_FILTER_FLAG_OP_TYPE_FILTER_FLAG	file_pathline_numberr   MenuItemfile_line_func
IndexErrorRL)	r,   rowcolr   r   r   	menu_itemtextcommandr   r   r   valueQ   s6    

zProfileDataTableView.valuec             C   s
   t | jS )N)lenr    )r,   r   r   r   	row_count   s    zProfileDataTableView.row_countc             C   s
   t | jS )N)rG   r$   )r,   r   r   r   column_count   s    z!ProfileDataTableView.column_countc             C   s   | j S )N)r$   )r,   r   r   r   column_names   s    z!ProfileDataTableView.column_namesc             C   s
   | j | S )N)r+   )r,   rB   r   r   r   column_sort_id   s    z#ProfileDataTableView.column_sort_id)NNN)__name__
__module____qualname____doc__r   TIME_UNIT_USr.   rF   rH   rI   rJ   rK   r   r   r   r   r   0   s   !  
/r   c             C   s   |r| | jjsdS |r0| jr,| | js0dS |dkrL| jrL| j|k rLdS |dkrh| jrh| j|krhdS | jdk	r|r| | jsdS |dk	r|| jsdS |r|| jjsdS dS )a  Filter function for list_profile command.

  Args:
    profile_datum: A `ProfileDatum` object.
    node_name_regex: Regular expression pattern object to filter by name.
    file_path_regex: Regular expression pattern object to filter by file path.
    op_type_regex: Regular expression pattern object to filter by op type.
    op_time_interval: `Interval` for filtering op time.
    exec_time_interval: `Interval` for filtering exec time.
    min_lineno: Lower bound for 1-based line number, inclusive.
      If <= 0, has no effect.
    max_lineno: Upper bound for 1-based line number, exclusive.
      If <= 0, has no effect.
    # TODO(cais): Maybe filter by function name.

  Returns:
    True iff profile_datum should be included.
  Fr   NT)	matchr   r6   r;   r<   r   containsr   r   )profile_datumnode_name_regexfile_path_regexop_type_regexop_time_intervalexec_time_interval
min_lineno
max_linenor   r   r   _list_profile_filter   s.    



r\   c             C   sV   |t kr| jjS |tkr| jS |tkr,| jS |tkr:| jS |t	krJ| jj
S | jjS dS )a  Get a profile_datum property to sort by in list_profile command.

  Args:
    profile_datum: A `ProfileDatum` object.
    sort_by: (string) indicates a value to sort by.
      Must be one of SORT_BY* constants.

  Returns:
    profile_datum property to sort by.
  N)r%   r   r6   r&   r   r*   r>   r(   r   r)   r   Zall_start_micros)rT   sort_byr   r   r   _list_profile_sort_key   s    r^   c               @   sz   e Zd ZdZdd ZdddZdd Zdd
dZdd Ze	j
Ze	jZdZdZdZdZdddZdd Zdd Zdd ZdS )ProfileAnalyzerzAnalyzer for profiling data.c             C   s$  || _ |std|| _i | _tjdtjd}|jddt tt	ddd |jd	dt
 t
t	dd
d |jddt tt	ddd |jdddt	ddd |jddtddd |j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#d$ttttttg d |jd%d&d'd(d)d* |jd+d,t	tjd-d$tj d. d || jd/< tjd0tjd}|jd1t	d2d3 |jd4t	d5dgd5d6d7 |jd+d,t	tjd-d$tj d. d |jddt tt	dd8d |jd	dt
 t
t	dd9d |jddt tt	dd:d |jd;d<td=d>d || jd?< d@S )AzProfileAnalyzer constructor.

    Args:
      graph: (tf.Graph) Python graph object.
      run_metadata: A `RunMetadata` protobuf object.

    Raises:
      ValueError: If run_metadata is None.
    z+No RunMetadata passed for profile analysis.zList nodes profile information.)descriptionusagez-dz--%s zfilter device name by regex.)desttypedefaulthelpz-nzfilter node name by regex.z-tzfilter op type by regex.z-fz--file_path_filterfile_path_filterzlfilter by file name at the top position of node's creation stack that does not belong to TensorFlow library.z--min_linenorZ   rQ   zW(Inclusive) lower bound for 1-based line number in source file. If <= 0, has no effect.z--max_linenor[   zW(Exclusive) upper bound for 1-based line number in source file. If <= 0, has no effect.z-ez--execution_timeexecution_timezFilter by execution time interval (includes compute plus pre- and post -processing time). Supported units are s, ms and us (default). E.g. -e >100s, -e <100, -e [100us,1000ms]z-oz	--op_timer   zFilter by op time interval (only includes compute time). Supported units are s, ms and us (default). E.g. -e >100s, -e <100, -e [100us,1000ms]z-sz	--sort_byr]   z#the field to sort the data by: (%s)z | z-rz	--reversereverse
store_truez+sort the data in reverse (descending) order)rc   actionrf   z--time_unitr   zTime unit ()list_profilez>Print a Python source file with line-level profile informationsource_file_pathzPath to the source_file_path)rd   rf   z--cost_typer   zType of cost to display)rd   choicesre   rf   zFilter device name by regex.zFilter node name by regex.zFilter op type by regex.z--init_line	init_liner   z/The 1-based line number to scroll to initially.print_sourceN)_graph
ValueError_run_metadata_arg_parsersargparseArgumentParserSUPPRESSadd_argumentr8   r7   r9   r:   intr'   joinr%   r&   r(   r)   r*   r   rP   Z
TIME_UNITS)r,   graphrun_metadataZapr   r   r   r.      s   



zProfileAnalyzer.__init__Nc                sn  d}|rd|kr|d }| j d |jr:tjndjrPtjnd jrftjndj	r|tj	ndj
rtj
ndtdg}jrtjnd}|  }t| jjj}xt|D ]}| jjj| }	|r||	jr؇ fdd||	D }
t|
fdd	jd
}
|| j|	j|||
jjjjjj
|d qW |S )aV  Command handler for list_profile.

    List per-operation profile information.

    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.
    P   colsrm   Nrb   c                s,   g | ]$}t | jjd r|qS ))rZ   r[   )r\   rZ   r[   )r   r   )rY   rV   rU   rX   rW   parsedr   r   r     s
    z0ProfileAnalyzer.list_profile.<locals>.<listcomp>c                s   t |  jS )N)r^   r]   )r   )r   r   r   <lambda>      z.ProfileAnalyzer.list_profile.<locals>.<lambda>)keyri   )r   r   r   screen_cols)ru   
parse_argsr   r   Zparse_time_intervalrh   r   recompilerg   r   r   RichTextLinesr   _get_profile_data_generatorrG   rt   
step_stats	dev_statsrangerR   devicesortedri   extend_get_list_profile_linesr]   r   )r,   argsscreen_infor   outputdevice_name_regexdata_generatordevice_countindexdevice_statsprofile_datar   )rY   rV   rU   rX   rW   r   r   rm   ~  s<     

zProfileAnalyzer.list_profilec                s   i  i i i xt| j  D ]f}x6t|jD ](}|d }|d }|d }t|s,P q,W | |j< ||j< ||j< |j|j< qW  fdd}|S )z~Get function that generates `ProfileDatum` objects.

    Returns:
      A function that generates `ProfileDatum` objects.
    r   r/   r0   c             3   sj   xd| j D ]Z}|jdks|jdkr"qt| j| |jd|jd|jd|jdV  qW d S )NZ_SOURCEZ_SINKrb   r   )
node_statsr6   r	   ZProfileDatumr   get)Zdevice_step_statsr   )node_to_file_pathnode_to_func_namenode_to_line_numbernode_to_op_typer   r   profile_data_generator  s    zKProfileAnalyzer._get_profile_data_generator.<locals>.profile_data_generator)rr   Zget_operationsreversed	tracebackr
   Zguess_is_tensorflow_py_librarynamerd   )r,   opZtrace_entryr;   line_num	func_namer   r   )r   r   r   r   r   r     s"    



z+ProfileAnalyzer._get_profile_data_generatorr~   c             C   s  t ||d}tdd |D }tdd |D }ddtj||dtj||dg}dd	 | D }x.tt|D ]}t|| t|| ||< qpW x`tt|D ]P}x:t| D ]*}t|| t|j	||||	|
d
||< qW ||  d7  < qW t
d| g}d|d ||f }|t
| |t
  d}t
 }xt| D ]|}| | }||}d||f }||kr|s|d7 }td|}|t
||dgd7 }|t
d|| t|  7 }qFW || xvt| D ]f}t
 }xNt| D ]>}|j	||||	|
d
}||7 }|t
d|| t|  7 }qW || qW d}x*t||D ]\}}|d| |7 }qXW |t
  |t
| t|S )a6  Get `RichTextLines` object for list_profile command for a given device.

    Args:
      device_name: (string) Device name.
      device_index: (int) Device index.
      device_count: (int) Number of devices.
      profile_datum_list: List of `ProfileDatum` objects.
      sort_by: (string) Identifier of column to sort. Sort identifier
          must match value of SORT_OPS_BY_OP_NAME, SORT_OPS_BY_OP_TYPE,
          SORT_OPS_BY_EXEC_TIME, SORT_OPS_BY_MEMORY or SORT_OPS_BY_LINE.
      sort_reverse: (bool) Whether to sort in descending instead of default
          (ascending) order.
      time_unit: time unit, must be in cli_shared.TIME_UNITS.
      device_name_filter: Regular expression to filter by device name.
      node_name_filter: Regular expression to filter by node name.
      op_type_filter: Regular expression to filter by op type.
      screen_cols: (int) Number of columns available on the screen (i.e.,
        available screen width).

    Returns:
      `RichTextLines` object containing a table that displays profiling
      information for each op.
    )r   c             s   s   | ]}|j V  qd S )N)r   )r   r   r   r   r   	<genexpr>  s    z:ProfileAnalyzer._get_list_profile_lines.<locals>.<genexpr>c             s   s   | ]}|j jV  qd S )N)r   r   )r   r   r   r   r   r     s   zDevice Totalrb   )r   c             S   s   g | ]}t |qS r   )rG   )r   column_namer   r   r   r     s    z;ProfileAnalyzer._get_list_profile_lines.<locals>.<listcomp>)r   r   r   r0   -zDevice %d of %d: %sr/   rm   z%s -s %sz -rNbold)r5    z{:<%d})r   sumr   r   rJ   r   rG   maxrH   rF   r@   appendrI   rK   r   r=   zipformat#rich_text_lines_from_rich_line_list)r,   Zdevice_nameZdevice_indexr   r-   r]   Zsort_reverser   r   r   r   r   r   total_op_timetotal_exec_timeZdevice_total_rowcolumn_widthsrB   rA   r   Z
device_rowbase_commandr   Zsort_idrE   Zhead_menu_itemZnew_rowZnew_cellZrow_strwidthr   r   r   r     sr    


"
"z'ProfileAnalyzer._get_list_profile_linesc          	   C   sr   t | }dd | D }xNt| D ]>}x8t|D ],}t|| t t||| d ||< q:W q,W |S )zDetermine the maximum column widths for each data list.

    Args:
      profile_data: list of ProfileDatum objects.

    Returns:
      List of column widths in the same order as columns in data.
    c             S   s   g | ]}t |qS r   )rG   )r   r   r   r   r   r   K  s    zGProfileAnalyzer._measure_list_profile_column_widths.<locals>.<listcomp>r0   )rG   rJ   r   rH   r   r7   Z
row_values)r,   r   Znum_columnsZwidthsrA   rB   r   r   r   #_measure_list_profile_column_widthsA  s    	.z3ProfileAnalyzer._measure_list_profile_column_widthsz#nodesz(#execs)linenosourcec       !         s   ~| j d |}|jr$t|jnd}g }|  }t| jjj	}x>t
|D ]2}| jjj	| }	|rp||	jspqL|||	 qLW tj|tj|j|j|jd}
|
std|j dt|jf dt|jf dt|jf gS d}x(|
D ] }| |
| |j}t||}qW t|j\}}d}|j}|d t|d t| jd	 |d
 t d d  | d d t|   | j! d d t| j!   | j"d}|t | j#| j$d7 }t d d  d   | j d d t| j   d d   | j"d}|t | j%dd7 }||g}i }xt&|D ]\}}|d	 }||
krn|
| }| '| ||j||}|}|d d t|  7 }t t(j)| ||j|j*d| j"d}|d d t|  7 }||7 }t+|jd }d|||d	 f }|jr|dt|jf 7 }|jr|dt|jf 7 }|jr"|dt|jf 7 }t,d|}t d|j-|j.f | j"|gd}|d d t|  7 }||7 }nt dt/ fdd D  }t d| | j$} | d d t|   7 } || 7 }||7 }|0| |j1|krt|d	 |tj2< qW tj3||dS )aG  Print a Python source file with line-level profile information.

    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.
    rq   N)r   r   zuThe source file %s does not contain any profile information for the previous Session run under the following filters:z
  --%s: %sr   
   r1   r/   )cost_bar
total_costnum_nodes_execsr<   r   r   r   r   )r5   r<   r   )r   $z8lp --file_path_filter %s --min_lineno %d --max_lineno %dz --%s %sz%d(%d)c             3   s   | ]}|d kr | V  qdS )r<   Nr   )r   Zcol_name)r   r   r   r     s    z/ProfileAnalyzer.print_source.<locals>.<genexpr>z L%d)annotations)4ru   r   r   r   r   r   rG   rt   r   r   r   rR   r   r   r
   Zannotate_source_against_profileospath
expanduserrn   r   r   r   r   r8   r9   r:   _get_total_cost	cost_typer   load_source_NUM_EXECS_SUB_HEADr@   _NUM_NODES_HEAD_LINE_COST_ATTR_LINENO_HEAD_LINE_NUM_ATTR_SOURCE_HEAD	enumerate_render_normalized_cost_barr   r   r   escaper=   Z
node_countZnode_exec_countr   r   rp   ZINIT_SCROLL_POS_KEYr   )!r,   r   r   r   r   r   r   r   r   r   Zsource_annotationZmax_total_costZ
line_indexr   Zsource_linesZline_num_widthZcost_bar_max_lengthZtotal_cost_headheadZsub_headlinesZoutput_annotationsir   r   
annotationr   Zannotated_linerg   rE   rC   r   Zline_num_columnr   )r   r   rq   Y  s    



(
.




zProfileAnalyzer.print_sourcec             C   s,   |dkr|j S |dkr|jS td| d S )Nr   r   zUnsupported cost type: %s)r   r   rs   )r,   Zaggregated_profiler   r   r   r   r     s
    zProfileAnalyzer._get_total_costc             C   sl   t tt|| | }|p d}td| jd}|td| d||   d| jgd7 }|td| jd7 }|S )as  Render a text bar representing a normalized cost.

    Args:
      cost: the absolute value of the cost.
      max_cost: the maximum cost value to normalize the absolute cost with.
      length: (int) length of the cost bar, in number of characters, excluding
        the brackets on the two ends.

    Returns:
      An instance of debugger_cli_common.RichTextLine.
    r/   [)r5   |r   r   ])rz   npceilfloatr@   r   )r,   ZcostZmax_costlengthZ	num_ticksr   r   r   r   r     s    z+ProfileAnalyzer._render_normalized_cost_barc             C   s   | j |  S )N)ru   format_help)r,   Zhandler_namer   r   r   get_help  s    zProfileAnalyzer.get_help)N)NNNr~   )N)rL   rM   rN   rO   r.   rm   r   r   r   r   Z
COLOR_CYANr   ZCOLOR_YELLOWr   r   r   r   r   rq   r   r   r   r   r   r   r   r_      s&    
;& 
a
 r_   cursesc             C   sV   ~t | |}tj||d}|jd|j|ddgd |jd|j|ddgd |S )a  Create an instance of CursesUI based on a `tf.Graph` and `RunMetadata`.

  Args:
    graph: Python `Graph` object.
    run_metadata: A `RunMetadata` protobuf object.
    ui_type: (str) requested UI type, e.g., "curses", "readline".
    on_ui_exit: (`Callable`) the callback to be called when the UI exits.
    config: An instance of `cli_config.CLIConfig`.

  Returns:
    (base_ui.BaseUI) A BaseUI subtype object with a set of standard analyzer
      commands and tab-completions registered.
  )
on_ui_exitrm   lp)Zprefix_aliasesrq   r4   )r_   r   Zget_uiZregister_command_handlerrm   r   rq   )r|   r}   Zui_typer   configZanalyzerclir   r   r   create_profiler_ui   s    


r   )rQ   rQ   )r   NN)#rO   
__future__r   r   r   rv   r   r   numpyr   Ztensorflow.python.debug.clir   r   r   r   Ztensorflow.python.debug.libr	   r
   ZRichLiner@   r%   r&   r(   r)   r'   r*   r8   r9   r:   objectr   r\   r^   r_   r   r   r   r   r   <module>   sF   i 
,    '  