
    =me72                         d Z dZdZdZddlZddlZddlmZ ddlZddl	Z	ddl
Z
ddlmZ dZd	Z G d
 d      Z G d de
j                         Z G d d      Z G d de      Zej(                  ddefd       Zd Zd Zy)zManuel Holtgrewez Copyright 2022, Manuel Holtgrewezmanuel.holtgrewe@bihealth.deMIT    N)chain)logger   g      ?c                   @    e Zd ZdZed        Z	 	 	 	 	 	 	 	 	 ddZd Zy)BenchmarkRecordzRecord type for benchmark timesc                 $    dj                  d      S )N	)
szh:m:smax_rssmax_vmsmax_ussmax_pssio_inio_out	mean_loadcpu_time)join)klasss    3lib/python3.12/site-packages/snakemake/benchmark.py
get_headerzBenchmarkRecord.get_header   s    yy
 	
    Nc
                     || _         || _        || _        || _        || _        || _        || _        |xs d| _        |	xs d| _        d | _	        d | _
        t               | _        t               | _        d| _        y )Nr   F)running_timer   r   r   r   r   r   
cpu_usagesr   
first_time	prev_timedictprocessed_procssetskipped_procsdata_collected)
selfr   r   r   r   r   r   r   r   r   s
             r   __init__zBenchmarkRecord.__init__*   sx     ) 
$/ A#v U#r   c                    d }d }| j                   rt        j                  dj                  | j                   D cg c]  }d|d    d|d    d c}             t        j                  d	j                  | j                  D cg c]  }d|d    d|d    d
 c}             | j
                  rdj                  t        || j                  d |t        j                  | j                              | j                  | j                  | j                  | j                  | j                  | j                  | j                   | j                  z  | j"                  f
            S t        j$                  d       dj                  | j                  d |t        j                  | j                              ddddddddg
      S c c}w c c}w )z9Return ``str`` with the TSV representation of this recordc                 F    | yt        | t              r| dS t        |       S )z5Conversion of value to str for TSV (None becomes "-")-z.2f)
isinstancefloatstr)xs    r   
to_tsv_strz*BenchmarkRecord.to_tsv.<locals>.to_tsv_strW   s'    yAu%C!1vr   c                     t        | j                  d      \  }}t        |d      \  }}d|||fz  }| j                  rd }d || j                        z  |z   }|S )z;Conversion of timedelta to str without fractions of seconds<   z%d:%02d:%02dc                 2    | t        |       dk7  xr dxs dfS )N   r    )abs)ns    r   pluralz@BenchmarkRecord.to_tsv.<locals>.timedelta_to_str.<locals>.pluralg   s    c!fk1c7R77r   z
%d day%s, )divmodsecondsdays)r+   mmsshhr   r4   s         r   timedelta_to_strz0BenchmarkRecord.to_tsv.<locals>.timedelta_to_str`   s_    AIIr*FBB^FB"b"-Avv8 "F166N2a7Hr   zBenchmark: not collected for ; z{'pid': r   z, 'name': 'r0   z''}zBenchmark: collected for ; z'}r
   z.4f)r6   z@Benchmark: unable to collect cpu and memory benchmark statisticsNA)r!   r   debugr   r   r"   mapr   datetime	timedeltar   r   r   r   r   r   r   r   warning)r#   r,   r;   records       r   to_tsvzBenchmarkRecord.to_tsvT   s   		 LLT '+&8&8" $F1I;k&)DI LLT '+&:&:" $F1I;k&)CH 99,,S1(););DDUDU)VW

$*;*;; ( NNR 99((-$X%7%7@Q@Q%RS Os   GG)	NNNNNNNNN)__name__
__module____qualname____doc__classmethodr   r$   rC    r   r   r   r      s@    )
 
$ ($TQr   r   c                   $    e Zd ZdZddZd Zd Zy)DaemonTimerz3A variant of threading.The timer that is daemonizedNc                     t         j                  j                  | d       || _        || _        ||ng | _        ||ni | _        t        j                         | _        y )NT)daemon)		threadingThreadr$   intervalfunctionargskwargsEventfinished)r#   rP   rQ   rR   rS   s        r   r$   zDaemonTimer.__init__   sS    !!$t!4   ,D"	 & 2f!)r   c                 8    | j                   j                          y)z)Stop the timer if it hasn't finished yet.N)rU   r    r#   s    r   cancelzDaemonTimer.cancel   s    r   c                    | j                   j                  | j                         | j                   j                         s& | j                  | j
                  i | j                   | j                   j                          y )N)rU   waitrP   is_setrQ   rR   rS   r    rW   s    r   runzDaemonTimer.run   sS    4==)}}##%DMM49944r   )NN)rD   rE   rF   rG   r$   rX   r\   rI   r   r   rK   rK      s    =*r   rK   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)ScheduledPeriodicTimerzScheduling of periodic events

    Up to self._interval, schedule actions per second, above schedule events
    in self._interval second gaps.
    c                 <    d| _         || _        d | _        d| _        y )Nr   T)_times_called	_interval_timer_stopped)r#   rP   s     r   r$   zScheduledPeriodicTimer.__init__   s    !r   c                 L   | j                          | xj                  dz  c_        d| _        | j                  | j                  kD  r&t	        | j                  | j
                        | _        nt	        t        | j
                        | _        | j                  j                          y)zStart the intervalic timerr0   FN)	workr`   rc   ra   rK   _actionrb   BENCHMARK_INTERVAL_SHORTstartrW   s    r   rh   zScheduledPeriodicTimer.start   sn    		a.%dnndllCDK%&>MDKr   c                 >   | j                          | xj                  dz  c_        | j                  | j                  kD  r&t        | j                  | j                        | _        nt        t        | j                        | _        | j
                  j                          y)zInternally, called by timerr0   N)re   r`   ra   rK   rf   rb   rg   rh   rW   s    r   rf   zScheduledPeriodicTimer._action   sg    		a.%dnndllCDK%&>MDKr   c                     t        d      )zOverride to perform the actionzOverride me!)NotImplementedErrorrW   s    r   re   zScheduledPeriodicTimer.work   s    !.11r   c                 F    | j                   j                          d| _        y)zCall to cancel any eventsTN)rb   rX   rc   rW   s    r   rX   zScheduledPeriodicTimer.cancel   s    r   N)	rD   rE   rF   rG   r$   rh   rf   re   rX   rI   r   r   r^   r^      s     	2r   r^   c                   &    e Zd ZdZefdZd Zd Zy)BenchmarkTimerz9Allows easy observation of a given PID for resource usagec                     dd l }t        j                  | |       || _        |j	                  | j                        | _        || _        i | _        y )Nr   )psutilr^   r$   pidProcessmainbench_recordprocs)r#   rq   rt   rP   rp   s        r   r$   zBenchmarkTimer.__init__   s?    ''h7NN488,	(
r   c                 l    ddl }	 | j                          y# |j                  $ r Y yt        $ r Y yw xY w)zWrite statisticsr   N)rp   _update_recordNoSuchProcessAttributeError)r#   rp   s     r   re   zBenchmarkTimer.work   s9    	!## 	 		s    333c                 >   ddl }d\  }}}}d\  }}d}d}	d}
d}	 t        j                         }t        | j                  f| j                  j	                  d            D ]]  }| j
                  j                  |j                  |      }|j                         5  | j                  j                  r-|	|j                         || j                  j                  z
  z  z  }		 |j                         }||j"                  z  }||j$                  z  }||j&                  z  }||j(                  z  }|r/	 |j+                         }||j,                  z  }||j.                  z  }|j3                         }|j4                  |j6                  z   | j                  j8                  |j                  |j!                         f<   ddd       ` t;        | j                  j8                  j=                               }
|| j                  _
        | j                  j>                  s|| j                  _
        |dz  }|dz  }|dz  }|dz  }|r|dz  }|dz  }nd}d}d}|r0d| j                  _         tC        | j                  jD                  xs d|      | j                  _"        tC        | j                  jF                  xs d|      | j                  _#        tC        | j                  jH                  xs d|      | j                  _$        tC        | j                  jJ                  xs d|      | j                  _%        || j                  _&        || j                  _'        | j                  xjP                  |	z  c_(        |
| j                  _)        yy# |j                  $ rK | j                  j                  j                  |j                  |j!                         f       Y ddd       zw xY w# t0        $ r}d}Y d}~d}~ww xY w# 1 sw Y   xY w# |j                  $ r
}Y d}~yd}~ww xY w)	zPerform the actual measurementr   N)r   r   r   r   )r   r   TF)	recursivei   )*rp   timer   rs   childrenru   
setdefaultrq   oneshotrt   r   cpu_percentmemory_full_infoErrorr!   addnamerssvmsusspssio_counters
read_byteswrite_bytesrk   	cpu_timesusersystemr   sumvaluesr   r"   maxr   r   r   r   r   r   r   r   )r#   rp   r   r   r   r   r   r   check_ior   r   r"   	this_timeprocmeminfoioinfonier   es                      r   rw   zBenchmarkTimer._update_record  s    (S#sv
9			ItyylDII,>,>,>,NO "zz,,TXXt<\\^  ((22"d&6&6&8%(9(9(C(CC' 
!"&"7"7"9 7;;&C7;;&C7;;&C7;;&C-%)%5%5%7F!V%6%66E"f&8&88F
 !% 0I!)9)99 %%55txx6MN=   "H 4,,<<CCEFH*3D'$$//.7!!+;C;C;C;C$+%!N
 /3D,(+D,=,=,E,E,JC(PD%(+D,=,=,E,E,JC(PD%(+D,=,=,E,E,JC(PD%(+D,=,=,E,E,JC(PD%&+D#'-D$((J6()1D& ] "<< ! ))77;;TXXtyy{<ST    !  3 -',H-3   h || 		s   A?P AO6N .>O6-.OAO65BP  AOO6
P OO6	O3&O.(O6.O33O66P 	;P PPN)rD   rE   rF   rG   BENCHMARK_INTERVALr$   re   rw   rI   r   r   rn   rn      s    C3E 
	W2r   rn   c              #   :  K   |xs
 t               }| du r| yt        j                         }t        t        | xs t	        j
                               ||      }|j                          | |j                          t        j                         |z
  |_        yw)a  Measure benchmark parameters while within the context manager

    Yields a ``BenchmarkRecord`` with the results (values are set after
    leaving context).

    If ``pid`` is ``None`` then the PID of the current process will be used.
    If ``benchmark_record`` is ``None`` then a new ``BenchmarkRecord`` is
    created and returned, otherwise, the object passed as this parameter is
    returned.

    Usage::

        with benchmarked() as bench_result:
            pass
    FN)	r   r|   rn   intosgetpidrh   rX   r   )rq   benchmark_recordrP   result
start_timebench_threads         r   benchmarkedr   ^  sz     " 2!2F
e|YY[
%c#*<&=vxP"iikJ6s   BBc                     t        t        j                         |       | D ]  }t        |j                         |        y)z/Write benchmark records to file-like the object)fileN)printr   r   rC   )recordsfile_rs      r   print_benchmark_recordsr   {  s4    	/
$
$
&U3 &ahhju%&r   c                 ^    t        |d      5 }t        | |       ddd       y# 1 sw Y   yxY w)z'Write benchmark records to file at pathwtN)openr   )r   pathfs      r   write_benchmark_recordsr     s-    	dD	 ,Q+, , ,s   #,)
__author____copyright__	__email____license__
contextlibr?   	itertoolsr   r   r|   rN   snakemake.loggingr   r   rg   r   rO   rK   r^   rn   contextmanagerr   r   r   rI   r   r   <module>r      s   
2*	    	   $    O Od)"" ,) )Xq2+ q2h 4:L 7 78&,r   