def load_platform(): """ Create a simple 2-hosts platform */ ________ __________ | Sender |===============| Receiver | |________| Link1 |__________| """ zone = NetZone.create_full_zone("Zone1") sender = zone.create_host("sender", 1).seal() receiver = zone.create_host("receiver", 1).seal() link = zone.create_split_duplex_link("link1", 1e6) # setting same callbacks (could be different) for link UP/DOWN in split-duplex link link.get_link_up().set_sharing_policy( Link.SharingPolicy.NONLINEAR, functools.partial(link_nonlinear, link.get_link_up())) link.get_link_down().set_sharing_policy( Link.SharingPolicy.NONLINEAR, functools.partial(link_nonlinear, link.get_link_down())) link.set_latency(10e-6).seal() # create routes between nodes zone.add_route(sender.get_netpoint(), receiver.get_netpoint(), None, None, [LinkInRoute(link, LinkInRoute.Direction.UP)], True) zone.seal() # create actors Sender/Receiver Actor.create("receiver", receiver, Receiver(9)) Actor.create("sender", sender, Sender(9))
def master(): this_actor.info("Start 1st sleeper") actor = Actor.create("1st sleeper from master", Host.current(), sleeper) this_actor.info("Join the 1st sleeper (timeout 2)") actor.join(2) this_actor.info("Start 2nd sleeper") actor = Actor.create("2nd sleeper from master", Host.current(), sleeper) this_actor.info("Join the 2nd sleeper (timeout 4)") actor.join(4) this_actor.info("Start 3rd sleeper") actor = Actor.create("3rd sleeper from master", Host.current(), sleeper) this_actor.info("Join the 3rd sleeper (timeout 2)") actor.join(2) this_actor.info("Start 4th sleeper") actor = Actor.create("4th sleeper from master", Host.current(), sleeper) this_actor.info("Waiting 4") this_actor.sleep_for(4) this_actor.info("Join the 4th sleeper after its end (timeout 1)") actor.join(1) this_actor.info("Goodbye now!") this_actor.sleep_for(1) this_actor.info("Goodbye now!")
def my_daemon(): """The daemon, displaying a message every 3 seconds until all other processes stop""" Actor.self().daemonize() while True: this_actor.info("Hello from the infinite loop") this_actor.sleep_for(3.0) this_actor.info( "I will never reach that point: daemons are killed when regular processes are done" )
def load_platform(): """ Create a simple 1-host platform """ zone = NetZone.create_empty_zone("Zone1") runner_host = zone.create_host("runner", 1e6) runner_host.set_sharing_policy( Host.SharingPolicy.NONLINEAR, functools.partial(cpu_nonlinear, runner_host)) runner_host.seal() zone.seal() # create actor runner Actor.create("runner", runner_host, runner)
def monitor(): boivin = Host.by_name("Boivin") jacquelin = Host.by_name("Jacquelin") fafard = Host.by_name("Fafard") actor = Actor.create("worker", fafard, worker, boivin, jacquelin) this_actor.sleep_for(5) this_actor.info("After 5 seconds, move the process to {:s}".format( jacquelin.name)) actor.host = jacquelin this_actor.sleep_until(15) this_actor.info("At t=15, move the process to {:s} and resume it.".format( fafard.name)) actor.host = fafard actor.resume()
def dream_master(): """The Dream master""" this_actor.info("Let's create a lazy guy.") # Create a lazy_guy process lazy = Actor.create("Lazy", this_actor.get_host(), lazy_guy) this_actor.info("Let's wait a little bit...") this_actor.sleep_for(10) # Wait for 10 seconds this_actor.info("Let's wake the lazy guy up! >:) BOOOOOUUUHHH!!!!") if lazy.is_suspended(): lazy.resume() # Then wake up the lazy_guy else: this_actor.error( "I was thinking that the lazy guy would be suspended now") this_actor.sleep_for(5) # Repeat two times: this_actor.info("Suspend the lazy guy while he's sleeping...") lazy.suspend() # Suspend the lazy_guy while he's asleep this_actor.info("Let him finish his siesta.") this_actor.sleep_for(10) # Wait for 10 seconds this_actor.info("Wake up, lazy guy!") lazy.resume() # Then wake up the lazy_guy again this_actor.sleep_for(5) this_actor.info("Suspend again the lazy guy while he's sleeping...") lazy.suspend() this_actor.info("This time, don't let him finish his siesta.") this_actor.sleep_for(2) this_actor.info("Wake up, lazy guy!") lazy.resume() this_actor.sleep_for(5) this_actor.info( "Give a 2 seconds break to the lazy guy while he's working...") lazy.suspend() this_actor.sleep_for(2) this_actor.info("Back to work, lazy guy!") lazy.resume() this_actor.info("OK, I'm done here.")
def killer(): this_actor.info("Hello!") # - First start a victim process victim_a = Actor.create("victim A", Host.by_name("Fafard"), victim_a_fun) victim_b = Actor.create("victim B", Host.by_name("Jupiter"), victim_b_fun) this_actor.sleep_for(10) # - Wait for 10 seconds # - Resume it from its suspended state this_actor.info("Resume the victim A") victim_a.resume() this_actor.sleep_for(2) this_actor.info("Kill the victim A") # - and then kill it Actor.by_pid(victim_a.pid).kill( ) # You can retrieve an actor from its PID (and then kill it) this_actor.sleep_for(1) # that's a no-op, there is no zombies in SimGrid this_actor.info("Kill victim B, even if it's already dead") victim_b.kill() this_actor.sleep_for(1) this_actor.info("Start a new actor, and kill it right away") victim_c = Actor.create("victim C", Host.by_name("Jupiter"), victim_a_fun) victim_c.kill() this_actor.sleep_for(1) this_actor.info("Killing everybody but myself") Actor.kill_all() this_actor.info("OK, goodbye now. I commit a suicide.") this_actor.exit() this_actor.info( "This line never gets displayed: I'm already dead since the previous line." )
this_actor.info("Join the 3rd sleeper (timeout 2)") actor.join(2) this_actor.info("Start 4th sleeper") actor = Actor.create("4th sleeper from master", Host.current(), sleeper) this_actor.info("Waiting 4") this_actor.sleep_for(4) this_actor.info("Join the 4th sleeper after its end (timeout 1)") actor.join(1) this_actor.info("Goodbye now!") this_actor.sleep_for(1) this_actor.info("Goodbye now!") if __name__ == '__main__': e = Engine(sys.argv) if len(sys.argv) < 2: raise AssertionError( "Usage: actor-join.py platform_file [other parameters]") e.load_platform(sys.argv[1]) Actor.create("master", Host.by_name("Tremblay"), master) e.run() this_actor.info("Simulation time {}".format(Engine.get_clock()))
this_actor.sleep_for(1) this_actor.info("Start a new actor, and kill it right away") victim_c = Actor.create("victim C", Host.by_name("Jupiter"), victim_a_fun) victim_c.kill() this_actor.sleep_for(1) this_actor.info("Killing everybody but myself") Actor.kill_all() this_actor.info("OK, goodbye now. I commit a suicide.") this_actor.exit() this_actor.info( "This line never gets displayed: I'm already dead since the previous line.") if __name__ == '__main__': e = Engine(sys.argv) if len(sys.argv) < 2: raise AssertionError( "Usage: actor-kill.py platform_file [other parameters]") e.load_platform(sys.argv[1]) # Load the platform description # Create and deploy killer process, that will create the victim actors Actor.create("killer", Host.by_name("Tremblay"), killer) e.run()
if __name__ == '__main__': # Here comes the main function of your program # When your program starts, you have to first start a new simulation engine, as follows e = Engine(sys.argv) # Then you should load a platform file, describing your simulated platform e.load_platform("../../platforms/small_platform.xml") # And now you have to ask SimGrid to actually start your actors. # # The easiest way to do so is to implement the behavior of your actor in a single function, # as we do here for the receiver actors. This function can take any kind of parameters, as # long as the last parameters of Actor::create() match what your function expects. Actor.create("receiver", Host.by_name("Fafard"), receiver, "mb42") # If your actor is getting more complex, you probably want to implement it as a class instead, # as we do here for the sender actors. The main behavior goes into operator()() of the class. # # You can then directly start your actor, as follows: Actor.create("sender1", Host.by_name("Tremblay"), Sender()) # If you want to pass parameters to your class, that's very easy: just use your constructors Actor.create("sender2", Host.by_name("Jupiter"), Sender("GloubiBoulga")) # But starting actors directly is considered as a bad experimental habit, since it ties the code # you want to test with the experimental scenario. Starting your actors from an external deployment # file in XML ensures that you can test your code in several scenarios without changing the code itself. # # For that, you first need to register your function or your actor as follows. e.register_actor("sender", Sender)
# execute() tells SimGrid to pause the calling actor until # its host has computed the amount of flops passed as a parameter this_actor.execute(98095) this_actor.info("Done.") # This simple example does not do anything beyond that def privileged(): # You can also specify the priority of your execution as follows. # An execution of priority 2 computes twice as fast as a regular one. # # So instead of a half/half sharing between the two executions, # we get a 1/3 vs 2/3 sharing. this_actor.execute(98095, priority=2) this_actor.info("Done.") # Note that the timings printed when executing this example are a bit misleading, # because the uneven sharing only last until the privileged actor ends. # After this point, the unprivileged one gets 100% of the CPU and finishes # quite quickly. if __name__ == '__main__': e = Engine(sys.argv) e.load_platform(sys.argv[1]) Actor.create("executor", Host.by_name("Tremblay"), executor) Actor.create("privileged", Host.by_name("Tremblay"), privileged) e.run()
this_actor.sleep_for(5) this_actor.info("Suspend again the lazy guy while he's sleeping...") lazy.suspend() this_actor.info("This time, don't let him finish his siesta.") this_actor.sleep_for(2) this_actor.info("Wake up, lazy guy!") lazy.resume() this_actor.sleep_for(5) this_actor.info( "Give a 2 seconds break to the lazy guy while he's working...") lazy.suspend() this_actor.sleep_for(2) this_actor.info("Back to work, lazy guy!") lazy.resume() this_actor.info("OK, I'm done here.") if __name__ == '__main__': e = Engine(sys.argv) if len(sys.argv) < 2: raise AssertionError( "Usage: actor-suspend.py platform_file [other parameters]") e.load_platform(sys.argv[1]) # Load the platform description hosts = e.get_all_hosts() Actor.create("dream_master", hosts[0], dream_master) e.run() # Run the simulation
class Canceller: """This actor cancels the ongoing execution after a while.""" def __call__(self): computation_amount = this_actor.get_host().speed this_actor.info( "Canceller executes {:.0f} flops, should take 1 second.".format( computation_amount)) activity = this_actor.exec_init(computation_amount).start() this_actor.sleep_for(0.5) this_actor.info("I changed my mind, cancel!") activity.cancel() this_actor.info("Goodbye from canceller!") if __name__ == '__main__': e = Engine(sys.argv) if len(sys.argv) < 2: raise AssertionError( "Usage: exec-async.py platform_file [other parameters]") e.load_platform(sys.argv[1]) Actor.create("wait", Host.by_name("Fafard"), Waiter()) Actor.create("monitor", Host.by_name("Ginette"), Monitor()) Actor.create("cancel", Host.by_name("Boivin"), Canceller()) e.run()
def create_sata_disk(host: Host, disk_name: str): """ Same for a SATA disk, only read operation follows a non-linear resource sharing """ disk = host.create_disk(disk_name, "68MBps", "50MBps") disk.set_sharing_policy(Disk.Operation.READ, Disk.SharingPolicy.NONLINEAR, functools.partial(sata_dynamic_sharing, disk)) # this is the default behavior, expliciting only to make it clearer disk.set_sharing_policy(Disk.Operation.WRITE, Disk.SharingPolicy.LINEAR) disk.set_sharing_policy(Disk.Operation.READWRITE, Disk.SharingPolicy.LINEAR) if __name__ == '__main__': e = Engine(sys.argv) # simple platform containing 1 host and 2 disk zone = NetZone.create_full_zone("bob_zone") bob = zone.create_host("bob", 1e6) create_ssd_disk(bob, "Edel (SSD)") create_sata_disk(bob, "Griffon (SATA II)") zone.seal() Actor.create("runner", bob, host) e.run() this_actor.info("Simulated time: %g" % Engine.get_clock()) # explicitly deleting Engine object to avoid segfault during cleanup phase. # During Engine destruction, the cleanup of std::function linked to non_linear callback is called. # If we let the cleanup by itself, it fails trying on its destruction because the python main program # has already freed its variables del (e)
activity.start() this_actor.sleep_for(0.5) this_actor.info( "Loads before the move: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format( boivin.load, fafard.load, ginette.load)) activity.host = boivin this_actor.sleep_for(0.1) this_actor.info( "Loads after the move: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format( boivin.load, fafard.load, ginette.load)) activity.wait() this_actor.info("Done!") if __name__ == '__main__': e = Engine(sys.argv) e.load_platform(sys.argv[1]) Actor.create("test", Host.by_name("Fafard"), Wizard()) e.run()
def monitor(): boivin = Host.by_name("Boivin") jacquelin = Host.by_name("Jacquelin") fafard = Host.by_name("Fafard") actor = Actor.create("worker", fafard, worker, boivin, jacquelin) this_actor.sleep_for(5) this_actor.info("After 5 seconds, move the process to {:s}".format( jacquelin.name)) actor.host = jacquelin this_actor.sleep_until(15) this_actor.info("At t=15, move the process to {:s} and resume it.".format( fafard.name)) actor.host = fafard actor.resume() if __name__ == '__main__': e = Engine(sys.argv) if len(sys.argv) < 2: raise AssertionError( "Usage: actor-migration.py platform_file [other parameters]") e.load_platform(sys.argv[1]) Actor.create("monitor", Host.by_name("Boivin"), monitor) e.run()
this_actor.info("Let's do some work (for 10 sec on Boivin).") this_actor.execute(980.95e6) this_actor.info("I'm done now. I leave even if it makes the daemon die.") def my_daemon(): """The daemon, displaying a message every 3 seconds until all other processes stop""" Actor.self().daemonize() while True: this_actor.info("Hello from the infinite loop") this_actor.sleep_for(3.0) this_actor.info( "I will never reach that point: daemons are killed when regular processes are done" ) if __name__ == '__main__': e = Engine(sys.argv) if len(sys.argv) < 2: raise AssertionError( "Usage: actor-daemon.py platform_file [other parameters]") e.load_platform(sys.argv[1]) Actor.create("worker", Host.by_name("Boivin"), worker) Actor.create("daemon", Host.by_name("Tremblay"), my_daemon) e.run()
host.pstate = new_pstate this_actor.info("Changed power peak={:f}".format(host.speed)) # Run a second task this_actor.execute(workload) task_time = Engine.get_clock() - task_time this_actor.info("Task2 duration: {:.2f}".format(task_time)) # Verify that the default pstate is set to 0 host2 = Host.by_name("MyHost2") this_actor.info("Count of Processor states={:d}".format( host2.get_pstate_count())) this_actor.info("Final power peak={:f}".format(host2.speed)) if __name__ == '__main__': e = Engine(sys.argv) if len(sys.argv) < 2: raise AssertionError( "Usage: exec-dvfs.py platform_file [other parameters] (got {:d} params)" .format(len(sys.argv))) e.load_platform(sys.argv[1]) Actor.create("dvfs_test", Host.by_name("MyHost1"), Dvfs()) Actor.create("dvfs_test", Host.by_name("MyHost2"), Dvfs()) e.run()
def load_platform(): """ Creates a mixed platform, using many methods available in the API """ root = NetZone.create_floyd_zone("root") hosts = [] # dijkstra dijkstra = NetZone.create_dijkstra_zone("dijkstra") msg_base = "Creating zone: " this_actor.info(msg_base + dijkstra.name) dijkstra.set_parent(root) host1 = dijkstra.create_host("host1", [1e9, 1e8]).set_core_count(2) hosts.append(host1) host1.create_disk("disk1", 1e5, 1e4).seal() host1.create_disk("disk2", "1MBps", "1Mbps").seal() host1.seal() host2 = dijkstra.create_host("host2", ["1Gf", "1Mf"]).seal() hosts.append(host2) link1 = dijkstra.create_link( "link1_up", [1e9]).set_latency(1e-3).set_concurrency_limit(10).seal() link2 = dijkstra.create_link("link1_down", ["1GBps"]).set_latency("1ms").seal() dijkstra.add_route(host1.get_netpoint(), host2.get_netpoint(), None, None, [LinkInRoute(link1)], False) dijkstra.add_route(host2.get_netpoint(), host1.get_netpoint(), None, None, [LinkInRoute(link2)], False) dijkstra.seal() # vivaldi vivaldi = NetZone.create_vivaldi_zone("vivaldi") this_actor.info(msg_base + vivaldi.name) vivaldi.set_parent(root) host3 = vivaldi.create_host("host3", 1e9).set_coordinates("1 1 1").seal() host4 = vivaldi.create_host("host4", "1Gf").set_coordinates("2 2 2").seal() hosts.append(host3) hosts.append(host4) # empty empty = NetZone.create_empty_zone("empty") this_actor.info(msg_base + empty.name) empty.set_parent(root) host5 = empty.create_host("host5", 1e9) hosts.append(host5) empty.seal() # wifi wifi = NetZone.create_wifi_zone("wifi") this_actor.info(msg_base + wifi.name) wifi.set_parent(root) router = wifi.create_router("wifi_router") wifi.set_property("access_point", "wifi_router") host6 = wifi.create_host("host6", ["100.0Mf", "50.0Mf", "20.0Mf"]).seal() hosts.append(host6) wifi_link = wifi.create_link("AP1", ["54Mbps", "36Mbps", "24Mbps"]).seal() wifi_link.set_host_wifi_rate(host6, 1) wifi.seal() # create routes between netzones link_a = vivaldi.create_link("linkA", 1e9).seal() link_b = vivaldi.create_link("linkB", "1GBps").seal() link_c = vivaldi.create_link("linkC", "1GBps").seal() root.add_route(dijkstra.get_netpoint(), vivaldi.get_netpoint(), host1.get_netpoint(), host3.get_netpoint(), [LinkInRoute(link_a)], True) root.add_route(vivaldi.get_netpoint(), empty.get_netpoint(), host3.get_netpoint(), host5.get_netpoint(), [LinkInRoute(link_b)], True) root.add_route(empty.get_netpoint(), wifi.get_netpoint(), host5.get_netpoint(), router, [LinkInRoute(link_c)], True) # create actors Sender/Receiver Actor.create("sender", hosts[0], Sender(hosts)) for host in hosts: Actor.create("receiver", host, Receiver())