Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid recompiling executable if already compiled in previous tests #69

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 50 additions & 11 deletions regtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ def find_build_dirs(tests):
last_safe = False

for obj in tests:

# keep track of the build directory and which source tree it is
# in (e.g. the extra build dir)

# first find the list of unique build directories
dir_pair = (obj.buildDir, obj.extra_build_dir)
if build_dirs.count(dir_pair) == 0:
build_dirs.append(dir_pair)

# re-make all problems that specify an extra compile argument,
# and the test that comes after, just to make sure that any
# unique build commands are seen.
Expand All @@ -67,9 +67,9 @@ def find_build_dirs(tests):
obj.reClean = 0
else:
last_safe = True

return build_dirs

def cmake_setup(suite):
"Setup for cmake"

Expand Down Expand Up @@ -536,14 +536,48 @@ def test_suite(argv):
coutfile = "{}/{}.make.out".format(output_dir, test.name)

if suite.sourceTree == "C_Src" or test.testSrcTree == "C_Src":
if suite.useCmake:
comp_string, rc = suite.build_test_cmake(test=test, outfile=coutfile)
else:
comp_string, rc = suite.build_c(test=test, outfile=coutfile)

executable = test_util.get_recent_filename(bdir, "", ".ex")
# First check whether an executable was already compiled with
# the same options (not enabled for CMake, for now)
found_previous_test = False
if test.avoid_recompiling and not suite.useCmake:
comp_string = suite.get_comp_string_c(test=test, outfile=coutfile)
# Loop over the existing tests
for previous_test in test_list:
# Check if the compile command was the same
if previous_test.comp_string == comp_string:
found_previous_test = True
break

# Avoid recompiling in this case
if found_previous_test:
suite.log.log("found pre-built executable for this test")
with open(coutfile, "a") as cf:
cf.write("found pre-built executable for this test\n")
rc = 0
executable = previous_test.executable
# Otherwise recompile
else:
if suite.useCmake:
comp_string, rc = suite.build_test_cmake(test=test, outfile=coutfile)
else:
comp_string, rc = suite.build_c(test=test, outfile=coutfile)
executable = test_util.get_recent_filename(bdir, "", ".ex")
# Store the executable (to avoid recompiling for other tests)
if test.avoid_recompiling and executable is not None:
# Create a unique directory for these compilations options,
# by using the hash of the compilation options as the directory name
if not os.path.exists('PreviouslyCompiled'):
os.mkdir('PreviouslyCompiled')
dir_name = os.path.join( 'PreviouslyCompiled', str(hash(comp_string)) )
if not os.path.exists( dir_name ):
os.mkdir(dir_name)
# Copy the executable to that unique directory
shutil.copy( executable, dir_name )

test.comp_string = comp_string
# Register name of the executable
test.executable = executable

# make return code is 0 if build was successful
if rc == 0:
Expand Down Expand Up @@ -572,7 +606,12 @@ def test_suite(argv):

needed_files = []
if executable is not None:
needed_files.append((executable, "move"))
if test.avoid_recompiling:
# Find unique directory where the executable is stored
dir_name = os.path.join( 'PreviouslyCompiled', str(hash(test.comp_string)) )
needed_files.append((os.path.join(dir_name,executable), "copy"))
else:
needed_files.append((executable, "move"))

if test.run_as_script:
needed_files.append((test.run_as_script, "copy"))
Expand Down
13 changes: 11 additions & 2 deletions suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def __init__(self, name):
self.nlevels = None # set but running fboxinfo on the output

self.comp_string = None # set automatically
self.executable = None # set automatically
self.run_command = None # set automatically

self.job_info_field1 = ""
Expand Down Expand Up @@ -343,6 +344,7 @@ def set_runs_to_average(self, value):

# Static member variables, set explicitly in apply_args in Suite class
compile_only = False
avoid_recompiling = False
skip_comparison = False
global_tolerance = None
global_particle_tolerance = None
Expand Down Expand Up @@ -879,8 +881,8 @@ def make_realclean(self, repo="source"):

test_util.run(cmd)

def build_c(self, test=None, opts="", target="", outfile=None, c_make_additions=None):

def get_comp_string_c(self, test=None, opts="", target="",
outfile=None, c_make_additions=None):
build_opts = ""
if c_make_additions is None:
c_make_additions = self.add_to_c_make_command
Expand Down Expand Up @@ -911,6 +913,12 @@ def build_c(self, test=None, opts="", target="", outfile=None, c_make_additions=
self.MAKE, self.numMakeJobs, self.amrex_dir,
all_opts, self.COMP, c_make_additions, target)

return comp_string

def build_c(self, test=None, opts="", target="",
outfile=None, c_make_additions=None):
comp_string = self.get_comp_string_c( test, opts, target,
outfile, c_make_additions )
self.log.log(comp_string)
stdout, stderr, rc = test_util.run(comp_string, outfile=outfile)

Expand Down Expand Up @@ -1069,6 +1077,7 @@ def apply_args(self):
args = self.args

Test.compile_only = args.compile_only
Test.avoid_recompiling = args.avoid_recompiling
Test.skip_comparison = args.skip_comparison
Test.global_tolerance = args.tolerance
Test.global_particle_tolerance = args.particle_tolerance
Expand Down
2 changes: 2 additions & 0 deletions test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ def get_args(arg_string=None):
"options that control how the tests are run")
run_group.add_argument("--compile_only", action="store_true",
help="test only that the code compiles, without running anything")
run_group.add_argument("--avoid_recompiling", action="store_true",
help="avoid recompiling, if an executable was already build with the same compilation options, in a previous test")
run_group.add_argument("--with_valgrind", action="store_true",
help="run with valgrind")
run_group.add_argument("--valgrind_options", type=str, default="--leak-check=yes --log-file=vallog.%p",
Expand Down