1 # Copyright (c) 2006-2023. The SimGrid Team. All rights reserved.
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the license (GNU LGPL) which comes with this package.
7 This example demonstrates how to dynamically modify a graph of tasks.
9 Assuming we have two instances of a service placed on different hosts,
10 we want to send data alternatively to thoses instances.
12 We consider the following graph:
15 ┌────────────────────────┐
27 └────────────────────────┘
32 from argparse import ArgumentParser
34 from simgrid import Engine, Task, CommTask, ExecTask
37 parser = ArgumentParser()
42 help='path to the platform description'
44 return parser.parse_args()
47 print(f'[{Engine.clock}] {t} finished ({t.get_count()})')
49 def switch_destination(t, hosts):
50 t.destination = hosts[switch_destination.count % 2]
51 switch_destination.count += 1
52 switch_destination.count = 0
54 def switch_successor(t, execs):
55 t.remove_successor(execs[t.get_count() % 2])
56 t.add_successor(execs[t.get_count() % 2 - 1])
58 if __name__ == '__main__':
61 e.load_platform(args.platform)
64 tremblay = e.host_by_name('Tremblay')
65 jupiter = e.host_by_name('Jupiter')
66 fafard = e.host_by_name('Fafard')
69 comm0 = CommTask.init("comm0")
71 comm0.source = tremblay
72 exec1 = ExecTask.init("exec1", 1e9, jupiter)
73 exec2 = ExecTask.init("exec2", 1e9, fafard)
74 comm1 = CommTask.init("comm1", 1e7, jupiter, tremblay)
75 comm2 = CommTask.init("comm2", 1e7, fafard, tremblay)
77 # Create the initial graph by defining dependencies between tasks
78 exec1.add_successor(comm1)
79 exec2.add_successor(comm2)
81 # Add a callback when tasks end for log purpose
82 Task.on_completion_cb(callback)
84 # Add a callback before each firing of comm0
85 # It switches the destination of comm0
86 comm0.on_this_start_cb(lambda t: switch_destination(t, [jupiter, fafard]))
88 # Add a callback before comm0 send tokens to successors
89 # It switches the successor of comm0
90 comm0.on_this_completion_cb(lambda t: switch_successor(t, [exec1,exec2]))
92 # Enqueue two firings for task exec1
93 comm0.enqueue_firings(4)