Skip to content

Key the compiled models by the load options and honor RECOMPILE in LLJit - #1424

Closed
matthiaskoenig wants to merge 1 commit into
sys-bio:developfrom
matthiaskoenig:lljit-object-cache
Closed

matthiaskoenig wants to merge 1 commit into
sys-bio:developfrom
matthiaskoenig:lljit-object-cache

Conversation

@matthiaskoenig

Copy link
Copy Markdown
Collaborator

LLJit reused the object of a model compiled earlier in the process
whenever the md5 of the SBML matched. The key did not hold the load
options, so a model loaded with another LLJIT_OPTIMIZATION_LEVEL kept
the code of the first level, and a model loaded with other options,
e.g. MUTABLE_INITIAL_CONDITIONS, got code without the functions it
needs and crashed. LOADSBMLOPTIONS_RECOMPILE did not prevent the reuse.

getSBMLMD5 now returns a key of the md5 of the SBML, the load options
except RECOMPILE (they include the JIT and its optimization level) and
LOADSBMLOPTIONS_PERMISSIVE, which the code generation reads. The model
cache of the LLVMModelGenerator and the object cache of LLJit use it,
and the copy of getSBMLMD5 in the LLVMModelGenerator is gone. Each LLJit
has its own object cache in front of the shared one: with RECOMPILE it
compiles the module instead of looking for it, and it keeps the object
of its model, which saveState uses instead of looking up the shared
cache, where another model may have replaced it. The shared cache holds
shared objects and locks its lookups too.

Fixes #1420.

With develop, this crashes in the second RoadRunner with "Could not find symbol getFloatingSpeciesAmount", and works with this change:

import roadrunner
C = roadrunner.Config
C.setValue(C.LLVM_BACKEND, C.LLJIT)
C.setValue(C.LOADSBMLOPTIONS_MUTABLE_INITIAL_CONDITIONS, True)
roadrunner.RoadRunner("feedback.xml")
C.setValue(C.LOADSBMLOPTIONS_MUTABLE_INITIAL_CONDITIONS, False)
roadrunner.RoadRunner("feedback.xml")

The script of #1420 now compiles the model three times, once for each load.

LLJit reused the object of a model compiled earlier in the process
whenever the md5 of the SBML matched. The key did not hold the load
options, so a model loaded with another LLJIT_OPTIMIZATION_LEVEL kept
the code of the first level, and a model loaded with other options,
e.g. MUTABLE_INITIAL_CONDITIONS, got code without the functions it
needs and crashed. LOADSBMLOPTIONS_RECOMPILE did not prevent the reuse.

getSBMLMD5 now returns a key of the md5 of the SBML, the load options
except RECOMPILE (they include the JIT and its optimization level) and
LOADSBMLOPTIONS_PERMISSIVE, which the code generation reads. The model
cache of the LLVMModelGenerator and the object cache of LLJit use it,
and the copy of getSBMLMD5 in the LLVMModelGenerator is gone. Each LLJit
has its own object cache in front of the shared one: with RECOMPILE it
compiles the module instead of looking for it, and it keeps the object
of its model, which saveState uses instead of looking up the shared
cache, where another model may have replaced it. The shared cache holds
shared objects and locks its lookups too.

Fixes sys-bio#1420.
@luciansmith

Copy link
Copy Markdown

Recreated in #1440.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LLJit reuses the compiled object of a model in a process despite LOADSBMLOPTIONS_RECOMPILE and a changed optimization level

2 participants