Updated the LSODE integrator to be thread-safe#147
Open
yantosca wants to merge 3 commits into
Open
Conversation
yantosca
marked this pull request as draft
April 23, 2026 19:47
yantosca
force-pushed
the
feature/lsode-thread-safe
branch
3 times, most recently
from
April 23, 2026 20:26
114cb08 to
9cb4057
Compare
yantosca
force-pushed
the
feature/lsode-thread-safe
branch
from
May 28, 2026 17:50
9cb4057 to
ef2651d
Compare
yantosca
force-pushed
the
feature/lsode-thread-safe
branch
2 times, most recently
from
June 10, 2026 16:35
9ee9bde to
97592da
Compare
yantosca
force-pushed
the
feature/lsode-thread-safe
branch
2 times, most recently
from
June 18, 2026 14:01
23945ae to
4d1c9b2
Compare
yantosca
force-pushed
the
feature/lsode-thread-safe
branch
2 times, most recently
from
July 8, 2026 15:00
73ef28b to
c9bb684
Compare
yantosca
marked this pull request as ready for review
July 8, 2026 19:21
RolfSander
reviewed
Jul 8, 2026
RolfSander
left a comment
Contributor
There was a problem hiding this comment.
Sorry, I don't know much about thread-safe coding, so I won't be able to
contribute anything useful here...
yantosca
requested review from
RolfSander and
obin1
and removed request for
RolfSander
July 9, 2026 15:07
Contributor
Author
|
Thanks @RolfSander. We can hold off on merging until someone else reviews it. @obin1 would you be willing take a look? |
int/lsode.f90 - Refactored (with Claude AI) to be thread-safe. Removed the COMMON /DLS001/ block and replaced with threadprivate variables. CHANGELOG.md - Updated accordingly Signed-off-by: Bob Yantosca <yantosca@seas.harvard.edu>
STEPMIN is written by INTEGRATE() on every call and read back by some integrators (e.g. the TLM) as the next call's starting step, so a shared STEPMIN races across OpenMP threads and can leak one thread's step size into another's. Declare it THREADPRIVATE in gen.c so all generated _Global.f90 files pick it up (STEPMAX is write-once/read-only and does not need this). Also declare LUNIT/MESFLG THREADPRIVATE inside IXSAV in lsode.f90: despite the COMMON /DLS001/ removal, these SAVE locals still have static storage shared across all threads and calls, and XERRWD reads them via IXSAV on every error/warning path.
docs/source/reference/known-bugs.rst docs/source/tech_info/07_numerical_methods.rst - Removed warnings that LSODE is not thread safe, as we have now fixed this. CHANGELOG.md - Updated accordingly Signed-off-by: Bob Yantosca <yantosca@seas.harvard.edu>
yantosca
force-pushed
the
feature/lsode-thread-safe
branch
from
July 15, 2026 17:46
e2d7568 to
62e914b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In this PR we have modified the
int/lsode.f90integrator to be OpenMP thread-safe. This is done by removing theCOMMON /DLS001/common block declaration. All variables that used to be in the common block are now declared as local variables within routineDLSODEand are therefore reachable by other internal routines used by LSODE under itsCONTAINSstatement.The refactoring was done with Claude Code AI.
Summary of Changes Applied
Do_Update_*flags!$OMP THREADPRIVATE(...)directive after the threeLOGICALdeclarationsDLSODEdeclarationsINTEGER INIT,MXSTEP,...,IOWNS+KPP_REAL ROWNS,CCMAX,...+COMMON /DLS001/block; replaced with named local variablesCONIT,CRATE,EL(13),ELCO(13,12),...covering all 218 reals and 37 integersDINTDYINTEGER IOWND,IOWNS,...+KPP_REAL ROWNS,...+COMMON /DLS001/; variables now reached via host associationDPREPJIERretained as a local integerDSOLSYDSRCOMCOMMON /DLS001/no longer exists)DSTODEINTEGER IOWND,IALTH,...+KPP_REAL CONIT,CRATE,EL,...+COMMON /DLS001/; all state reached via host associationLUNIT!$OMP THREADPRIVATEin functionIXSAVMESFLG!$OMP THREADPRIVATEin functionIXSAVSTEPMIN!$OMP THREADPRIVATEinROOT_Global.f90orROOT_Global.F90