Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
simdag properties example
authorquasar <quasar@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 1 Nov 2007 16:42:09 +0000 (16:42 +0000)
committerquasar <quasar@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 1 Nov 2007 16:42:09 +0000 (16:42 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@4954 48e7efb5-ca39-0410-a469-dd3cf9ba447f

examples/simdag/Makefile.am
examples/simdag/Makefile.in
examples/simdag/properties/Makefile [new file with mode: 0644]
examples/simdag/properties/prop.xml [new file with mode: 0755]
examples/simdag/properties/sd_prop.c [new file with mode: 0755]
examples/simdag/properties/test_prop.tesh [new file with mode: 0755]

index 5cdb4c5..8bb03f0 100644 (file)
@@ -7,17 +7,22 @@
 
 INCLUDES = -I$(top_srcdir)/include
 AM_CFLAGS = -g
-EXTRA_DIST = 2clusters.xml
+EXTRA_DIST = 2clusters.xml \
+             properties/prop.xml
 
-CLEANFILES = sd_test.trace
+CLEANFILES = sd_test.trace \
+             properties/sd_prop
 
 TESTS_ENVIRONMENT = $(top_builddir)/tools/tesh/tesh
 
-TESTS = test_simdag.tesh test_simdag2.tesh 
-check_PROGRAMS = sd_test sd_test2
+TESTS = test_simdag.tesh test_simdag2.tesh properties/test_prop.tesh
+check_PROGRAMS = sd_test sd_test2 properties/sd_prop
 
 bin_PROGRAMS = 
 
+properties_sd_prop_SOURCES = properties/sd_prop.c
+properties_sd_prop_LDADD = $(top_builddir)/src/libsimgrid.la
+
 sd_test_SOURCES = sd_test.c
 sd_test_LDADD =        $(top_builddir)/src/libsimgrid.la
 
index 2b5230e..e9f62b8 100644 (file)
@@ -44,7 +44,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
-check_PROGRAMS = sd_test$(EXEEXT) sd_test2$(EXEEXT)
+check_PROGRAMS = sd_test$(EXEEXT) sd_test2$(EXEEXT) \
+       properties/sd_prop$(EXEEXT)
 bin_PROGRAMS =
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
        $(top_srcdir)/acmacro/dist-files.mk
@@ -66,6 +67,10 @@ CONFIG_CLEAN_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(bin_PROGRAMS)
+am_properties_sd_prop_OBJECTS = sd_prop.$(OBJEXT)
+properties_sd_prop_OBJECTS = $(am_properties_sd_prop_OBJECTS)
+properties_sd_prop_DEPENDENCIES = $(top_builddir)/src/libsimgrid.la
+am__dirstamp = $(am__leading_dot)dirstamp
 am_sd_test_OBJECTS = sd_test.$(OBJEXT)
 sd_test_OBJECTS = $(am_sd_test_OBJECTS)
 sd_test_DEPENDENCIES = $(top_builddir)/src/libsimgrid.la
@@ -84,8 +89,10 @@ CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
        $(LDFLAGS) -o $@
-SOURCES = $(sd_test_SOURCES) $(sd_test2_SOURCES)
-DIST_SOURCES = $(sd_test_SOURCES) $(sd_test2_SOURCES)
+SOURCES = $(properties_sd_prop_SOURCES) $(sd_test_SOURCES) \
+       $(sd_test2_SOURCES)
+DIST_SOURCES = $(properties_sd_prop_SOURCES) $(sd_test_SOURCES) \
+       $(sd_test2_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -226,10 +233,16 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 INCLUDES = -I$(top_srcdir)/include
 AM_CFLAGS = -g
-EXTRA_DIST = 2clusters.xml
-CLEANFILES = sd_test.trace
+EXTRA_DIST = 2clusters.xml \
+             properties/2clusters.xml
+
+CLEANFILES = sd_test.trace \
+             properties/sd_prop
+
 TESTS_ENVIRONMENT = $(top_builddir)/tools/tesh/tesh
-TESTS = test_simdag.tesh test_simdag2.tesh 
+TESTS = test_simdag.tesh test_simdag2.tesh properties/test_prop.tesh
+properties_sd_prop_SOURCES = properties/sd_prop.c
+properties_sd_prop_LDADD = $(top_builddir)/src/libsimgrid.la
 sd_test_SOURCES = sd_test.c
 sd_test_LDADD = $(top_builddir)/src/libsimgrid.la
 sd_test2_SOURCES = sd_test2.c
@@ -302,6 +315,12 @@ clean-checkPROGRAMS:
          echo " rm -f $$p $$f"; \
          rm -f $$p $$f ; \
        done
+properties/$(am__dirstamp):
+       @$(MKDIR_P) properties
+       @: > properties/$(am__dirstamp)
+properties/sd_prop$(EXEEXT): $(properties_sd_prop_OBJECTS) $(properties_sd_prop_DEPENDENCIES) properties/$(am__dirstamp)
+       @rm -f properties/sd_prop$(EXEEXT)
+       $(LINK) $(properties_sd_prop_OBJECTS) $(properties_sd_prop_LDADD) $(LIBS)
 sd_test$(EXEEXT): $(sd_test_OBJECTS) $(sd_test_DEPENDENCIES) 
        @rm -f sd_test$(EXEEXT)
        $(LINK) $(sd_test_OBJECTS) $(sd_test_LDADD) $(LIBS)
@@ -315,6 +334,7 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sd_prop.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sd_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sd_test2.Po@am__quote@
 
@@ -339,6 +359,20 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
 
+sd_prop.o: properties/sd_prop.c
+@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sd_prop.o -MD -MP -MF $(DEPDIR)/sd_prop.Tpo -c -o sd_prop.o `test -f 'properties/sd_prop.c' || echo '$(srcdir)/'`properties/sd_prop.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/sd_prop.Tpo $(DEPDIR)/sd_prop.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='properties/sd_prop.c' object='sd_prop.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sd_prop.o `test -f 'properties/sd_prop.c' || echo '$(srcdir)/'`properties/sd_prop.c
+
+sd_prop.obj: properties/sd_prop.c
+@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sd_prop.obj -MD -MP -MF $(DEPDIR)/sd_prop.Tpo -c -o sd_prop.obj `if test -f 'properties/sd_prop.c'; then $(CYGPATH_W) 'properties/sd_prop.c'; else $(CYGPATH_W) '$(srcdir)/properties/sd_prop.c'; fi`
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/sd_prop.Tpo $(DEPDIR)/sd_prop.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='properties/sd_prop.c' object='sd_prop.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sd_prop.obj `if test -f 'properties/sd_prop.c'; then $(CYGPATH_W) 'properties/sd_prop.c'; else $(CYGPATH_W) '$(srcdir)/properties/sd_prop.c'; fi`
+
 mostlyclean-libtool:
        -rm -f *.lo
 
@@ -522,6 +556,7 @@ clean-generic:
 
 distclean-generic:
        -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+       -rm -f properties/$(am__dirstamp)
 
 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
diff --git a/examples/simdag/properties/Makefile b/examples/simdag/properties/Makefile
new file mode 100644 (file)
index 0000000..95aa425
--- /dev/null
@@ -0,0 +1,30 @@
+all: sd_prop 
+masterslave: sd_prop.o
+
+INSTALL_PATH = $$HOME
+CC = gcc
+PEDANTIC_PARANOID_FREAK =       -O0 -Wshadow -Wcast-align \
+                               -Waggregate-return -Wmissing-prototypes -Wmissing-declarations \
+                               -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \
+                               -Wmissing-noreturn -Wredundant-decls -Wnested-externs \
+                               -Wpointer-arith -Wwrite-strings -finline-functions
+REASONABLY_CAREFUL_DUDE =      -Wall
+NO_PRAYER_FOR_THE_WICKED =     -w -O2 
+WARNINGS =                     $(REASONABLY_CAREFUL_DUDE)
+CFLAGS = -g $(WARNINGS)
+
+INCLUDES = -I$(INSTALL_PATH)/include
+DEFS = -L$(INSTALL_PATH)/lib/
+LDADD = -lm -lsimgrid 
+LIBS = 
+
+%: %.o
+       $(CC) $(INCLUDES) $(DEFS) $(CFLAGS) $^ $(LIBS) $(LDADD) -o $@ 
+
+%.o: %.c
+       $(CC) $(INCLUDES) $(DEFS) $(CFLAGS) -c -o $@ $<
+
+clean:
+       rm -f $(BIN_FILES) *.o *~
+.SUFFIXES:
+.PHONY : clean
diff --git a/examples/simdag/properties/prop.xml b/examples/simdag/properties/prop.xml
new file mode 100755 (executable)
index 0000000..43feb4b
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "surfxml.dtd">
+<platform version="2">
+  <host id="C1-01" power="1000000000">
+    <prop id="Hdd" value="180"/>
+    <prop id="mem" value="4"/>
+  </host>
+  <host id="C1-00" power="1000000000">
+    <prop id="Hdd" value="120"/>
+  </host>
+  <link id="6" bandwidth="125000000" latency="0.000100">
+    <prop id="type" value="Ethernet"/>
+  </link>
+  <link id="0" bandwidth="125000000" latency="0.000100">
+    <prop id="type" value="ethernet"/>
+  </link>
+  <route src="C1-00" dst="C1-01"><link:ctn id="6"/><link:ctn id="0"/></route>
+  <route src="C1-01" dst="C1-00"><link:ctn id="0"/><link:ctn id="6"/></route>
+</platform>
diff --git a/examples/simdag/properties/sd_prop.c b/examples/simdag/properties/sd_prop.c
new file mode 100755 (executable)
index 0000000..f8d80fd
--- /dev/null
@@ -0,0 +1,232 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "simdag/simdag.h"
+#include "xbt/ex.h"
+#include "xbt/log.h"
+#include "xbt/dynar.h"
+#include "xbt/dict.h"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(sd_test,
+                            "Logging specific to this SimDag example");
+
+int main(int argc, char **argv) {
+  int i;
+
+  /* initialisation of SD */
+  SD_init(&argc, argv);
+
+  /*  xbt_log_control_set("sd.thres=debug"); */
+
+  if (argc < 2) {
+    INFO1("Usage: %s platform_file", argv[0]);
+    INFO1("example: %s sd_platform.xml", argv[0]);
+    exit(1);
+  }
+
+  /* creation of the environment */
+  const char * platform_file = argv[1];
+  SD_create_environment(platform_file);
+
+  /* test the estimation functions */
+  const SD_workstation_t *workstations = SD_workstation_get_list();
+  SD_workstation_t w1 = workstations[0];
+  SD_workstation_t w2 = workstations[1];
+  SD_workstation_set_access_mode(w2, SD_WORKSTATION_SEQUENTIAL_ACCESS);
+  const char *name1 = SD_workstation_get_name(w1);
+  const char *name2 = SD_workstation_get_name(w2);
+
+  xbt_dict_t props;
+  INFO1("Property list for workstation %s", name1);
+  /* Get the property list of the workstation 1 */
+  props = SD_workstation_get_properties(w1);
+  xbt_dict_cursor_t cursor = NULL;
+  char *key,*data;
+
+  /* Print the properties of the workstation 1 */
+  xbt_dict_foreach(props,cursor,key,data) {
+  INFO2("Property: %s has value: %s",key,data);
+  }
+  /* Try to get a property that does not exist */
+  char *noexist=xbt_strdup("Memory");
+  const char *value = SD_workstation_get_property_value(w1,noexist);
+  if ( value == NULL) 
+    INFO1("Property: %s is undefined", noexist);
+  else
+    INFO2("Property: %s has value: %s", noexist, value);
+  
+  INFO1("Property list for workstation %s", name2);
+  /* Get the property list of the workstation 2 */
+  props = SD_workstation_get_properties(w2);
+  cursor = NULL;
+
+  /* Print the properties of the workstation 2 */
+  xbt_dict_foreach(props,cursor,key,data) {
+  INFO2("Property: %s on host: %s",key,data);
+  }
+
+  const double computation_amount1 = 2000000;
+  const double computation_amount2 = 1000000;
+  const double communication_amount12 = 2000000;
+  const double communication_amount21 = 3000000;
+  INFO3("Computation time for %f flops on %s: %f", computation_amount1, name1,
+       SD_workstation_get_computation_time(w1, computation_amount1));
+  INFO3("Computation time for %f flops on %s: %f", computation_amount2, name2,
+       SD_workstation_get_computation_time(w2, computation_amount2));
+
+  INFO2("Route between %s and %s:", name1, name2);   
+  const SD_link_t *route = SD_route_get_list(w1, w2);
+  int route_size = SD_route_get_size(w1, w2);
+  for (i = 0; i < route_size; i++) {
+    INFO3("\tLink %s: latency = %f, bandwidth = %f", SD_link_get_name(route[i]),
+         SD_link_get_current_latency(route[i]), SD_link_get_current_bandwidth(route[i]));
+      
+    props = SD_link_get_properties(route[i]);
+    xbt_dict_cursor_t cursor = NULL;
+    char *key,*data;
+
+    /* Print the properties of the current link */
+    xbt_dict_foreach(props,cursor,key,data) {
+    INFO3("Link %s property: %s has value: %s",SD_link_get_name(route[i]),key,data);
+
+    /* Try to get a property that does not exist */
+    noexist=xbt_strdup("Other");
+    value = SD_link_get_property_value(route[i], noexist);
+    if ( value == NULL) 
+      INFO2("Property: %s for link %s is undefined", noexist, SD_link_get_name(route[i]));
+    else
+      INFO3("Link %s property: %s has value: %s",SD_link_get_name(route[i]),noexist,value);
+  }
+
+  }
+  INFO2("Route latency = %f, route bandwidth = %f", SD_route_get_current_latency(w1, w2),
+       SD_route_get_current_bandwidth(w1, w2));
+  INFO4("Communication time for %f bytes between %s and %s: %f", communication_amount12, name1, name2,
+       SD_route_get_communication_time(w1, w2, communication_amount12));
+  INFO4("Communication time for %f bytes between %s and %s: %f", communication_amount21, name2, name1,
+       SD_route_get_communication_time(w2, w1, communication_amount21));
+
+  /* creation of the tasks and their dependencies */
+  SD_task_t taskA = SD_task_create("Task A", NULL, 10.0);
+  SD_task_t taskB = SD_task_create("Task B", NULL, 40.0);
+  SD_task_t taskC = SD_task_create("Task C", NULL, 30.0);
+  SD_task_t taskD = SD_task_create("Task D", NULL, 60.0);
+  
+
+  SD_task_dependency_add(NULL, NULL, taskB, taskA);
+  SD_task_dependency_add(NULL, NULL, taskC, taskA);
+  SD_task_dependency_add(NULL, NULL, taskD, taskB);
+  SD_task_dependency_add(NULL, NULL, taskD, taskC);
+  /*  SD_task_dependency_add(NULL, NULL, taskA, taskD); /\* deadlock */
+
+  xbt_ex_t ex;
+
+  TRY {
+    SD_task_dependency_add(NULL, NULL, taskA, taskA); /* shouldn't work and must raise an exception */
+    xbt_die("Hey, I can add a dependency between Task A and Task A!");
+  }
+  CATCH (ex) {
+    if (ex.category != arg_error)
+
+      RETHROW; /* this is a serious error */
+    xbt_ex_free(ex);
+  }
+  
+  TRY {
+    SD_task_dependency_add(NULL, NULL, taskB, taskA); /* shouldn't work and must raise an exception */
+    xbt_die("Oh oh, I can add an already existing dependency!");
+  }
+  CATCH (ex) {
+    if (ex.category != arg_error)
+      RETHROW;
+    xbt_ex_free(ex);
+  }
+
+  TRY {
+    SD_task_dependency_remove(taskA, taskC); /* shouldn't work and must raise an exception */
+    xbt_die("Dude, I can remove an unknown dependency!");
+  }
+  CATCH (ex) {
+    if (ex.category != arg_error)
+      RETHROW;
+    xbt_ex_free(ex);
+  }
+
+  TRY {
+    SD_task_dependency_remove(taskC, taskC); /* shouldn't work and must raise an exception */
+    xbt_die("Wow, I can remove a dependency between Task C and itself!");
+  }
+  CATCH (ex) {
+    if (ex.category != arg_error)
+      RETHROW;
+    xbt_ex_free(ex);
+  }
+
+
+  /* if everything is ok, no exception is forwarded or rethrown by main() */
+
+  /* watch points */
+  SD_task_watch(taskD, SD_DONE);
+  SD_task_watch(taskB, SD_DONE);
+  SD_task_unwatch(taskD, SD_DONE);
+  
+
+  /* scheduling parameters */
+
+  const int workstation_number = 2;
+  const SD_workstation_t workstation_list[] = {w1, w2};
+  double computation_amount[] = {computation_amount1, computation_amount2};
+  double communication_amount[] =
+    {
+      0, communication_amount12,
+      communication_amount21, 0
+    };
+  double rate = -1.0;
+
+  /* estimated time */
+  SD_task_t task = taskD;
+  INFO2("Estimated time for '%s': %f", SD_task_get_name(task),
+       SD_task_get_execution_time(task, workstation_number, workstation_list,
+                                  computation_amount, communication_amount, rate));
+
+  /* let's launch the simulation! */
+
+  SD_task_schedule(taskA, workstation_number, workstation_list,
+                  computation_amount, communication_amount, rate);
+  SD_task_schedule(taskB, workstation_number, workstation_list,
+                  computation_amount, communication_amount, rate);
+  SD_task_schedule(taskC, workstation_number, workstation_list,
+                  computation_amount, communication_amount, rate);
+  SD_task_schedule(taskD, workstation_number, workstation_list,
+                  computation_amount, communication_amount, rate);
+
+  SD_task_t *changed_tasks;
+
+  changed_tasks = SD_simulate(-1.0);
+  for (i = 0; changed_tasks[i] != NULL; i++) {
+    INFO3("Task '%s' start time: %f, finish time: %f",
+         SD_task_get_name(changed_tasks[i]),
+         SD_task_get_start_time(changed_tasks[i]),
+         SD_task_get_finish_time(changed_tasks[i]));
+  }
+  
+  xbt_assert0(changed_tasks[0] == taskD &&
+             changed_tasks[1] == taskB &&
+             changed_tasks[2] == NULL,
+             "Unexpected simulation results");
+
+  xbt_free(changed_tasks);
+
+  DEBUG0("Destroying tasks...");
+
+  SD_task_destroy(taskA);
+  SD_task_destroy(taskB);
+  SD_task_destroy(taskC);
+  SD_task_destroy(taskD);
+
+  DEBUG0("Tasks destroyed. Exiting SimDag...");
+
+  SD_exit();
+  return 0;
+}
+
diff --git a/examples/simdag/properties/test_prop.tesh b/examples/simdag/properties/test_prop.tesh
new file mode 100755 (executable)
index 0000000..63a8da0
--- /dev/null
@@ -0,0 +1,35 @@
+#! ./tesh
+
+p Simple test of simdag with properties
+
+$ $SG_TEST_EXENV ./sd_prop ${srcdir:=.}/prop.xml
+> [0.000000] [sd_test/INFO] Property list for workstation C1-00
+> [0.000000] [sd_test/INFO] Property: Hdd has value: 120
+> [0.000000] [sd_test/INFO] Property: Memory is undefined
+> [0.000000] [sd_test/INFO] Property list for workstation C1-01
+> [0.000000] [sd_test/INFO] Property: mem on host: 4
+> [0.000000] [sd_test/INFO] Property: Hdd on host: 180
+> [0.000000] [sd_test/INFO] Computation time for 2000000.000000 flops on C1-00: 0.002000
+> [0.000000] [sd_test/INFO] Computation time for 1000000.000000 flops on C1-01: 0.001000
+> [0.000000] [sd_test/INFO] Route between C1-00 and C1-01:
+> [0.000000] [sd_test/INFO]    Link 6: latency = 0.000100, bandwidth = 125000000.000000
+> [0.000000] [sd_test/INFO] Link 6 property: type has value: Ethernet
+> [0.000000] [sd_test/INFO] Property: Other for link 6 is undefined
+> [0.000000] [sd_test/INFO]    Link 0: latency = 0.000100, bandwidth = 125000000.000000
+> [0.000000] [sd_test/INFO] Link 0 property: type has value: ethernet
+> [0.000000] [sd_test/INFO] Property: Other for link 0 is undefined
+> [0.000000] [sd_test/INFO] Route latency = 0.000200, route bandwidth = 125000000.000000
+> [0.000000] [sd_test/INFO] Communication time for 2000000.000000 bytes between C1-00 and C1-01: 0.016200
+> [0.000000] [sd_test/INFO] Communication time for 3000000.000000 bytes between C1-01 and C1-00: 0.024200
+> [0.000000] [sd_test/INFO] Estimated time for 'Task D': 1.512000
+> [0.000000] [sd_kernel/INFO] Starting simulation...
+> [0.000000] [sd_kernel/INFO] Executing task 'Task D'
+> [3.600200] [sd_kernel/INFO] Task 'Task D' done
+> [3.600200] [sd_kernel/INFO] Executing task 'Task B'
+> [3.600200] [sd_kernel/INFO] Executing task 'Task C'
+> [6.000400] [sd_kernel/INFO] Task 'Task B' done
+> [6.000400] [sd_task/INFO] Watch point reached with task 'Task B'!
+> [6.000400] [sd_kernel/INFO] Simulation finished
+> [6.000400] [sd_test/INFO] Task 'Task D' start time: 0.000000, finish time: 3.600200
+> [6.000400] [sd_test/INFO] Task 'Task B' start time: 3.600200, finish time: 6.000400
+