Skip to content
Snippets Groups Projects
Commit b1962aed authored by René Schöne's avatar René Schöne
Browse files

Introducing self-made memory measurement using procfs.

- added property presleep to wait before each run (to fetch the pid for memory measurement)
parent 508a9cc1
No related branches found
No related tags found
No related merge requests found
......@@ -354,9 +354,10 @@
"No valid arguments found, use 'all', 'dirs', 'prefix', 'suffix' or a number of ids."))
(define (measurement-cli-call command-line)
(let ([first (if (= 0 (length command-line)) #f (car command-line))])
(if (= 0 (length command-line)) (print-usage)
(let ([first (car command-line)])
(sleep preesleep)
(cond
[(= 0 (length command-line)) (print-usage)]
[(string=? "all" first) (for-each run-test (map car params) (map cdr params))]
[(string=? "dirs" first) (for-each (lambda (entry) (display (car entry)) (display " ")) params)]
[(string=? "prefix" first)
......@@ -365,4 +366,4 @@
[(string=? "suffix" first)
(let ([param_subset (filter (lambda (p) (string-suffix? (cadr command-line) (car p))) params)])
(for-each run-test (map car param_subset) (map cdr param_subset)))]
[else (for-each run-test command-line (map (lambda (id) (cdr (assoc id params))) command-line))]))))
[else (for-each run-test command-line (map (lambda (id) (cdr (assoc id params))) command-line))])))))
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, re, os, csv, timeit, shutil, json
import sys, re, os, csv, timeit, shutil, json, threading, time
from datetime import datetime
from glob import glob, iglob
from subprocess import Popen
from subprocess import Popen, check_output, CalledProcessError
try:
from fabric.api import task, lcd, hosts, cd, run, get, execute
from fabric.colors import red, green
from fabric.contrib.console import confirm
# from fabric.contrib.console import confirm
except ImportError:
from fabric_workaround import task, red, lcd, green
import utils, properties
......@@ -82,18 +82,57 @@ def larceny(*dirs):
""" Measure larceny once. """
do_gen(call_larceny, 1, dirs)
class MemoryMeasurement(threading.Thread):
def __init__(self, logfile_id, prog_name):
threading.Thread.__init__(self)
self.logfile_id = logfile_id
self.prog_name = prog_name
self.running = True
self.pid = None
self.daemon = True
def run(self):
# find pid of prog
while self.running:
try:
self.pid = int(check_output(['pidof', '-s', self.prog_name]))
break
except CalledProcessError:
time.sleep(0.5)
# start thread periodically reading from /proc/$pid/status | grep VmSize
with open(self.logfile_id, 'w') as out_fd:
writer = csv.writer(out_fd)
writer.writerow(['time','vmsize'])
try:
while self.running:
time.sleep(1)
with open('/proc/{}/status'.format(self.pid)) as proc_fd:
lines = proc_fd.readlines()
size = next((l.split(':')[1].strip() for l in lines if l.startswith('VmSize')), None)
writer.writerow([datetime.today().isoformat(), size])
except IOError:
self.running = False
def abort(self):
self.running = False
def start_memory_measurement(logfile_id, prog_name):
thr = MemoryMeasurement(logfile_id, prog_name)
thr.start()
return thr
def do_gen(call_impl, number, dirs, memory = False):
cmd = 'measure'
with timed():
setup_profiling_dirs(call_impl, cmd)
for _ in xrange(int(number)):
if memory:
FNULL = open(os.devnull, 'w')
dstat_cmds = ['dstat', '-tclmdC', 'total,0,1,2,3', '--output']#, logfile_id]
for d in dirs:
process = Popen(dstat_cmds + [dstat_log(d)], stdout = FNULL)
thr = start_memory_measurement(memory_log(d), \
'racket' if call_impl == call_racket else 'larceny')
call_impl('cli.scm', cmd, d, capture = False)
process.kill()
thr.abort()
thr.join()
else:
call_impl('cli.scm', cmd, 'all' if dirs == () else ' '.join(dirs), capture = False)
# call_impl('larceny_profiling.scm', 'measure', 'all' if dirs == () else ' '.join(dirs), capture = False)
......@@ -101,6 +140,7 @@ def do_gen(call_impl, number, dirs, memory = False):
# conflate_results(skip_sol = True)
def dstat_log(directory): return 'profiling/{}/dstat.log'.format(directory)
def memory_log(directory): return 'profiling/{}/memory.csv'.format(directory)
def dirname(d): return os.path.split(os.path.dirname(d))[-1]
......@@ -427,12 +467,13 @@ def check():
with open('dependencies.txt') as fd:
if 'ilp-noncached\n' in fd:
noncached_scm = True
print 'Evaluation is set to:\n- {0}, {1}\n- {2}\n- {3}\n- {4}'.format(
print 'Evaluation is set to:\n'+'\n- '.join((
red('non-cached') if properties.noncached.value else 'cached',
red('flushed') if properties.flushed.value else 'unflushed',
(green('Yes: ') if properties.timing.value else 'No ') + 'measurement of execution times',
(green('Yes: ') if properties.profiling.value else 'No ') + 'profiling of attribute metrics',
(green('Yes: ') if properties.lp_write.value else 'No ') + 'write of LP files',)
(green('Yes: ') if properties.lp_write.value else 'No ') + 'write of LP files',
'Wait {0} second(s) before each experiment'.format(properties.preesleep.value)))
if noncached_scm != properties.noncached.value:
print 'Attention: Compiled ilp ({}) differs from properties file setting ({}).'.format(
nc_tostring(noncached_scm), nc_tostring(properties.noncached.value))
......@@ -453,6 +494,19 @@ def help():
print '4. (Mandatory) Execute distinction-of-changes, to create splitted csv files'
print '5. (Optional) Rerun notebook to update diagrams'
def confirm(question, default_val = False):
prompt = question
if isinstance(default_val, bool):
prompt += ' [{0}]'.format('Y/n' if default_val else 'y/N')
answer = raw_input(prompt + ' ')
if answer == '':
answer = default_val
if isinstance(default_val, bool):
return answer in ('y','Y','yes','Yes',True)
if isinstance(default_val,int):
return int(answer)
return answer
@task
def setup(name = None, to_default = False):
"""
......
......@@ -5,25 +5,27 @@ properties_fname = 'scheme.properties'
def int_to_bool(i):
return i in ('1', 1, True)
def bool_to_int(b):
return 1 if b else 0
class PItem(object):
def __init__(self, name, question, default, key, conv = int_to_bool):
def __init__(self, name, question, default, key, conv_read = int_to_bool, conv_write = bool_to_int):
self.name = name
self.question = question
self.default = default
self.key = key
self.conv = conv
self.conv_r = conv_read
self.conv_w = conv_write
self._value = default
@property
def value(self):
return self._value
@value.setter
def value(self, new_value):
self._value = self.conv(new_value)
self._value = self.conv_r(new_value)
def write_value(self):
def v(value):
return 1 if value else 0
local_quiet(r'sed -i "s/{0}\(\s*\)= {1}/{0}\1= {2}/" {3}'.format(
self.key, v(not self.value), v(self.value), properties_fname))
self.key, self.conv_w(not self.value), self.conv_w(self.value), properties_fname))
timing = PItem('timing', 'Measure runtimes?', False, 'timing')
log_info = PItem('info', 'Log INFO messages?', True, 'log.info')
......@@ -32,8 +34,10 @@ lp_write = PItem('lp', 'Write out ILP files?', False, 'measure.lp.write')
profiling = PItem('profiling', 'Profile attribute metrics?', True, 'measure.profiling')
flushed = PItem('flushed', 'Use strategy "flushed"?', False, 'measure.flush')
noncached = PItem('noncached', 'Use strategy "noncached"?', False, 'measure.non-cached')
preesleep = PItem('presleep', 'Seconds to wait before running complete run?', 0.0, 'measure.presleep',
conv_read = float, conv_write = lambda x : x if x else '.*' )
items = [timing, log_info, log_debug, lp_write, profiling, flushed, noncached]
items = [timing, log_info, log_debug, lp_write, profiling, flushed, noncached, preesleep]
#class Properties(object):
# def __init__(self, f):
......
......@@ -2,7 +2,7 @@
(library
(mquat properties)
(export timing? profiling? log.debug? log.info? log.warn? write-ilp? measure-flush? measure-non-cached?)
(export timing? profiling? log.debug? log.info? log.warn? write-ilp? measure-flush? measure-non-cached? preesleep)
(import (rnrs) (only (srfi :13) string-tokenize string-index string-trim-both) (srfi :14))
(define (file->char_list path)
......@@ -43,4 +43,5 @@
(define log.warn? (get-value "log.warn" #t))
(define write-ilp? (get-value "measure.lp.write" #f))
(define measure-flush? (get-value "measure.flush" #f))
(define measure-non-cached? (get-value "measure.non-cached" #f)))
(define measure-non-cached? (get-value "measure.non-cached" #f))
(define preesleep (get-value "measure.preesleep" 0.0)))
......@@ -8,3 +8,4 @@ measure.lp.write = 0
measure.profiling = 1
measure.flush = 0
measure.non-cached = 0
measure.presleep = 2.0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment