https://simgrid.org/doc/latest/Installing_SimGrid.html#installing-from-the-source.
No action is required if you use pre-compiled packages.
+General:
+ - Modifications of the Profile mechanism, with some impact on users
+ - Addition of a new (S4U) method to init profiles from generic functions to improve versatility
+ - Fix initial behaviour of state_profiles
+ - Modify periodicity to behave like a period, and not like a loop delay
+
XBT:
- Drop xbt_dynar_shrink().
include src/kernel/resource/VirtualMachineImpl.hpp
include src/kernel/resource/WifiLinkImpl.cpp
include src/kernel/resource/WifiLinkImpl.hpp
-include src/kernel/resource/profile/DatedValue.cpp
-include src/kernel/resource/profile/DatedValue.hpp
include src/kernel/resource/profile/Event.hpp
include src/kernel/resource/profile/FutureEvtSet.cpp
include src/kernel/resource/profile/FutureEvtSet.hpp
> [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard'
> [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off.
> [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process
-> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (7:sleeper@Lilibeth) Start sleeping...
-> [ 0.010309] (1:master@Tremblay) Send to worker-0 completed
-> [ 0.010309] (2:worker@Tremblay) Start execution...
+> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (2:worker@Tremblay) Waiting a message on worker-0
> [ 0.000000] (3:worker@Jupiter) Waiting a message on worker-1
> [ 0.000000] (5:worker@Ginette) Waiting a message on worker-3
> [ 0.000000] (6:worker@Bourassa) Waiting a message on worker-4
+> [ 0.010309] (1:master@Tremblay) Send to worker-0 completed
+> [ 0.010309] (2:worker@Tremblay) Start execution...
> [ 0.010309] (1:master@Tremblay) Send a message to worker-1
> [ 1.000000] (0:maestro@) Restart actors on host Fafard
-> [ 1.000000] (8:worker@Fafard) Waiting a message on worker-2
> [ 1.000000] (1:master@Tremblay) Mmh. The communication with 'worker-1' failed. Nevermind. Let's keep going!
+> [ 1.000000] (7:sleeper@Lilibeth) done sleeping.
+> [ 1.000000] (8:worker@Fafard) Waiting a message on worker-2
> [ 1.000000] (1:master@Tremblay) Send a message to worker-2
-> [ 2.000000] (1:master@Tremblay) Mmh. The communication with 'worker-2' failed. Nevermind. Let's keep going!
> [ 2.000000] (0:maestro@) Restart actors on host Jupiter
+> [ 2.000000] (1:master@Tremblay) Mmh. The communication with 'worker-2' failed. Nevermind. Let's keep going!
> [ 2.000000] (1:master@Tremblay) Send a message to worker-3
> [ 2.000000] (9:worker@Jupiter) Waiting a message on worker-1
> [ 2.010309] (2:worker@Tremblay) Execution complete.
> [ 2.010309] (2:worker@Tremblay) Waiting a message on worker-0
+> [ 3.030928] (5:worker@Ginette) Start execution...
> [ 3.030928] (1:master@Tremblay) Send to worker-3 completed
> [ 3.030928] (1:master@Tremblay) Send a message to worker-4
-> [ 3.030928] (5:worker@Ginette) Start execution...
+> [ 4.061856] (6:worker@Bourassa) Start execution...
> [ 4.061856] (1:master@Tremblay) Send to worker-4 completed
> [ 4.061856] (1:master@Tremblay) Send a message to worker-0
-> [ 4.061856] (6:worker@Bourassa) Start execution...
+> [ 4.072165] (2:worker@Tremblay) Start execution...
> [ 4.072165] (1:master@Tremblay) Send to worker-0 completed
> [ 4.072165] (1:master@Tremblay) Send a message to worker-1
-> [ 4.072165] (2:worker@Tremblay) Start execution...
> [ 5.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 5.000000] (10:sleeper@Lilibeth) Start sleeping...
+> [ 5.030928] (10:sleeper@Lilibeth) Start sleeping...
> [ 5.030928] (5:worker@Ginette) Execution complete.
> [ 5.030928] (5:worker@Ginette) Waiting a message on worker-3
+> [ 5.103093] (9:worker@Jupiter) Start execution...
> [ 5.103093] (1:master@Tremblay) Send to worker-1 completed
> [ 5.103093] (1:master@Tremblay) Send a message to worker-2
-> [ 5.103093] (9:worker@Jupiter) Start execution...
-> [ 6.000000] (10:sleeper@Lilibeth) done sleeping.
+> [ 6.030928] (10:sleeper@Lilibeth) done sleeping.
> [ 6.061856] (6:worker@Bourassa) Execution complete.
> [ 6.061856] (6:worker@Bourassa) Waiting a message on worker-4
> [ 6.072165] (2:worker@Tremblay) Execution complete.
> [ 6.072165] (2:worker@Tremblay) Waiting a message on worker-0
> [ 7.103093] (9:worker@Jupiter) Execution complete.
> [ 7.103093] (9:worker@Jupiter) Waiting a message on worker-1
+> [ 15.000000] (0:maestro@) Restart actors on host Lilibeth
+> [ 15.103093] (11:sleeper@Lilibeth) Start sleeping...
> [ 15.103093] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 15.103093] (1:master@Tremblay) Send a message to worker-3
-> [ 15.103093] (1:master@Tremblay) Mmh. The communication with 'worker-3' failed. Nevermind. Let's keep going!
-> [ 15.103093] (1:master@Tremblay) Send a message to worker-4
> [ 15.103093] (5:worker@Ginette) Mmh. Something went wrong. Nevermind. Let's keep going!
> [ 15.103093] (5:worker@Ginette) Waiting a message on worker-3
+> [ 15.103093] (1:master@Tremblay) Mmh. The communication with 'worker-3' failed. Nevermind. Let's keep going!
+> [ 15.103093] (1:master@Tremblay) Send a message to worker-4
+> [ 16.103093] (11:sleeper@Lilibeth) done sleeping.
+> [ 16.134021] (6:worker@Bourassa) Start execution...
> [ 16.134021] (1:master@Tremblay) Send to worker-4 completed
> [ 16.134021] (1:master@Tremblay) Send a message to worker-0
-> [ 16.134021] (6:worker@Bourassa) Start execution...
+> [ 16.144330] (2:worker@Tremblay) Start execution...
> [ 16.144330] (1:master@Tremblay) Send to worker-0 completed
> [ 16.144330] (1:master@Tremblay) Send a message to worker-1
-> [ 16.144330] (2:worker@Tremblay) Start execution...
+> [ 17.175258] (9:worker@Jupiter) Start execution...
> [ 17.175258] (1:master@Tremblay) Send to worker-1 completed
> [ 17.175258] (1:master@Tremblay) Send a message to worker-2
-> [ 17.175258] (9:worker@Jupiter) Start execution...
> [ 18.134021] (6:worker@Bourassa) Execution complete.
> [ 18.134021] (6:worker@Bourassa) Waiting a message on worker-4
> [ 18.144330] (2:worker@Tremblay) Execution complete.
> [ 18.144330] (2:worker@Tremblay) Waiting a message on worker-0
> [ 19.175258] (9:worker@Jupiter) Execution complete.
> [ 19.175258] (9:worker@Jupiter) Waiting a message on worker-1
-> [ 20.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 20.000000] (11:sleeper@Lilibeth) Start sleeping...
-> [ 21.000000] (11:sleeper@Lilibeth) done sleeping.
+> [ 25.000000] (0:maestro@) Restart actors on host Lilibeth
+> [ 27.175258] (12:sleeper@Lilibeth) Start sleeping...
> [ 27.175258] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 27.175258] (1:master@Tremblay) Send a message to worker-3
+> [ 28.175258] (12:sleeper@Lilibeth) done sleeping.
+> [ 28.206186] (5:worker@Ginette) Start execution...
> [ 28.206186] (1:master@Tremblay) Send to worker-3 completed
> [ 28.206186] (1:master@Tremblay) Send a message to worker-4
-> [ 28.206186] (1:master@Tremblay) Mmh. The communication with 'worker-4' failed. Nevermind. Let's keep going!
-> [ 28.206186] (1:master@Tremblay) Send a message to worker-0
-> [ 28.206186] (5:worker@Ginette) Start execution...
> [ 28.206186] (6:worker@Bourassa) Mmh. Something went wrong. Nevermind. Let's keep going!
> [ 28.206186] (6:worker@Bourassa) Waiting a message on worker-4
+> [ 28.206186] (1:master@Tremblay) Mmh. The communication with 'worker-4' failed. Nevermind. Let's keep going!
+> [ 28.206186] (1:master@Tremblay) Send a message to worker-0
+> [ 28.216495] (2:worker@Tremblay) Start execution...
> [ 28.216495] (1:master@Tremblay) Send to worker-0 completed
> [ 28.216495] (1:master@Tremblay) Send a message to worker-1
-> [ 28.216495] (2:worker@Tremblay) Start execution...
+> [ 29.247423] (9:worker@Jupiter) Start execution...
> [ 29.247423] (1:master@Tremblay) Send to worker-1 completed
> [ 29.247423] (1:master@Tremblay) Send a message to worker-2
-> [ 29.247423] (9:worker@Jupiter) Start execution...
> [ 30.206186] (5:worker@Ginette) Execution complete.
> [ 30.206186] (5:worker@Ginette) Waiting a message on worker-3
> [ 30.216495] (2:worker@Tremblay) Execution complete.
> [ 31.247423] (9:worker@Jupiter) Execution complete.
> [ 31.247423] (9:worker@Jupiter) Waiting a message on worker-1
> [ 35.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 35.000000] (12:sleeper@Lilibeth) Start sleeping...
-> [ 36.000000] (12:sleeper@Lilibeth) done sleeping.
+> [ 39.247423] (13:sleeper@Lilibeth) Start sleeping...
> [ 39.247423] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 39.247423] (1:master@Tremblay) Send a message to worker-3
+> [ 40.247423] (13:sleeper@Lilibeth) done sleeping.
+> [ 40.278351] (5:worker@Ginette) Start execution...
> [ 40.278351] (1:master@Tremblay) Send to worker-3 completed
> [ 40.278351] (1:master@Tremblay) Send a message to worker-4
-> [ 40.278351] (5:worker@Ginette) Start execution...
+> [ 41.309278] (6:worker@Bourassa) Start execution...
> [ 41.309278] (1:master@Tremblay) Send to worker-4 completed
> [ 41.309278] (1:master@Tremblay) All tasks have been dispatched. Let's tell everybody the computation is over.
> [ 41.309278] (2:worker@Tremblay) I'm done. See you!
-> [ 41.309278] (6:worker@Bourassa) Start execution...
> [ 41.309278] (9:worker@Jupiter) I'm done. See you!
> [ 42.309278] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
-> [ 43.309278] (0:maestro@) Simulation time 43.3093
-> [ 43.309278] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-3'. Nevermind. Let's keep going!
-> [ 43.309278] (1:master@Tremblay) Goodbye now!
> [ 43.309278] (6:worker@Bourassa) Execution complete.
> [ 43.309278] (6:worker@Bourassa) Waiting a message on worker-4
+> [ 43.309278] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-3'. Nevermind. Let's keep going!
> [ 43.309278] (6:worker@Bourassa) I'm done. See you!
+> [ 43.309278] (1:master@Tremblay) Goodbye now!
+> [ 43.309278] (0:maestro@) Simulation time 43.3093
p Testing a simple master/worker example application handling failures. TCP crosstraffic ENABLED
> [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard'
> [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off.
> [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process
+> [ 0.000000] (7:sleeper@Lilibeth) Start sleeping...
> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (2:worker@Tremblay) Waiting a message on worker-0
> [ 0.000000] (3:worker@Jupiter) Waiting a message on worker-1
> [ 0.000000] (5:worker@Ginette) Waiting a message on worker-3
> [ 0.000000] (6:worker@Bourassa) Waiting a message on worker-4
-> [ 0.000000] (7:sleeper@Lilibeth) Start sleeping...
-> [ 0.010825] (2:worker@Tremblay) Start execution...
> [ 0.010825] (1:master@Tremblay) Send to worker-0 completed
+> [ 0.010825] (2:worker@Tremblay) Start execution...
> [ 0.010825] (1:master@Tremblay) Send a message to worker-1
> [ 1.000000] (0:maestro@) Restart actors on host Fafard
-> [ 1.000000] (8:worker@Fafard) Waiting a message on worker-2
> [ 1.000000] (1:master@Tremblay) Mmh. The communication with 'worker-1' failed. Nevermind. Let's keep going!
+> [ 1.000000] (7:sleeper@Lilibeth) done sleeping.
+> [ 1.000000] (8:worker@Fafard) Waiting a message on worker-2
> [ 1.000000] (1:master@Tremblay) Send a message to worker-2
> [ 2.000000] (0:maestro@) Restart actors on host Jupiter
-> [ 2.000000] (9:worker@Jupiter) Waiting a message on worker-1
> [ 2.000000] (1:master@Tremblay) Mmh. The communication with 'worker-2' failed. Nevermind. Let's keep going!
> [ 2.000000] (1:master@Tremblay) Send a message to worker-3
+> [ 2.000000] (9:worker@Jupiter) Waiting a message on worker-1
> [ 2.010825] (2:worker@Tremblay) Execution complete.
> [ 2.010825] (2:worker@Tremblay) Waiting a message on worker-0
> [ 3.082474] (5:worker@Ginette) Start execution...
> [ 4.175773] (1:master@Tremblay) Send to worker-0 completed
> [ 4.175773] (1:master@Tremblay) Send a message to worker-1
> [ 5.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 5.000000] (10:sleeper@Lilibeth) Start sleeping...
+> [ 5.082474] (10:sleeper@Lilibeth) Start sleeping...
> [ 5.082474] (5:worker@Ginette) Execution complete.
> [ 5.082474] (5:worker@Ginette) Waiting a message on worker-3
> [ 5.258247] (9:worker@Jupiter) Start execution...
> [ 5.258247] (1:master@Tremblay) Send to worker-1 completed
> [ 5.258247] (1:master@Tremblay) Send a message to worker-2
-> [ 6.000000] (10:sleeper@Lilibeth) done sleeping.
+> [ 6.082474] (10:sleeper@Lilibeth) done sleeping.
> [ 6.164948] (6:worker@Bourassa) Execution complete.
> [ 6.164948] (6:worker@Bourassa) Waiting a message on worker-4
> [ 6.175773] (2:worker@Tremblay) Execution complete.
> [ 6.175773] (2:worker@Tremblay) Waiting a message on worker-0
> [ 7.258247] (9:worker@Jupiter) Execution complete.
> [ 7.258247] (9:worker@Jupiter) Waiting a message on worker-1
+> [ 15.000000] (0:maestro@) Restart actors on host Lilibeth
+> [ 15.258247] (11:sleeper@Lilibeth) Start sleeping...
> [ 15.258247] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 15.258247] (1:master@Tremblay) Send a message to worker-3
> [ 15.258247] (5:worker@Ginette) Mmh. Something went wrong. Nevermind. Let's keep going!
> [ 15.258247] (5:worker@Ginette) Waiting a message on worker-3
> [ 15.258247] (1:master@Tremblay) Mmh. The communication with 'worker-3' failed. Nevermind. Let's keep going!
> [ 15.258247] (1:master@Tremblay) Send a message to worker-4
+> [ 16.258247] (11:sleeper@Lilibeth) done sleeping.
> [ 16.340722] (6:worker@Bourassa) Start execution...
> [ 16.340722] (1:master@Tremblay) Send to worker-4 completed
> [ 16.340722] (1:master@Tremblay) Send a message to worker-0
> [ 18.351546] (2:worker@Tremblay) Waiting a message on worker-0
> [ 19.434021] (9:worker@Jupiter) Execution complete.
> [ 19.434021] (9:worker@Jupiter) Waiting a message on worker-1
-> [ 20.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 20.000000] (11:sleeper@Lilibeth) Start sleeping...
-> [ 21.000000] (11:sleeper@Lilibeth) done sleeping.
+> [ 25.000000] (0:maestro@) Restart actors on host Lilibeth
+> [ 27.434021] (12:sleeper@Lilibeth) Start sleeping...
> [ 27.434021] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 27.434021] (1:master@Tremblay) Send a message to worker-3
+> [ 28.434021] (12:sleeper@Lilibeth) done sleeping.
> [ 28.516495] (5:worker@Ginette) Start execution...
> [ 28.516495] (1:master@Tremblay) Send to worker-3 completed
> [ 28.516495] (1:master@Tremblay) Send a message to worker-4
> [ 31.609794] (9:worker@Jupiter) Execution complete.
> [ 31.609794] (9:worker@Jupiter) Waiting a message on worker-1
> [ 35.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 35.000000] (12:sleeper@Lilibeth) Start sleeping...
-> [ 36.000000] (12:sleeper@Lilibeth) done sleeping.
+> [ 39.609794] (13:sleeper@Lilibeth) Start sleeping...
> [ 39.609794] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 39.609794] (1:master@Tremblay) Send a message to worker-3
+> [ 40.609794] (13:sleeper@Lilibeth) done sleeping.
> [ 40.692268] (5:worker@Ginette) Start execution...
> [ 40.692268] (1:master@Tremblay) Send to worker-3 completed
> [ 40.692268] (1:master@Tremblay) Send a message to worker-4
0 1.0
2 0.5
)",
- 2))
+ 4))
->seal();
// Add a watcher of the changes
-1 -1.0
+1 0.0
2 1.0
LOOPAFTER 8
<?xml version='1.0'?>
<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
<platform version="4.1">
- <trace id="A" periodicity="1.0">
+ <trace id="A" periodicity="21.0">
0.0 1.0
11.0 0.5
20.0 0.9
</trace>
- <trace id="A_failure" periodicity="10.0">
- 1.0 -1.0
+ <trace id="A_failure" periodicity="12.0">
+ 1.0 0.0
2.0 1.0
</trace>
- <trace id="B" periodicity="10.0">
+ <trace id="B" periodicity="30.0">
0.0 1.0
10.0 0.8
20.0 0.4
> [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard'
> [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off.
> [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process
-> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (7:sleeper@Lilibeth) Start sleeping...
-> [ 0.010309] (1:master@Tremblay) Send to worker-0 completed
-> [ 0.010309] (2:worker@Tremblay) Start execution...
+> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (2:worker@Tremblay) Waiting a message on worker-0
> [ 0.000000] (3:worker@Jupiter) Waiting a message on worker-1
> [ 0.000000] (5:worker@Ginette) Waiting a message on worker-3
> [ 0.000000] (6:worker@Bourassa) Waiting a message on worker-4
+> [ 0.010309] (1:master@Tremblay) Send to worker-0 completed
+> [ 0.010309] (2:worker@Tremblay) Start execution...
> [ 0.010309] (1:master@Tremblay) Send a message to worker-1
> [ 1.000000] (0:maestro@) Restart actors on host Fafard
-> [ 1.000000] (8:worker@Fafard) Waiting a message on worker-2
> [ 1.000000] (1:master@Tremblay) Mmh. The communication with 'worker-1' failed. Nevermind. Let's keep going!
+> [ 1.000000] (7:sleeper@Lilibeth) done sleeping.
> [ 1.000000] (1:master@Tremblay) Send a message to worker-2
-> [ 2.000000] (1:master@Tremblay) Mmh. The communication with 'worker-2' failed. Nevermind. Let's keep going!
+> [ 1.000000] (8:worker@Fafard) Waiting a message on worker-2
> [ 2.000000] (0:maestro@) Restart actors on host Jupiter
-> [ 2.000000] (1:master@Tremblay) Send a message to worker-3
+> [ 2.000000] (1:master@Tremblay) Mmh. The communication with 'worker-2' failed. Nevermind. Let's keep going!
> [ 2.000000] (9:worker@Jupiter) Waiting a message on worker-1
+> [ 2.000000] (1:master@Tremblay) Send a message to worker-3
> [ 2.010309] (2:worker@Tremblay) Execution complete.
> [ 2.010309] (2:worker@Tremblay) Waiting a message on worker-0
+> [ 3.030928] (5:worker@Ginette) Start execution...
> [ 3.030928] (1:master@Tremblay) Send to worker-3 completed
> [ 3.030928] (1:master@Tremblay) Send a message to worker-4
-> [ 3.030928] (5:worker@Ginette) Start execution...
+> [ 4.061856] (6:worker@Bourassa) Start execution...
> [ 4.061856] (1:master@Tremblay) Send to worker-4 completed
> [ 4.061856] (1:master@Tremblay) Send a message to worker-0
-> [ 4.061856] (6:worker@Bourassa) Start execution...
+> [ 4.072165] (2:worker@Tremblay) Start execution...
> [ 4.072165] (1:master@Tremblay) Send to worker-0 completed
> [ 4.072165] (1:master@Tremblay) Send a message to worker-1
-> [ 4.072165] (2:worker@Tremblay) Start execution...
> [ 5.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 5.000000] (10:sleeper@Lilibeth) Start sleeping...
+> [ 5.030928] (10:sleeper@Lilibeth) Start sleeping...
> [ 5.030928] (5:worker@Ginette) Execution complete.
> [ 5.030928] (5:worker@Ginette) Waiting a message on worker-3
+> [ 5.103093] (9:worker@Jupiter) Start execution...
> [ 5.103093] (1:master@Tremblay) Send to worker-1 completed
> [ 5.103093] (1:master@Tremblay) Send a message to worker-2
-> [ 5.103093] (9:worker@Jupiter) Start execution...
-> [ 6.000000] (10:sleeper@Lilibeth) done sleeping.
+> [ 6.030928] (10:sleeper@Lilibeth) done sleeping.
> [ 6.061856] (6:worker@Bourassa) Execution complete.
> [ 6.061856] (6:worker@Bourassa) Waiting a message on worker-4
> [ 6.072165] (2:worker@Tremblay) Execution complete.
> [ 6.072165] (2:worker@Tremblay) Waiting a message on worker-0
> [ 7.103093] (9:worker@Jupiter) Execution complete.
> [ 7.103093] (9:worker@Jupiter) Waiting a message on worker-1
+> [ 15.000000] (0:maestro@) Restart actors on host Lilibeth
+> [ 15.103093] (11:sleeper@Lilibeth) Start sleeping...
> [ 15.103093] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 15.103093] (1:master@Tremblay) Send a message to worker-3
-> [ 15.103093] (1:master@Tremblay) Mmh. The communication with 'worker-3' failed. Nevermind. Let's keep going!
-> [ 15.103093] (1:master@Tremblay) Send a message to worker-4
> [ 15.103093] (5:worker@Ginette) Mmh. Something went wrong. Nevermind. Let's keep going!
> [ 15.103093] (5:worker@Ginette) Waiting a message on worker-3
+> [ 15.103093] (1:master@Tremblay) Mmh. The communication with 'worker-3' failed. Nevermind. Let's keep going!
+> [ 15.103093] (1:master@Tremblay) Send a message to worker-4
+> [ 16.103093] (11:sleeper@Lilibeth) done sleeping.
+> [ 16.134021] (6:worker@Bourassa) Start execution...
> [ 16.134021] (1:master@Tremblay) Send to worker-4 completed
> [ 16.134021] (1:master@Tremblay) Send a message to worker-0
-> [ 16.134021] (6:worker@Bourassa) Start execution...
+> [ 16.144330] (2:worker@Tremblay) Start execution...
> [ 16.144330] (1:master@Tremblay) Send to worker-0 completed
> [ 16.144330] (1:master@Tremblay) Send a message to worker-1
-> [ 16.144330] (2:worker@Tremblay) Start execution...
+> [ 17.175258] (9:worker@Jupiter) Start execution...
> [ 17.175258] (1:master@Tremblay) Send to worker-1 completed
> [ 17.175258] (1:master@Tremblay) Send a message to worker-2
-> [ 17.175258] (9:worker@Jupiter) Start execution...
> [ 18.134021] (6:worker@Bourassa) Execution complete.
> [ 18.134021] (6:worker@Bourassa) Waiting a message on worker-4
> [ 18.144330] (2:worker@Tremblay) Execution complete.
> [ 18.144330] (2:worker@Tremblay) Waiting a message on worker-0
> [ 19.175258] (9:worker@Jupiter) Execution complete.
> [ 19.175258] (9:worker@Jupiter) Waiting a message on worker-1
-> [ 20.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 20.000000] (11:sleeper@Lilibeth) Start sleeping...
-> [ 21.000000] (11:sleeper@Lilibeth) done sleeping.
+> [ 25.000000] (0:maestro@) Restart actors on host Lilibeth
+> [ 27.175258] (12:sleeper@Lilibeth) Start sleeping...
> [ 27.175258] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 27.175258] (1:master@Tremblay) Send a message to worker-3
+> [ 28.175258] (12:sleeper@Lilibeth) done sleeping.
+> [ 28.206186] (5:worker@Ginette) Start execution...
> [ 28.206186] (1:master@Tremblay) Send to worker-3 completed
> [ 28.206186] (1:master@Tremblay) Send a message to worker-4
-> [ 28.206186] (1:master@Tremblay) Mmh. The communication with 'worker-4' failed. Nevermind. Let's keep going!
-> [ 28.206186] (1:master@Tremblay) Send a message to worker-0
-> [ 28.206186] (5:worker@Ginette) Start execution...
> [ 28.206186] (6:worker@Bourassa) Mmh. Something went wrong. Nevermind. Let's keep going!
> [ 28.206186] (6:worker@Bourassa) Waiting a message on worker-4
+> [ 28.206186] (1:master@Tremblay) Mmh. The communication with 'worker-4' failed. Nevermind. Let's keep going!
+> [ 28.206186] (1:master@Tremblay) Send a message to worker-0
+> [ 28.216495] (2:worker@Tremblay) Start execution...
> [ 28.216495] (1:master@Tremblay) Send to worker-0 completed
> [ 28.216495] (1:master@Tremblay) Send a message to worker-1
-> [ 28.216495] (2:worker@Tremblay) Start execution...
+> [ 29.247423] (9:worker@Jupiter) Start execution...
> [ 29.247423] (1:master@Tremblay) Send to worker-1 completed
> [ 29.247423] (1:master@Tremblay) Send a message to worker-2
-> [ 29.247423] (9:worker@Jupiter) Start execution...
> [ 30.206186] (5:worker@Ginette) Execution complete.
> [ 30.206186] (5:worker@Ginette) Waiting a message on worker-3
> [ 30.216495] (2:worker@Tremblay) Execution complete.
> [ 31.247423] (9:worker@Jupiter) Execution complete.
> [ 31.247423] (9:worker@Jupiter) Waiting a message on worker-1
> [ 35.000000] (0:maestro@) Restart actors on host Lilibeth
-> [ 35.000000] (12:sleeper@Lilibeth) Start sleeping...
-> [ 36.000000] (12:sleeper@Lilibeth) done sleeping.
+> [ 39.247423] (13:sleeper@Lilibeth) Start sleeping...
> [ 39.247423] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
> [ 39.247423] (1:master@Tremblay) Send a message to worker-3
+> [ 40.247423] (13:sleeper@Lilibeth) done sleeping.
+> [ 40.278351] (5:worker@Ginette) Start execution...
> [ 40.278351] (1:master@Tremblay) Send to worker-3 completed
> [ 40.278351] (1:master@Tremblay) Send a message to worker-4
-> [ 40.278351] (5:worker@Ginette) Start execution...
+> [ 41.309278] (6:worker@Bourassa) Start execution...
> [ 41.309278] (1:master@Tremblay) Send to worker-4 completed
> [ 41.309278] (1:master@Tremblay) All tasks have been dispatched. Let's tell everybody the computation is over.
> [ 41.309278] (2:worker@Tremblay) I'm done. See you!
-> [ 41.309278] (6:worker@Bourassa) Start execution...
> [ 41.309278] (9:worker@Jupiter) I'm done. See you!
> [ 42.309278] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-2'. Nevermind. Let's keep going!
-> [ 43.309278] (0:maestro@) Simulation time 43.3093
-> [ 43.309278] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-3'. Nevermind. Let's keep going!
-> [ 43.309278] (1:master@Tremblay) Goodbye now!
> [ 43.309278] (6:worker@Bourassa) Execution complete.
> [ 43.309278] (6:worker@Bourassa) Waiting a message on worker-4
-> [ 43.309278] (6:worker@Bourassa) I'm done. See you!
\ No newline at end of file
+> [ 43.309278] (1:master@Tremblay) Mmh. Got timeouted while speaking to 'worker-3'. Nevermind. Let's keep going!
+> [ 43.309278] (6:worker@Bourassa) I'm done. See you!
+> [ 43.309278] (1:master@Tremblay) Goodbye now!
+> [ 43.309278] (0:maestro@) Simulation time 43.3093
# every two seconds
lili = e.netzone_root.create_host("Lilibeth", 25e6)
lili.set_speed_profile("""0 1.0
- 2 0.5""", 2)
+ 2 0.5""", 4)
lili.seal()
# Add a watcher of the changes
#define SIMGRID_KERNEL_PROFILEBUILDER_HPP
#include <simgrid/forward.h>
+#include <functional>
namespace simgrid {
namespace kernel {
namespace profile {
+
+/** @brief Modeling of the availability profile (due to an external load) or the churn
+ *
+ * There is 4 main concepts in this module:
+ * - #simgrid::kernel::profile::DatedValue: a pair <timestamp, value> (both are of type double)
+ * - #simgrid::kernel::profile::Profile: a list of dated values
+ * - #simgrid::kernel::profile::Event: links a given trace to a given SimGrid resource.
+ * A Cpu for example has 2 kinds of events: state (ie, is it ON/OFF) and speed,
+ * while a link has 3 iterators: state, bandwidth and latency.
+ * - #simgrid::kernel::profile::FutureEvtSet: makes it easy to find the next occurring event of all profiles
+ */
+class XBT_PUBLIC DatedValue {
+public:
+ double date_ = 0;
+ double value_ = 0;
+ explicit DatedValue() = default;
+ explicit DatedValue(double d, double v) : date_(d), value_(v) {}
+ bool operator==(DatedValue const& e2) const;
+ bool operator!=(DatedValue const& e2) const { return not(*this == e2); }
+};
+
+std::ostream& operator << (std::ostream& out, const DatedValue& dv);
/**
* @brief Simple builder for Profile classes.
*
*/
class XBT_PUBLIC ProfileBuilder {
public:
+
+ /** @brief A function called to populate the set of timed-values of a profile.
+ *
+ * When the profile is repeating, the callback is called only once upon Profile construction.
+ * Then the timed values are repeated after a fixed repeat_delay.
+ *
+ * When the profile is not repeating, the callback is called each time the profile data has been exhausted.
+ * More precisely, each time an FutureEvtSet reached the end of the vector of timed values of the profile.
+ *
+ * Note that the callback is only supposed to append values to the values vector, not modify or remove existing ones,
+ * because other FutureEvtSet may still need previous values.
+ *
+ * @param values The vector of the profile values, where new data can be appended.
+ *
+ */
+ using UpdateCb = void(std::vector<DatedValue>& values);
+
static Profile* from_file(const std::string& path);
static Profile* from_string(const std::string& name, const std::string& input, double periodicity);
+
+ static Profile* from_void();
+
+ /** Create a profile from a callback
+ *
+ * @param name: The *unique* name of the profile
+ * @param cb: A callback object/function to populate the profile
+ * @param repeat_delay: Ignored if strictly negative. Otherwise, profile is repeating and repeat_delay is inserted between two iterations.
+ *
+ * @return the newly created profile
+ */
+ static Profile* from_callback(const std::string& name, const std::function<UpdateCb>& cb, double repeat_delay);
+
};
} // namespace profile
} // namespace kernel
} // namespace simgrid
-#endif /* SIMGRID_KERNEL_PROFILEBUILDER_HPP */
\ No newline at end of file
+#endif /* SIMGRID_KERNEL_PROFILEBUILDER_HPP */
+++ /dev/null
-/* Copyright (c) 2004-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. */
-
-#include "src/kernel/resource/profile/DatedValue.hpp"
-#include <cmath>
-
-namespace simgrid {
-namespace kernel {
-namespace profile {
-
-bool DatedValue::operator==(DatedValue const& e2) const
-{
- return (fabs(date_ - e2.date_) < 0.0001) && (fabs(value_ - e2.value_) < 0.0001);
-}
-
-} // namespace profile
-} // namespace kernel
-} // namespace simgrid
+++ /dev/null
-/* Copyright (c) 2004-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. */
-
-#ifndef SIMGRID_KERNEL_PROFILE_DATEDVALUE
-#define SIMGRID_KERNEL_PROFILE_DATEDVALUE
-
-#include "simgrid/forward.h"
-#include <iostream>
-
-namespace simgrid {
-namespace kernel {
-namespace profile {
-
-/** @brief Modeling of the availability profile (due to an external load) or the churn
- *
- * There is 4 main concepts in this module:
- * - #simgrid::kernel::profile::DatedValue: a pair <timestamp, value> (both are of type double)
- * - #simgrid::kernel::profile::Profile: a list of dated values
- * - #simgrid::kernel::profile::Event: links a given trace to a given SimGrid resource.
- * A Cpu for example has 2 kinds of events: state (ie, is it ON/OFF) and speed,
- * while a link has 3 iterators: state, bandwidth and latency.
- * - #simgrid::kernel::profile::FutureEvtSet: makes it easy to find the next occurring event of all profiles
- */
-class XBT_PUBLIC DatedValue {
-public:
- double date_ = 0;
- double value_ = 0;
- explicit DatedValue() = default;
- explicit DatedValue(double d, double v) : date_(d), value_(v) {}
- bool operator==(DatedValue const& e2) const;
- bool operator!=(DatedValue const& e2) const { return not(*this == e2); }
-};
-
-} // namespace profile
-} // namespace kernel
-} // namespace simgrid
-
-#endif
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/kernel/resource/profile/Profile.hpp"
-#include "simgrid/forward.h"
-#include "src/kernel/resource/profile/DatedValue.hpp"
+#include "xbt/asserts.h"
#include "src/kernel/resource/profile/Event.hpp"
#include "src/kernel/resource/profile/FutureEvtSet.hpp"
#include "src/kernel/resource/profile/StochasticDatedValue.hpp"
#include <ostream>
#include <sstream>
#include <unordered_map>
+#include <utility>
#include <vector>
+#include <string>
static std::unordered_map<std::string, simgrid::kernel::profile::Profile*> trace_list;
namespace kernel {
namespace profile {
-Profile::Profile()
-{
- /* Add the first fake event storing the time at which the trace begins */
- event_list.emplace_back(0, -1);
- stochastic_event_list.emplace_back(0, -1);
-}
-Profile::~Profile() = default;
-
/** @brief Register this profile for that resource onto that FES,
* and get an iterator over the integrated trace */
Event* Profile::schedule(FutureEvtSet* fes, resource::Resource* resource)
event->resource = resource;
event->free_me = false;
- xbt_assert((event->idx < event_list.size()), "Your profile should have at least one event!");
-
fes_ = fes;
- fes_->add_event(0.0 /* start time */, event);
- if (stochastic) {
- xbt_assert(event->idx < stochastic_event_list.size(), "Your profile should have at least one stochastic event!");
- futureDV = stochastic_event_list.at(event->idx).get_datedvalue();
- }
+ if(event_list.empty())
+ cb(event_list);
+
+ if(event_list.empty()) {
+ event->free_me = false;
+ } else {
+ //FIXME: This is a bug, but keep old behaviour for now
+ //fes_->add_event(0, event);
+ fes_->add_event(event_list[0].date_, event);
+ }
return event;
}
{
double event_date = fes_->next_date();
- if (not stochastic) {
- DatedValue dateVal = event_list.at(event->idx);
+ DatedValue dateVal = event_list.at(event->idx);
- if (event->idx < event_list.size() - 1) {
- fes_->add_event(event_date + dateVal.date_, event);
- event->idx++;
- } else if (dateVal.date_ > 0) { /* Last element. Shall we loop? */
- fes_->add_event(event_date + dateVal.date_, event);
- event->idx = 1; /* idx=0 is a placeholder to store when events really start */
- } else { /* If we don't loop, we don't need this event anymore */
- event->free_me = true;
- }
- return dateVal;
- } else {
- DatedValue dateVal = futureDV;
- if (event->idx < stochastic_event_list.size() - 1) {
- event->idx++;
- } else if (stochasticloop) { /* We have reached the last element and we have to loop. */
- event->idx = 1;
- } else {
- event->free_me = true; /* We have reached the last element, but we don't need to loop. */
- }
+ event->idx++;
- if (not event->free_me) { // In the case there is an element, we draw the next event
- futureDV = stochastic_event_list.at(event->idx).get_datedvalue();
- fes_->add_event(event_date + futureDV.date_, event);
- }
- return dateVal;
+ if (event->idx == event_list.size())
+ cb(event_list);
+ if(event->idx>=event_list.size())
+ event->free_me = true;
+ else {
+ DatedValue& nextDateVal=event_list.at(event->idx);
+ xbt_assert(nextDateVal.date_>=0);
+ xbt_assert(nextDateVal.value_>=0);
+ fes_->add_event(event_date +nextDateVal.date_, event);
}
+ return dateVal;
}
-static bool is_comment_or_empty_line(const std::string& val)
-{
- return (val[0] == '#' || val[0] == '\0' || val[0] == '%');
-}
-
-static bool is_normal_distribution(const std::string& val)
-{
- return (val == "NORM" || val == "NORMAL" || val == "GAUSS" || val == "GAUSSIAN");
-}
-
-static bool is_exponential_distribution(const std::string& val)
-{
- return (val == "EXP" || val == "EXPONENTIAL");
-}
-
-static bool is_uniform_distribution(const std::string& val)
-{
- return (val == "UNIF" || val == "UNIFORM");
-}
-
-Profile* Profile::from_string(const std::string& name, const std::string& input, double periodicity)
-{
- int linecount = 0;
- auto* profile = new simgrid::kernel::profile::Profile();
- simgrid::kernel::profile::DatedValue* last_event = &(profile->event_list.back());
-
+Profile::Profile(const std::string& name, const std::function<ProfileBuilder::UpdateCb>& cb, double repeat_delay): name(name),cb(std::move(cb)),repeat_delay(repeat_delay) {
xbt_assert(trace_list.find(name) == trace_list.end(), "Refusing to define trace %s twice", name.c_str());
-
- std::vector<std::string> list;
- boost::split(list, input, boost::is_any_of("\n\r"));
- for (auto val : list) {
- simgrid::kernel::profile::DatedValue event;
- simgrid::kernel::profile::StochasticDatedValue stochevent;
- linecount++;
- boost::trim(val);
- if (is_comment_or_empty_line(val))
- continue;
- if (sscanf(val.c_str(), "PERIODICITY %lg\n", &periodicity) == 1)
- continue;
- if (sscanf(val.c_str(), "LOOPAFTER %lg\n", &periodicity) == 1)
- continue;
- if (val == "STOCHASTIC LOOP") {
- profile->stochastic = true;
- profile->stochasticloop = true;
- continue;
- }
- if (val == "STOCHASTIC") {
- profile->stochastic = true;
- continue;
- }
-
- if (profile->stochastic) {
- unsigned int i;
- unsigned int j;
- std::istringstream iss(val);
- std::vector<std::string> splittedval((std::istream_iterator<std::string>(iss)),
- std::istream_iterator<std::string>());
-
- xbt_assert(not splittedval.empty(), "Invalid profile line");
-
- if (splittedval[0] == "DET") {
- stochevent.date_law = Distribution::DET;
- i = 2;
- } else if (is_normal_distribution(splittedval[0])) {
- stochevent.date_law = Distribution::NORM;
- i = 3;
- } else if (is_exponential_distribution(splittedval[0])) {
- stochevent.date_law = Distribution::EXP;
- i = 2;
- } else if (is_uniform_distribution(splittedval[0])) {
- stochevent.date_law = Distribution::UNIF;
- i = 3;
- } else {
- xbt_die("Unknown law %s", splittedval[0].c_str());
- }
-
- xbt_assert(splittedval.size() > i, "Invalid profile line");
- if (i == 2) {
- stochevent.date_params = {std::stod(splittedval[1])};
- } else if (i == 3) {
- stochevent.date_params = {std::stod(splittedval[1]), std::stod(splittedval[2])};
- }
-
- if (splittedval[i] == "DET") {
- stochevent.value_law = Distribution::DET;
- j = 1;
- } else if (is_normal_distribution(splittedval[i])) {
- stochevent.value_law = Distribution::NORM;
- j = 2;
- } else if (is_exponential_distribution(splittedval[i])) {
- stochevent.value_law = Distribution::EXP;
- j = 1;
- } else if (is_uniform_distribution(splittedval[i])) {
- stochevent.value_law = Distribution::UNIF;
- j = 2;
- } else {
- xbt_die("Unknown law %s", splittedval[i].c_str());
- }
-
- xbt_assert(splittedval.size() > i + j, "Invalid profile line");
- if (j == 1) {
- stochevent.value_params = {std::stod(splittedval[i + 1])};
- } else if (j == 2) {
- stochevent.value_params = {std::stod(splittedval[i + 1]), std::stod(splittedval[i + 2])};
- }
-
- profile->stochastic_event_list.emplace_back(stochevent);
- } else {
- xbt_assert(sscanf(val.c_str(), "%lg %lg\n", &event.date_, &event.value_) == 2,
- "%s:%d: Syntax error in trace\n%s", name.c_str(), linecount, input.c_str());
-
- xbt_assert(last_event->date_ <= event.date_,
- "%s:%d: Invalid trace: Events must be sorted, but time %g > time %g.\n%s", name.c_str(), linecount,
- last_event->date_, event.date_, input.c_str());
- last_event->date_ = event.date_ - last_event->date_;
-
- profile->event_list.emplace_back(event);
- last_event = &(profile->event_list.back());
- }
- }
- if (last_event) {
- if (periodicity > 0) {
- last_event->date_ = periodicity + profile->event_list.at(0).date_;
- } else {
- last_event->date_ = -1;
- }
- }
-
- trace_list.insert({name, profile});
-
- return profile;
-}
-Profile* Profile::from_file(const std::string& path)
-{
- xbt_assert(not path.empty(), "Cannot parse a trace from an empty filename");
- xbt_assert(trace_list.find(path) == trace_list.end(), "Refusing to define trace %s twice", path.c_str());
-
- auto f = std::unique_ptr<std::ifstream>(surf_ifsopen(path));
- xbt_assert(not f->fail(), "Cannot open file '%s' (path=%s)", path.c_str(), (boost::join(surf_path, ":")).c_str());
-
- std::stringstream buffer;
- buffer << f->rdbuf();
-
- return Profile::from_string(path, buffer.str(), -1);
+ trace_list.insert({name,this});
+ cb(event_list);
}
} // namespace profile
#define SIMGRID_KERNEL_PROFILE_HPP
#include "simgrid/forward.h"
-#include "src/kernel/resource/profile/DatedValue.hpp"
+#include "simgrid/kernel/ProfileBuilder.hpp"
#include "src/kernel/resource/profile/FutureEvtSet.hpp"
#include "src/kernel/resource/profile/StochasticDatedValue.hpp"
#include <queue>
#include <vector>
+#include <string>
namespace simgrid {
namespace kernel {
* It is useful to model dynamic platforms, where an external load that makes the resource availability change over
* time. To model that, you have to set several profiles per resource: one for the on/off state and one for each
* numerical value (computational speed, bandwidth and/or latency).
+ *
+ * There are two behaviours. Either a callback is used to populate the profile when the set has been exhausted,
+ * or the callback is called only during construction and the initial set is repeated over and over, after a fixed repeating delay.
*/
class XBT_PUBLIC Profile {
public:
- /** Creates an empty trace */
- explicit Profile();
- virtual ~Profile();
+
+ /** @brief Create a profile. There are two behaviours. Either the callback is
+ *
+ * @param name The name of the profile (checked for uniqueness)
+ * @param cb A callback object/function that populates the profile.
+ * @param repeat_delay If strictly negative, it is ignored and the callback is called when an event reached the end of the event_list.
+ * If zero or positive, the initial set repeats after the provided delay.
+ */
+ explicit Profile(const std::string& name, const std::function<ProfileBuilder::UpdateCb>& cb, double repeat_delay);
+ virtual ~Profile()=default;
Event* schedule(FutureEvtSet* fes, resource::Resource* resource);
DatedValue next(Event* event);
const std::vector<DatedValue>& get_event_list() const { return event_list; }
- const std::vector<StochasticDatedValue>& get_stochastic_event_list() const { return stochastic_event_list; }
-
- static Profile* from_file(const std::string& path);
- static Profile* from_string(const std::string& name, const std::string& input, double periodicity);
-
+ const std::string get_name() const { return name; }
+ bool is_repeating() const { return repeat_delay>=0;}
+ double get_repeat_delay() const { return repeat_delay;}
+
private:
+ std::string name;
+ std::function<ProfileBuilder::UpdateCb> cb;
std::vector<DatedValue> event_list;
- std::vector<StochasticDatedValue> stochastic_event_list;
-
FutureEvtSet* fes_ = nullptr;
- bool stochastic = false;
- bool stochasticloop = false;
- DatedValue futureDV;
+ double repeat_delay;
};
} // namespace profile
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/kernel/ProfileBuilder.hpp"
+#include "simgrid/forward.h"
#include "src/kernel/resource/profile/Profile.hpp"
+#include "src/kernel/resource/profile/StochasticDatedValue.hpp"
+#include "src/surf/surf_interface.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/intrusive/options.hpp>
+#include <cstddef>
+#include <fstream>
+#include <sstream>
+
namespace simgrid {
namespace kernel {
namespace profile {
+bool DatedValue::operator==(DatedValue const& e2) const
+{
+ return (fabs(date_ - e2.date_) < 0.0001) && (fabs(value_ - e2.value_) < 0.0001);
+}
+
+std::ostream& operator << (std::ostream& out, const DatedValue& dv) {
+ out<<"(+"<<dv.date_<<','<<dv.value_<<')';
+ return out;
+}
+
+/** @brief This callback implements the support for legacy profile syntax
+*
+* These profiles support two orthogonal concepts:
+* - One-shot/Loop: the given list of {date,value} pairs can be repeated forever or just once.
+* - Deterministic/Stochastic: dates and/or values can be drawn according to a stochastic law.
+*
+* A legacy profile is composed of "global" instructions and "local" instructions.
+*
+* Global instructions set properties that are true for all {date,value} pairs. They include
+* - STOCHASTIC -> declare that the profile will use stochastic {date,value} pairs and not loop.
+* - STOCHASTIC_LOOP -> declare that the profile will use stochastic {date,value} pairs and loop.
+* - PERIODICITY -> declare the period for each iteration of the profile pattern.
+* - LOOP_AFTER -> declare that the profile pattern will start over after a fixed delay
+*
+* Note that PERIODICITY and LOOP_AFTER have slightly different meanings.
+* PERIODICITY represents the delay between two iterations, for instance the time for the first pair of the pattern in two successive iterations.
+* Hence, PERIODICITY only has meaning for completely deterministic profiles.
+* LOOP_AFTER represents an additional delay between the last pair of a profile pattern iteration and the first pair of the next iteration.
+*
+* Local instructions define one {date,value} pair, or more exactly one pattern.
+* In effect, when a profile loops or has stochastic components, the actual {date,value} pairs will be generated dynamically.
+* Roughly, a local instruction is a line with the following syntax:
+* <date spec> <value spec>
+*
+* Both date and value specifications may have one of the following formats:
+* - <num> : in completely deterministic profiles, use this number
+* - DET <num> : in stochastic profiles, use this number
+* - NORM <mean> <standard deviation> : draw number from a normal distribution of given parameters
+* - UNIF <min> <max> : draw number from an uniform distribution of given parameters
+* - EXP <lambda> : draw number from an exponential distribution of given parameters
+*
+* Note that in stochastic profiles, the date component is (necessarily) representing the delay between two pairs;
+* whereas in deterministic profiles, the date components represent the absolute date at which the elements are used in the first iteration.
+*/
+
+class LegacyUpdateCb {
+
+std::vector<StochasticDatedValue> pattern;
+
+bool stochastic;
+
+bool loop;
+
+double loop_delay;
+
+static bool is_comment_or_empty_line(const std::string& val)
+{
+ return (val[0] == '#' || val[0] == '\0' || val[0] == '%');
+}
+
+static bool is_normal_distribution(const std::string& val)
+{
+ return (val == "NORM" || val == "NORMAL" || val == "GAUSS" || val == "GAUSSIAN");
+}
+
+static bool is_exponential_distribution(const std::string& val)
+{
+ return (val == "EXP" || val == "EXPONENTIAL");
+}
+
+static bool is_uniform_distribution(const std::string& val)
+{
+ return (val == "UNIF" || val == "UNIFORM");
+}
+
+public:
+ LegacyUpdateCb(const std::string& input, double periodicity): stochastic(false),loop(periodicity>0),loop_delay(0)
+ {
+ int linecount = 0;
+ std::vector<std::string> list;
+ double last_date=0;
+ boost::split(list, input, boost::is_any_of("\n\r"));
+ for (auto val : list) {
+ simgrid::kernel::profile::DatedValue event;
+ simgrid::kernel::profile::StochasticDatedValue stochevent;
+ linecount++;
+ boost::trim(val);
+ if (is_comment_or_empty_line(val))
+ continue;
+ if (sscanf(val.c_str(), "PERIODICITY %lg\n", &periodicity) == 1) {
+ loop=true;
+ continue;
+ }
+ if (sscanf(val.c_str(), "LOOPAFTER %lg\n", &loop_delay) == 1) {
+ loop=true;
+ continue;
+ }
+ if (val == "STOCHASTIC LOOP") {
+ stochastic=true;
+ loop=true;
+ continue;
+ }
+ if (val == "STOCHASTIC") {
+ stochastic=true;
+ continue;
+ }
+
+ unsigned int i;
+ unsigned int j;
+ std::istringstream iss(val);
+ std::vector<std::string> splittedval((std::istream_iterator<std::string>(iss)),
+ std::istream_iterator<std::string>());
+
+ xbt_assert(not splittedval.empty(), "Invalid profile line");
+
+ if (splittedval[0] == "DET") {
+ stochevent.date_law = Distribution::DET;
+ i = 2;
+ } else if (is_normal_distribution(splittedval[0])) {
+ stochevent.date_law = Distribution::NORM;
+ i = 3;
+ } else if (is_exponential_distribution(splittedval[0])) {
+ stochevent.date_law = Distribution::EXP;
+ i = 2;
+ } else if (is_uniform_distribution(splittedval[0])) {
+ stochevent.date_law = Distribution::UNIF;
+ i = 3;
+ } else {
+ xbt_assert(not stochastic);
+ stochevent.date_law = Distribution::DET;
+ i = 1;
+ }
+
+ xbt_assert(splittedval.size() > i, "Invalid profile line");
+ if (i == 1 or i == 2) {
+ stochevent.date_params = {std::stod(splittedval[i-1])};
+ } else if (i == 3) {
+ stochevent.date_params = {std::stod(splittedval[1]), std::stod(splittedval[2])};
+ }
+
+ if (splittedval[i] == "DET") {
+ stochevent.value_law = Distribution::DET;
+ j = 1;
+ } else if (is_normal_distribution(splittedval[i])) {
+ stochevent.value_law = Distribution::NORM;
+ j = 2;
+ } else if (is_exponential_distribution(splittedval[i])) {
+ stochevent.value_law = Distribution::EXP;
+ j = 1;
+ } else if (is_uniform_distribution(splittedval[i])) {
+ stochevent.value_law = Distribution::UNIF;
+ j = 2;
+ } else {
+ xbt_assert(not stochastic);
+ stochevent.value_law = Distribution::DET;
+ j = 0;
+ }
+
+ xbt_assert(splittedval.size() > i + j, "Invalid profile line");
+ if (j == 0 or j == 1) {
+ stochevent.value_params = {std::stod(splittedval[i + j])};
+ } else if (j == 2) {
+ stochevent.value_params = {std::stod(splittedval[i + 1]), std::stod(splittedval[i + 2])};
+ }
+
+ if(not stochastic) {
+ //In this mode, dates read from the string are absolute values
+ double new_date=stochevent.date_params[0];
+ xbt_assert(new_date>=0,"Profile time value is negative, why?");
+ xbt_assert( last_date <= new_date ,
+ "%d: Invalid trace: Events must be sorted, but time %g > time %g.\n%s", linecount,
+ last_date, new_date, input.c_str());
+ stochevent.date_params[0]-=last_date;
+ last_date=new_date;
+ }
+
+ pattern.emplace_back(stochevent);
+ }
+
+ xbt_assert(not stochastic or periodicity <= 0, "If you want periodicity with stochastic profiles, use LOOP_AFTER");
+ if(periodicity>0) {
+ xbt_assert(loop and loop_delay==0);
+ loop_delay=periodicity - last_date;
+ }
+
+ xbt_assert(loop_delay>=0,"Profile loop conditions are not realizable!");
+
+ }
+
+ double get_repeat_delay() {
+ if(not stochastic and loop)
+ return loop_delay;
+ return -1.0;
+ }
+
+ void operator() (std::vector<DatedValue>& event_list) {
+ size_t initial_size=event_list.size();
+ if( loop or not initial_size ){
+ for(auto dv : pattern)
+ event_list.emplace_back(dv.get_datedvalue());
+ if(initial_size)
+ event_list.at(initial_size).date_+=loop_delay;
+ }
+ }
+
+
+};
+
+
Profile* ProfileBuilder::from_string(const std::string& name, const std::string& input, double periodicity)
{
- return Profile::from_string(name, input, periodicity);
+ LegacyUpdateCb cb(input, periodicity);
+ return new Profile(name,cb,cb.get_repeat_delay());
}
Profile* ProfileBuilder::from_file(const std::string& path)
{
- return Profile::from_file(path);
+ xbt_assert(not path.empty(), "Cannot parse a trace from an empty filename");
+ auto f = std::unique_ptr<std::ifstream>(surf_ifsopen(path));
+ xbt_assert(not f->fail(), "Cannot open file '%s' (path=%s)", path.c_str(), (boost::join(surf_path, ":")).c_str());
+
+ std::stringstream buffer;
+ buffer << f->rdbuf();
+
+ LegacyUpdateCb cb(buffer.str(), -1);
+ return new Profile(path,cb,cb.get_repeat_delay());
}
+
+Profile* ProfileBuilder::from_void() {
+ static Profile void_profile("__void__",[](std::vector<DatedValue>&){},-1.0);
+ return &void_profile;
+}
+
+Profile* ProfileBuilder::from_callback(const std::string& name, const std::function<UpdateCb>& cb, double repeat_delay) {
+ return new Profile(name, cb, repeat_delay);
+}
+
+
} // namespace profile
} // namespace kernel
} // namespace simgrid
\ No newline at end of file
#include "catch.hpp"
#include "src/kernel/resource/Resource.hpp"
-#include "src/kernel/resource/profile/DatedValue.hpp"
#include "src/kernel/resource/profile/Event.hpp"
-#include "src/kernel/resource/profile/Profile.hpp"
+#include "simgrid/kernel/ProfileBuilder.hpp"
#include "src/kernel/resource/profile/StochasticDatedValue.hpp"
#include "src/surf/surf_interface.hpp"
static std::vector<simgrid::kernel::profile::DatedValue> trace2vector(const char* str)
{
std::vector<simgrid::kernel::profile::DatedValue> res;
- simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
+ simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::ProfileBuilder::from_string("TheName", str, 0);
XBT_VERB("---------------------------------------------------------");
XBT_VERB("data>>\n%s<<data\n", str);
for (auto const& evt : trace->get_event_list())
return res;
}
-static std::vector<simgrid::kernel::profile::StochasticDatedValue> trace2selist(const char* str)
-{
- const simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
- std::vector<simgrid::kernel::profile::StochasticDatedValue> stocevlist = trace->get_stochastic_event_list();
- tmgr_finalize();
- return stocevlist;
-}
-
TEST_CASE("kernel::profile: Resource profiles, defining the external load", "kernel::profile")
{
SECTION("No event, no loop")
REQUIRE(want == got);
}
-
+/*
SECTION("One stochastic event (parsing)")
{
using simgrid::kernel::profile::Distribution;
REQUIRE(want == got);
}
-
+*/
SECTION("Two stochastic events (drawing each distribution)")
{
simgrid::xbt::random::set_implem_xbt();
#define SIMGRID_KERNEL_PROFILE_STOCHASTICDATEDVALUE
#include "simgrid/forward.h"
-#include "src/kernel/resource/profile/DatedValue.hpp"
+#include "simgrid/kernel/ProfileBuilder.hpp"
#include <vector>
namespace simgrid {
#include "cpu_ti.hpp"
#include "simgrid/kernel/routing/NetZoneImpl.hpp"
#include "simgrid/s4u/Engine.hpp"
+#include "xbt/asserts.h"
#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/resource/profile/Event.hpp"
#include "src/kernel/resource/profile/Profile.hpp"
{
double integral = 0;
double time = 0;
- unsigned long nb_points = profile->get_event_list().size() + 1;
+ double prev_value = 1;
+ const std::vector<profile::DatedValue>& events=profile->get_event_list();
+ xbt_assert(not events.empty());
+ unsigned long nb_points = events.size() + 1;
time_points_.reserve(nb_points);
integral_.reserve(nb_points);
- for (auto const& val : profile->get_event_list()) {
+ for (auto const& val : events) {
+ time += val.date_;
+ integral += val.date_ * prev_value;
time_points_.push_back(time);
integral_.push_back(integral);
- time += val.date_;
- integral += val.date_ * val.value_;
+ prev_value = val.value_;
}
+
+ double delay=profile->get_repeat_delay()+ events.at(0).date_;
+
+ xbt_assert( events.back().value_==prev_value,"Profiles need to end as they start");
+ time += delay;
+ integral += delay*prev_value;
+
time_points_.push_back(time);
integral_.push_back(integral);
}
return;
}
+ xbt_assert(speed_profile->is_repeating());
+
/* only one point available, fixed trace */
if (speed_profile->get_event_list().size() == 1) {
value_ = speed_profile->get_event_list().front().value_;
/* count the total time of trace file */
for (auto const& val : speed_profile->get_event_list())
total_time += val.date_;
+ total_time += speed_profile->get_repeat_delay();
profile_ = std::make_unique<CpuTiProfile>(speed_profile);
last_time_ = total_time;
if (profile && profile->get_event_list().size() > 1) {
kernel::profile::DatedValue val = profile->get_event_list().back();
if (val.date_ < 1e-12) {
- auto* prof = new kernel::profile::Profile();
+ auto* prof = profile::ProfileBuilder::from_void();
speed_.event = prof->schedule(&profile::future_evt_set, this);
}
}
{
simgrid::kernel::profile::Profile* profile;
if (not args->file.empty()) {
- profile = simgrid::kernel::profile::Profile::from_file(args->file);
+ profile = simgrid::kernel::profile::ProfileBuilder::from_file(args->file);
} else {
xbt_assert(not args->pc_data.empty(), "Trace '%s' must have either a content, or point to a file on disk.",
args->id.c_str());
- profile = simgrid::kernel::profile::Profile::from_string(args->id, args->pc_data, args->periodicity);
+ profile = simgrid::kernel::profile::ProfileBuilder::from_string(args->id, args->pc_data, args->periodicity);
}
traces_set_list.insert({args->id, profile});
}
if (A_surfxml_host_availability___file[0] != '\0') {
XBT_WARN("The availability_file attribute in <host> is now deprecated. Please, use 'speed_file' instead.");
- host.speed_trace = simgrid::kernel::profile::Profile::from_file(A_surfxml_host_availability___file);
+ host.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_host_availability___file);
}
if (A_surfxml_host_speed___file[0] != '\0')
- host.speed_trace = simgrid::kernel::profile::Profile::from_file(A_surfxml_host_speed___file);
+ host.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_host_speed___file);
host.state_trace = A_surfxml_host_state___file[0]
- ? simgrid::kernel::profile::Profile::from_file(A_surfxml_host_state___file)
+ ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_host_state___file)
: nullptr;
host.coord = A_surfxml_host_coordinates;
peer.speed_trace = nullptr;
if (A_surfxml_peer_availability___file[0] != '\0') {
XBT_WARN("The availability_file attribute in <peer> is now deprecated. Please, use 'speed_file' instead.");
- peer.speed_trace = simgrid::kernel::profile::Profile::from_file(A_surfxml_peer_availability___file);
+ peer.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_peer_availability___file);
}
if (A_surfxml_peer_speed___file[0] != '\0')
- peer.speed_trace = simgrid::kernel::profile::Profile::from_file(A_surfxml_peer_speed___file);
+ peer.speed_trace = simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_peer_speed___file);
peer.state_trace = A_surfxml_peer_state___file[0]
- ? simgrid::kernel::profile::Profile::from_file(A_surfxml_peer_state___file)
+ ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_peer_state___file)
: nullptr;
if (A_surfxml_peer_lat[0] != '\0')
link.bandwidths = xbt_parse_get_bandwidths(surf_parsed_filename, surf_parse_lineno, A_surfxml_link_bandwidth,
"bandwidth of link " + link.id);
link.bandwidth_trace = A_surfxml_link_bandwidth___file[0]
- ? simgrid::kernel::profile::Profile::from_file(A_surfxml_link_bandwidth___file)
+ ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_link_bandwidth___file)
: nullptr;
link.latency =
xbt_parse_get_time(surf_parsed_filename, surf_parse_lineno, A_surfxml_link_latency, "latency of link " + link.id);
link.latency_trace = A_surfxml_link_latency___file[0]
- ? simgrid::kernel::profile::Profile::from_file(A_surfxml_link_latency___file)
+ ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_link_latency___file)
: nullptr;
link.state_trace = A_surfxml_link_state___file[0]
- ? simgrid::kernel::profile::Profile::from_file(A_surfxml_link_state___file)
+ ? simgrid::kernel::profile::ProfileBuilder::from_file(A_surfxml_link_state___file)
: nullptr;
switch (A_surfxml_link_sharing___policy) {
<host id="erin" speed="500Mf" speed_file="erin.avail"/> <!--uses someone else's trace -->
</zone>
- <trace id="myTrace" periodicity="1.0">
+ <trace id="myTrace" periodicity="21.0">
0.0 1.0
11.0 0.5
20.0 0.8
<trace_connect trace="myTrace" element="alice" kind="SPEED"/>
- <trace id="myTrace" file="bob.trace" periodicity="1.0"/>
+ <trace id="myTrace" file="bob.trace" periodicity="21.0"/>
<trace_connect trace="myTrace" element="bob" kind="SPEED"/>
</platform>
$ ./host-multicore-speed-file
> [carol:carol:(1) 0.000000] [s4u_test/INFO] Running 1 tasks (1.5e6) in a 2*(1e6) speed host. Should take 2s (1 (limited by core) + 1 (limited by speed file)
> [erin:erin:(2) 0.000000] [s4u_test/INFO] Running a 2 tasks: a small .5e6 and a big 2e6.
-> [erin:erin:(3) 0.000000] [s4u_test/INFO] Running a 2 tasks: a small .5e6 and a big 2e6.
-> [erin:erin:(3) 0.500000] [s4u_test/INFO] Finished the small task
-> [erin:erin:(3) 0.500000] [s4u_test/INFO] Waiting big task to finish
-> [erin:erin:(3) 1.000000] [s4u_test/INFO] Unable to finish big task, host went down
-> [carol:carol:(1) 2.000000] [s4u_test/INFO] Finished running 2 activities, elapsed 2.000000
-> [carol:carol:(1) 2.000000] [s4u_test/INFO] Running 1 tasks (.8e6) in a 2*(1e6) speed host with limited rate (.4e6). Should take 2s (limited by rate)
-> [carol:carol:(1) 4.000000] [s4u_test/INFO] Finished running 2 activities, elapsed 2.000000
-> [carol:carol:(1) 4.000000] [s4u_test/INFO] Running 1 tasks (1.1e6) in a 2*(1e6) speed host with limited rate (.6e6). Should take 2s (.6 limited by rate + .5 limited by speed file)
-> [carol:carol:(1) 6.000000] [s4u_test/INFO] Finished running 2 activities, elapsed 2.000000
-> [carol:carol:(1) 6.000000] [s4u_test/INFO] Running 2 tasks (1e6) in a 2*(1e6) speed host. Should take 1s
-> [carol:carol:(1) 7.000000] [s4u_test/INFO] Finished running 2 activities, elapsed 1.000000
-> [carol:carol:(1) 7.000000] [s4u_test/INFO] Running 2 tasks (.5e6) in a .5*2*(1e6) speed host. Should take 1s
-> [carol:carol:(1) 8.000000] [s4u_test/INFO] Finished running 2 activities, elapsed 1.000000
-> [carol:carol:(1) 8.000000] [s4u_test/INFO] Running 2 tasks (1.1e6) with limited rate (.6e6). Should take 2s (0.6 limited by rate + 0.5 limited by speed file)
-> [carol:carol:(1) 10.000000] [s4u_test/INFO] Finished running 2 activities, elapsed 2.000000
-> [carol:carol:(1) 10.000000] [s4u_test/INFO] Running 2 tasks (.8e6) with limited rate (.4e6). Should take 2s (limited by rate)
-> [carol:carol:(1) 12.000000] [s4u_test/INFO] Finished running 2 activities, elapsed 2.000000
-> [carol:carol:(1) 12.000000] [s4u_test/INFO] I'm done. See you!
-> [12.000000] [s4u_test/INFO] Simulation time 12
+> [erin:erin:(2) 0.500000] [s4u_test/INFO] Finished the small task
+> [erin:erin:(2) 0.500000] [s4u_test/INFO] Waiting big task to finish
+> [erin:erin:(2) 1.000000] [s4u_test/INFO] Unable to finish big task, host went down
+> [carol:carol:(1) 1.500000] [s4u_test/INFO] Finished running 2 activities, elapsed 1.500000
+> [carol:carol:(1) 1.500000] [s4u_test/INFO] Running 1 tasks (.8e6) in a 2*(1e6) speed host with limited rate (.4e6). Should take 2s (limited by rate)
+> [carol:carol:(1) 3.500000] [s4u_test/INFO] Finished running 2 activities, elapsed 2.000000
+> [carol:carol:(1) 3.500000] [s4u_test/INFO] Running 1 tasks (1.1e6) in a 2*(1e6) speed host with limited rate (.6e6). Should take 2s (.6 limited by rate + .5 limited by speed file)
+> [carol:carol:(1) 5.333333] [s4u_test/INFO] Finished running 2 activities, elapsed 1.833333
+> [carol:carol:(1) 5.333333] [s4u_test/INFO] Running 2 tasks (1e6) in a 2*(1e6) speed host. Should take 1s
+> [carol:carol:(1) 6.333333] [s4u_test/INFO] Finished running 2 activities, elapsed 1.000000
+> [carol:carol:(1) 6.333333] [s4u_test/INFO] Running 2 tasks (.5e6) in a .5*2*(1e6) speed host. Should take 1s
+> [carol:carol:(1) 6.833333] [s4u_test/INFO] Finished running 2 activities, elapsed 0.500000
+> [carol:carol:(1) 6.833333] [s4u_test/INFO] Running 2 tasks (1.1e6) with limited rate (.6e6). Should take 2s (0.6 limited by rate + 0.5 limited by speed file)
+> [carol:carol:(1) 8.666667] [s4u_test/INFO] Finished running 2 activities, elapsed 1.833333
+> [carol:carol:(1) 8.666667] [s4u_test/INFO] Running 2 tasks (.8e6) with limited rate (.4e6). Should take 2s (limited by rate)
+> [carol:carol:(1) 10.666667] [s4u_test/INFO] Finished running 2 activities, elapsed 2.000000
+> [carol:carol:(1) 10.666667] [s4u_test/INFO] I'm done. See you!
+> [10.666667] [s4u_test/INFO] Simulation time 10.6667
src/kernel/resource/VirtualMachineImpl.cpp
src/kernel/resource/WifiLinkImpl.cpp
- src/kernel/resource/profile/DatedValue.cpp
- src/kernel/resource/profile/DatedValue.hpp
src/kernel/resource/profile/Event.hpp
src/kernel/resource/profile/FutureEvtSet.cpp
src/kernel/resource/profile/FutureEvtSet.hpp