Skip to content

Hybrid: a second solve in the same process sets up its own output - #33

Merged
jcschaff merged 1 commit into
mainfrom
fix/hybrid-second-solve
Oct 8, 2026
Merged

jcschaff merged 1 commit into
mainfrom
fix/hybrid-second-solve

Conversation

@jcschaff

@jcschaff jcschaff commented Oct 7, 2026

Copy link
Copy Markdown
Member

Fixes #23.

Cause. Under lldb, the second pyvcell_fvsolver.solve() on hybrid inputs stops with EXC_BAD_ACCESS (address=0x0) in VCellSmoldynOutput::computeHistogram(), called from SimTool::start1(). The sequence:

  1. smoldynInit creates a new VCellSmoldynOutput for every hybrid run.
  2. Its output arrays are set up by parseInput.
  3. cmdVCellWriteOutput calls parseInput only once per process, behind a function-level static bool firstTime, and collects the block's lines in a static stringstream.
  4. On the second solve, the new output object is never parsed, and computeHistogram reads its null arrays.

cmdVCellDataProcess keeps the same kind of state in statics.

Fix. That state now lives on the VCellSmoldynOutput: outputInputParsed, outputInput, dataProcessInputParsed, dataProcessInput and dataProcName. Each run starts clean. The standalone smoldyn_x64 executable runs one simulation per process, so its behaviour is unchanged.

Verified (macOS arm64, cp312-abi3 wheel built from this branch):

  • Three hybrid solves of the same inputs in one Python process all return 0, where the stock wheel segfaults on the second.
  • The three result archives are bit-identical (same seed), so no state leaks from one run into the next.

Not changed: leftover cleanup. The hybrid path never calls vcellhybrid::smoldynEnd, so the Smoldyn sim and the previous VCellSmoldynOutput leak once per solve. That costs memory but is harmless here. Freeing them needs ~VCellSmoldynOutput to stop dereferencing the freed smoldynSim, which is better left to a separate change.

🤖 Generated with Claude Code

cmdVCellWriteOutput collected the vcellWriteOutput block and parsed it into
the VCellSmoldynOutput once per process, guarded by a function-level static.
smoldynInit creates a new VCellSmoldynOutput for every hybrid run, so the
second solve's output was never parsed and computeHistogram dereferenced its
null output arrays (EXC_BAD_ACCESS in VCellSmoldynOutput::computeHistogram,
called from SimTool::start1). cmdVCellDataProcess kept the same kind of state.

That state now lives on the VCellSmoldynOutput, so each run starts clean.

Fixes #23.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jcschaff
jcschaff merged commit 7841f43 into main Oct 8, 2026
12 checks passed
@jcschaff jcschaff mentioned this pull request Oct 8, 2026
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.

Second spatial-hybrid (FV + Smoldyn) solve in the same process segfaults (pyvcell_fvsolver.solve)

1 participant