From 218469c25852672b0199d20a2a3a626dd10991f3 Mon Sep 17 00:00:00 2001 From: Dominic Kempf <dominic.kempf@iwr.uni-heidelberg.de> Date: Thu, 4 Oct 2018 13:16:38 +0200 Subject: [PATCH] Implement proper file locking to allow multiple processes to autotune the same stuff --- python/dune/perftool/sumfact/autotune.py | 46 ++++++++++++------------ python/setup.py | 2 +- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/python/dune/perftool/sumfact/autotune.py b/python/dune/perftool/sumfact/autotune.py index 771b792a..2cdd2e08 100644 --- a/python/dune/perftool/sumfact/autotune.py +++ b/python/dune/perftool/sumfact/autotune.py @@ -11,6 +11,7 @@ from pytools import product import os import re import subprocess +import filelock def get_cmake_cache_entry(entry): @@ -193,28 +194,29 @@ def autotune_realization(sf): name = os.path.join(dir, "autotune_sumfact_{}".format(sf.function_name)) filename = os.path.join(dir, "{}.cc".format(basename)) logname = os.path.join(dir, "{}.log".format(basename)) - - # If the log file already exists, we can reuse the benchmark results - # and do not need to rerun it. - if not os.path.isfile(logname): - # Generate and compile a benchmark program - with cache_restoring(): - generate_standalone_code(sf, filename, logname) - - ret = subprocess.call(compiler_invocation(name, filename)) - assert ret == 0 - - # Check whether the user specified an execution wrapper - call = [] - wrapper = get_cmake_cache_entry("DUNE_PERFTOOL_BENCHMARK_WRAPPER") - if wrapper: - call.append(wrapper) - - # Run the benchmark program - call.append(name) - devnull = open(os.devnull, 'w') - ret = subprocess.call(call, stdout=devnull, stderr=subprocess.STDOUT) - assert ret == 0 + lock = "{}.lock".format(name) + + # Generate and compile a benchmark program + with cache_restoring(): + with filelock.FileLock(lock): + if not os.path.isfile(logname): + if os.path.isfile(filename): + generate_standalone_code(sf, filename, logname) + + ret = subprocess.call(compiler_invocation(name, filename)) + assert ret == 0 + + # Check whether the user specified an execution wrapper + call = [] + wrapper = get_cmake_cache_entry("DUNE_PERFTOOL_BENCHMARK_WRAPPER") + if wrapper: + call.append(wrapper) + + # Run the benchmark program + call.append(name) + devnull = open(os.devnull, 'w') + ret = subprocess.call(call, stdout=devnull, stderr=subprocess.STDOUT) + assert ret == 0 # Extract the result form the log file return float(next(iter(open(logname, "r")))) / 1000000 diff --git a/python/setup.py b/python/setup.py index 476a9f6f..e4517d2f 100644 --- a/python/setup.py +++ b/python/setup.py @@ -41,7 +41,7 @@ setup(name='dune.perftool', 'dune.perftool.ufl', 'dune.perftool.ufl.transformations', ], - install_requires=['dune.testtools', 'sympy', 'frozendict', 'pytest', 'pytest-pep8'], + install_requires=['dune.testtools', 'sympy', 'frozendict', 'pytest', 'pytest-pep8', 'filelock'], cmdclass={'test': PyTest}, entry_points = { "console_scripts": [ -- GitLab