Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Pylint examples/*.py.
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Thu, 17 Feb 2022 14:40:05 +0000 (15:40 +0100)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Thu, 17 Feb 2022 14:49:54 +0000 (15:49 +0100)
27 files changed:
examples/c/app-bittorrent/generate.py
examples/c/dht-kademlia/generate.py
examples/c/dht-pastry/generate.py
examples/cpp/dht-kademlia/generate.py
examples/deprecated/java/app/bittorrent/generate.py
examples/python/actor-create/actor-create.py
examples/python/actor-daemon/actor-daemon.py
examples/python/actor-join/actor-join.py
examples/python/actor-kill/actor-kill.py
examples/python/actor-lifetime/actor-lifetime.py
examples/python/actor-migrate/actor-migrate.py
examples/python/actor-suspend/actor-suspend.py
examples/python/actor-yield/actor-yield.py
examples/python/app-masterworkers/app-masterworkers.py
examples/python/clusters-multicpu/clusters-multicpu.py
examples/python/comm-wait/comm-wait.py
examples/python/comm-waitall/comm-waitall.py
examples/python/comm-waitany/comm-waitany.py
examples/python/exec-async/exec-async.py
examples/python/exec-basic/exec-basic.py
examples/python/exec-cpu-nonlinear/exec-cpu-nonlinear.py
examples/python/exec-dvfs/exec-dvfs.py
examples/python/exec-remote/exec-remote.py
examples/python/io-degradation/io-degradation.py
examples/python/network-nonlinear/network-nonlinear.py
examples/python/platform-failures/platform-failures.py
examples/python/platform-profile/platform-profile.py

index 345e739..aaaa1f9 100755 (executable)
@@ -6,10 +6,12 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This script generates a specific deployment file for the Bittorrent example.
-# It assumes that the platform will be a cluster.
-# Usage: python generate.py nb_nodes nb_bits end_date percentage
-# Example: python generate.py 10000 5000
+"""
+This script generates a specific deployment file for the Bittorrent example.
+It assumes that the platform will be a cluster.
+Usage: python generate.py nb_nodes nb_bits end_date percentage
+Example: python generate.py 10000 5000
+"""
 
 import sys
 import random
index 1af0de6..9986fb8 100755 (executable)
@@ -6,6 +6,10 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
+"""
+Usage: python generate.py nb_nodes nb_bits end_date > deployment_file.xml
+"""
+
 import sys
 import random
 
index e517a3c..0db8029 100755 (executable)
@@ -6,10 +6,12 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This script generates a specific deployment file for the Chord example.
-# It assumes that the platform will be a cluster.
-# Usage: python generate.py nb_nodes nb_bits end_date
-# Example: python generate.py 100000 32 1000
+"""
+This script generates a specific deployment file for the Chord example.
+It assumes that the platform will be a cluster.
+Usage: python generate.py nb_nodes nb_bits end_date
+Example: python generate.py 100000 32 1000
+"""
 
 import sys
 import random
index 1af0de6..9986fb8 100755 (executable)
@@ -6,6 +6,10 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
+"""
+Usage: python generate.py nb_nodes nb_bits end_date > deployment_file.xml
+"""
+
 import sys
 import random
 
index efb011d..a565dc1 100755 (executable)
@@ -6,10 +6,12 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This script generates a specific deployment file for the Bittorrent example.
-# It assumes that the platform will be a cluster.
-# Usage: python generate.py nb_nodes nb_bits end_date percentage
-# Example: python generate.py 10000 5000
+"""
+This script generates a specific deployment file for the Bittorrent example.
+It assumes that the platform will be a cluster.
+Usage: python generate.py nb_nodes nb_bits end_date percentage
+Example: python generate.py 10000 5000
+"""
 
 import sys
 import random
index 4b04a06..0f4e01e 100644 (file)
@@ -3,21 +3,23 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This example shows how to declare and start your actors.
-#
-# The first step is to declare the code of your actors (what they do exactly does not matter to this example) and then
-# you ask SimGrid to start your actors. There is three ways of doing so:
-# - Directly, by instantiating your actor as parameter to Actor::create()
-# - By first registering your actors before instantiating it;
-# - Through the deployment file.
-#
-# This example shows all these solutions, even if you obviously should use only one of these solutions to start your
-# actors. The most advised solution is to use a deployment file, as it creates a clear separation between your
-# application and the settings to test it. This is a better scientific methodology. Actually, starting an actor with
-# Actor.create() is mostly useful to start an actor from another actor.
+"""
+This example shows how to declare and start your actors.
+
+The first step is to declare the code of your actors (what they do exactly does not matter to this example) and then
+you ask SimGrid to start your actors. There is three ways of doing so:
+- Directly, by instantiating your actor as parameter to Actor::create()
+- By first registering your actors before instantiating it;
+- Through the deployment file.
+
+This example shows all these solutions, even if you obviously should use only one of these solutions to start your
+actors. The most advised solution is to use a deployment file, as it creates a clear separation between your
+application and the settings to test it. This is a better scientific methodology. Actually, starting an actor with
+Actor.create() is mostly useful to start an actor from another actor.
+"""
 
-from simgrid import Actor, Engine, Host, Mailbox, this_actor
 import sys
+from simgrid import Actor, Engine, Host, Mailbox, this_actor
 
 
 def receiver(mailbox_name):
index 457aed1..a6f1b83 100644 (file)
@@ -3,8 +3,12 @@
 # This program is free software you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, this_actor
+"""
+Usage: actor-daemon.py platform_file [other parameters]
+"""
+
 import sys
+from simgrid import Actor, Engine, Host, this_actor
 
 
 def worker():
index 25dfab0..d64118d 100644 (file)
@@ -3,8 +3,12 @@
 # This program is free software you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, this_actor
+"""
+Usage: actor-join.py platform_file [other parameters]
+"""
+
 import sys
+from simgrid import Actor, Engine, Host, this_actor
 
 
 def sleeper():
index a662641..5adff31 100644 (file)
@@ -3,8 +3,12 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, this_actor
+"""
+Usage: actor-kill.py platform_file [other parameters]
+"""
+
 import sys
+from simgrid import Actor, Engine, Host, this_actor
 
 
 def victim_a_fun():
index adc4658..a8dec3f 100644 (file)
@@ -3,17 +3,19 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This Python file acts as the foil to the corresponding XML file, where the
-# action takes place: Actors are started and stopped at predefined time
+"""
+This Python file acts as the foil to the corresponding XML file, where the
+action takes place: Actors are started and stopped at predefined time
+"""
 
-from simgrid import Engine, this_actor
 import sys
+from simgrid import Engine, this_actor
 
 
 class Sleeper:
     """This actor just sleeps until termination"""
 
-    def __init__(self, *args):
+    def __init__(self):
         this_actor.on_exit(lambda: this_actor.info("Exiting now (done sleeping or got killed)."))
 
     def __call__(self):
index b78dbfc..9cac4bb 100644 (file)
@@ -3,20 +3,22 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This example demonstrate the actor migrations.
-#
-# The worker actor first move by itself, and then start an execution.
-# During that execution, the monitor migrates the worker, that wakes up on another host.
-# The execution was of the right amount of flops to take exactly 5 seconds on the first host
-# and 5 other seconds on the second one, so it stops after 10 seconds.
-#
-# Then another migration is done by the monitor while the worker is suspended.
-#
-# Note that worker() takes an uncommon set of parameters,
-# and that this is perfectly accepted by create().
+"""
+This example demonstrate the actor migrations.
+
+The worker actor first move by itself, and then start an execution.
+During that execution, the monitor migrates the worker, that wakes up on another host.
+The execution was of the right amount of flops to take exactly 5 seconds on the first host
+and 5 other seconds on the second one, so it stops after 10 seconds.
+
+Then another migration is done by the monitor while the worker is suspended.
+
+Note that worker() takes an uncommon set of parameters,
+and that this is perfectly accepted by create().
+"""
 
-from simgrid import Actor, Engine, Host, this_actor
 import sys
+from simgrid import Actor, Engine, Host, this_actor
 
 
 def worker(first_host, second_host):
index fae11b6..af021b6 100644 (file)
@@ -3,8 +3,12 @@
 # This program is free software you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, this_actor
+"""
+Usage: actor-suspend.py platform_file [other parameters]
+"""
+
 import sys
+from simgrid import Actor, Engine, this_actor
 
 
 def lazy_guy():
index d20a54b..d82b20f 100644 (file)
@@ -3,19 +3,20 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, this_actor
-import sys
+"""
+This example does not much: It just spans over-polite actor that yield a large amount
+of time before ending.
 
-# This example does not much: It just spans over-polite actor that yield a large amount
-# of time before ending.
-#
-# This serves as an example for the simgrid.yield() function, with which an actor can request
-# to be rescheduled after the other actor that are ready at the current timestamp.
-#
-# It can also be used to benchmark our context-switching mechanism.
+This serves as an example for the simgrid.yield() function, with which an actor can request
+to be rescheduled after the other actor that are ready at the current timestamp.
 
+It can also be used to benchmark our context-switching mechanism.
+"""
 
-def yielder (number_of_yields):
+import sys
+from simgrid import Actor, Engine, Host, this_actor
+
+def yielder(number_of_yields):
     for _ in range(number_of_yields):
         this_actor.yield_()
     this_actor.info("I yielded {:d} times. Goodbye now!".format(number_of_yields))
@@ -24,7 +25,7 @@ if __name__ == '__main__':
     e = Engine(sys.argv)
 
     e.load_platform(sys.argv[1])             # Load the platform description
-  
+
     Actor.create("yielder", Host.by_name("Tremblay"), yielder, 10)
     Actor.create("yielder", Host.by_name("Ruby"), yielder, 15)
 
index 6eb8b19..9ae2653 100644 (file)
@@ -1,56 +1,57 @@
-# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved.          
+# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved.
 
 # This program is free software; you can redistribute it and/or modify it
-# under the terms of the license (GNU LGPL) which comes with this package. 
+# under the terms of the license (GNU LGPL) which comes with this package.
 
+"""
 # ##################################################################################
 # Take this tutorial online: https://simgrid.org/doc/latest/Tutorial_Algorithms.html
 # ##################################################################################
+"""
 
-from simgrid import Engine, Mailbox, this_actor
 import sys
+from simgrid import Engine, Mailbox, this_actor
 
 # master-begin
 def master(*args):
-  assert len(args) > 3, f"Actor master requires 3 parameters plus the workers' names, but got {len(args)}"
-  tasks_count = int(args[0])
-  compute_cost = int(args[1])
-  communicate_cost = int(args[2])
-  workers = []
-  for i in range(3, len(args)): 
-    workers.append(Mailbox.by_name(args[i]))
-  this_actor.info(f"Got {len(workers)} workers and {tasks_count} tasks to process")
-
-  for i in range(tasks_count): # For each task to be executed: 
-      # - Select a worker in a round-robin way
-      mailbox = workers[i % len(workers)]
-
-      # - Send the computation amount to the worker
-      if (tasks_count < 10000 or (tasks_count < 100000 and i % 10000 == 0) or i % 100000 == 0):
-        this_actor.info(f"Sending task {i} of {tasks_count} to mailbox '{mailbox.name}'")
-      mailbox.put(compute_cost, communicate_cost)
-
-  this_actor.info("All tasks have been dispatched. Request all workers to stop.")
-  for i in range (len(workers)):
-      # The workers stop when receiving a negative compute_cost
-      mailbox = workers[i]
-      mailbox.put(-1, 0)
+    assert len(args) > 3, f"Actor master requires 3 parameters plus the workers' names, but got {len(args)}"
+    tasks_count = int(args[0])
+    compute_cost = int(args[1])
+    communicate_cost = int(args[2])
+    workers = []
+    for i in range(3, len(args)):
+        workers.append(Mailbox.by_name(args[i]))
+    this_actor.info(f"Got {len(workers)} workers and {tasks_count} tasks to process")
+
+    for i in range(tasks_count): # For each task to be executed:
+        # - Select a worker in a round-robin way
+        mailbox = workers[i % len(workers)]
+
+        # - Send the computation amount to the worker
+        if (tasks_count < 10000 or (tasks_count < 100000 and i % 10000 == 0) or i % 100000 == 0):
+            this_actor.info(f"Sending task {i} of {tasks_count} to mailbox '{mailbox.name}'")
+        mailbox.put(compute_cost, communicate_cost)
+
+    this_actor.info("All tasks have been dispatched. Request all workers to stop.")
+    for mailbox in workers:
+        # The workers stop when receiving a negative compute_cost
+        mailbox.put(-1, 0)
 # master-end
 
 # worker-begin
 def worker(*args):
-  assert len(args) == 0, "The worker expects to not get any argument"
-
-  mailbox = Mailbox.by_name(this_actor.get_host().name)
-  done = False
-  while not done:
-    compute_cost = mailbox.get()
-    if compute_cost > 0: # If compute_cost is valid, execute a computation of that cost 
-      this_actor.execute(compute_cost)
-    else: # Stop when receiving an invalid compute_cost
-      done = True
-
-  this_actor.info("Exiting now.")
+    assert not args, "The worker expects to not get any argument"
+
+    mailbox = Mailbox.by_name(this_actor.get_host().name)
+    done = False
+    while not done:
+        compute_cost = mailbox.get()
+        if compute_cost > 0: # If compute_cost is valid, execute a computation of that cost
+            this_actor.execute(compute_cost)
+        else: # Stop when receiving an invalid compute_cost
+            done = True
+
+    this_actor.info("Exiting now.")
 # worker-end
 
 # main-begin
@@ -64,7 +65,7 @@ if __name__ == '__main__':
     e.register_actor("worker", worker)
 
     # Load the platform description and then deploy the application
-    e.load_platform(sys.argv[1]) 
+    e.load_platform(sys.argv[1])
     e.load_deployment(sys.argv[2])
 
     # Run the simulation
index 8673890..637eab5 100644 (file)
@@ -3,15 +3,17 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This example shows how to build a torus cluster with multi-core hosts.
-#
-# However, each leaf in the torus is a StarZone, composed of several CPUs
-#
-# Each actor runs in a specific CPU. One sender broadcasts a message to all receivers.
+"""
+This example shows how to build a torus cluster with multi-core hosts.
+
+However, each leaf in the torus is a StarZone, composed of several CPUs
+
+Each actor runs in a specific CPU. One sender broadcasts a message to all receivers.
+"""
 
-import simgrid
 import sys
 import typing
+import simgrid
 
 
 class Sender:
@@ -56,8 +58,9 @@ class Receiver:
 #####################################################################################################
 
 
-def create_hostzone(zone: simgrid.NetZone, coord: typing.List[int], ident: int) -> typing.Tuple[simgrid.NetPoint, simgrid.NetPoint]:
-    """
+def create_hostzone(zone: simgrid.NetZone, coord: typing.List[int], ident: int) -> typing.Tuple[simgrid.NetPoint,
+                                                                                                simgrid.NetPoint]:
+    r"""
     Callback to set a cluster leaf/element
 
     In our example, each leaf if a StarZone, composed of 8 CPUs.
@@ -103,8 +106,8 @@ def create_hostzone(zone: simgrid.NetZone, coord: typing.List[int], ident: int)
         link = host_zone.create_split_duplex_link("link-" + cpu_name, link_bw)
         link.set_latency(link_lat).seal()
         # connecting CPU to outer world
-        host_zone.add_route(host.netpoint, None, None, None, [
-                            simgrid.LinkInRoute(link, simgrid.LinkInRoute.Direction.UP)], True)
+        host_zone.add_route(host.netpoint, None, None, None,
+                            [simgrid.LinkInRoute(link, simgrid.LinkInRoute.Direction.UP)], True)
 
     # seal newly created netzone
     host_zone.seal()
@@ -119,8 +122,8 @@ def create_limiter(zone: simgrid.NetZone, coord: typing.List[int], ident: int) -
 
     The coord parameter depends on the cluster being created:
     - Torus: Direct translation of the Torus' dimensions, e.g. (0, 0, 0) for a 3-D Torus
-    - Fat-Tree: A pair (level in the tree, ident), e.g. (0, 0) for first leaf in the tree and (1,0) for the first switch at
-    level 1.
+    - Fat-Tree: A pair (level in the tree, ident), e.g. (0, 0) for first leaf in the tree and (1,0) for the first switch
+    at level 1.
     - Dragonfly: a tuple (group, chassis, blades/routers, nodes), e.g. (0, 0, 0, 0) for first node in the cluster. To
     identify the router inside a (group, chassis, blade), we use MAX_UINT in the last parameter (e.g. 0, 0, 0,
     4294967295).
@@ -169,14 +172,15 @@ def create_torus_cluster():
     Cluster</a>
     """
     # create the torus cluster, 10Gbs link between elements in the cluster
-    simgrid.NetZone.create_torus_zone("cluster", None, [2, 2, 2], simgrid.ClusterCallbacks(create_hostzone, None, create_limiter), 10e9, 10e-6,
+    simgrid.NetZone.create_torus_zone("cluster", None, [2, 2, 2],
+                                      simgrid.ClusterCallbacks(create_hostzone, None, create_limiter), 10e9, 10e-6,
                                       simgrid.Link.SharingPolicy.SPLITDUPLEX).seal()
 
 #####################################################################################################
 
 
 def create_fat_tree_cluster():
-    """
+    r"""
     Creates a Fat-Tree cluster
 
     Creates a Fat-Tree cluster with 2 levels and 6 nodes
@@ -224,14 +228,15 @@ def create_fat_tree_cluster():
     Cluster</a>
     """
     # create the fat tree cluster, 10Gbs link between elements in the cluster
-    simgrid.NetZone.create_fatTree_zone("cluster", None, simgrid.FatTreeParams(2, [2, 3], [1, 2], [1, 1]), simgrid.ClusterCallbacks(create_hostzone, None, create_limiter), 10e9,
-                                        10e-6, simgrid.Link.SharingPolicy.SPLITDUPLEX).seal()
+    simgrid.NetZone.create_fatTree_zone("cluster", None, simgrid.FatTreeParams(2, [2, 3], [1, 2], [1, 1]),
+                                        simgrid.ClusterCallbacks(create_hostzone, None, create_limiter), 10e9, 10e-6,
+                                        simgrid.Link.SharingPolicy.SPLITDUPLEX).seal()
 
 #####################################################################################################
 
 
 def create_dragonfly_cluster():
-    """
+    r"""
     Creates a Dragonfly cluster
 
     Creates a Dragonfly cluster with 2 groups and 16 nodes
@@ -269,13 +274,14 @@ def create_dragonfly_cluster():
     Cluster</a>
     """
     # create the dragonfly cluster, 10Gbs link between elements in the cluster
-    simgrid.NetZone.create_dragonfly_zone("cluster", None, simgrid.DragonflyParams([2, 2], [2, 1], [2, 2], 2), simgrid.ClusterCallbacks(
-        create_hostzone, None, create_limiter), 10e9, 10e-6, simgrid.Link.SharingPolicy.SPLITDUPLEX).seal()
+    simgrid.NetZone.create_dragonfly_zone("cluster", None, simgrid.DragonflyParams([2, 2], [2, 1], [2, 2], 2),
+                                          simgrid.ClusterCallbacks(create_hostzone, None, create_limiter), 10e9, 10e-6,
+                                          simgrid.Link.SharingPolicy.SPLITDUPLEX).seal()
 
 ###################################################################################################
 
 
-if __name__ == '__main__':
+def main():
     e = simgrid.Engine(sys.argv)
     platform = sys.argv[1]
 
@@ -298,3 +304,6 @@ if __name__ == '__main__':
 
     # runs the simulation
     e.run()
+
+if __name__ == '__main__':
+    main()
index 8f4f728..95c1e9c 100644 (file)
@@ -4,57 +4,59 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, Mailbox, this_actor
-import sys
+"""
+This example shows how to use simgrid::s4u::this_actor::wait() to wait for a given communication.
 
-# This example shows how to use simgrid::s4u::this_actor::wait() to wait for a given communication.
-#
-# As for the other asynchronous examples, the sender initiate all the messages it wants to send and
-# pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently.
-#
-# The sender then loops until there is no ongoing communication.
+As for the other asynchronous examples, the sender initiate all the messages it wants to send and
+pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently.
+
+The sender then loops until there is no ongoing communication.
+"""
+
+import sys
+from simgrid import Actor, Engine, Host, Mailbox, this_actor
 
 
 def sender(messages_count, msg_size, receivers_count):
-     # List in which we store all ongoing communications
-     pending_comms = []
+    # List in which we store all ongoing communications
+    pending_comms = []
 
-     # Vector of the used mailboxes
-     mboxes = [Mailbox.by_name("receiver-{:d}".format(i)) for i in range(0, receivers_count)]
+    # Vector of the used mailboxes
+    mboxes = [Mailbox.by_name("receiver-{:d}".format(i)) for i in range(0, receivers_count)]
 
-     # Start dispatching all messages to receivers, in a round robin fashion
-     for i in range(0, messages_count):
-         content = "Message {:d}".format(i)
-         mbox = mboxes[i % receivers_count]
+    # Start dispatching all messages to receivers, in a round robin fashion
+    for i in range(0, messages_count):
+        content = "Message {:d}".format(i)
+        mbox = mboxes[i % receivers_count]
 
-         this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
+        this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
 
-         # Create a communication representing the ongoing communication, and store it in pending_comms
-         comm = mbox.put_async(content, msg_size)
-         pending_comms.append(comm)
+        # Create a communication representing the ongoing communication, and store it in pending_comms
+        comm = mbox.put_async(content, msg_size)
+        pending_comms.append(comm)
 
-     # Start sending messages to let the workers know that they should stop
-     for i in range(0, receivers_count):
-         mbox = mboxes[i]
-         this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
-         comm = mbox.put_async("finalize", 0)
-         pending_comms.append(comm)
+    # Start sending messages to let the workers know that they should stop
+    for i in range(0, receivers_count):
+        mbox = mboxes[i]
+        this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
+        comm = mbox.put_async("finalize", 0)
+        pending_comms.append(comm)
 
-     this_actor.info("Done dispatching all messages")
+    this_actor.info("Done dispatching all messages")
 
-     # Now that all message exchanges were initiated, wait for their completion, in order of creation.
-     for comm in pending_comms:
-         comm.wait()
-     this_actor.info("Goodbye now!")
+    # Now that all message exchanges were initiated, wait for their completion, in order of creation.
+    for comm in pending_comms:
+        comm.wait()
+    this_actor.info("Goodbye now!")
 
-def receiver(id):
-     mbox = Mailbox.by_name("receiver-{:d}".format(id))
-     this_actor.info("Wait for my first message")
-     while True:
-         received = mbox.get()
-         this_actor.info("I got a '{:s}'.".format(received))
-         if received == "finalize":
-             break  # If it's a finalize message, we're done.
+def receiver(my_id):
+    mbox = Mailbox.by_name("receiver-{:d}".format(my_id))
+    this_actor.info("Wait for my first message")
+    while True:
+        received = mbox.get()
+        this_actor.info("I got a '{:s}'.".format(received))
+        if received == "finalize":
+            break  # If it's a finalize message, we're done.
 
 
 if __name__ == '__main__':
@@ -64,5 +66,5 @@ if __name__ == '__main__':
 
     Actor.create("sender", Host.by_name("Tremblay"), sender, 3, 50000000, 1)
     Actor.create("receiver", Host.by_name("Ruby"), receiver, 0)
-  
+
     e.run()
index 38a34f1..0ffa0d2 100644 (file)
@@ -3,53 +3,55 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor,Comm, Engine, Host, Mailbox, this_actor
-import sys
+"""
+This example shows how to block on the completion of a set of communications.
 
-# This example shows how to block on the completion of a set of communications.
-#
-# As for the other asynchronous examples, the sender initiate all the messages it wants to send and
-# pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently.
-#
-# The sender then blocks until all ongoing communication terminate, using simgrid.Comm.wait_all()
+As for the other asynchronous examples, the sender initiate all the messages it wants to send and
+pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently.
+
+The sender then blocks until all ongoing communication terminate, using simgrid.Comm.wait_all()
+"""
+
+import sys
+from simgrid import Actor, Comm, Engine, Host, Mailbox, this_actor
 
 
 def sender(messages_count, msg_size, receivers_count):
-     # List in which we store all ongoing communications
-     pending_comms = []
+    # List in which we store all ongoing communications
+    pending_comms = []
 
-     # Vector of the used mailboxes
-     mboxes = [Mailbox.by_name("receiver-{:d}".format(i))
-               for i in range(0, receivers_count)]
+    # Vector of the used mailboxes
+    mboxes = [Mailbox.by_name("receiver-{:d}".format(i))
+              for i in range(0, receivers_count)]
 
-     # Start dispatching all messages to receivers, in a round robin fashion
-     for i in range(0, messages_count):
-         content = "Message {:d}".format(i)
-         mbox = mboxes[i % receivers_count]
+    # Start dispatching all messages to receivers, in a round robin fashion
+    for i in range(0, messages_count):
+        content = "Message {:d}".format(i)
+        mbox = mboxes[i % receivers_count]
 
-         this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
+        this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
 
-         # Create a communication representing the ongoing communication, and store it in pending_comms
-         comm = mbox.put_async(content, msg_size)
-         pending_comms.append(comm)
+        # Create a communication representing the ongoing communication, and store it in pending_comms
+        comm = mbox.put_async(content, msg_size)
+        pending_comms.append(comm)
 
-     # Start sending messages to let the workers know that they should stop
-     for i in range(0, receivers_count):
-         mbox = mboxes[i]
-         this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
-         comm = mbox.put_async("finalize", 0)
-         pending_comms.append(comm)
+    # Start sending messages to let the workers know that they should stop
+    for i in range(0, receivers_count):
+        mbox = mboxes[i]
+        this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
+        comm = mbox.put_async("finalize", 0)
+        pending_comms.append(comm)
 
-     this_actor.info("Done dispatching all messages")
+    this_actor.info("Done dispatching all messages")
 
-     # Now that all message exchanges were initiated, wait for their completion in one single call
-     Comm.wait_all(pending_comms)
+    # Now that all message exchanges were initiated, wait for their completion in one single call
+    Comm.wait_all(pending_comms)
 
-     this_actor.info("Goodbye now!")
+    this_actor.info("Goodbye now!")
 
 
-def receiver(id):
-    mbox = Mailbox.by_name("receiver-{:d}".format(id))
+def receiver(my_id):
+    mbox = Mailbox.by_name("receiver-{:d}".format(my_id))
 
     this_actor.info("Wait for my first message")
     while True:
index c59ccd0..d19c590 100644 (file)
@@ -3,67 +3,70 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Comm, Engine, Host, Mailbox, this_actor
-import sys
+"""
+This example shows how to block on the completion of a set of communications.
 
-# This example shows how to block on the completion of a set of communications.
-#
-# As for the other asynchronous examples, the sender initiate all the messages it wants to send and
-# pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently.
-#
-# The sender then loops until there is no ongoing communication. Using wait_any() ensures that the sender
-# will notice events as soon as they occur even if it does not follow the order of the container.
-#
-# Here, finalize messages will terminate earlier because their size is 0, so they travel faster than the
-# other messages of this application.  As expected, the trace shows that the finalize of worker 1 is
-# processed before 'Message 5' that is sent to worker 0.
+As for the other asynchronous examples, the sender initiate all the messages it wants to send and
+pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently.
+
+The sender then loops until there is no ongoing communication. Using wait_any() ensures that the sender
+will notice events as soon as they occur even if it does not follow the order of the container.
+
+Here, finalize messages will terminate earlier because their size is 0, so they travel faster than the
+other messages of this application.  As expected, the trace shows that the finalize of worker 1 is
+processed before 'Message 5' that is sent to worker 0.
+"""
+
+import sys
+from simgrid import Actor, Comm, Engine, Host, Mailbox, this_actor
 
 
 def sender(messages_count, msg_size, receivers_count):
-     # List in which we store all ongoing communications
-     pending_comms = []
-
-     # Vector of the used mailboxes
-     mboxes = [Mailbox.by_name("receiver-{:d}".format(i))
-               for i in range(0, receivers_count)]
-
-     # Start dispatching all messages to receivers, in a round robin fashion
-     for i in range(0, messages_count):
-         content = "Message {:d}".format(i)
-         mbox = mboxes[i % receivers_count]
-
-         this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
-
-         # Create a communication representing the ongoing communication, and store it in pending_comms
-         comm = mbox.put_async(content, msg_size)
-         pending_comms.append(comm)
-
-     # Start sending messages to let the workers know that they should stop
-     for i in range(0, receivers_count):
-         mbox = mboxes[i]
-         this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
-         comm = mbox.put_async("finalize", 0)
-         pending_comms.append(comm)
-
-     this_actor.info("Done dispatching all messages")
-
-     # Now that all message exchanges were initiated, wait for their completion, in order of completion.
-     #
-     # This loop waits for first terminating message with wait_any() and remove it with del, until all comms are
-     # terminated.
-     # Even in this simple example, the pending comms do not terminate in the exact same order of creation.
-     while pending_comms:
-         changed_pos = Comm.wait_any(pending_comms)
-         del pending_comms[changed_pos]
-         if (changed_pos != 0):
-             this_actor.info(
-                  "Remove the {:d}th pending comm: it terminated earlier than another comm that was initiated first.".format(changed_pos))
-
-     this_actor.info("Goodbye now!")
-
-
-def receiver(id):
-    mbox = Mailbox.by_name("receiver-{:d}".format(id))
+    # List in which we store all ongoing communications
+    pending_comms = []
+
+    # Vector of the used mailboxes
+    mboxes = [Mailbox.by_name("receiver-{:d}".format(i))
+              for i in range(0, receivers_count)]
+
+    # Start dispatching all messages to receivers, in a round robin fashion
+    for i in range(0, messages_count):
+        content = "Message {:d}".format(i)
+        mbox = mboxes[i % receivers_count]
+
+        this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
+
+        # Create a communication representing the ongoing communication, and store it in pending_comms
+        comm = mbox.put_async(content, msg_size)
+        pending_comms.append(comm)
+
+    # Start sending messages to let the workers know that they should stop
+    for i in range(0, receivers_count):
+        mbox = mboxes[i]
+        this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
+        comm = mbox.put_async("finalize", 0)
+        pending_comms.append(comm)
+
+    this_actor.info("Done dispatching all messages")
+
+    # Now that all message exchanges were initiated, wait for their completion, in order of completion.
+    #
+    # This loop waits for first terminating message with wait_any() and remove it with del, until all comms are
+    # terminated.
+    # Even in this simple example, the pending comms do not terminate in the exact same order of creation.
+    while pending_comms:
+        changed_pos = Comm.wait_any(pending_comms)
+        del pending_comms[changed_pos]
+        if changed_pos != 0:
+            this_actor.info(
+                "Remove the {:d}th pending comm: it terminated earlier than another comm that was initiated first."
+                .format(changed_pos))
+
+    this_actor.info("Goodbye now!")
+
+
+def receiver(my_id):
+    mbox = Mailbox.by_name("receiver-{:d}".format(my_id))
     this_actor.info("Wait for my first message")
     while True:
         received = mbox.get()
index 86c7b16..0758543 100644 (file)
@@ -3,12 +3,19 @@
 # This program is free software you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, this_actor
+"""
+Usage: exec-async.py platform_file [other parameters]
+"""
+
 import sys
+from simgrid import Actor, Engine, Host, this_actor
 
 
 class Waiter:
-    """ This actor simply waits for its task completion after starting it. That's exactly equivalent to synchronous execution. """
+    """
+    This actor simply waits for its task completion after starting it.
+    That's exactly equivalent to synchronous execution.
+    """
 
     def __call__(self):
         computation_amount = this_actor.get_host().speed
index 0e6e2e2..754fe71 100644 (file)
@@ -3,8 +3,8 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, this_actor
 import sys
+from simgrid import Actor, Engine, Host, this_actor
 
 
 def executor():
index e95f64a..d4d9498 100644 (file)
@@ -3,21 +3,21 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This example shows how to simulate a non-linear resource sharing for
-# CPUs.
+"""
+This example shows how to simulate a non-linear resource sharing for CPUs.
+"""
 
-
-from simgrid import Actor, Engine, NetZone, Host, this_actor
-import sys
 import functools
+import sys
+from simgrid import Actor, Engine, NetZone, Host, this_actor
 
 
 def runner():
     computation_amount = this_actor.get_host().speed
     n_task = 10
 
-    this_actor.info("Execute %d tasks of %g flops, should take %d second in a CPU without degradation. It will take the double here." % (
-        n_task, computation_amount, n_task))
+    this_actor.info("Execute %d tasks of %g flops, should take %d second in a CPU without degradation. \
+It will take the double here." % (n_task, computation_amount, n_task))
     tasks = [this_actor.exec_init(computation_amount).start()
              for _ in range(n_task)]
 
@@ -64,4 +64,4 @@ if __name__ == '__main__':
     # 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)
+    del e
index 7a7a5dd..f8d8dff 100644 (file)
@@ -3,8 +3,12 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, this_actor
+"""
+Usage: exec-dvfs.py platform_file [other parameters]
+"""
+
 import sys
+from simgrid import Actor, Engine, Host, this_actor
 
 
 class Dvfs:
@@ -26,7 +30,8 @@ class Dvfs:
         # Change power peak
         new_pstate = 2
 
-        this_actor.info("Changing power peak value to {:f} (at index {:d})".format( host.pstate_speed(new_pstate), new_pstate))
+        this_actor.info("Changing power peak value to {:f} (at index {:d})".format(host.pstate_speed(new_pstate),
+                                                                                   new_pstate))
 
         host.pstate = new_pstate
 
@@ -47,7 +52,8 @@ class Dvfs:
 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)))
+        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())
index ba1cf12..2e4f2b9 100644 (file)
@@ -3,8 +3,8 @@
 # This program is free software you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, this_actor
 import sys
+from simgrid import Actor, Engine, Host, this_actor
 
 
 class Wizard:
@@ -21,7 +21,8 @@ class Wizard:
         this_actor.info("It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).")
 
         this_actor.sleep_for(0.1)
-        this_actor.info("Loads in flops/s: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format(boivin.load, fafard.load,
+        this_actor.info("Loads in flops/s: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format(boivin.load,
+                                                                                                fafard.load,
                                                                                                 ginette.load))
         activity.wait()
         this_actor.info("Done!")
index de16c34..f6b6042 100644 (file)
@@ -3,20 +3,22 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This example shows how to simulate a non-linear resource sharing for disk
-# operations.
-#
-# It is inspired on the paper
-# "Adding Storage Simulation Capacities to the SimGridToolkit: Concepts, Models, and API"
-# Available at : https://hal.inria.fr/hal-01197128/document
-#
-# It shows how to simulate concurrent operations degrading overall performance of IO
-# operations (specifically the effects presented in Fig. 8 of the paper).
+"""
+This example shows how to simulate a non-linear resource sharing for disk
+operations.
+
+It is inspired on the paper
+"Adding Storage Simulation Capacities to the SimGridToolkit: Concepts, Models, and API"
+Available at : https://hal.inria.fr/hal-01197128/document
+
+It shows how to simulate concurrent operations degrading overall performance of IO
+operations (specifically the effects presented in Fig. 8 of the paper).
+"""
 
 
-from simgrid import Actor, Engine, NetZone, Host, Disk, this_actor
-import sys
 import functools
+import sys
+from simgrid import Actor, Engine, NetZone, Host, Disk, this_actor
 
 
 def estimate_bw(disk: Disk, n_flows: int, read: bool):
@@ -35,7 +37,7 @@ def estimate_bw(disk: Disk, n_flows: int, read: bool):
         disk.name, "read" if read else "write", n_flows, estimated_bw))
 
 
-def host():
+def host_runner():
     # Estimating bw for each disk and considering concurrent flows
     for n in range(1, 15, 2):
         for disk in Host.current().get_disks():
@@ -57,11 +59,12 @@ def ssd_dynamic_sharing(disk: Disk, op: str, capacity: float, n: int) -> float:
     # measurements for SSD disks
     speed = {
         "write": {1: 131.},
-        "read": {1: 152., 2: 161., 3: 184., 4: 197., 5: 207., 6: 215., 7: 220., 8: 224., 9: 227., 10: 231., 11: 233., 12: 235., 13: 237., 14: 238., 15: 239.}
+        "read": {1: 152., 2: 161., 3: 184., 4: 197., 5: 207., 6: 215., 7: 220., 8: 224., 9: 227., 10: 231., 11: 233.,
+                 12: 235., 13: 237., 14: 238., 15: 239.}
     }
 
     # no special bandwidth for this disk sharing N flows, just returns maximal capacity
-    if (n in speed[op]):
+    if n in speed[op]:
         capacity = speed[op][n]
 
     return capacity
@@ -112,7 +115,7 @@ if __name__ == '__main__':
     create_sata_disk(bob, "Griffon (SATA II)")
     zone.seal()
 
-    Actor.create("runner", bob, host)
+    Actor.create("runner", bob, host_runner)
 
     e.run()
     this_actor.info("Simulated time: %g" % e.clock)
@@ -121,4 +124,4 @@ if __name__ == '__main__':
     # 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)
+    del e
index e8f2de6..40cb0b7 100644 (file)
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-# This example shows how to simulate a non-linear resource sharing for
-# network links.
+"""
+This example shows how to simulate a non-linear resource sharing for network links.
+"""
 
-from simgrid import Actor, Engine, Comm, Mailbox, NetZone, Link, LinkInRoute, this_actor
-import sys
 import functools
+import sys
+from simgrid import Actor, Engine, Comm, Mailbox, NetZone, Link, LinkInRoute, this_actor
 
 class Sender:
-  """
-  Send a series of messages to mailbox "receiver"
-  """
-  def __init__(self, msg_count: int, msg_size=int(1e6)):
-    self.msg_count = msg_count
-    self.msg_size = msg_size
+    """
+    Send a series of messages to mailbox "receiver"
+    """
+    def __init__(self, msg_count: int, msg_size=int(1e6)):
+        self.msg_count = msg_count
+        self.msg_size = msg_size
 
-  # Actors that are created as object will execute their __call__ method.
-  # So, the following constitutes the main function of the Sender actor.
-  def __call__(self):
-    pending_comms = []
-    mbox = Mailbox.by_name("receiver")
+    # Actors that are created as object will execute their __call__ method.
+    # So, the following constitutes the main function of the Sender actor.
+    def __call__(self):
+        pending_comms = []
+        mbox = Mailbox.by_name("receiver")
 
-    for i in range(self.msg_count):
-      msg = "Message " + str(i)
-      size = self.msg_size * (i + 1)
-      this_actor.info("Send '%s' to '%s, msg size: %d'" % (msg, mbox.name, size))
-      comm = mbox.put_async(msg, size)
-      pending_comms.append(comm)
+        for i in range(self.msg_count):
+            msg = "Message " + str(i)
+            size = self.msg_size * (i + 1)
+            this_actor.info("Send '%s' to '%s, msg size: %d'" % (msg, mbox.name, size))
+            comm = mbox.put_async(msg, size)
+            pending_comms.append(comm)
 
-    this_actor.info("Done dispatching all messages")
+        this_actor.info("Done dispatching all messages")
 
-    # Now that all message exchanges were initiated, wait for their completion in one single call
-    Comm.wait_all(pending_comms)
+        # Now that all message exchanges were initiated, wait for their completion in one single call
+        Comm.wait_all(pending_comms)
 
-    this_actor.info("Goodbye now!")
+        this_actor.info("Goodbye now!")
 
 class Receiver:
-  """
-  Receiver actor: wait for N messages on the mailbox "receiver"
-  """
+    """
+    Receiver actor: wait for N messages on the mailbox "receiver"
+    """
 
-  def __init__(self, msg_count=10):
-    self.msg_count = msg_count
+    def __init__(self, msg_count=10):
+        self.msg_count = msg_count
 
-  def __call__(self):
-    mbox = Mailbox.by_name("receiver")
+    def __call__(self):
+        mbox = Mailbox.by_name("receiver")
 
-    pending_msgs = []
-    pending_comms = []
+        pending_msgs = []
+        pending_comms = []
 
-    this_actor.info("Wait for %d messages asynchronously" % self.msg_count)
-    for _ in range(self.msg_count):
-      comm, data = mbox.get_async()
-      pending_comms.append(comm)
-      pending_msgs.append(data)
+        this_actor.info("Wait for %d messages asynchronously" % self.msg_count)
+        for _ in range(self.msg_count):
+            comm, data = mbox.get_async()
+            pending_comms.append(comm)
+            pending_msgs.append(data)
 
-    while len(pending_comms) > 0:
-      index = Comm.wait_any(pending_comms)
-      msg = pending_msgs[index].get()
-      this_actor.info("I got '%s'." % msg)
-      del pending_comms[index]
-      del pending_msgs[index]
+        while pending_comms:
+            index = Comm.wait_any(pending_comms)
+            msg = pending_msgs[index].get()
+            this_actor.info("I got '%s'." % msg)
+            del pending_comms[index]
+            del pending_msgs[index]
 
 ####################################################################################################
 def link_nonlinear(link: Link, capacity: float, n: int) -> float:
-  """
-  Non-linear resource sharing for links
-
-  Note that the callback is called twice in this example:
-   1) link UP: with the number of active flows (from 9 to 1)
-   2) link DOWN: with 0 active flows. A crosstraffic communication is happing
-   in the down link, but it's not considered as an active flow.
-  """
-  # emulates a degradation in link according to the number of flows
-  # you probably want something more complex than that and based on real
-  # experiments
-  capacity = min(capacity, capacity * (1.0 - (n - 1) / 10.0))
-  this_actor.info("Link %s, %d active communications, new capacity %f" % (link.name, n, capacity))
-  return capacity
+    """
+    Non-linear resource sharing for links
+
+    Note that the callback is called twice in this example:
+    1) link UP: with the number of active flows (from 9 to 1)
+    2) link DOWN: with 0 active flows. A crosstraffic communication is happing
+    in the down link, but it's not considered as an active flow.
+    """
+    # emulates a degradation in link according to the number of flows
+    # you probably want something more complex than that and based on real
+    # experiments
+    capacity = min(capacity, capacity * (1.0 - (n - 1) / 10.0))
+    this_actor.info("Link %s, %d active communications, new capacity %f" % (link.name, n, capacity))
+    return capacity
 
 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.link_up.set_sharing_policy(
-      Link.SharingPolicy.NONLINEAR,
-      functools.partial(link_nonlinear, link.link_up))
-  link.link_down.set_sharing_policy(
-      Link.SharingPolicy.NONLINEAR,
-      functools.partial(link_nonlinear, link.link_down))
-  link.set_latency(10e-6).seal()
-
-  # create routes between nodes
-  zone.add_route(sender.netpoint, receiver.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))
+    """
+    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.link_up.set_sharing_policy(Link.SharingPolicy.NONLINEAR,
+                                    functools.partial(link_nonlinear, link.link_up))
+    link.link_down.set_sharing_policy(Link.SharingPolicy.NONLINEAR,
+                                      functools.partial(link_nonlinear, link.link_down))
+    link.set_latency(10e-6).seal()
+
+    # create routes between nodes
+    zone.add_route(sender.netpoint, receiver.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))
 
 ###################################################################################################
 
 if __name__ == '__main__':
-  e = Engine(sys.argv)
+    e = Engine(sys.argv)
 
-  # create platform
-  load_platform()
+    # create platform
+    load_platform()
 
-  # runs the simulation
-  e.run()
+    # runs the simulation
+    e.run()
 
-  # explicitly deleting Engine object to avoid segfault during cleanup phase.
-  # During Engine destruction, the cleanup of std::function linked to link_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)
+    # explicitly deleting Engine object to avoid segfault during cleanup phase.
+    # During Engine destruction, the cleanup of std::function linked to link_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
index d285aaf..a944466 100644 (file)
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
-from simgrid import Actor, Engine, Host, Mailbox, this_actor, NetworkFailureException, TimeoutException
-import sys
 
-# This example shows how to work with the state profile of a host or a link,
-# specifying when the resource must be turned on or off.
-#
-# To set such a profile, the first way is to use a file in the XML, while the second is to use the programmatic
-# interface, as exemplified in the main() below. Once this profile is in place, the resource will automatically
-# be turned on and off.
-#
-# The actors running on a host that is turned off are forcefully killed
-# once their on_exit callbacks are executed. They cannot avoid this fate.
-# Since we specified on_failure="RESTART" for each actors in the XML file,
-# they will be automatically restarted when the host starts again.
-#
-# Communications using failed links will .. fail.
+"""
+This example shows how to work with the state profile of a host or a link,
+specifying when the resource must be turned on or off.
+
+To set such a profile, the first way is to use a file in the XML, while the second is to use the programmatic
+interface, as exemplified in the main() below. Once this profile is in place, the resource will automatically
+be turned on and off.
+
+The actors running on a host that is turned off are forcefully killed
+once their on_exit callbacks are executed. They cannot avoid this fate.
+Since we specified on_failure="RESTART" for each actors in the XML file,
+they will be automatically restarted when the host starts again.
+
+Communications using failed links will .. fail.
+"""
+
+import sys
+from simgrid import Actor, Engine, Host, Mailbox, this_actor, NetworkFailureException, TimeoutException
 
 def master(* args):
-  assert len(args) == 4, f"Actor master requires 4 parameters, but got {len(args)} ones."
-  tasks_count   = int(args[0])
-  comp_size     = int(args[1])
-  comm_size     = int(args[2])
-  workers_count = int(args[3])
-
-  this_actor.info(f"Got {workers_count} workers and {tasks_count} tasks to process")
-
-  for i in range(tasks_count): # For each task to be executed: 
-    # - Select a worker in a round-robin way
-    mailbox = Mailbox.by_name(f"worker-{i % workers_count}")
-    try:
-      this_actor.info(f"Send a message to {mailbox.name}")
-      mailbox.put(comp_size, comm_size, 10.0)
-      this_actor.info(f"Send to {mailbox.name} completed")
-    except TimeoutException:
-      this_actor.info(f"Mmh. Got timeouted while speaking to '{mailbox.name}'. Nevermind. Let's keep going!")
-    except NetworkFailureException:
-      this_actor.info(f"Mmh. The communication with '{mailbox.name}' failed. Nevermind. Let's keep going!")
-
-  this_actor.info("All tasks have been dispatched. Let's tell everybody the computation is over.")
-  for i in range (workers_count):
-    # - Eventually tell all the workers to stop by sending a "finalize" task
-    mailbox = Mailbox.by_name(f"worker-{i % workers_count}")
-    try:
-      mailbox.put(-1.0, 0, 1.0)
-    except TimeoutException:
-      this_actor.info(f"Mmh. Got timeouted while speaking to '{mailbox.name}'. Nevermind. Let's keep going!")
-    except NetworkFailureException:
-      this_actor.info(f"Mmh. The communication with '{mailbox.name}' failed. Nevermind. Let's keep going!")
-
-  this_actor.info("Goodbye now!")
+    assert len(args) == 4, f"Actor master requires 4 parameters, but got {len(args)} ones."
+    tasks_count = int(args[0])
+    comp_size = int(args[1])
+    comm_size = int(args[2])
+    workers_count = int(args[3])
+
+    this_actor.info(f"Got {workers_count} workers and {tasks_count} tasks to process")
+
+    for i in range(tasks_count): # For each task to be executed:
+        # - Select a worker in a round-robin way
+        mailbox = Mailbox.by_name(f"worker-{i % workers_count}")
+        try:
+            this_actor.info(f"Send a message to {mailbox.name}")
+            mailbox.put(comp_size, comm_size, 10.0)
+            this_actor.info(f"Send to {mailbox.name} completed")
+        except TimeoutException:
+            this_actor.info(f"Mmh. Got timeouted while speaking to '{mailbox.name}'. Nevermind. Let's keep going!")
+        except NetworkFailureException:
+            this_actor.info(f"Mmh. The communication with '{mailbox.name}' failed. Nevermind. Let's keep going!")
+
+    this_actor.info("All tasks have been dispatched. Let's tell everybody the computation is over.")
+    for i in range(workers_count):
+        # - Eventually tell all the workers to stop by sending a "finalize" task
+        mailbox = Mailbox.by_name(f"worker-{i % workers_count}")
+        try:
+            mailbox.put(-1.0, 0, 1.0)
+        except TimeoutException:
+            this_actor.info(f"Mmh. Got timeouted while speaking to '{mailbox.name}'. Nevermind. Let's keep going!")
+        except NetworkFailureException:
+            this_actor.info(f"Mmh. The communication with '{mailbox.name}' failed. Nevermind. Let's keep going!")
+
+    this_actor.info("Goodbye now!")
 
 def worker(* args):
-  assert len(args) == 1, "Expecting one parameter"
-  my_id               = int(args[0])
-
-  mailbox = Mailbox.by_name(f"worker-{my_id}")
-  done = False
-  while not done:
-    try:
-      this_actor.info(f"Waiting a message on {mailbox.name}")
-      compute_cost = mailbox.get()
-      if compute_cost > 0: # If compute_cost is valid, execute a computation of that cost 
-        this_actor.info("Start execution...")
-        this_actor.execute(compute_cost)
-        this_actor.info("Execution complete.")
-      else: # Stop when receiving an invalid compute_cost
-        this_actor.info("I'm done. See you!")
-        done = True
-    except NetworkFailureException:
-      this_actor.info("Mmh. Something went wrong. Nevermind. Let's keep going!")
+    assert len(args) == 1, "Expecting one parameter"
+    my_id = int(args[0])
+
+    mailbox = Mailbox.by_name(f"worker-{my_id}")
+    done = False
+    while not done:
+        try:
+            this_actor.info(f"Waiting a message on {mailbox.name}")
+            compute_cost = mailbox.get()
+            if compute_cost > 0: # If compute_cost is valid, execute a computation of that cost
+                this_actor.info("Start execution...")
+                this_actor.execute(compute_cost)
+                this_actor.info("Execution complete.")
+            else: # Stop when receiving an invalid compute_cost
+                this_actor.info("I'm done. See you!")
+                done = True
+        except NetworkFailureException:
+            this_actor.info("Mmh. Something went wrong. Nevermind. Let's keep going!")
 
 def sleeper():
-  this_actor.info("Start sleeping...")
-  this_actor.sleep_for(1)
-  this_actor.info("done sleeping.")
+    this_actor.info("Start sleeping...")
+    this_actor.sleep_for(1)
+    this_actor.info("done sleeping.")
 
 if __name__ == '__main__':
-  assert len(sys.argv) > 2, f"Usage: python app-masterworkers.py platform_file deployment_file"
+    assert len(sys.argv) > 2, f"Usage: python app-masterworkers.py platform_file deployment_file"
 
-  e = Engine(sys.argv)
+    e = Engine(sys.argv)
 
-  # This is how to attach a profile to an host that is created from the XML file.
-  # This should be done before calling load_platform(), as the on_creation() event is fired when loading the platform.
-  # You can never set a new profile to a resource that already have one.
-  def on_creation(host):
-    if (host.name == "Bourrassa"):
-      host.set_state_profile("67 0\n70 1\n", 0)
-  Host.on_creation_cb(on_creation)
+    # This is how to attach a profile to an host that is created from the XML file.
+    # This should be done before calling load_platform(), as the on_creation() event is fired when loading the platform.
+    # You can never set a new profile to a resource that already have one.
+    def on_creation(host):
+        if host.name == "Bourrassa":
+            host.set_state_profile("67 0\n70 1\n", 0)
+    Host.on_creation_cb(on_creation)
 
-  e.load_platform(sys.argv[1])
+    e.load_platform(sys.argv[1])
 
-  e.register_actor("master", master)
-  e.register_actor("worker", worker)
-  e.load_deployment(sys.argv[2])
+    e.register_actor("master", master)
+    e.register_actor("worker", worker)
+    e.load_deployment(sys.argv[2])
 
-  # Add a new host programatically, and attach a state profile to it
-  lili = e.netzone_root.create_host("Lilibeth", 1e15)
-  lili.set_state_profile("4 0\n5 1\n", 10)
-  lili.seal()
+    # Add a new host programatically, and attach a state profile to it
+    lili = e.netzone_root.create_host("Lilibeth", 1e15)
+    lili.set_state_profile("4 0\n5 1\n", 10)
+    lili.seal()
 
-  # Create an actor on that new host, to monitor its own state
-  actor = Actor.create("sleeper", lili, sleeper)
-  actor.set_auto_restart(True)
+    # Create an actor on that new host, to monitor its own state
+    actor = Actor.create("sleeper", lili, sleeper)
+    actor.set_auto_restart(True)
 
-  e.run()
+    e.run()
 
-  this_actor.info(f"Simulation time {e.clock:.4f}")
+    this_actor.info(f"Simulation time {e.clock:.4f}")
index 1fb9611..82b6146 100644 (file)
@@ -3,46 +3,50 @@
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the license (GNU LGPL) which comes with this package.
 
-from simgrid import Actor, Engine, Host, Link, this_actor
-import sys
+"""
+This example demonstrates how to attach a profile to a host or a link, to specify external changes to the resource
+speed.
+The first way to do so is to use a file in the XML, while the second is to use the programmatic interface.
+"""
 
-# This example demonstrates how to attach a profile to a host or a link, to specify external changes to the resource speed.
-# The first way to do so is to use a file in the XML, while the second is to use the programmatic interface.
+import sys
+from simgrid import Actor, Engine, Host, Link, this_actor
 
 def watcher():
-  jupiter  = Host.by_name("Jupiter")
-  fafard   = Host.by_name("Fafard")
-  lilibeth = Host.by_name("Lilibeth")
-  link1    = Link.by_name("1")
-  link2    = Link.by_name("2")
-
-  (links, lat) = jupiter.route_to(fafard)
-  path = ""
-  for l in links:
-    path += ("" if len(path)==0 else ", ") + "link '" + l.name + "'"
-  this_actor.info(f"Path from Jupiter to Fafard: {path} (latency: {lat:.6f}s).")
-
-  for _ in range(10):
-    this_actor.info("Fafard: %.0fMflops, Jupiter: %4.0fMflops, Lilibeth: %3.1fMflops, Link1: (%.2fMB/s %.0fms), Link2: (%.2fMB/s %.0fms)" % (
-             fafard.speed * fafard.available_speed / 1000000,
-             jupiter.speed * jupiter.available_speed / 1000000,
-             lilibeth.speed * lilibeth.available_speed / 1000000, 
-             link1.bandwidth / 1000, link1.latency * 1000, 
-             link2.bandwidth / 1000, link2.latency * 1000))
-    this_actor.sleep_for(1)
+    jupiter = Host.by_name("Jupiter")
+    fafard = Host.by_name("Fafard")
+    lilibeth = Host.by_name("Lilibeth")
+    link1 = Link.by_name("1")
+    link2 = Link.by_name("2")
+
+    (links, lat) = jupiter.route_to(fafard)
+    path = ""
+    for l in links:
+        path += ("" if not path else ", ") + "link '" + l.name + "'"
+    this_actor.info(f"Path from Jupiter to Fafard: {path} (latency: {lat:.6f}s).")
+
+    for _ in range(10):
+        this_actor.info("Fafard: %.0fMflops, Jupiter: %4.0fMflops, Lilibeth: %3.1fMflops, \
+Link1: (%.2fMB/s %.0fms), Link2: (%.2fMB/s %.0fms)" % (fafard.speed * fafard.available_speed / 1000000,
+                                                       jupiter.speed * jupiter.available_speed / 1000000,
+                                                       lilibeth.speed * lilibeth.available_speed / 1000000,
+                                                       link1.bandwidth / 1000, link1.latency * 1000,
+                                                       link2.bandwidth / 1000, link2.latency * 1000))
+        this_actor.sleep_for(1)
 
 if __name__ == '__main__':
-  e = Engine(sys.argv)
-  # Load the platform description
-  e.load_platform(sys.argv[1])
+    e = Engine(sys.argv)
+    # Load the platform description
+    e.load_platform(sys.argv[1])
 
-  # Add a new host programmatically, and attach a simple speed profile to it (alternate between full and half speed every two seconds
-  lili = e.netzone_root.create_host("Lilibeth", 25e6)
-  lili.set_speed_profile("""0 1.0
-2 0.5""", 2)
-  lili.seal()
+    # Add a new host programmatically, and attach a simple speed profile to it (alternate between full and half speed
+    # every two seconds
+    lili = e.netzone_root.create_host("Lilibeth", 25e6)
+    lili.set_speed_profile("""0 1.0
+    2 0.5""", 2)
+    lili.seal()
 
-  # Add a watcher of the changes
-  Actor.create("watcher", Host.by_name("Fafard"), watcher)
+    # Add a watcher of the changes
+    Actor.create("watcher", Host.by_name("Fafard"), watcher)
 
-  e.run()
+    e.run()