Package: simulus
Quick StartSimulus is an open-source discrete-event simulator in Python. Simulus implements a process-oriented simulation world-view with several advanced features to ease modeling and simulation tasks with both events and processes.  Simulus also supports parallel and distributed simulation (since version 1.2). We will soon add support for real-time simulation (planned for version 1.3).Online documentation:http://simulus.readthedocs.io/Source code repository:https://github.com/liuxfiu/simulus/License:
MIT -- see the file LICENSE for details.InstallationSimulus should run with Python version 2.8 and above. If your python is too old, you should consider updating your Python as well aspip(Python’s package manager).You should be able to install simulus withpip:pip install simulusThis will install simulus system-wide for all users (assuming you have the necessary privilege on your machine). The installation will also automatically include all Python packages needed by simulus.You can also install simulus for just yourself, using:pip install --user simulusIf you had simulus installed previously, you can always upgrade the existing simulus installation with the newest release, using:pip install --upgrade --user simulusYou can also install the most recent development version via:pip install -e git+https://github.com/liuxfiu/simulus.git#egg=simulusBasic UsageWe show the basic use of simulus in the following. The purpose here is show some of the basic capabilities of simulus. For more detailed explanation and to learn to use simulus, you should check out the simulus tutorial mentioned above.Simulus can work in two ways. One way is through events. The user schedules events. Simulus makes sure all events are sorted in timestamp order. When an event happens, simulus advances the simulation time to the event and calls the event handler, which is just a user-defined function. While processing the event, the user can schedule new events into the simulated future. We call this approachdirect event scheduling.The other way is through processes. The user can create processes and have them run and interact. Each process is a separate thread of control. During its execution, a process may be suspended, by either sleeping for some time or getting blocked when requesting for some resources currently unavailable. The process resumes execution when the specified time has passed or after the resource blocking conditions have been removed. We call this approachprocess scheduling.In simulus, both direct event scheduling and process scheduling can be used together seamlessly to achieve the modeling tasks.The following is a hello-world example, which simply schedules a function (a.k.a. an event handler) to be invoked in the simulated future. Inside the function, the user schedules the same function again.importsimulusdefprint_message():print("Hello world at time",sim.now)sim.sched(print_message,offset=10)sim=simulus.simulator()sim.sched(print_message,until=10)sim.run(100)Hello world at time 10
Hello world at time 20
Hello world at time 30
Hello world at time 40
Hello world at time 50
Hello world at time 60
Hello world at time 70
Hello world at time 80
Hello world at time 90The following is the same hello-world example, but instead we use a process. A process is a continuous thread of execution. In the example, once started, the process loops forever. Inside each iteration, the process prints out a message and then sleeps for some time.importsimulusdefprint_message():whileTrue:print("Hello world at time",sim.now)sim.sleep(10)sim=simulus.simulator()sim.process(print_message,until=10)sim.run(100)Hello world at time 10
Hello world at time 20
Hello world at time 30
Hello world at time 40
Hello world at time 50
Hello world at time 60
Hello world at time 70
Hello world at time 80
Hello world at time 90Simulus allows events and processes to coexist. For example, simulus supports conditional-wait on both events and processes. The following shows an example that models Tom and Jerry entering a race.Tom is modeled by processes. Each time Tom enters the race, we create a process, which callssleep()to represent the time duration for the run. The time duration is a random variable from a normal distribution with a mean of 100 and a standard deviation of 50 (and a cutoff below zero). Jerry is modeled by events. Each time Jerry enters the race, we schedule an event usingsched()with a time offset representing the time duration for the run. The time duration is a random variable from a uniform distribution between 50 and 100.Tom and Jerry compete for ten times; the next race would start as soon as the previous one finishes. For each race, whoever runs the fastest wins. But if they run for more than 100, both are disqualified for that race. The simulation finds out who eventually wins more races.importsimulusfromrandomimportseed,gauss,uniformseed(321)deftom():sim.sleep(max(0,gauss(100,50)))print("%g: tom finished"%sim.now)defjerry():print("%g: jerry finished"%sim.now)defcompete():tom_won,jerry_won=0,0for_inrange(10):print("<--- competition starts at%g-->"%sim.now)p=sim.process(tom)# run, tom, run!e=sim.sched(jerry,offset=uniform(50,150))# run, jerry, run!# let the race begin...(r1,r2),timedout=sim.wait((p,e),100,method=any)# the return values indicate which wait conditions have been satisfiediftimedout:print("%g: both disqualified"%sim.now)sim.cancel(p)# both tom and ...sim.cancel(e)# jerry can stop running nowelifr1:print("%g: tom wins"%sim.now)tom_won+=1sim.cancel(e)# jerry can stop running nowelse:print("%g: jerry wins"%sim.now)jerry_won+=1sim.cancel(p)# tom can stop running nowprint("final result: tom:jerry=%d:%d"%(tom_won,jerry_won))sim=simulus.simulator()sim.process(compete)sim.run()<--- competition starts at 0 -->
77.5459: jerry finished
77.5459: jerry wins
<--- competition starts at 77.5459 -->
171.749: jerry finished
171.749: jerry wins
<--- competition starts at 171.749 -->
271.749: both disqualified
<--- competition starts at 271.749 -->
357.072: tom finished
357.072: tom wins
<--- competition starts at 357.072 -->
430.387: tom finished
430.387: tom wins
<--- competition starts at 430.387 -->
485.297: tom finished
485.297: tom wins
<--- competition starts at 485.297 -->
585.297: both disqualified
<--- competition starts at 585.297 -->
611.838: tom finished
611.838: tom wins
<--- competition starts at 611.838 -->
711.838: both disqualified
<--- competition starts at 711.838 -->
811.838: both disqualified
final result: tom:jerry=4:2Simulus also provides several advanced features to ease the common modeling and simulation tasks, including those for modeling single-server or multi-server queues, for performing producer-consumer synchronization over bounded buffers, and for conducting message-passing communication among the processes.For example, simulus provides the modeling abstraction of a "store", which is a facility for storing countable objects (such as jobs in a queue, packets in a network router, and i/o requests arrived at a storage device), or for storing uncountable quantities or volumes (such as gas in a tank, water in a reservoir, and battery power in a mobile device). The following example shows the use of store as a bounded buffer with multiple producers and consumers.importsimulusfromrandomimportseed,expovariateseed(12345)items_produced=0# keep track the number of items being produceddefproducer(idx):globalitems_producedwhileTrue:sim.sleep(expovariate(1))# take time to produce an itemserial_no=items_produceditems_produced+=1print("%f: producer%dproduces item [%d]"%(sim.now,idx,serial_no))s.put(obj=serial_no)print("%f: producer%dstores item [%d] in buffer"%(sim.now,idx,serial_no))defconsumer(idx):whileTrue:serial_no=s.get()print("%f: consumer%dretrieves item [%d] from buffer"%(sim.now,idx,serial_no))sim.sleep(expovariate(1))# take time to consume the itemprint("%f: consumer%dconsumes item [%d]"%(sim.now,idx,serial_no))sim=simulus.simulator()# create a buffer with 3 slotss=sim.store(capacity=3)# create 2 producers and 3 consumersforiinrange(2):sim.process(producer,i)foriinrange(3):sim.process(consumer,i)sim.run(5)0.010221: producer 1 produces item [0]
0.010221: producer 1 stores item [0] in buffer
0.010221: consumer 0 retrieves item [0] from buffer
0.364955: consumer 0 consumes item [0]
0.538916: producer 0 produces item [1]
0.538916: producer 0 stores item [1] in buffer
0.538916: consumer 2 retrieves item [1] from buffer
0.754168: consumer 2 consumes item [1]
0.998434: producer 0 produces item [2]
0.998434: producer 0 stores item [2] in buffer
0.998434: consumer 1 retrieves item [2] from buffer
1.174799: consumer 1 consumes item [2]
1.754371: producer 1 produces item [3]
1.754371: producer 1 stores item [3] in buffer
1.754371: consumer 0 retrieves item [3] from buffer
1.833163: producer 0 produces item [4]
1.833163: producer 0 stores item [4] in buffer
1.833163: consumer 2 retrieves item [4] from buffer
1.887065: producer 1 produces item [5]
1.887065: producer 1 stores item [5] in buffer
1.887065: consumer 1 retrieves item [5] from buffer
2.024740: consumer 2 consumes item [4]
2.321655: consumer 0 consumes item [3]
2.325417: consumer 1 consumes item [5]
2.658879: producer 0 produces item [6]
2.658879: producer 0 stores item [6] in buffer
2.658879: consumer 2 retrieves item [6] from buffer
2.692757: producer 1 produces item [7]
2.692757: producer 1 stores item [7] in buffer
2.692757: consumer 0 retrieves item [7] from buffer
2.754613: consumer 2 consumes item [6]
3.223988: consumer 0 consumes item [7]CreditsSimulus is developed and maintained by Jason Liu (jasonxliu2010@gmail.com). The project started as a summer pet project in 2019. Simulus is open source and free. The author hopes that you'll find simulus useful in your projects, for teaching, for research development, or for any endeavors.If you are using simulus in any extended way, the author would appreciate if you can drop a brief email to let him know about your projects using simulus. If you have any questions or comments about simulus, send emails to him too. The author would certainly try his best to respond to them in a timely fashion.1.2.1 (2019-09-09)NewAdded LANL benchmark model. [Jason Liu]ChangesAdded bucket for uncountable quantities (as opposed of using store), and added muxtree example. [Jason Liu]1.2.0 (2019-08-14)NewFinished parallel simulation tutorial. [Jason Liu]Changed simulator's run() to run up to but not including the given time; updated parallel simulation tutorial. [Jason Liu]Changed argparse to happen at import time; added simulator.sync() function; fixed phold.py in advanced example. [Jason Liu]Added ability for sync to have multiple runs and enabled runtime performance reporting. [Jason Liu]Added parallel simulation support, including SPMD (using MPI), SMP (using processes), and both. [Jason Liu]Preliminary performance tuning; disabled expensive debug logging; added context manager for resource. [Jason Liu]ChangesSome UI updates and added parallel simulation tutorial. [Jason Liu]1.1.5 (2019-07-26)NewAdded logging support and runtime performance metrics. [Jason Liu]Added jupyter notebooks for queuing models. [Jason Liu]Tagged 1.1.4 and release. [Jason Liu]1.1.4 (2019-07-17)NewAdded support for dynamic process priorities. [Jason Liu]Added data collector support; tagged 1.1.3. [Jason Liu]ChangesChanged RunStats name to DataSeries, and QDIS.RANDOM to QDIS.SIRO. [Jason Liu]Removed dependence on runstats. [Jason Liu]Changelog1.1.3 (2019-07-15)NewUpdated data collectors for resources and facilities. [Jason Liu]Tag and release version 1.1.2. [Jason Liu]Added mechanisms for consistent, independent random number generators. [Jason Liu]ChangesRestructured tutorial document.1.1.2 (2019-07-10)NewAdded documentation for mailbox and examples. [Jason Liu]ChangesAdded section on using store with examples. [Jason Liu]1.1.1 (2019-07-09)NewSphinx generated documents for simulus api. [Jason Liu]ChangesMoved to github, fixed pipenv requirements, changed cancel() to also kill process, and made trappable a public interface with retval.Updated README.md from readme.ipynb; updated tutorial. [Jason Liu]OtherSet theme jekyll-theme-cayman. [liuxfiu]Tagged and published version 1.1.0. [Jason Liu]1.1.0 (2019-07-07)NewAdded sections to explain the use of resource and store in tutorial; also added readme jupyter notebook.Added store facility and some examples, including most simpy examples. [Jason Liu]Added a couple simpy examples (carwash, moviegoers). [Jason Liu]Changed sched() and process() to allow arbitrary functions; examples and documents have been updated accordingly. [Jason Liu]Added regression pytest and tox support. [Jason Liu]Changed the use of super() in init methods.Changed tomjerry.py; gauss distribution may return negative time. [Jason Liu]1.0.5 (2019-07-04)NewNew trappables and conditional waits (1.0.5).Added support for changelogs generated from git logs.Changed resource reserve to acquire. [Jason Liu]Redesigned trappables; the processes, events, semaphores, traps, and resources now work with a more intuitive interface design. [Jason Liu]Added initial implementation of resource and qstats. [Jason Liu]1.0.4 (2019-07-04)NewFinished trappables and timed waits implementation and accompanying documents (1.0.4). [Jason Liu]Updated documents for using trappables and timed wait; and a bug fix. [Jason Liu]Added support for conditional wait (wait on multiple trappables and timed wait). [Jason Liu]1.0.1 (2019-07-04)NewPip ready; simulus has been published on pypi (1.0.1, 1.0.2, 1.0.3). [Jason Liu]0.0.3 (2019-07-04)NewAdding trapping mechanisms for inter-process communication. [Jason Liu]0.0.2 (2019-07-04)NewAdded some examples using processes for user document. [Jason Liu]Added useful functions for direct event scheduling (including resched, cancel, peek, step, and show_calendar). [Jason Liu]Added phold example (to test processes). [Jason Liu]ChangesRestructured examples directory (0.0.2). [Jason Liu]FixFixed process scheduling issue. [Jason Liu]0.0.1 (2019-07-04)NewFirst implementation of simulus, with support of events, processes, semaphores, and simulators; and also the jupyter notebook establishing the simple use cases. [Jason Liu]This project got started in the evening on June 14, 2019 with a simple idea of creating an easy-to-use python simulator to replace our somewhat dilapitated Simian simulator and also outdoing the esoteric SimPy simulator. [Jason Liu]ChangesUpdated the jupyter notebooks. [Jason Liu]Updated README.md (mindless update). [Jason Liu]Updated README.md. [Jason Liu]