Skip to content

Efficient use of DEVITO_JIT_BACKDOOR in large codes with many Operators

Fabio Luporini edited this page Dec 5, 2019 · 2 revisions

The DEVITO_JIT_BACKDOOR is a useful mechanism to experiment with manual code changes, but it requires re-running the whole application each time one wants to try something new. If the application is big, possibly with many Operators, this can be a pain. So, here's a possible (template) solution, which still exploits the DEVITO_JIT_BACKDOOR.

from shutil import copyfile
from devito import *

configuration['jit-backdoor'] = True

# Dummy operator
grid = Grid(shape=(3, 3))
f = TimeFunction(name='f', grid=grid)
eq = Eq(f.forward, f + 1)
op = Operator(eq)

i = 0
another_run = [True]

while another_run[0]:
    old_cfile = "%s.c" % str(op._compiler.get_jit_dir().joinpath(op._soname))

    # Force compilation *and* loading upon the next `op.apply`
    op._lib = None
    op._cfunction = None
    del op._soname

    # Add a dummy config entry so that the next `op._soname` generated by Devito
    # will be different than the old ones. This makes sure that a *new* shared object
    # is created and loaded. If we used the old `soname`, it wouldn't work, as it's
    # already been loaded in the Python environment, and unloading unfortunately is all
    # but straightforward and safe
    configuration.add(str(i), True)
    i += 1

    new_cfile = "%s.c" % str(op._compiler.get_jit_dir().joinpath(op._soname))
    copyfile(old_cfile, new_cfile)

    # Now prepare for the next run; manually edit and save `new_cfile`, then `exit`
    # to proceed with jit-compilation and execution
    from IPython import embed; embed()

    # jit-compilation, execution
    op.apply(time_M=0)