aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fl.fischer@fau.de>2020-05-11 14:30:39 +0200
committerFlorian Fischer <florian.fl.fischer@fau.de>2020-06-02 11:18:47 +0200
commitffacbbece6af0f84d4bc7c8c4365797e8a433ef7 (patch)
tree57ad32954b0e3903b3c9472090f2f414efd8dfc5
parentf2ebd50f099af160bc39584afa95f812215630d1 (diff)
downloadallocbench-ffacbbece6af0f84d4bc7c8c4365797e8a433ef7.tar.gz
allocbench-ffacbbece6af0f84d4bc7c8c4365797e8a433ef7.zip
format the source code using yapf
-rw-r--r--allocbench/allocator.py29
-rw-r--r--allocbench/allocators/mimalloc.py1
-rw-r--r--allocbench/allocators/scalloc.py3
-rw-r--r--allocbench/allocators/tcmalloc.py5
-rw-r--r--allocbench/artifact.py15
-rw-r--r--allocbench/benchmark.py14
-rw-r--r--allocbench/benchmarks/dj_trace.py2
-rw-r--r--allocbench/benchmarks/espresso.py3
-rw-r--r--allocbench/benchmarks/httpd.py2
-rw-r--r--allocbench/benchmarks/keydb.py5
-rw-r--r--allocbench/benchmarks/larson.py2
-rw-r--r--allocbench/benchmarks/loop.py62
-rw-r--r--allocbench/benchmarks/mysql.py9
-rw-r--r--allocbench/benchmarks/raxmlng.py2
-rw-r--r--allocbench/benchmarks/rdtsc.py2
-rw-r--r--allocbench/facter.py4
-rw-r--r--allocbench/globalvars.py11
-rw-r--r--allocbench/plots.py77
-rw-r--r--allocbench/util.py2
-rwxr-xr-xmerge.py38
-rwxr-xr-xscripts/histogram.py27
-rwxr-xr-xscripts/paper_plots.py87
-rwxr-xr-xscripts/print_facts.py10
23 files changed, 265 insertions, 147 deletions
diff --git a/allocbench/allocator.py b/allocbench/allocator.py
index 0eefce2..cbeee06 100644
--- a/allocbench/allocator.py
+++ b/allocbench/allocator.py
@@ -98,14 +98,17 @@ class Allocator:
patch_content = patch_file.read()
# check if patch is already applied
- not_patched = run_cmd(
- ["patch", "-R", "-p0", "-s", "-f", "--dry-run", "--verbose"],
- cwd=cwd,
- input=patch_content,
- check=False).returncode
+ not_patched = run_cmd([
+ "patch", "-R", "-p0", "-s", "-f", "--dry-run", "--verbose"
+ ],
+ cwd=cwd,
+ input=patch_content,
+ check=False).returncode
if not_patched:
try:
- run_cmd(["patch", "-p0", "--verbose"], cwd=cwd, input=patch_content)
+ run_cmd(["patch", "-p0", "--verbose"],
+ cwd=cwd,
+ input=patch_content)
except CalledProcessError as err:
print_debug(err.stderr, file=sys.stderr)
print_error(f"Patching of {self.name} failed.")
@@ -180,6 +183,7 @@ class Allocator:
print_debug("Resulting dictionary:", res_dict)
return res_dict
+
def collect_installed_allocators():
"""Collect allocators using installed system libraries"""
@@ -214,6 +218,7 @@ def collect_installed_allocators():
return allocators
+
def collect_available_allocators():
"""Collect all allocator definitions shipped with allocbench"""
@@ -228,6 +233,7 @@ def collect_available_allocators():
return available_allocators
+
def read_allocators_collection_file(alloc_path):
"""Read and evaluate a python file looking for an exported dict called allocators"""
@@ -276,11 +282,16 @@ def collect_allocators(allocators):
# interpret name as allocator name or wildcard
else:
- matched_allocators = fnmatch.filter(available_allocators.keys(), name)
+ matched_allocators = fnmatch.filter(available_allocators.keys(),
+ name)
if matched_allocators:
- ret.update({a: available_allocators[a].build() for a in matched_allocators})
+ ret.update({
+ a: available_allocators[a].build()
+ for a in matched_allocators
+ })
else:
print_error(
name,
- "is neither a python file or a known allocator definition.")
+ "is neither a python file or a known allocator definition."
+ )
return ret
diff --git a/allocbench/allocators/mimalloc.py b/allocbench/allocators/mimalloc.py
index c6952c5..8f8f1ff 100644
--- a/allocbench/allocators/mimalloc.py
+++ b/allocbench/allocators/mimalloc.py
@@ -34,5 +34,6 @@ class Mimalloc(Allocator):
super().__init__(name, **kwargs)
+
# pylint: disable=invalid-name
mimalloc = Mimalloc("mimalloc", version="v1.6.0")
diff --git a/allocbench/allocators/scalloc.py b/allocbench/allocators/scalloc.py
index d009226..4541a03 100644
--- a/allocbench/allocators/scalloc.py
+++ b/allocbench/allocators/scalloc.py
@@ -42,7 +42,8 @@ class Scalloc(Allocator):
super().__init__(name, **kwargs)
def build(self):
- with open("/proc/sys/vm/overcommit_memory", "r") as overcommit_memory_file:
+ with open("/proc/sys/vm/overcommit_memory",
+ "r") as overcommit_memory_file:
if overcommit_memory_file.read()[0] != "1":
raise AssertionError("""\
vm.overcommit_memory not set
diff --git a/allocbench/allocators/tcmalloc.py b/allocbench/allocators/tcmalloc.py
index 450b613..2c026a5 100644
--- a/allocbench/allocators/tcmalloc.py
+++ b/allocbench/allocators/tcmalloc.py
@@ -84,8 +84,9 @@ tcmalloc_gperftools_align = TCMallocGperftools("TCMalloc-Gperftools-Aligned",
version="gperftools-2.7",
color="xkcd:navy blue")
-tcmalloc_gperftools_align.ld_preload = (f"{BUILDDIR}/align_to_cl.so "
- f"{tcmalloc_gperftools_align.ld_preload}")
+tcmalloc_gperftools_align.ld_preload = (
+ f"{BUILDDIR}/align_to_cl.so "
+ f"{tcmalloc_gperftools_align.ld_preload}")
tcmalloc_gperftools_cacheline_exclusive = TCMallocGperftools(
"TCMalloc-Gperftools-Cacheline-Exclusive",
diff --git a/allocbench/artifact.py b/allocbench/artifact.py
index 3504486..28b82aa 100644
--- a/allocbench/artifact.py
+++ b/allocbench/artifact.py
@@ -72,12 +72,16 @@ class GitArtifact(Artifact):
# check if we have already provided this checkout
if os.path.exists(location):
try:
- run_cmd(["git", "fetch", "--force"], output_verbosity=1, cwd=location)
+ run_cmd(["git", "fetch", "--force"],
+ output_verbosity=1,
+ cwd=location)
except CalledProcessError:
print_error(f"Failed to update {location}")
raise
try:
- run_cmd(["git", "reset", "--hard", checkout], output_verbosity=1, cwd=location)
+ run_cmd(["git", "reset", "--hard", checkout],
+ output_verbosity=1,
+ cwd=location)
except CalledProcessError:
print_error(f"Failed to update {location}")
raise
@@ -90,7 +94,9 @@ class GitArtifact(Artifact):
# update repo
print_status(f'Updating git repository "{self.name}" ...')
try:
- run_cmd(["git", "fetch", "--force"], output_verbosity=1, cwd=self.repo)
+ run_cmd(["git", "fetch", "--force"],
+ output_verbosity=1,
+ cwd=self.repo)
except CalledProcessError:
print_error(f"Failed to update {self.name}")
raise
@@ -125,7 +131,8 @@ class ArchiveArtifact(Artifact):
f'Archive format "{format}" not in supported list {self.supported_formats}'
)
self.archive_format = archive_format
- self.archive = os.path.join(self.basedir, f"{self.name}.{self.archive_format}")
+ self.archive = os.path.join(self.basedir,
+ f"{self.name}.{self.archive_format}")
self.checksum = checksum
def retrieve(self):
diff --git a/allocbench/benchmark.py b/allocbench/benchmark.py
index 6a2e7f2..afcb126 100644
--- a/allocbench/benchmark.py
+++ b/allocbench/benchmark.py
@@ -547,8 +547,10 @@ class Benchmark:
# Preallocator hook
if hasattr(self, "preallocator_hook"):
- self.preallocator_hook((alloc_name, alloc), run, # pylint: disable=no-member
- os.environ)
+ self.preallocator_hook(
+ (alloc_name, alloc),
+ run, # pylint: disable=no-member
+ os.environ)
# Run benchmark for alloc
for perm in self.iterate_args():
@@ -637,12 +639,8 @@ class Benchmark:
result, res.stderr, alloc_name, perm)
if hasattr(self, "process_output"): # pylint: disable=no-member
- self.process_output(
- result,
- res.stdout,
- res.stderr,
- alloc_name,
- perm)
+ self.process_output(result, res.stdout, res.stderr,
+ alloc_name, perm)
# save a valid result so we can expand invalid ones
if valid_result is None:
diff --git a/allocbench/benchmarks/dj_trace.py b/allocbench/benchmarks/dj_trace.py
index 09adcd4..e96ab5d 100644
--- a/allocbench/benchmarks/dj_trace.py
+++ b/allocbench/benchmarks/dj_trace.py
@@ -385,7 +385,7 @@ class BenchmarkDJTrace(Benchmark):
for perm in self.iterate_args(args=args):
cycles = abplt.get_y_data(self, "{cycles}", allocator,
- perm)[0]
+ perm)[0]
times = func_times_means[allocator][perm]
rss = rss_means[allocator][perm]
print(fmt.format(perm.workload, cycles, times[0], times[1],
diff --git a/allocbench/benchmarks/espresso.py b/allocbench/benchmarks/espresso.py
index 0b9b852..7960286 100644
--- a/allocbench/benchmarks/espresso.py
+++ b/allocbench/benchmarks/espresso.py
@@ -69,8 +69,7 @@ class BenchmarkEspresso(Benchmark):
self.cmd = "espresso{binary_suffix} {file}"
self.args = {
- "file":
- [os.path.join(BENCHSRCDIR, name, "largest.espresso")]
+ "file": [os.path.join(BENCHSRCDIR, name, "largest.espresso")]
}
self.requirements = ["espresso"]
diff --git a/allocbench/benchmarks/httpd.py b/allocbench/benchmarks/httpd.py
index a601612..ac06459 100644
--- a/allocbench/benchmarks/httpd.py
+++ b/allocbench/benchmarks/httpd.py
@@ -50,7 +50,7 @@ class BenchmarkHTTPD(Benchmark):
"ab", "-V")
@staticmethod
- def process_output(result, stdout, stderr, allocator, perm): # pylint: disable=too-many-arguments, unused-argument
+ def process_output(result, stdout, stderr, allocator, perm): # pylint: disable=too-many-arguments, unused-argument
result["time"] = re.search(
"Time taken for tests:\\s*(\\d*\\.\\d*) seconds", stdout).group(1)
result["requests"] = re.search(
diff --git a/allocbench/benchmarks/keydb.py b/allocbench/benchmarks/keydb.py
index 1cb6e64..3aeb6f1 100644
--- a/allocbench/benchmarks/keydb.py
+++ b/allocbench/benchmarks/keydb.py
@@ -53,7 +53,8 @@ class BenchmarkKeyDB(Benchmark):
keydb_dir = os.path.join(self.build_dir, "keydb")
if not os.path.exists(os.path.join(self.build_dir, "keydb-server")):
- keydb_artifact = GitArtifact("keydb", "https://github.com/JohnSully/KeyDB")
+ keydb_artifact = GitArtifact("keydb",
+ "https://github.com/JohnSully/KeyDB")
os.makedirs(self.build_dir, exist_ok=True)
@@ -92,7 +93,7 @@ class BenchmarkKeyDB(Benchmark):
os.link(src, dest)
@staticmethod
- def process_output(result, stdout, stderr, allocator, perm): # pylint: disable=too-many-arguments, unused-argument
+ def process_output(result, stdout, stderr, allocator, perm): # pylint: disable=too-many-arguments, unused-argument
cmds = ["Sets", "Gets", "Waits", "Totals"]
stats = ["ops", "hits", "misses", "latency", "throughput"]
for line in stdout.splitlines():
diff --git a/allocbench/benchmarks/larson.py b/allocbench/benchmarks/larson.py
index cc78be7..0d25126 100644
--- a/allocbench/benchmarks/larson.py
+++ b/allocbench/benchmarks/larson.py
@@ -72,7 +72,7 @@ class BenchmarkLarson(Benchmark):
super().__init__(name)
@staticmethod
- def process_output(result, stdout, stderr, target, perm): # pylint: disable=too-many-arguments, unused-argument
+ def process_output(result, stdout, stderr, target, perm): # pylint: disable=too-many-arguments, unused-argument
for line in stdout.splitlines():
res = THROUGHPUT_RE.match(line)
if res:
diff --git a/allocbench/benchmarks/loop.py b/allocbench/benchmarks/loop.py
index 1c22da8..ae7d36b 100644
--- a/allocbench/benchmarks/loop.py
+++ b/allocbench/benchmarks/loop.py
@@ -57,53 +57,49 @@ class BenchmarkLoop(Benchmark):
super().__init__(name)
@staticmethod
- def process_output(result, stdout, stderr, alloc, perm): # pylint: disable=too-many-arguments, unused-argument
+ def process_output(result, stdout, stderr, alloc, perm): # pylint: disable=too-many-arguments, unused-argument
result["mops"] = perm.threads / float(result["task-clock"])
def summary(self):
# Speed
- plt.plot(
- self,
- "{mops}",
- fig_options={
- 'ylabel': 'MOPS/cpu-second',
- 'title': 'Loop: {fixed_part_str}',
- 'autoticks': False,
- },
- file_postfix="time")
+ plt.plot(self,
+ "{mops}",
+ fig_options={
+ 'ylabel': 'MOPS/cpu-second',
+ 'title': 'Loop: {fixed_part_str}',
+ 'autoticks': False,
+ },
+ file_postfix="time")
# L1 cache misses
- plt.plot(
- self,
- "({L1-dcache-load-misses}/{L1-dcache-loads})*100",
- fig_options={
- 'ylabel': "L1 misses in %",
- 'title': "Loop l1 cache misses: {fixed_part_str}",
- 'autoticks': False,
- },
- file_postfix="l1misses")
+ plt.plot(self,
+ "({L1-dcache-load-misses}/{L1-dcache-loads})*100",
+ fig_options={
+ 'ylabel': "L1 misses in %",
+ 'title': "Loop l1 cache misses: {fixed_part_str}",
+ 'autoticks': False,
+ },
+ file_postfix="l1misses")
# Speed Matrix
- plt.write_best_doublearg_tex_table(
- self,
- "{mops}",
- file_postfix="time.matrix")
-
- plt.write_tex_table(
- self,
- [{
- "label": "MOPS/s",
- "expression": "{mops}",
- "sort": ">"
- }],
- file_postfix="mops.table")
+ plt.write_best_doublearg_tex_table(self,
+ "{mops}",
+ file_postfix="time.matrix")
+
+ plt.write_tex_table(self, [{
+ "label": "MOPS/s",
+ "expression": "{mops}",
+ "sort": ">"
+ }],
+ file_postfix="mops.table")
plt.export_stats_to_csv(self, "task-clock")
plt.export_stats_to_dataref(self, "task-clock")
# pgfplot test
plt.pgfplot(self,
- self.iterate_args(fixed={"maxsize": 1024}, args=self.results["args"]),
+ self.iterate_args(fixed={"maxsize": 1024},
+ args=self.results["args"]),
"int(perm.threads)",
"{mops}",
xlabel="Threads",
diff --git a/allocbench/benchmarks/mysql.py b/allocbench/benchmarks/mysql.py
index 111d482..611405d 100644
--- a/allocbench/benchmarks/mysql.py
+++ b/allocbench/benchmarks/mysql.py
@@ -185,7 +185,7 @@ class BenchmarkMYSQL(Benchmark):
shutil.rmtree(self.build_dir, ignore_errors=True)
@staticmethod
- def process_output(result, stdout, stderr, allocator, perm): # pylint: disable=too-many-arguments, unused-argument
+ def process_output(result, stdout, stderr, allocator, perm): # pylint: disable=too-many-arguments, unused-argument
result["transactions"] = re.search("transactions:\\s*(\\d*)",
stdout).group(1)
result["queries"] = re.search("queries:\\s*(\\d*)", stdout).group(1)
@@ -294,7 +294,8 @@ class BenchmarkMYSQL(Benchmark):
fname = ".".join([self.name, "transactions.tex"])
headers = [perm.nthreads for perm in self.iterate_args(args=args)]
with open(fname, "w") as table_file:
- print("\\begin{tabular}{| l" + " l" * len(headers) + " |}", file=table_file)
+ print("\\begin{tabular}{| l" + " l" * len(headers) + " |}",
+ file=table_file)
print("Fäden / Allokator ", end=" ", file=table_file)
for head in headers:
print("& {}".format(head), end=" ", file=table_file)
@@ -311,7 +312,9 @@ class BenchmarkMYSQL(Benchmark):
color = "red"
else:
color = "black"
- print(entry_string.format(color, mean), end=" ", file=table_file)
+ print(entry_string.format(color, mean),
+ end=" ",
+ file=table_file)
print("\\\\", file=table_file)
print("\\end{tabular}", file=table_file)
diff --git a/allocbench/benchmarks/raxmlng.py b/allocbench/benchmarks/raxmlng.py
index b943e4e..be2a080 100644
--- a/allocbench/benchmarks/raxmlng.py
+++ b/allocbench/benchmarks/raxmlng.py
@@ -76,7 +76,7 @@ class BenchmarkRaxmlng(Benchmark):
os.remove(direntry)
@staticmethod
- def process_output(result, stdout, stderr, allocator, perm): # pylint: disable=too-many-arguments, unused-argument, no-self-use
+ def process_output(result, stdout, stderr, allocator, perm): # pylint: disable=too-many-arguments, unused-argument, no-self-use
result["runtime"] = RUNTIME_RE.search(stdout).group("runtime")
def summary(self):
diff --git a/allocbench/benchmarks/rdtsc.py b/allocbench/benchmarks/rdtsc.py
index 0600f4c..4414d49 100644
--- a/allocbench/benchmarks/rdtsc.py
+++ b/allocbench/benchmarks/rdtsc.py
@@ -47,7 +47,7 @@ class BenchmarkRdtsc(Benchmark):
super().__init__(name)
@staticmethod
- def process_output(result, stdout, stderr, alloc, perm): # pylint: disable=too-many-arguments, unused-argument
+ def process_output(result, stdout, stderr, alloc, perm): # pylint: disable=too-many-arguments, unused-argument
all_cycles = []
for line in stdout.splitlines():
all_cycles.append(int(line.split()[1]))
diff --git a/allocbench/facter.py b/allocbench/facter.py
index 57f5abd..afc1d02 100644
--- a/allocbench/facter.py
+++ b/allocbench/facter.py
@@ -30,6 +30,7 @@ from allocbench.util import print_debug, print_info, print_warn, run_cmd
FACTS = {}
+
def collect_facts():
"""Collect general facts about the benchmark environment"""
# Populate allocbench.globalvars.facts on import
@@ -93,8 +94,9 @@ def load_facts(path=None):
print_info(f"Loading facts from: {filename}")
+
def allocbench_version():
- "Store and return allocbench version string."""
+ """Store and return allocbench version string."""
if "allocbench" in FACTS:
return FACTS["allocbench"]
diff --git a/allocbench/globalvars.py b/allocbench/globalvars.py
index bb41dad..f2a98f0 100644
--- a/allocbench/globalvars.py
+++ b/allocbench/globalvars.py
@@ -14,7 +14,6 @@
#
# You should have received a copy of the GNU General Public License
# along with allocbench. If not, see <http://www.gnu.org/licenses/>.
-
"""Global variables for allocbench
VERBOSITY: Verbosity level -1: quiet, 0: status, 1: info, 2: stdout of subcommands, 3: debug info
@@ -33,13 +32,13 @@ RESDIR: Directory were the benchmark results are stored
import inspect
import os
-
VERBOSITY = 0
ALLOCATORS = {}
# /.../allocbench/allocbench
-SRCDIR = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+SRCDIR = os.path.dirname(
+ os.path.abspath(inspect.getfile(inspect.currentframe())))
# /.../allocbench/allocbench/benchmarks
BENCHSRCDIR = os.path.join(SRCDIR, "benchmarks")
@@ -58,8 +57,10 @@ ALLOCBUILDDIR = os.path.join(BUILDDIR, "allocators")
RESDIR = None
-BENCHMARKS = [e[:-3] for e in os.listdir(os.path.join(ALLOCBENCHDIR, BENCHSRCDIR))
- if e[-3:] == ".py" and e != "__init__.py"]
+BENCHMARKS = [
+ e[:-3] for e in os.listdir(os.path.join(ALLOCBENCHDIR, BENCHSRCDIR))
+ if e[-3:] == ".py" and e != "__init__.py"
+]
SUMMARY_FILE_EXT = "svg"
diff --git a/allocbench/plots.py b/allocbench/plots.py
index c73b737..cf7a0e3 100644
--- a/allocbench/plots.py
+++ b/allocbench/plots.py
@@ -32,7 +32,7 @@ from allocbench.globalvars import SUMMARY_FILE_EXT, LATEX_CUSTOM_PREAMBLE
from allocbench.util import print_debug, print_warn
# This is useful when evaluating strings in the plot functions. str(np.NaN) == "nan"
-nan = np.NaN # pylint: disable=invalid-name
+nan = np.NaN # pylint: disable=invalid-name
DEFAULT_PLOT_OPTIONS = {
'plot': {
@@ -69,20 +69,20 @@ DEFAULT_FIG_OPTIONS = {
FIGURES = {}
+
def _set_all_alloc_colors(allocators):
"""Populate all not set allocator colors with matplotlib 'C' colors"""
explicit_colors = [
v["color"] for v in allocators.values() if v["color"] is not None
]
matplotlib_c_colors = ["C" + str(i) for i in range(0, 10)]
- avail_colors = [
- c for c in matplotlib_c_colors if c not in explicit_colors
- ]
+ avail_colors = [c for c in matplotlib_c_colors if c not in explicit_colors]
for alloc in allocators.values():
if alloc["color"] is None:
alloc["color"] = avail_colors.pop()
+
def get_alloc_color(bench, alloc):
"""Retrieve color of an allocator"""
if isinstance(alloc, str):
@@ -96,20 +96,26 @@ def get_alloc_color(bench, alloc):
#https://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string
def _eval_with_stat(bench, evaluation, alloc, perm, stat):
"""Helper to evaluate a datapoint description string as arithmetic operation"""
-
def _eval(node):
"""evaluate a arithmetic ast node"""
# supported operators
- operators = {ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul,
- ast.Div: operator.truediv, ast.Pow: operator.pow, ast.BitXor: operator.xor,
- ast.USub: operator.neg}
-
- if isinstance(node, ast.Num): # <number>
+ operators = {
+ ast.Add: operator.add,
+ ast.Sub: operator.sub,
+ ast.Mult: operator.mul,
+ ast.Div: operator.truediv,
+ ast.Pow: operator.pow,
+ ast.BitXor: operator.xor,
+ ast.USub: operator.neg
+ }
+
+ if isinstance(node, ast.Num): # <number>
return node.n
- if isinstance(node, ast.BinOp): # <left> <operator> <right>
- return operators[type(node.op)](_eval(node.left), _eval(node.right))
- if isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
+ if isinstance(node, ast.BinOp): # <left> <operator> <right>
+ return operators[type(node.op)](_eval(node.left),
+ _eval(node.right))
+ if isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
return operators[type(node.op)](_eval(node.operand))
raise TypeError(node)
@@ -128,8 +134,7 @@ def _eval_with_stat(bench, evaluation, alloc, perm, stat):
return _eval(node.body)
except TypeError:
print_debug(traceback.format_exc())
- print_warn(
- f"{expr} could not be evaluated as arithmetic operation")
+ print_warn(f"{expr} could not be evaluated as arithmetic operation")
return nan
@@ -151,6 +156,7 @@ def get_y_data(bench, expression, allocator, perms, stat="mean", scale=None):
return y_data
+
def _create_plot_options(plot_type, **kwargs):
"""
Create a plot options dictionary.
@@ -177,6 +183,7 @@ def _create_plot_options(plot_type, **kwargs):
return options
+
def _create_figure_options(plot_type, fig_label, **kwargs):
"""
Create a figure options dictionary
@@ -206,6 +213,7 @@ def _create_figure_options(plot_type, fig_label, **kwargs):
return options
+
def _plot(bench,
allocators,
y_expression,
@@ -276,7 +284,8 @@ def _plot(bench,
plt.legend(loc=fig_options['legend_pos'])
if not fig_options['autoticks']:
- plt.xticks(_x_data - (len(allocators) / 2 * plot_options['width']), x_data)
+ plt.xticks(_x_data - (len(allocators) / 2 * plot_options['width']),
+ x_data)
plt.xlabel(fig_options['xlabel'])
plt.ylabel(fig_options['ylabel'])
@@ -291,6 +300,7 @@ def _plot(bench,
return fig
+
def plot(bench,
y_expression,
plot_type='errorbar',
@@ -361,14 +371,17 @@ def plot(bench,
for loose_arg in x_args:
x_data = args[loose_arg]
- fixed_args = [[(k, v) for v in args[k]] for k in args if k != loose_arg]
+ fixed_args = [[(k, v) for v in args[k]] for k in args
+ if k != loose_arg]
for fixed_part_tuple in itertools.product(*fixed_args):
- fixed_part = {k:v for k, v in fixed_part_tuple}
+ fixed_part = {k: v for k, v in fixed_part_tuple}
- fixed_part_str = ".".join([f'{k}={v}' for k, v in fixed_part.items()])
+ fixed_part_str = ".".join(
+ [f'{k}={v}' for k, v in fixed_part.items()])
fig_label = f'{bench.name}.{fixed_part_str}.{file_postfix}'
- cur_plot_options = _create_plot_options(plot_type, **plot_options or {})
+ cur_plot_options = _create_plot_options(plot_type, **plot_options
+ or {})
cur_fig_options = {}
@@ -378,7 +391,8 @@ def plot(bench,
if isinstance(value, str):
cur_fig_options[option] = value.format(**substitutions)
- cur_fig_options = _create_figure_options(plot_type, fig_label, **cur_fig_options)
+ cur_fig_options = _create_figure_options(plot_type, fig_label,
+ **cur_fig_options)
# plot specific defaults
cur_fig_options.setdefault("ylabel", y_expression)
@@ -397,13 +411,19 @@ def plot(bench,
sumdir=sumdir,
file_ext=file_ext)
+
def print_common_facts(comment_symbol="", file=None):
print(comment_symbol, "Common facts:", file=file)
for fact, value in facter.FACTS.items():
print(f"{comment_symbol} {fact}: {value}", file=file)
print(file=file)
-def print_facts(bench, comment_symbol="", print_common=True, print_allocators=False, file=None):
+
+def print_facts(bench,
+ comment_symbol="",
+ print_common=True,
+ print_allocators=False,
+ file=None):
"""Write collected facts about used system and benchmark to file"""
print(comment_symbol, bench.name, file=file)
print(file=file)
@@ -416,7 +436,9 @@ def print_facts(bench, comment_symbol="", print_common=True, print_allocators=Fa
print(comment_symbol, f"{fact}: {value}", file=file)
if print_allocators:
- print(comment_symbol, f'allocators: {" ".join(bench.results["allocators"])}', file=file)
+ print(comment_symbol,
+ f'allocators: {" ".join(bench.results["allocators"])}',
+ file=file)
print(file=file)
@@ -755,7 +777,7 @@ def pgfplot(bench,
for alloc_name, alloc_dict in allocators.items():
if colors:
# define color
- rgb = matplotlib.colors.to_rgb(get_alloc_color(bench, alloc_dict)) # pylint: disable=unused-variable
+ rgb = matplotlib.colors.to_rgb(get_alloc_color(bench, alloc_dict)) # pylint: disable=unused-variable
color_definitions += (f"\\providecolor{{{alloc_name}-color}}"
"{{rgb}}{{{rgb[0]},{rgb[1]},{rgb[2]}}}\n")
style_definitions += (f"\\pgfplotsset{{{alloc_name}/"
@@ -777,7 +799,12 @@ def pgfplot(bench,
for perm in perms:
xval = _eval_with_stat(bench, xexpr, alloc_name, perm, "mean")
- yval = _get_y_data(bench, yexpr, alloc_name, perm, "mean", scale=scale)
+ yval = _get_y_data(bench,
+ yexpr,
+ alloc_name,
+ perm,
+ "mean",
+ scale=scale)
error = ""
if error_bars:
error = f" {_eval_with_stat(bench, yexpr, alloc_name, perm, 'std')}"
diff --git a/allocbench/util.py b/allocbench/util.py
index 681211f..ff18137 100644
--- a/allocbench/util.py
+++ b/allocbench/util.py
@@ -30,7 +30,7 @@ def run_cmd(cmd,
shell=False,
check=True,
cwd=None,
- input=None): # pylint: disable=redefined-builtin
+ input=None): # pylint: disable=redefined-builtin
"""subprocess.run wrapper which cares about the set verbosity"""
if capture:
stdout = subprocess.PIPE
diff --git a/merge.py b/merge.py
index 7d95d90..ca20092 100755
--- a/merge.py
+++ b/merge.py
@@ -16,7 +16,6 @@
#
# You should have received a copy of the GNU General Public License
# along with allocbench. If not, see <http://www.gnu.org/licenses/>.
-
"""Merge two compatible results of an allocbench run"""
import argparse
@@ -28,6 +27,7 @@ import sys
import allocbench.facter as facter
from allocbench.util import print_license_and_exit
+
def load_file(filename):
if filename.endswith("json"):
with open(filename, "r") as json_file:
@@ -42,13 +42,27 @@ def main():
print_license_and_exit()
parser = argparse.ArgumentParser(description="Merge to allocbench results")
- parser.add_argument("src", help="results which should be merged into dest", type=str)
- parser.add_argument("dest", help="results in which src should be merged", type=str)
- parser.add_argument("--license", help="print license info and exit", action='store_true')
- parser.add_argument("--version", help="print version info and exit", action='version',
+ parser.add_argument("src",
+ help="results which should be merged into dest",
+ type=str)
+ parser.add_argument("dest",
+ help="results in which src should be merged",
+ type=str)
+ parser.add_argument("--license",
+ help="print license info and exit",
+ action='store_true')
+ parser.add_argument("--version",
+ help="print version info and exit",
+ action='version',
version=f"allocbench {facter.allocbench_version()}")
- parser.add_argument("-b", "--benchmarks", help="benchmarks to summarize", nargs='+')
- parser.add_argument("-x", "--exclude-benchmarks", help="benchmarks to exclude", nargs='+')
+ parser.add_argument("-b",
+ "--benchmarks",
+ help="benchmarks to summarize",
+ nargs='+')
+ parser.add_argument("-x",
+ "--exclude-benchmarks",
+ help="benchmarks to exclude",
+ nargs='+')
args = parser.parse_args()
@@ -66,7 +80,9 @@ def main():
dest_save = os.path.join(args.dest, os.path.basename(src_save))
if not os.path.isfile(dest_save):
- print(f"Can't merge {src_save} because {os.path.basename(src_save)} not in {args.dest}")
+ print(
+ f"Can't merge {src_save} because {os.path.basename(src_save)} not in {args.dest}"
+ )
continue
src_results = load_file(src_save)
@@ -79,11 +95,13 @@ def main():
continue
print("merging", alloc, "from", src_save, "into", dest_save)
- dest_results["allocators"][alloc] = src_results["allocators"][alloc]
+ dest_results["allocators"][alloc] = src_results["allocators"][
+ alloc]
dest_results[alloc] = src_results[alloc]
dest_results["stats"][alloc] = src_results["stats"][alloc]
- with open(os.path.splitext(dest_save)[0] + ".json", "w") as result_file:
+ with open(os.path.splitext(dest_save)[0] + ".json",
+ "w") as result_file:
json.dump(dest_results, result_file)
diff --git a/scripts/histogram.py b/scripts/histogram.py
index 2bf6779..f1f8464 100755
--- a/scripts/histogram.py
+++ b/scripts/histogram.py
@@ -16,7 +16,6 @@
#
# You should have received a copy of the GNU General Public License
# along with allocbench. If not, see <http://www.gnu.org/licenses/>.
-
"""Plot an interactive histogram from malt or chattymalloc output file"""
import argparse
@@ -28,17 +27,29 @@ import sys
import matplotlib.pyplot as plt
-currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+currentdir = os.path.dirname(
+ os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
def main():
- parser = argparse.ArgumentParser(description="Plot histograms using a malt or chattymalloc output file")
- parser.add_argument("input_file", help="path to malt or chattymalloc output file", type=str)
- parser.add_argument("-e", "--export", help="export to csv", action="store_true")
- parser.add_argument("-n", "--no-ascii", help="don't output a ascii histogram", action="store_true")
- parser.add_argument("-i", "--interactive", help="open interactive matplotlib histogram plots",
+ parser = argparse.ArgumentParser(
+ description="Plot histograms using a malt or chattymalloc output file")
+ parser.add_argument("input_file",
+ help="path to malt or chattymalloc output file",
+ type=str)
+ parser.add_argument("-e",
+ "--export",
+ help="export to csv",
+ action="store_true")
+ parser.add_argument("-n",
+ "--no-ascii",
+ help="don't output a ascii histogram",
+ action="store_true")
+ parser.add_argument("-i",
+ "--interactive",
+ help="open interactive matplotlib histogram plots",
action="store_true")
args = parser.parse_args()
@@ -87,7 +98,6 @@ def main():
else:
sizes_bigger_32K.append(size * amount)
-
plt.figure(0)
plt.hist(sizes_smaller_4K, 200)
plt.title("Sizes smaller than 4K")
@@ -105,5 +115,6 @@ def main():
plt.title("All sizes")
plt.show()
+
if __name__ == "__main__":
main()
diff --git a/scripts/paper_plots.py b/scripts/paper_plots.py
index 49ec15d..f79cf3a 100755
--- a/scripts/paper_plots.py
+++ b/scripts/paper_plots.py
@@ -24,7 +24,8 @@ import inspect
import os
import sys
-currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+currentdir = os.path.dirname(
+ os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
@@ -36,15 +37,24 @@ from allocbench.util import print_status, print_warn, print_error
from allocbench.util import print_license_and_exit
ALLOCATOR_NAMES = [a.name for a in paper_allocators]
-SURVEY_ALLOCATORS = [a.name for a in paper_allocators if not '-' in a.name or a.name not in ["speedymalloc", "bumpptr"]]
+SURVEY_ALLOCATORS = [
+ a.name for a in paper_allocators
+ if not '-' in a.name or a.name not in ["speedymalloc", "bumpptr"]
+]
TCMALLOCS = [a.name for a in paper_allocators if a.name.startswith("TCMalloc")]
-ALIGNED_ALLOCATORS = [a.name for a in paper_allocators if a.name.endswith("-Aligned")]
+ALIGNED_ALLOCATORS = [
+ a.name for a in paper_allocators if a.name.endswith("-Aligned")
+]
def falsesharing_plots(falsesharing):
args = falsesharing.results["args"]
- falsesharing.results["allocators"] = {k: v for k, v in falsesharing.results["allocators"].items() if k in ALLOCATOR_NAMES}
+ falsesharing.results["allocators"] = {
+ k: v
+ for k, v in falsesharing.results["allocators"].items()
+ if k in ALLOCATOR_NAMES
+ }
plt.pgfplot_legend(falsesharing, columns=5)
@@ -53,12 +63,17 @@ def falsesharing_plots(falsesharing):
for allocator in falsesharing.results["allocators"]:
sequential_perm = falsesharing.Perm(bench=bench, threads=1)
- for perm in falsesharing.iterate_args_fixed({"bench": bench}, args=args):
- for i, measure in enumerate(falsesharing.results[allocator][perm]):
+ for perm in falsesharing.iterate_args_fixed({"bench": bench},
+ args=args):
+ for i, measure in enumerate(
+ falsesharing.results[allocator][perm]):
sequential_time = float(falsesharing.results[allocator]
- [sequential_perm][i]["time"])
- measure["speedup"] = sequential_time / float(measure["time"])
- measure["l1chache_misses"] = float(measure["L1-dcache-load-misses"]) / float(measure["L1-dcache-loads"]) * 100
+ [sequential_perm][i]["time"])
+ measure["speedup"] = sequential_time / float(
+ measure["time"])
+ measure["l1chache_misses"] = float(
+ measure["L1-dcache-load-misses"]) / float(
+ measure["L1-dcache-loads"]) * 100
# delete and recalculate stats
del falsesharing.results["stats"]
@@ -67,7 +82,8 @@ def falsesharing_plots(falsesharing):
# pgfplots
for bench in args["bench"]:
plt.pgfplot(falsesharing,
- falsesharing.iterate_args_fixed({"bench": bench}, args=args),
+ falsesharing.iterate_args_fixed({"bench": bench},
+ args=args),
"int(perm.threads)",
"{speedup}",
xlabel="Threads",
@@ -75,9 +91,14 @@ def falsesharing_plots(falsesharing):
title=f"{bench}: Speedup",
postfix=f"{bench}.speedup")
+
def blowup_plots(blowup):
args = blowup.results["args"]
- blowup.results["allocators"] = {k: v for k, v in blowup.results["allocators"].items() if k in ALLOCATOR_NAMES}
+ blowup.results["allocators"] = {
+ k: v
+ for k, v in blowup.results["allocators"].items()
+ if k in ALLOCATOR_NAMES
+ }
# hack ideal rss in data set
blowup.results["allocators"]["Ideal-RSS"] = {"color": "xkcd:gold"}
@@ -86,11 +107,11 @@ def blowup_plots(blowup):
blowup.results["stats"]["Ideal-RSS"][perm] = {
"mean": {
"VmHWM": 1024 * 100
- },
+ },
"std": {
"VmHWM": 0
- }
}
+ }
plt.pgfplot(blowup,
blowup.iterate_args(args),
@@ -103,9 +124,13 @@ def blowup_plots(blowup):
axis_attr="\txtick=data,\n\tsymbolic x coords={blowup}",
bar=True)
+
def loop_plots(loop):
args = loop.results["args"]
- loop.results["allocators"] = {k: v for k, v in loop.results["allocators"].items() if k in ALLOCATOR_NAMES}
+ loop.results["allocators"] = {
+ k: v
+ for k, v in loop.results["allocators"].items() if k in ALLOCATOR_NAMES
+ }
plt.pgfplot(loop,
loop.iterate_args_fixed({"threads": 40}, args),
@@ -116,9 +141,10 @@ def loop_plots(loop):
title="Loop: 40 threads",
postfix="threads.40")
+
def mysqld_plots(mysql):
args = mysql.results["args"]
-# mysql.results["allocators"] = {k: v for k, v in mysql.results["allocators"].items() if k in SURVEY_ALLOCATORS}
+ # mysql.results["allocators"] = {k: v for k, v in mysql.results["allocators"].items() if k in SURVEY_ALLOCATORS}
plt.pgfplot(mysql,
mysql.iterate_args(args),
@@ -142,9 +168,14 @@ def mysqld_plots(mysql):
plt.pgfplot_legend(mysql, columns=5)
+
def keydb_plots(keydb):
args = keydb.results["args"]
- keydb.results["allocators"] = {k: v for k, v in keydb.results["allocators"].items() if k in SURVEY_ALLOCATORS}
+ keydb.results["allocators"] = {
+ k: v
+ for k, v in keydb.results["allocators"].items()
+ if k in SURVEY_ALLOCATORS
+ }
for fixed_arg in args:
loose_arg = [a for a in args if a != fixed_arg][0]
@@ -159,20 +190,26 @@ def keydb_plots(keydb):
postfix=f"{fixed_arg}.{arg_value}",
bar=True)
+
def summarize(benchmarks=None, exclude_benchmarks=None):
"""summarize the benchmarks in the resdir"""
cwd = os.getcwd()
- for benchmark, func in {"blowup": blowup_plots, "falsesharing": falsesharing_plots,
- "mysql": mysqld_plots, "keydb": keydb_plots,
- "loop": loop_plots}.items():
+ for benchmark, func in {
+ "blowup": blowup_plots,
+ "falsesharing": falsesharing_plots,
+ "mysql": mysqld_plots,
+ "keydb": keydb_plots,
+ "loop": loop_plots
+ }.items():
if benchmarks and not benchmark in benchmarks:
continue
if exclude_benchmarks and benchmark in exclude_benchmarks:
continue
- bench_module = importlib.import_module(f"allocbench.benchmarks.{benchmark}")
+ bench_module = importlib.import_module(
+ f"allocbench.benchmarks.{benchmark}")
if not hasattr(bench_module, benchmark):
print_error(f"{benchmark} has no member {benchmark}")
@@ -188,7 +225,8 @@ def summarize(benchmarks=None, exclude_benchmarks=None):
print_status(f"Summarizing {bench.name} ...")
- res_dir = os.path.join(allocbench.globalvars.resdir, bench.name, "paper")
+ res_dir = os.path.join(allocbench.globalvars.resdir, bench.name,
+ "paper")
if not os.path.isdir(res_dir):
os.makedirs(res_dir)
os.chdir(res_dir)
@@ -216,9 +254,10 @@ def main():
"--exclude-benchmarks",
help="benchmarks to exclude",
nargs='+')
- parser.add_argument("--latex-preamble",
- help="latex code to include in the preamble of generated standalones",
- type=str)
+ parser.add_argument(
+ "--latex-preamble",
+ help="latex code to include in the preamble of generated standalones",
+ type=str)
args = parser.parse_args()
diff --git a/scripts/print_facts.py b/scripts/print_facts.py
index 389028e..ec9404c 100755
--- a/scripts/print_facts.py
+++ b/scripts/print_facts.py
@@ -16,7 +16,6 @@
#
# You should have received a copy of the GNU General Public License
# along with allocbench. If not, see <http://www.gnu.org/licenses/>.
-
"""Print facts about an allocbench result directory"""
import argparse
@@ -25,7 +24,8 @@ import inspect
import os
import sys
-CURRENTDIR = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+CURRENTDIR = os.path.dirname(
+ os.path.abspath(inspect.getfile(inspect.currentframe())))
PARENTDIR = os.path.dirname(CURRENTDIR)
sys.path.insert(0, PARENTDIR)
@@ -36,7 +36,8 @@ from allocbench.util import print_error
def main():
- parser = argparse.ArgumentParser(description="Print facts about an allocbench result directory")
+ parser = argparse.ArgumentParser(
+ description="Print facts about an allocbench result directory")
parser.add_argument("results", help="path to allocbench results", type=str)
args = parser.parse_args()
@@ -49,7 +50,8 @@ def main():
os.chdir(args.results)
for benchmark in BENCHMARKS:
- bench_module = importlib.import_module(f"allocbench.benchmarks.{benchmark}")
+ bench_module = importlib.import_module(
+ f"allocbench.benchmarks.{benchmark}")
if not hasattr(bench_module, benchmark):
print_error(f"{benchmark} has no member {benchmark}")