Skip to content

Commit db3225e

Browse files
authored
Merge pull request #2888 from devitocodes/load-so
compiler: load so directly when source is missing (e.g deleted c file)
2 parents 2fa5517 + e16a579 commit db3225e

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

devito/arch/compiler.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,14 @@ def jit_compile(self, soname, code):
386386
# Typically we end up here
387387
# Make a suite of cache directories based on the soname
388388
cache_dir.mkdir(parents=True, exist_ok=True)
389+
390+
# Has the library already been compiled?
391+
try:
392+
self.load(target)
393+
return False, src_file
394+
except OSError:
395+
# The .so file isn't present, we need to compile it
396+
pass
389397
else:
390398
# Warning: dropping `code` on the floor in favor to whatever is written
391399
# within `src_file`

tests/test_cinterface.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import os
2+
import sys
3+
from contextlib import suppress
24

35
from devito import Eq, Grid, Operator, TimeFunction, configuration
46
from devito.types import Timer
@@ -37,3 +39,31 @@ def test_basic():
3739
assert isinstance(timers, Timer)
3840
assert 'struct profiler\n{' not in ccode
3941
assert 'struct profiler\n{' in hcode
42+
43+
44+
def test_load_without_source():
45+
grid = Grid(shape=(4, 4))
46+
47+
f = TimeFunction(name='f', grid=grid)
48+
49+
eq = Eq(f.forward, f + 1.)
50+
51+
name = "foo"
52+
op = Operator(eq, name=name)
53+
54+
# Make sure the so file is not present
55+
dirname = op._compiler.get_jit_dir()
56+
soname = op._soname
57+
ext = '.dylib' if sys.platform == "darwin" else '.so'
58+
with suppress(FileNotFoundError):
59+
os.remove(f"{os.path.join(dirname, soname)}{ext}")
60+
61+
# Trigger compilation
62+
recompiled, src_file = op._compiler.jit_compile(op._soname, str(op))
63+
assert recompiled
64+
65+
os.remove(src_file)
66+
# Trigger compilation again. It should skip the C part and directly load the .so file
67+
recompiled, src_file = op._compiler.jit_compile(op._soname, str(op))
68+
assert not recompiled
69+
assert not os.path.isfile(src_file)

0 commit comments

Comments
 (0)