Skip to content

Fix callable evaluator failing in subprocess workers#423

Open
powerpratik wants to merge 1 commit intoalgorithmicsuperintelligence:mainfrom
powerpratik:fix/callable-evaluator-cross-process
Open

Fix callable evaluator failing in subprocess workers#423
powerpratik wants to merge 1 commit intoalgorithmicsuperintelligence:mainfrom
powerpratik:fix/callable-evaluator-cross-process

Conversation

@powerpratik
Copy link

Summary

  • Bug: _prepare_evaluator() stored callable evaluators in globals() of the api module, which is inaccessible from ProcessPoolExecutor worker processes. Workers import openevolve.api fresh and the dynamic attribute doesn't exist in their memory space, causing AttributeError on every evaluation.
  • Fix: Serialize the callable to disk via cloudpickle/pickle and have the evaluator wrapper load it from the file.
  • Docs: Added if __name__ == '__main__': guard to the library usage example in the README, with a note about macOS/Windows multiprocessing requirements.

Changes

File Change
openevolve/api.py Replace globals() storage with pickle-to-disk serialization
pyproject.toml Add cloudpickle>=2.0.0 dependency
tests/test_api.py Add 2 cross-process tests (simple callable + closure), update existing assertion
README.md Add __main__ guard to library example + note

Reproduction

Before this fix, using evolve_function(), evolve_code(), or evolve_algorithm() with process-parallel evaluation produces:

AttributeError: module 'openevolve.api' has no attribute '_openevolve_evaluator_XXXXXXXX'

Test plan

  • All 350 existing unit tests pass
  • 2 new tests verify callable evaluators work in a subprocess (simple function + closure)
  • Verified end-to-end with a local LLM endpoint (Ollama)

@CLAassistant
Copy link

CLAassistant commented Mar 2, 2026

CLA assistant check
All committers have signed the CLA.

_prepare_evaluator() stored callable evaluators in globals() of the api
module, which is inaccessible from ProcessPoolExecutor worker processes.
Workers import openevolve.api fresh and the dynamic attribute doesn't
exist in their memory space, causing AttributeError on every evaluation.

Fix: serialize the callable to disk via cloudpickle/pickle and have the
evaluator wrapper load it from the file. Also document the if __name__
== '__main__' guard requirement for macOS/Windows multiprocessing.

Verified with a local LLM endpoint (Ollama) to confirm cross-process
evaluation works end-to-end.
@powerpratik powerpratik force-pushed the fix/callable-evaluator-cross-process branch from 892e988 to 79b72b0 Compare March 2, 2026 02:09
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.

2 participants