Skip to main content

Simpy with

Project description

SerializableSimpy

SerializableSimpy Project aims to extends the capabilities of traditional SimPy by introducing serializability and parallelism.

Standard SimPy uses Python's yield keyword to implement events, which prevents object serialization and limits scalability. SerializableSimpy provides a "yield-less" implementation of DES logic, enabling:

  • Simulation state checkpointing: pause/resume/rollback
  • Parallelism: Multiprocessing and MPI-based

Full API Documentation: https://serializablesimpy.readthedocs.io

Why a new Discrete Event Simulator?

We designed SerializableSimpy around SimPy’s proven and intuitive API, which has a strong and active user base. However, SimPy’s reliance on generator-based coroutines limits its applicability in modern simulation workflows.

While inspired by SimPy, SerializableSimpy is not a drop-in replacement and does not implement all of SimPy’s API.

Installation & Dependencies

SerializableSimpy can be installed as a standalone Python module.

pip install serializable-simpy

To enable distributed execution via MPI, install:

pip install mpi4py

No other dependency is needed.

API difference with Simpy

This code pattern with Simpy

do_something_before(a,b,c)
yield env.timeout(10)
do_something_after(d,e,f)

In SerializableSimpy becomes:

do_something_before(a,b,c)
env.timeout(10, do_something_after, (d,e,f))

You can find many other Simpy examples converted in SerializableSimy here: [URL here]

Checkpointing Example

Here's an example to demonstrate how to use the objects

from SerializableSimpy.core import Environment, Process


class Clock(Process):
    def __init__(self, env, name, tick):
        self.name = name
        self.env = env
        self.tick = tick

    def on_initialize(self, env):
        self.env = env
        self.on_tick()

    def on_tick(self):
        print(self.name, self.env.now)
        self.env.timeout(self.tick, self.on_tick,
                         ())  # `yield env.timeout(tick)` becomes `env.timeout(tick, on_tick, ())`


env = Environment()
env.process(Clock(env, 'fast', 0.5))
env.process(Clock(env, 'slow', 1))

env.run(until=2)

# Saving/Restoring with pickle is possible
import pickle

with open("checkpoint.pkl", "wb") as f:
    pickle.dump(env, f)
del env
print("Restoring")
with open("checkpoint.pkl", "rb") as f:
    env = pickle.load(f)

env.run(until=4)

Prints:

fast 0
slow 0
fast 0.5
slow 1
fast 1.0
fast 1.5
fast 2.0
slow 2
fast 2.5
slow 3
fast 3.0
fast 3.5

Inspired from the official Simpy code: https://gitlab.com/team-simpy/simpy. Simpy in its current shape cannot serialize objects. Let's take the simplest example of the homepage.

import simpy
def clock(env, name, tick):
    while True:
        print(name, env.now)
        yield env.timeout(tick)

env = simpy.Environment()
env.process(clock(env, 'fast', 0.5))
env.process(clock(env, 'slow', 1))
env.run(until=2)

import pickle
with open("checkpoint.pkl","wb") as f:
    pickle.dump(env, f) # ❌ TypeError: cannot pickle 'generator' object

Using Parallel Environments

SerializableSimpy supports multiple runtime backends. Choose based on your use case:

# Sequential environemnt:
from SerializableSimpy.core import Environment 
env=Environment(initial_time=0.) 
env.run(until=1.)

# MPI (Message Passing Interface) environemnt :
from SerializableSimpy.MPI_core import MPIGlobalEnv
env=MPIGlobalEnv(initial_time=0.) 
env.run(until=1., delta=0.1)

# Multiprocessing environemnt (Shared memory):
from SerializableSimpy.MP_core import MPGlobalEnv
env=MPGlobalEnv(initial_time=0.) 
env.run(until=1., delta=0.1)

Note: Parallel simulation requires setting a delta time step to synchronize local environments. A small delta may improve accuracy at the cost of communication/synchronization overhead.

Parallel Simulation Benchmark

In the folder ./application/tuto/parallelism/, you'll find three implementations of a producer-consumer model—a common DES pattern in manufacturing and logistics.

Execution Comparison

Parallel Method User Code Lines Time (sec.) Consumed Items Multi-Machine Compatible
Sequential 54 40.04 20
Multiprocessing 63 20.05 19
MPI 67 20.02 18

Observations:

  • MPI introduces lower overhead than multiprocessing for producer-consumer setups. However, when delta becomes too small, synchronization overhead increases significantly hurting MPI performance more than multiprocessing.
  • Multiprocessing may yield final state closer to sequential. It is because they are not only synchronized every delta, but exchange through a shared memory during simulation. In the wost case, Multiprocessing processes are synchronized every delta. In the best case, computation time matches simulation time.

Running on MeluXina Supercomputer

See MeluXinaREADME.md for a detailed walkthrough on deploying SerializableSimpy on the MeluXina EuroHPC system.

Acknowledgment

SerializeSimpy contributor(s) would like to express their gratitude for the fruitful discussions and the collaboration that made this project possible between Goodyear company and the University of Luxembourg.

Supported by the Luxembourg National Research Fund 17941664

Supported by the Ministry of Economy (MECO) 17941664

Contact

For any questions or suggestions, please contact mailto:pierrick.pochelu@gmail.com.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

serializable_simpy-0.0.3.tar.gz (29.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

serializable_simpy-0.0.3-py3-none-any.whl (24.3 kB view details)

Uploaded Python 3

File details

Details for the file serializable_simpy-0.0.3.tar.gz.

File metadata

  • Download URL: serializable_simpy-0.0.3.tar.gz
  • Upload date:
  • Size: 29.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for serializable_simpy-0.0.3.tar.gz
Algorithm Hash digest
SHA256 5ba55b74dfb4f2c02a7746a57b7d3b0ebd23beba542b29fb74829af765583b7a
MD5 c701ea0cbaaecc1b9c7cf7dc40cfa2dc
BLAKE2b-256 ef893ceaac5f7f257125b5537077338df6d08714478d3e971c07b9ff379f80d5

See more details on using hashes here.

File details

Details for the file serializable_simpy-0.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for serializable_simpy-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 0c630052645cd6cae748daaaa828b3ae4ecacc2d22c09491ca8ac430c777ccbd
MD5 459ed8ef60338a1bc15890fc86997af1
BLAKE2b-256 4deeb6e46b78a4fed3921f25c22a22b6ff1d6ea9d487bb4da8d687a3bbab8349

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page