def __add__(self, other): tm = TelemetryInfo() for a in set(self.attributes((int, float))).intersection(set(other.attributes((int, float)))): if a not in ['timestamp', 'freephysmem', 'totalphysmem', 'freeswap', 'totalswap']: setattr(tm, a, getattr(self, a) + getattr(other, a)) tm.rusage = resource.struct_rusage([a + b for a, b in zip(self.rusage, other.rusage)]) return tm
def rusage_diff(r1, r2): """ Returns an rusage object where each field is the difference of the corresponding fields in `r1` and `r2`. """ rdiff = [(f1 - f2) for f1, f2 in zip(r1, r2)] return resource.struct_rusage(rdiff)
def create_struct_rusage(c_struct): return struct_rusage( (float(c_struct.ru_utime), float(c_struct.ru_stime), c_struct.ru_maxrss, c_struct.ru_ixrss, c_struct.ru_idrss, c_struct.ru_isrss, c_struct.ru_minflt, c_struct.ru_majflt, c_struct.ru_nswap, c_struct.ru_inblock, c_struct.ru_oublock, c_struct.ru_msgsnd, c_struct.ru_msgrcv, c_struct.ru_nsignals, c_struct.ru_nvcsw, c_struct.ru_nivcsw))
def track_iteration(range_type, start, stop=None, step=None, max_time=1.0): loops = 0 start_resources = resource.getrusage(resource.RUSAGE_SELF) target_time = time.time() + max_time while time.time() < target_time: loops += 1 range_obj = range_type(start, stop, step) result = [a for a in range_obj] stop_time = time.time() end_resources = resource.getrusage(resource.RUSAGE_SELF) assert len(result) == len(range_type(start, stop, step)) usage = resource.struct_rusage((end_resources[idx] - start_resources[idx]) for idx in range(len(end_resources))) duration = stop_time - (target_time - max_time) return loops, usage, duration
def create_struct_rusage(c_struct): return struct_rusage(( float(c_struct.ru_utime), float(c_struct.ru_stime), c_struct.ru_maxrss, c_struct.ru_ixrss, c_struct.ru_idrss, c_struct.ru_isrss, c_struct.ru_minflt, c_struct.ru_majflt, c_struct.ru_nswap, c_struct.ru_inblock, c_struct.ru_oublock, c_struct.ru_msgsnd, c_struct.ru_msgrcv, c_struct.ru_nsignals, c_struct.ru_nvcsw, c_struct.ru_nivcsw))
def diff_rusage(second, first): return resource.struct_rusage(map(sub, second, first))
def diff_rusage( r1, r2 ): return resource.struct_rusage(map( sub , r2, r1 ))
def diff_rusage( second, first ): return resource.struct_rusage(map( sub , second, first ))
def run_with_timeout(cmd, timeout=None, cwd=None, memlimit=None): proc = psutil.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, cwd=cwd, preexec_fn=(lambda: set_memlimit(memlimit, name=cmd[0])) if memlimit else None) timer_running = threading.Lock() def timer_func(): with timer_running: Runner.kill_proc_tree(proc) timer = threading.Timer(timeout, timer_func) if timeout else None try: if timer: timer.start() initial_time = datetime.datetime.now() try: initial_usage = resource.getrusage(resource.RUSAGE_CHILDREN) except Exception: logging.error('Cannot query system resources, no profiling available') initial_usage = None (outdata, outerr) = proc.communicate() real_time = datetime.datetime.now() - initial_time delta_usage = resource.struct_rusage( f1 - f0 for f0, f1 in zip(initial_usage, resource.getrusage(resource.RUSAGE_CHILDREN)) ) if initial_usage else None exitstatus = proc.wait(1) finally: if timer: # wait for the timer if it's running with timer_running: timeout_happened = timer.finished.is_set() # timeout_happened = real_time.total_seconds() > timeout timer.cancel() else: timeout_happened = False # collect relevant statistics stats = { 'command': cmd, 'exit_status': exitstatus, 'timeout_happened': timeout_happened, 'timeout': timeout, 'rtime': real_time.total_seconds(), 'workdir': os.getcwd() if cwd is None else cwd, 'stdout': outdata.decode(encoding='utf-8') if outdata is not None else '', 'stderr': outerr.decode(encoding='utf-8') if outerr is not None else '', 'hwinfo': Runner.hwinfo(), 'osinfo': Runner.osinfo(), 'sysload': Runner.sysload() } # get relevant keys from rusage for k in ('ru_utime', 'ru_stime', 'ru_maxrss', 'ru_ixrss', 'ru_idrss', 'ru_isrss', 'ru_inblock', 'ru_oublock'): stats[k] = getattr(delta_usage, k) return stats