aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--allocbench/allocator.py15
-rw-r--r--allocbench/allocators/bumpptr.py6
-rw-r--r--allocbench/allocators/tcmalloc.py7
-rw-r--r--allocbench/artifact.py28
-rw-r--r--allocbench/benchmark.py37
-rw-r--r--allocbench/benchmarks/espresso.py4
-rw-r--r--allocbench/directories.py97
-rw-r--r--allocbench/facter.py4
-rw-r--r--allocbench/globalvars.py35
-rwxr-xr-xbench.py39
10 files changed, 174 insertions, 98 deletions
diff --git a/allocbench/allocator.py b/allocbench/allocator.py
index 8e4f041..1906a1e 100644
--- a/allocbench/allocator.py
+++ b/allocbench/allocator.py
@@ -28,8 +28,10 @@ import sys
from typing import List, Optional
from allocbench.artifact import Artifact, ArchiveArtifact, GitArtifact
-from allocbench.globalvars import ALLOCBUILDDIR, ALLOCSRCDIR
from allocbench.util import print_status, print_debug, print_error, print_info2, run_cmd
+from allocbench.directories import (get_allocbench_build_dir,
+ get_allocbench_allocator_src_dir,
+ get_allocbench_allocator_build_dir)
LIBRARY_PATH = ""
for line in run_cmd(["ldconfig", "-v", "-N"],
@@ -38,8 +40,7 @@ for line in run_cmd(["ldconfig", "-v", "-N"],
if not line.startswith('\t'):
LIBRARY_PATH += line
-BUILDDIR = Path(ALLOCBUILDDIR)
-SRCDIR = BUILDDIR / "src"
+SRCDIR = Path(get_allocbench_build_dir()) / "src"
SRCDIR.mkdir(parents=True, exist_ok=True)
@@ -73,7 +74,7 @@ class Allocator:
self.class_file = Path(inspect.getfile(self.__class__))
self.name = name
self.srcdir = SRCDIR / self.name
- self.dir = BUILDDIR / self.name
+ self.dir = get_allocbench_allocator_build_dir() / self.name
self.patchdir = Path(self.class_file.parent, self.class_file.stem)
# Update attributes
@@ -158,7 +159,9 @@ class Allocator:
cmd = cmd.format(dir=self.dir, srcdir=self.srcdir)
try:
- run_cmd(cmd, cwd=BUILDDIR, shell=True)
+ run_cmd(cmd,
+ cwd=get_allocbench_allocator_build_dir(),
+ shell=True)
except CalledProcessError as err:
print_debug(err.stderr, file=sys.stderr)
print_error(f"Builing {self.name} failed")
@@ -228,7 +231,7 @@ def collect_available_allocators():
available_allocators = {}
- for alloc_def_path in Path(ALLOCSRCDIR).glob('*.py'):
+ for alloc_def_path in get_allocbench_allocator_src_dir().glob('*.py'):
alloc_module_name = f'allocbench.allocators.{alloc_def_path.stem}'
module = importlib.import_module(alloc_module_name)
for name, obj in module.__dict__.items():
diff --git a/allocbench/allocators/bumpptr.py b/allocbench/allocators/bumpptr.py
index 1d9d111..84097b1 100644
--- a/allocbench/allocators/bumpptr.py
+++ b/allocbench/allocators/bumpptr.py
@@ -22,9 +22,11 @@ See allocbench/bumpptr.c for the actual implementation.
"""
import os
-from allocbench.allocator import Allocator, BUILDDIR
+from allocbench.allocator import Allocator
+from allocbench.directories import get_allocbench_allocator_build_dir
# pylint: disable=invalid-name
bumpptr = Allocator("bumpptr",
- ld_preload=os.path.join(BUILDDIR, "bumpptr_alloc.so"),
+ ld_preload=str(get_allocbench_allocator_build_dir() /
+ "bumpptr_alloc.so"),
color="xkcd:black")
diff --git a/allocbench/allocators/tcmalloc.py b/allocbench/allocators/tcmalloc.py
index 2c026a5..ee15a9d 100644
--- a/allocbench/allocators/tcmalloc.py
+++ b/allocbench/allocators/tcmalloc.py
@@ -16,8 +16,9 @@
# along with allocbench.
"""TCMalloc definition for allocbench"""
-from allocbench.allocator import Allocator, BUILDDIR
+from allocbench.allocator import Allocator
from allocbench.artifact import GitArtifact
+from allocbench.directories import get_allocbench_allocator_build_dir
class TCMalloc(Allocator):
@@ -47,7 +48,7 @@ tcmalloc_align = TCMalloc("TCMalloc-Aligned",
version="1676100265bd189df6b5513feac15f102542367e",
color="xkcd:light blue")
-tcmalloc_align.ld_preload = f"{BUILDDIR}/align_to_cl.so {tcmalloc_align.ld_preload}"
+tcmalloc_align.ld_preload = f"{get_allocbench_allocator_build_dir()}/align_to_cl.so {tcmalloc_align.ld_preload}"
# pylint: enable=invalid-name
@@ -85,7 +86,7 @@ tcmalloc_gperftools_align = TCMallocGperftools("TCMalloc-Gperftools-Aligned",
color="xkcd:navy blue")
tcmalloc_gperftools_align.ld_preload = (
- f"{BUILDDIR}/align_to_cl.so "
+ f"{get_allocbench_allocator_build_dir()}/align_to_cl.so "
f"{tcmalloc_gperftools_align.ld_preload}")
tcmalloc_gperftools_cacheline_exclusive = TCMallocGperftools(
diff --git a/allocbench/artifact.py b/allocbench/artifact.py
index 22e50f3..06c08f2 100644
--- a/allocbench/artifact.py
+++ b/allocbench/artifact.py
@@ -22,24 +22,23 @@ Both flavours are version controlled archive with a checksum and git repositorie
with a specific checkout.
"""
-import os
from subprocess import CalledProcessError
-from allocbench.globalvars import ALLOCBENCHDIR
+from allocbench.directories import get_allocbench_base_dir
from allocbench.util import print_status, print_info, print_debug, print_error, run_cmd, sha1sum
-ARTIFACT_STORE_DIR = os.path.join(ALLOCBENCHDIR, "cache")
+ARTIFACT_STORE_DIR = get_allocbench_base_dir() / "cache"
class Artifact:
"""Base class for external ressources"""
def __init__(self, name):
self.name = name
- self.basedir = os.path.join(ARTIFACT_STORE_DIR, name)
+ self.basedir = ARTIFACT_STORE_DIR / name
def _retrieve(self, cmd):
"""Run cmd to retrieve the artifact"""
- os.makedirs(self.basedir, exist_ok=True)
+ self.basedir.mkdir(exist_ok=True)
print_status(f'Retrieving artifact "{self.name}" ...')
print_debug(f"By running: {cmd} in {self.basedir}")
@@ -54,7 +53,7 @@ class GitArtifact(Artifact):
def __init__(self, name, url):
super().__init__(name)
self.url = url
- self.repo = os.path.join(self.basedir, "repo")
+ self.repo = self.basedir / "repo"
def retrieve(self):
"""clone the git repo"""
@@ -64,10 +63,10 @@ class GitArtifact(Artifact):
def provide(self, checkout, location=None):
"""checkout new worktree at location"""
if not location:
- location = os.path.join(self.basedir, checkout)
+ location = self.basedir / checkout
# check if we have already provided this checkout
- if os.path.exists(location):
+ if location.exists():
try:
run_cmd(GIT_FETCH_CMD, output_verbosity=1, cwd=location)
except CalledProcessError:
@@ -83,7 +82,7 @@ class GitArtifact(Artifact):
return location
# check if we have already retrieved the repo
- if not os.path.exists(self.repo):
+ if not self.repo.exists():
self.retrieve()
worktree_cmd = ["git", "worktree", "add", location, checkout]
@@ -127,8 +126,7 @@ 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 = self.basedir / f"{self.name}.{self.archive_format}"
self.checksum = checksum
def retrieve(self):
@@ -139,7 +137,7 @@ class ArchiveArtifact(Artifact):
"""extract the archive"""
# Download archive
- if not os.path.exists(self.archive):
+ if not self.archive.exists():
self.retrieve()
# compare checksums
@@ -149,13 +147,13 @@ class ArchiveArtifact(Artifact):
f"Archive {self.archive} does not match provided checksum")
if not location:
- location = os.path.join(self.basedir, "content")
+ location = self.basedir / "content"
# Check if we already provided the archive at location
- if os.path.exists(location):
+ if location.exists():
return location
- os.makedirs(location, exist_ok=True)
+ location.mkdir(exist_ok=True)
# Extract archive
if self.archive_format == "tar":
diff --git a/allocbench/benchmark.py b/allocbench/benchmark.py
index 923b84f..e886ac5 100644
--- a/allocbench/benchmark.py
+++ b/allocbench/benchmark.py
@@ -33,6 +33,10 @@ from typing import Dict, Iterable, List, Optional
import numpy as np
+from allocbench.directories import (get_allocbench_benchmark_src_dir,
+ get_current_result_dir,
+ get_allocbench_benchmark_build_dir,
+ get_allocbench_build_dir)
import allocbench.facter as facter
import allocbench.globalvars
from allocbench.util import print_status, print_error, print_warn
@@ -183,13 +187,16 @@ class Benchmark:
# Set result_dir
if not hasattr(self, "result_dir"):
- self.result_dir = os.path.abspath(
- os.path.join(allocbench.globalvars.RESDIR or "", self.name))
+ res_dir = get_current_result_dir()
+ if res_dir:
+ self.result_dir = (res_dir / self.name).absolute()
+ else:
+ self.result_dir = self.name
+
# Set build_dir
if not hasattr(self, "build_dir"):
- self.build_dir = os.path.abspath(
- os.path.join(allocbench.globalvars.BUILDDIR, "benchmarks",
- self.name))
+ self.build_dir = (get_allocbench_benchmark_build_dir() /
+ self.name).absolute()
self.Perm = namedtuple("Perm", self.args.keys())
@@ -299,8 +306,7 @@ class Benchmark:
def check_requirements(self):
"""raise an error if a requirement is not found"""
- os.environ[
- "PATH"] += f"{os.pathsep}{allocbench.globalvars.BUILDDIR}/benchmarks/{self.name}"
+ os.environ["PATH"] += f"{os.pathsep}{self.build_dir}"
for requirement in self.requirements:
exe = find_cmd(requirement)
@@ -369,22 +375,23 @@ class Benchmark:
argv = []
if prepend:
+ build_dir = get_allocbench_build_dir()
if "cmd_prefix" in alloc:
prefix_argv = alloc["cmd_prefix"].format(
**substitutions).split()
argv.extend(prefix_argv)
# add exec wrapper so that a possible prefixed loader can execute shell scripts
- argv.append(f"{allocbench.globalvars.BUILDDIR}/exec")
+ argv.append(f"{build_dir / 'exec'}")
if self.measure_cmd != "":
measure_argv = self.measure_cmd.format(**substitutions)
measure_argv = prefix_cmd_with_abspath(measure_argv).split()
argv.extend(measure_argv)
- argv.append(f"{allocbench.globalvars.BUILDDIR}/exec")
+ argv.append(f"{build_dir / 'exec'}")
- ld_preload = f"{allocbench.globalvars.BUILDDIR}/print_status_on_exit.so"
- ld_preload += f" {allocbench.globalvars.BUILDDIR}/sig_handlers.so"
+ ld_preload = f"{build_dir / 'print_status_on_exit.so'}"
+ ld_preload += f" {build_dir / 'sig_handlers.so'}"
if "LD_PRELOAD" in env or alloc.get("LD_PRELOAD", ""):
ld_preload += f" {alloc.get('LD_PRELOAD', '')}"
@@ -419,7 +426,7 @@ class Benchmark:
substitutions = {
"alloc": alloc_name,
"perm": alloc_name,
- "builddir": allocbench.globalvars.BUILDDIR
+ "builddir": get_allocbench_build_dir()
}
substitutions.update(self.__dict__)
@@ -516,8 +523,7 @@ class Benchmark:
Benchmark.is_perf_allowed()
# add benchmark dir to PATH
- os.environ[
- "PATH"] += f"{os.pathsep}{allocbench.globalvars.BUILDDIR}/benchmarks/{self.name}"
+ os.environ["PATH"] += f"{os.pathsep}{self.build_dir}"
# save one valid result to expand invalid results
valid_result = {}
@@ -669,8 +675,7 @@ class Benchmark:
# reset PATH
os.environ["PATH"] = os.environ["PATH"].replace(
- f"{os.pathsep}{allocbench.globalvars.BUILDDIR}/benchmarks/{self.name}",
- "")
+ f"{os.pathsep}{self.build_dir}", "")
# expand invalid results
if valid_result != {}:
diff --git a/allocbench/benchmarks/espresso.py b/allocbench/benchmarks/espresso.py
index dbc099b..8ce4256 100644
--- a/allocbench/benchmarks/espresso.py
+++ b/allocbench/benchmarks/espresso.py
@@ -58,7 +58,7 @@ API function as well as memory placement strategies with good data locality.
import os
from allocbench.benchmark import Benchmark
-from allocbench.globalvars import BENCHSRCDIR
+from allocbench.directories import get_allocbench_benchmark_src_dir
import allocbench.plots as plt
@@ -71,7 +71,7 @@ class BenchmarkEspresso(Benchmark):
self.args = {"file": ["largest.espresso"]}
self.requirements = ["espresso"]
- self.run_dir = os.path.join(BENCHSRCDIR, name)
+ self.run_dir = get_allocbench_benchmark_src_dir() / name
super().__init__(name)
def summary(self):
diff --git a/allocbench/directories.py b/allocbench/directories.py
new file mode 100644
index 0000000..3c76f0f
--- /dev/null
+++ b/allocbench/directories.py
@@ -0,0 +1,97 @@
+# Copyright 2020 Florian Fischer <florian.fl.fischer@fau.de>
+#
+# This file is part of allocbench.
+#
+# allocbench is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# allocbench is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with allocbench. If not, see <http://www.gnu.org/licenses/>.
+"""Functions to obtain specific directories in the allocbench directory tree"""
+
+from pathlib import Path
+from typing import Optional, Union
+
+# /.../allocbench/allocbench
+SRCDIR = Path(__file__).parent
+
+
+def get_allocbench_src_dir() -> Path:
+ """Return path to allocbench's sources"""
+ return SRCDIR
+
+
+# /.../allocbench/
+BASEDIR = SRCDIR.parent
+
+
+def get_allocbench_base_dir() -> Path:
+ """Return path to allocbench's root directory"""
+ return BASEDIR
+
+
+# /.../allocbench/allocbench/benchmarks
+BENCHSRCDIR = SRCDIR / "benchmarks"
+
+
+def get_allocbench_benchmark_src_dir() -> Path:
+ """Return path to benchmark definitions and sources"""
+ return BENCHSRCDIR
+
+
+# /.../allocbench/allocbench/allocators
+ALLOCSRCDIR = SRCDIR / "allocators"
+
+
+def get_allocbench_allocator_src_dir() -> Path:
+ """Return path to allocator definitions"""
+ return ALLOCSRCDIR
+
+
+# /.../allocbench/build
+BUILDDIR = BASEDIR / "build"
+
+
+def get_allocbench_build_dir() -> Path:
+ """Return path to allocbench's build directory"""
+ return BUILDDIR
+
+
+# /.../allocbench/build/allocators
+ALLOCBUILDDIR = BUILDDIR / "allocators"
+
+
+def get_allocbench_allocator_build_dir() -> Path:
+ """Return path to the allocators build directory"""
+ return ALLOCBUILDDIR
+
+
+# /.../allocbench/build/allocators
+BENCHMARKBUILDDIR = BUILDDIR / "benchmarks"
+
+
+def get_allocbench_benchmark_build_dir() -> Path:
+ """Return path to the benchmarks build directory"""
+ return BENCHMARKBUILDDIR
+
+
+RESDIR = None
+
+
+def set_current_result_dir(resdir: Union[Path, str]):
+ """Set the path to the result directory of the current invocation and silently create it"""
+ global RESDIR
+ RESDIR = Path(resdir)
+ RESDIR.mkdir(parents=True, exist_ok=True)
+
+
+def get_current_result_dir() -> Optional[Path]:
+ """Return the path to the results of the current invocation"""
+ return RESDIR
diff --git a/allocbench/facter.py b/allocbench/facter.py
index 374c881..8aefbd8 100644
--- a/allocbench/facter.py
+++ b/allocbench/facter.py
@@ -25,7 +25,7 @@ import os
import platform
from subprocess import CalledProcessError
-from allocbench.globalvars import BUILDDIR
+from allocbench.directories import get_allocbench_build_dir
from allocbench.util import print_debug, print_info, print_warn, run_cmd
FACTS = {}
@@ -42,7 +42,7 @@ def collect_facts():
FACTS["cpus"] = multiprocessing.cpu_count()
FACTS["LD_PRELOAD"] = os.environ.get("LD_PRELOAD", None)
- with open(os.path.join(BUILDDIR, "ccinfo"), "r") as ccinfo:
+ with open(get_allocbench_build_dir() / "ccinfo", "r") as ccinfo:
FACTS["cc"] = ccinfo.readlines()[-1][:-1]
# get commit info from git
diff --git a/allocbench/globalvars.py b/allocbench/globalvars.py
index 1b3e5fb..7a84a40 100644
--- a/allocbench/globalvars.py
+++ b/allocbench/globalvars.py
@@ -19,46 +19,13 @@
VERBOSITY: Verbosity level -1: quiet, 0: status, 1: info, 2: stdout of subcommands, 3: debug info
ALLOCATORS: Dict holding the allocators to compare
BENCHMARKS: List of available benchmarks
-
-ALLOCBENCHDIR: Root directory of allocbench
-SRCDIR: Directory of allocbench sources
-BENCHSRCDIR: Source directory for all benchmarks
-ALLOCSRCDIR: Source directory for all benchmarks
-BUILDDIR: Path of the build directory
-ALLOCBUILDDIR: Path of the allocators build directory
-RESDIR: Directory were the benchmark results are stored
"""
-import inspect
-import os
from typing import Dict
-import allocbench.allocator
-
VERBOSITY = 0
-ALLOCATORS: Dict[str, allocbench.allocator.Allocator] = {}
-
-# /.../allocbench/allocbench
-SRCDIR = os.path.dirname(
- os.path.abspath(inspect.getfile(inspect.currentframe())))
-
-# /.../allocbench/allocbench/benchmarks
-BENCHSRCDIR = os.path.join(SRCDIR, "benchmarks")
-
-# /.../allocbench/allocbench/allocators
-ALLOCSRCDIR = os.path.join(SRCDIR, "allocators")
-
-# /.../allocbench
-ALLOCBENCHDIR = os.path.dirname(SRCDIR)
-
-# /.../allocbench/build
-BUILDDIR = os.path.join(ALLOCBENCHDIR, "build")
-
-# /.../allocbench/build/allocators
-ALLOCBUILDDIR = os.path.join(BUILDDIR, "allocators")
-
-RESDIR = None
+ALLOCATORS = {}
BENCHMARKS = [
e[:-3] for e in os.listdir(os.path.join(ALLOCBENCHDIR, BENCHSRCDIR))
diff --git a/bench.py b/bench.py
index 4458681..8d786d5 100755
--- a/bench.py
+++ b/bench.py
@@ -28,6 +28,7 @@ import traceback
from allocbench.allocator import collect_allocators
from allocbench.analyse import analyze_bench, analyze_allocators
from allocbench.benchmark import get_benchmark_object
+from allocbench.directories import get_current_result_dir, set_current_result_dir
import allocbench.facter as facter
import allocbench.globalvars
from allocbench.util import run_cmd
@@ -40,21 +41,24 @@ from summarize import summarize
def epilog():
"""Run tasks on exit"""
- # After early errors resdir may not be set
- if allocbench.globalvars.RESDIR is not None:
- if os.listdir(allocbench.globalvars.RESDIR) == []:
- print_warn("Remove empty resultdir")
- os.removedirs(allocbench.globalvars.RESDIR)
- else:
- endtime = datetime.datetime.now().isoformat()
- endtime = endtime[:endtime.rfind(':')]
- facter.FACTS["endtime"] = endtime
- facter.store_facts(allocbench.globalvars.RESDIR)
-
# remove a left over status file if some is present
if os.path.exists("status"):
os.remove("status")
+ res_dir = get_current_result_dir()
+ # After early errors resdir may not be set
+ if not res_dir:
+ return
+
+ if not res_dir.iterdir():
+ print_warn("Remove empty resultdir")
+ res_dir.rmdir()
+ else:
+ endtime = datetime.datetime.now().isoformat()
+ endtime = endtime[:endtime.rfind(':')]
+ facter.FACTS["endtime"] = endtime
+ facter.store_facts(res_dir)
+
def check_dependencies():
"""Check if known requirements of allocbench are met"""
@@ -149,14 +153,13 @@ def main():
# Create result directory
if args.resultdir:
- allocbench.globalvars.RESDIR = os.path.join(args.resultdir)
+ set_current_result_dir(args.resultdir)
else:
- allocbench.globalvars.RESDIR = os.path.join("results",
- facter.FACTS["hostname"],
- facter.FACTS["starttime"])
+ set_current_result_dir(
+ os.path.join("results", facter.FACTS["hostname"],
+ facter.FACTS["starttime"]))
- print_status("Writing results to:", allocbench.globalvars.RESDIR)
- os.makedirs(allocbench.globalvars.RESDIR, exist_ok=True)
+ print_status("Writing results to:", get_current_result_dir())
cwd = os.getcwd()
@@ -214,7 +217,7 @@ def main():
start_time).total_seconds()
# Save results in resultdir
- bench.save(allocbench.globalvars.RESDIR)
+ bench.save(get_current_result_dir())
if hasattr(bench, "cleanup"):
print_status("Cleaning up", bench.name, "...")