浏览代码

Add generatation of animated html trace of modular schedulers, with code from Anthony Simonet

Samuel Thibault 10 年之前
父节点
当前提交
ce9464d6b7

+ 1 - 0
AUTHORS

@@ -26,6 +26,7 @@ Cyril Roelandt <cyril.roelandt@inria.fr>
 Anthony Roy <theanthony33@gmail.com>
 Anthony Roy <theanthony33@gmail.com>
 Corentin Salingue <corentin.salingue@gmail.com>
 Corentin Salingue <corentin.salingue@gmail.com>
 Marc Sergent <marc.sergent@inria.fr>
 Marc Sergent <marc.sergent@inria.fr>
+Anthony Simonet <anthony.simonet@etu.u-bordeaux.fr>
 Luka Stanisic <luka.stanisic@imag.fr>
 Luka Stanisic <luka.stanisic@imag.fr>
 Ludovic Stordeur <ludovic.stordeur@inria.fr>
 Ludovic Stordeur <ludovic.stordeur@inria.fr>
 François Tessier <francois.tessier@inria.fr>
 François Tessier <francois.tessier@inria.fr>

+ 1 - 0
ChangeLog

@@ -106,6 +106,7 @@ New features:
   * Add tasks.rec trace output to make scheduling analysis easier.
   * Add tasks.rec trace output to make scheduling analysis easier.
   * Add Fortran 90 module and example using it
   * Add Fortran 90 module and example using it
   * New StarPU-MPI gdb debug functions
   * New StarPU-MPI gdb debug functions
+  * Generate animated html trace of modular schedulers.
 
 
 Small features:
 Small features:
   * Tasks can now have a name (via the field const char *name of
   * Tasks can now have a name (via the field const char *name of

+ 25 - 12
doc/doxygen/chapters/13offline_performance_tools.doxy

@@ -96,11 +96,11 @@ the execution.
 
 
 \subsection CreatingAGanttDiagram Creating a Gantt Diagram
 \subsection CreatingAGanttDiagram Creating a Gantt Diagram
 
 
-When the FxT trace file <c>filename</c> has been generated, it is possible to
+When the FxT trace file <c>prof_file_something</c> has been generated, it is possible to
 generate a trace in the Paje format by calling:
 generate a trace in the Paje format by calling:
 
 
 \verbatim
 \verbatim
-$ starpu_fxt_tool -i filename
+$ starpu_fxt_tool -i /tmp/prof_file_something
 \endverbatim
 \endverbatim
 
 
 Or alternatively, setting the environment variable \ref STARPU_GENERATE_TRACE
 Or alternatively, setting the environment variable \ref STARPU_GENERATE_TRACE
@@ -127,7 +127,7 @@ In the MPI execution case, collect the trace files from the MPI nodes, and
 specify them all on the command <c>starpu_fxt_tool</c>, for instance:
 specify them all on the command <c>starpu_fxt_tool</c>, for instance:
 
 
 \verbatim
 \verbatim
-$ starpu_fxt_tool -i filename1 -i filename2
+$ starpu_fxt_tool -i /tmp/prof_file_something1 -i /tmp/prof_file_something2
 \endverbatim
 \endverbatim
 
 
 By default, all tasks are displayed using a green color. To display tasks with
 By default, all tasks are displayed using a green color. To display tasks with
@@ -142,18 +142,18 @@ StarPU configure option, the value of the tag will show up in the trace.
 Traces can also be inspected by hand by using the tool <c>fxt_print</c>, for instance:
 Traces can also be inspected by hand by using the tool <c>fxt_print</c>, for instance:
 
 
 \verbatim
 \verbatim
-$ fxt_print -o -f filename
+$ fxt_print -o -f /tmp/prof_file_something
 \endverbatim
 \endverbatim
 
 
 Timings are in nanoseconds (while timings as seen in <c>vite</c> are in milliseconds).
 Timings are in nanoseconds (while timings as seen in <c>vite</c> are in milliseconds).
 
 
 \subsection CreatingADAGWithGraphviz Creating a DAG With Graphviz
 \subsection CreatingADAGWithGraphviz Creating a DAG With Graphviz
 
 
-When the FxT trace file <c>filename</c> has been generated, it is possible to
+When the FxT trace file <c>prof_file_something</c> has been generated, it is possible to
 generate a task graph in the DOT format by calling:
 generate a task graph in the DOT format by calling:
 
 
 \verbatim
 \verbatim
-$ starpu_fxt_tool -i filename
+$ starpu_fxt_tool -i /tmp/prof_file_something
 \endverbatim
 \endverbatim
 
 
 This will create a <c>dag.dot</c> file in the current directory. This file is a
 This will create a <c>dag.dot</c> file in the current directory. This file is a
@@ -166,11 +166,11 @@ $ dot -Tpdf dag.dot -o output.pdf
 
 
 \subsection TraceTaskDetails Getting task details
 \subsection TraceTaskDetails Getting task details
 
 
-When the FxT trace file <c>filename</c> has been generated, details on the
+When the FxT trace file <c>prof_file_something</c> has been generated, details on the
 executed tasks can be retrieved by calling:
 executed tasks can be retrieved by calling:
 
 
 \verbatim
 \verbatim
-$ starpu_fxt_tool -i filename
+$ starpu_fxt_tool -i /tmp/prof_file_something
 \endverbatim
 \endverbatim
 
 
 This will create a <c>tasks.rec</c> file in the current directory.  This file
 This will create a <c>tasks.rec</c> file in the current directory.  This file
@@ -182,11 +182,11 @@ analysis tools.  The performance models can be opened for instance by using
 
 
 \subsection MonitoringActivity Monitoring Activity
 \subsection MonitoringActivity Monitoring Activity
 
 
-When the FxT trace file <c>filename</c> has been generated, it is possible to
+When the FxT trace file <c>prof_file_something</c> has been generated, it is possible to
 generate an activity trace by calling:
 generate an activity trace by calling:
 
 
 \verbatim
 \verbatim
-$ starpu_fxt_tool -i filename
+$ starpu_fxt_tool -i /tmp/prof_file_something
 \endverbatim
 \endverbatim
 
 
 This will create a file <c>activity.data</c> in the current
 This will create a file <c>activity.data</c> in the current
@@ -213,6 +213,19 @@ evolution of the number of tasks available in the system during the execution.
 Ready tasks are shown in black, and tasks that are submitted but not
 Ready tasks are shown in black, and tasks that are submitted but not
 schedulable yet are shown in grey.
 schedulable yet are shown in grey.
 
 
+\subsection Animation Getting modular schedular animation
+
+When using modular schedulers (i.e. schedulers which use a modular architecture,
+and whose name start with "modular-"), the command
+
+\verbatim
+$ starpu_fxt_tool -i /tmp/prof_file_something
+\endverbatim
+
+will also produce a <c>trace.html</c> file which can be viewed in a
+javascript-enabled web browser. It shows the flow of tasks between the
+components of the modular scheduler.
+
 \section PerformanceOfCodelets Performance Of Codelets
 \section PerformanceOfCodelets Performance Of Codelets
 
 
 The performance model of codelets (see \ref PerformanceModelExample)
 The performance model of codelets (see \ref PerformanceModelExample)
@@ -299,11 +312,11 @@ compute GFlops.
 \image html starpu_chol_model_11_type.png
 \image html starpu_chol_model_11_type.png
 \image latex starpu_chol_model_11_type.eps "" width=\textwidth
 \image latex starpu_chol_model_11_type.eps "" width=\textwidth
 
 
-When the FxT trace file <c>filename</c> has been generated, it is possible to
+When the FxT trace file <c>prof_file_something</c> has been generated, it is possible to
 get a profiling of each codelet by calling:
 get a profiling of each codelet by calling:
 
 
 \verbatim
 \verbatim
-$ starpu_fxt_tool -i filename
+$ starpu_fxt_tool -i /tmp/prof_file_something
 $ starpu_codelet_profile distrib.data codelet_name
 $ starpu_codelet_profile distrib.data codelet_name
 \endverbatim
 \endverbatim
 
 

+ 3 - 1
include/starpu_fxt.h

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
- * Copyright (C) 2010-2011, 2013  Université de Bordeaux
+ * Copyright (C) 2010-2011, 2013, 2015  Université de Bordeaux
  * Copyright (C) 2010, 2011, 2013, 2014  CNRS
  * Copyright (C) 2010, 2011, 2013, 2014  CNRS
  *
  *
  * StarPU is free software; you can redistribute it and/or modify
  * StarPU is free software; you can redistribute it and/or modify
@@ -48,6 +48,8 @@ struct starpu_fxt_options
 	char *distrib_time_path;
 	char *distrib_time_path;
 	char *activity_path;
 	char *activity_path;
 	char *dag_path;
 	char *dag_path;
+	char *tasks_path;
+	char *anim_path;
 
 
 	char *file_prefix;
 	char *file_prefix;
 	uint64_t file_offset;
 	uint64_t file_offset;

+ 3 - 3
include/starpu_sched_component.h

@@ -90,13 +90,13 @@ struct starpu_sched_tree *starpu_sched_tree_get(unsigned sched_ctx_id);
 void starpu_sched_tree_update_workers(struct starpu_sched_tree *t);
 void starpu_sched_tree_update_workers(struct starpu_sched_tree *t);
 void starpu_sched_tree_update_workers_in_ctx(struct starpu_sched_tree *t);
 void starpu_sched_tree_update_workers_in_ctx(struct starpu_sched_tree *t);
 int starpu_sched_tree_push_task(struct starpu_task *task);
 int starpu_sched_tree_push_task(struct starpu_task *task);
-int starpu_sched_component_push_task(struct starpu_sched_component *component, struct starpu_task *task);
+int starpu_sched_component_push_task(struct starpu_sched_component *from, struct starpu_sched_component *to, struct starpu_task *task);
 struct starpu_task *starpu_sched_tree_pop_task(unsigned sched_ctx);
 struct starpu_task *starpu_sched_tree_pop_task(unsigned sched_ctx);
-struct starpu_task *starpu_sched_component_pull_task(struct starpu_sched_component * component);
+struct starpu_task *starpu_sched_component_pull_task(struct starpu_sched_component *from, struct starpu_sched_component *to);
 void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
 void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
 void starpu_sched_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
 void starpu_sched_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
 
 
-struct starpu_sched_component *starpu_sched_component_create(struct starpu_sched_tree *tree);
+struct starpu_sched_component *starpu_sched_component_create(struct starpu_sched_tree *tree, const char *name);
 void starpu_sched_component_destroy(struct starpu_sched_component *component);
 void starpu_sched_component_destroy(struct starpu_sched_component *component);
 void starpu_sched_component_destroy_rec(struct starpu_sched_component *component);
 void starpu_sched_component_destroy_rec(struct starpu_sched_component *component);
 int starpu_sched_component_can_execute_task(struct starpu_sched_component *component, struct starpu_task *task);
 int starpu_sched_component_can_execute_task(struct starpu_sched_component *component, struct starpu_task *task);

+ 1 - 0
src/Makefile.am

@@ -240,6 +240,7 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 		\
 	debug/traces/starpu_fxt_mpi.c				\
 	debug/traces/starpu_fxt_mpi.c				\
 	debug/traces/starpu_fxt_dag.c				\
 	debug/traces/starpu_fxt_dag.c				\
 	debug/traces/starpu_paje.c				\
 	debug/traces/starpu_paje.c				\
+	debug/traces/anim.c					\
 	debug/latency.c						\
 	debug/latency.c						\
 	debug/structures_size.c					\
 	debug/structures_size.c					\
 	profiling/profiling.c					\
 	profiling/profiling.c					\

+ 21 - 0
src/common/fxt.h

@@ -176,6 +176,11 @@
 #define	_STARPU_FUT_START_EXECUTING	0x5168
 #define	_STARPU_FUT_START_EXECUTING	0x5168
 #define	_STARPU_FUT_END_EXECUTING	0x5169
 #define	_STARPU_FUT_END_EXECUTING	0x5169
 
 
+#define _STARPU_FUT_SCHED_COMPONENT_NEW		0x516a
+#define _STARPU_FUT_SCHED_COMPONENT_CONNECT	0x516b
+#define _STARPU_FUT_SCHED_COMPONENT_PUSH	0x516c
+#define _STARPU_FUT_SCHED_COMPONENT_PULL	0x516d
+
 #ifdef STARPU_USE_FXT
 #ifdef STARPU_USE_FXT
 #include <fxt/fxt.h>
 #include <fxt/fxt.h>
 #include <fxt/fut.h>
 #include <fxt/fut.h>
@@ -830,6 +835,18 @@ do {										\
 #define _STARPU_TRACE_SCHED_COMPONENT_POP_PRIO(workerid, ntasks, exp_len)		\
 #define _STARPU_TRACE_SCHED_COMPONENT_POP_PRIO(workerid, ntasks, exp_len)		\
 	FUT_DO_PROBE4(_STARPU_FUT_SCHED_COMPONENT_POP_PRIO, _starpu_gettid(), workerid, ntasks, exp_len);
 	FUT_DO_PROBE4(_STARPU_FUT_SCHED_COMPONENT_POP_PRIO, _starpu_gettid(), workerid, ntasks, exp_len);
 
 
+#define _STARPU_TRACE_SCHED_COMPONENT_NEW(component)		\
+	_STARPU_FUT_DO_PROBE1STR(_STARPU_FUT_SCHED_COMPONENT_NEW, component, (component)->name);
+
+#define _STARPU_TRACE_SCHED_COMPONENT_CONNECT(parent, child)		\
+	FUT_DO_PROBE2(_STARPU_FUT_SCHED_COMPONENT_CONNECT, parent, child);
+
+#define _STARPU_TRACE_SCHED_COMPONENT_PUSH(from, to, task)		\
+	FUT_DO_PROBE5(_STARPU_FUT_SCHED_COMPONENT_PUSH, _starpu_gettid(), from, to, task, (task)->priority);
+
+#define _STARPU_TRACE_SCHED_COMPONENT_PULL(from, to, task)		\
+	FUT_DO_PROBE5(_STARPU_FUT_SCHED_COMPONENT_PULL, _starpu_gettid(), from, to, task, (task)->priority);
+
 #else // !STARPU_USE_FXT
 #else // !STARPU_USE_FXT
 
 
 /* Dummy macros in case FxT is disabled */
 /* Dummy macros in case FxT is disabled */
@@ -919,6 +936,10 @@ do {										\
 #define _STARPU_TRACE_SCHED_COMPONENT_POP_PRIO(workerid, ntasks, exp_len)	do {} while(0)
 #define _STARPU_TRACE_SCHED_COMPONENT_POP_PRIO(workerid, ntasks, exp_len)	do {} while(0)
 #define _STARPU_TRACE_HYPERVISOR_BEGIN()        do {} while(0)
 #define _STARPU_TRACE_HYPERVISOR_BEGIN()        do {} while(0)
 #define _STARPU_TRACE_HYPERVISOR_END()                  do {} while(0)
 #define _STARPU_TRACE_HYPERVISOR_END()                  do {} while(0)
+#define _STARPU_TRACE_SCHED_COMPONENT_NEW(component)	do {} while (0)
+#define _STARPU_TRACE_SCHED_COMPONENT_CONNECT(parent, child)	do {} while (0)
+#define _STARPU_TRACE_SCHED_COMPONENT_PUSH(from, to, task)	do {} while (0)
+#define _STARPU_TRACE_SCHED_COMPONENT_PULL(from, to, task)	do {} while (0)
 
 
 #endif // STARPU_USE_FXT
 #endif // STARPU_USE_FXT
 
 

+ 513 - 0
src/debug/traces/anim.c

@@ -0,0 +1,513 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2015  Université de Bordeaux
+ * Copyright (C) 2015  Anthony Simonet
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <common/uthash.h>
+#include <starpu.h>
+#include "starpu_fxt.h"
+
+static struct component {
+	UT_hash_handle hh;
+	char *name;
+	int workerid;
+	uint64_t ptr;
+	unsigned nchildren;
+	struct component **children;
+	struct component *parent;
+	unsigned ntasks;
+	unsigned npriotasks;
+} *components;
+
+static unsigned global_state = 1;
+static unsigned nsubmitted;
+static unsigned curq_size;
+static unsigned nflowing;
+
+#define COMPONENT_ADD(head, field, add) HASH_ADD(hh, head, field, sizeof(uint64_t), add);
+#define COMPONENT_FIND(head, find, out) HASH_FIND(hh, head, &find, sizeof(uint64_t), out);
+
+static struct component *fxt_component_root(void)
+{
+	struct component *comp, *tmp;
+	HASH_ITER(hh, components, comp, tmp)
+	{
+		while (comp->parent)
+			comp = comp->parent;
+		return comp;
+	}
+	return NULL;
+}
+
+void _starpu_fxt_component_new(uint64_t component, char *name)
+{
+	struct component *comp = malloc(sizeof(*comp));
+
+	if (!strncmp(name, "worker ", 7))
+	{
+		comp->name = strdup("worker");
+		comp->workerid = atoi(name+7);
+	}
+	else
+	{
+		comp->name = strdup(name);
+		comp->workerid = -1;
+	}
+	comp->ptr = component;
+	comp->nchildren = 0;
+	comp->children = NULL;
+	comp->parent = NULL;
+	comp->ntasks = 0;
+	comp->npriotasks = 0;
+
+	COMPONENT_ADD(components, ptr, comp);
+}
+
+static void fxt_component_dump(FILE *file, struct component *comp, unsigned depth)
+{
+	unsigned i;
+	fprintf(file,"%*s%s (%d %"PRIx64", %d tasks %d prio tasks)\n", 2*depth, "", comp->name, depth, comp->ptr, comp->ntasks, comp->npriotasks);
+	for (i = 0; i < comp->nchildren; i++)
+		if (comp->children[i]->parent == comp)
+			fxt_component_dump(file, comp->children[i], depth+1);
+}
+
+void _starpu_fxt_component_dump(FILE *file)
+{
+	fxt_component_dump(file, fxt_component_root(), 0);
+}
+
+static void fxt_worker_print(FILE *file, struct starpu_fxt_options *options, int workerid, unsigned comp_workerid, unsigned depth)
+{
+	fprintf(file, "\t\t\t%*s<table><tr><td class='worker_box%s'><center>%s\n", 2*depth, "",
+		(int) comp_workerid == workerid ? "_sched":"",
+		options->worker_names[comp_workerid]);
+	if (_starpu_last_codelet_symbol[comp_workerid][0])
+		fprintf(file, "\t\t\t%*s<table><tr><td class='run_task'>%s</td></tr></table>\n", 2*(depth+1), "", _starpu_last_codelet_symbol[comp_workerid]);
+	else
+		fprintf(file, "\t\t\t%*s<table><tr><td class='fake_task'></td></tr></table>\n", 2*(depth+1), "");
+	fprintf(file, "\t\t\t%*s</center></td></tr>\n", 2*depth, "");
+	fprintf(file, "\t\t\t%*s</table>", 2*depth, "");
+}
+
+static void fxt_component_print(FILE *file, struct starpu_fxt_options *options, int workerid, struct component *from, struct component *to, struct component *comp, unsigned depth)
+{
+	unsigned i, n;
+	unsigned ntasks = comp->ntasks + comp->npriotasks;
+
+	if (from == comp)
+		/* Additionally show now-empty slot */
+		ntasks++;
+
+	for (i = 0, n = 0; i < comp->nchildren; i++)
+		if (comp->children[i]->parent == comp)
+			n++;
+	fprintf(file, "\t\t\t%*s<table><tr><td class='box' colspan=%d><center>%s\n", 2*depth, "", n, comp->name);
+
+	if (!strcmp(comp->name,"prio") || !strcmp(comp->name,"fifo") || !strcmp(comp->name,"heft") || !strcmp(comp->name,"work_stealing"))
+	{
+		/* Show task queue */
+#define N 3
+		n = ntasks;
+		if (n > N)
+			n = N;
+		for (i = 0; i < N-n; i++)
+			fprintf(file, "\t\t\t%*s<table><tr><td class='fake_task'></td></tr></table>\n", 2*depth, "");
+		if (ntasks)
+		{
+			if (ntasks > N)
+				fprintf(file, "\t\t\t%*s<table><tr><td class='%s'>%d</td></tr></table>\n", 2*depth, "",
+					from == comp
+						? (comp->npriotasks >= N ? "last_task_full_prio" : "last_task_full")
+						: (comp->npriotasks >= N ? "task_prio" : "task"),
+					comp->ntasks + comp->npriotasks);
+			else
+				fprintf(file, "\t\t\t%*s<table><tr><td class='%s'></td></tr></table>\n", 2*depth, "",
+					from == comp
+						? "last_task_empty"
+						: (comp->ntasks ? "task" : "task_prio"));
+			for (i = 1; i < n; i++)
+				fprintf(file, "\t\t\t%*s<table><tr><td class='%s'></td></tr></table>\n", 2*depth, "",
+					n - i > comp->npriotasks ? "task" : "task_prio");
+		}
+	}
+	else
+	{
+		if (ntasks == 0)
+			fprintf(file, "\t\t\t%*s<table><tr><td class='fake_task'></td></tr></table>\n", 2*depth, "");
+		else if (ntasks == 1)
+			fprintf(file, "\t\t\t%*s<table><tr><td class='%s'></td></tr></table>\n", 2*depth, "",
+				from == comp
+					? "last_task_empty"
+					: (comp->npriotasks ? "task_prio" : "task"));
+		else
+			fprintf(file, "\t\t\t%*s<table><tr><td class='%s'>%d</td></tr></table>\n", 2*depth, "",
+				from == comp
+					? (comp->npriotasks ? "last_task_full_prio" : "last_task_full")
+					: (comp->npriotasks ? "task_prio" : "task"), comp->ntasks + comp->npriotasks);
+	}
+	fprintf(file, "\t\t\t%*s</center></td></tr>\n", 2*depth, "");
+
+	if (comp->nchildren > 0)
+	{
+		fprintf(file, "\t\t\t%*s<tr>\n", 2*depth, "");
+		for (i = 0; i < comp->nchildren; i++)
+			if (comp->children[i]->parent == comp)
+			{
+				fprintf(file, "\t\t\t%*s<td>\n", 2*depth, "");
+				fxt_component_print(file, options, workerid, from, to, comp->children[i], depth+1);
+				fprintf(file, "\t\t\t%*s</td>\n", 2*depth, "");
+			}
+		fprintf(file, "\t\t\t%*s</tr>\n", 2*depth, "");
+	}
+
+	if (!strcmp(comp->name, "worker"))
+	{
+		fprintf(file, "\t\t\t%*s<tr>\n", 2*depth, "");
+		fprintf(file, "\t\t\t%*s<td>\n", 2*depth, "");
+		fxt_worker_print(file, options, workerid, comp->workerid, depth+1);
+		fprintf(file, "\t\t\t%*s</td>\n", 2*depth, "");
+		fprintf(file, "\t\t\t%*s</tr>\n", 2*depth, "");
+	}
+
+	fprintf(file, "\t\t\t%*s</table>", 2*depth, "");
+}
+
+void _starpu_fxt_component_print(FILE *file, struct starpu_fxt_options *options, int workerid, struct component *from, struct component *to)
+{
+	fprintf(file, "<center>\n");
+	fxt_component_print(file, options, workerid, from, to, fxt_component_root(), 0);
+	fprintf(file, "</center>\n");
+}
+
+void _starpu_fxt_component_print_header(FILE *file)
+{
+	/* CSS and Javascript code from Anthony Simonet */
+	fprintf(file, "<!DOCTYPE html>\n");
+	fprintf(file, "<html lang='fr'>\n");
+	
+	fprintf(file, "\t<head>\n");
+	fprintf(file, "\t\t<meta charset='utf-8'>\n");
+	fprintf(file, "\t\t<link rel='stylesheet' href='http://code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css'>\n");
+	fprintf(file, "\t\t<script src='http://code.jquery.com/jquery-1.10.2.js'></script>\n");
+	fprintf(file, "\t\t<script src='http://code.jquery.com/ui/1.11.2/jquery-ui.js'></script>\n");
+	//fprintf(file, "\t\t<link rel='stylesheet' href='/resources/demos/style.css'>\n");
+	//fprintf(file, "\t\t<link rel='stylesheet' type='text/css' href='../styles.css'>\n");
+
+	fprintf(file, "\t\t<style>\n");
+
+	fprintf(file, "\t\t\ttable {\n");
+	fprintf(file, "\t\t\t\tmargin: 0;\n");
+	fprintf(file, "\t\t\t\tpadding: 0;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	fprintf(file, "\t\t\ttd {\n");
+	fprintf(file, "\t\t\t\tmargin: 0;\n");
+	fprintf(file, "\t\t\t\tpadding: 0;\n");
+	fprintf(file, "\t\t\t\tvertical-align: top;\n");
+	fprintf(file, "\t\t\t\ttext-align: center;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	fprintf(file, "\t\t\ttd.box {\n");
+	fprintf(file, "\t\t\t\tborder: solid 1px;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	fprintf(file, "\t\t\ttd.worker_box {\n");
+	fprintf(file, "\t\t\t\tborder: solid 1px;\n");
+	/* Fixed width to make output more homogeneous */
+	fprintf(file, "\t\t\t\twidth: 75px;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	fprintf(file, "\t\t\ttd.worker_box_sched {\n");
+	fprintf(file, "\t\t\t\tborder: solid 1px;\n");
+	/* Fixed width to make output more homogeneous */
+	fprintf(file, "\t\t\t\twidth: 75px;\n");
+	fprintf(file, "\t\t\t\tbackground-color: lightgreen;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	/* Task */
+	fprintf(file, "\t\t\ttd.task {\n");
+	fprintf(file, "\t\t\t\tborder: solid 1px;\n");
+	fprintf(file, "\t\t\t\twidth: 23px;\n");
+	fprintf(file, "\t\t\t\theight: 23px;\n");
+	fprintf(file, "\t\t\t\tbackground-color: #87CEEB;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	/* Task being run (with codelet name) */
+	fprintf(file, "\t\t\ttd.run_task {\n");
+	fprintf(file, "\t\t\t\tborder: solid 1px;\n");
+	fprintf(file, "\t\t\t\twidth: 69px;\n");
+	fprintf(file, "\t\t\t\tmax-width: 69px;\n");
+	fprintf(file, "\t\t\t\toverflow: hidden;\n");
+	fprintf(file, "\t\t\t\tfont-size: 50%%;\n");
+	fprintf(file, "\t\t\t\theight: 23px;\n");
+	fprintf(file, "\t\t\t\tbackground-color: #87CEEB;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	/* Prioritized Task */
+	fprintf(file, "\t\t\ttd.task_prio {\n");
+	fprintf(file, "\t\t\t\tborder: solid 1px;\n");
+	fprintf(file, "\t\t\t\twidth: 23px;\n");
+	fprintf(file, "\t\t\t\theight: 23px;\n");
+	fprintf(file, "\t\t\t\tbackground-color: red;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	/* Slot of previous task */
+	fprintf(file, "\t\t\ttd.last_task_empty {\n");
+	fprintf(file, "\t\t\t\tborder: dashed 1px;\n");
+	fprintf(file, "\t\t\t\twidth: 23px;\n");
+	fprintf(file, "\t\t\t\theight: 23px;\n");
+	fprintf(file, "\t\t\t\tbackground-color: white;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	/* Slot of previous task (but still other tasks) */
+	fprintf(file, "\t\t\ttd.last_task_full {\n");
+	fprintf(file, "\t\t\t\tborder: dashed 1px;\n");
+	fprintf(file, "\t\t\t\twidth: 23px;\n");
+	fprintf(file, "\t\t\t\theight: 23px;\n");
+	fprintf(file, "\t\t\t\tbackground-color: #87CEEB;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	/* Slot of previous task (but still other prioritized) */
+	fprintf(file, "\t\t\ttd.last_task_full_prio {\n");
+	fprintf(file, "\t\t\t\tborder: dashed 1px;\n");
+	fprintf(file, "\t\t\t\twidth: 23px;\n");
+	fprintf(file, "\t\t\t\theight: 23px;\n");
+	fprintf(file, "\t\t\t\tbackground-color: red;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	/* Empty task slot */
+	fprintf(file, "\t\t\ttd.fake_task {\n");
+	fprintf(file, "\t\t\t\twidth: 25px;\n");
+	fprintf(file, "\t\t\t\theight: 25px;\n");
+	fprintf(file, "\t\t\t}\n");
+
+	fprintf(file, "\t\t</style>\n");
+
+	fprintf(file, "\t\t<script>\n");
+	fprintf(file, "\t\t\tfunction getInput(){\n");
+	fprintf(file, "\t\t\t\tvar input = document.getElementById('input').value;\n");
+	fprintf(file, "\t\t\t\tif (input <= 0 || input > $('#slider').slider('option', 'max')){\n");
+	fprintf(file, "\t\t\t\t\talert('Invalid state value');\n");
+	fprintf(file, "\t\t\t\t}\n");
+	fprintf(file, "\t\t\t\tdocument.getElementById('et' + document.getElementById('etape').value).style.display = 'none';\n");
+	fprintf(file, "\t\t\t\tdocument.getElementById('et' + input).style.display = 'block';\n");
+	fprintf(file, "\t\t\t\t$('#etape').val(input);\n");
+	fprintf(file, "\t\t\t\t$('#slider').slider('value', input);\n");
+	fprintf(file, "\t\t\t}\n");
+	fprintf(file, "\t\t</script>\n");
+
+	fprintf(file, "\t\t<script>\n");
+	fprintf(file, "\t\t\tvar myVar = null;\n");
+	fprintf(file, "\t\t\tfunction changeState(number){\n");
+	fprintf(file, "\t\t\t\tvar state = document.getElementById('etape').value;\n");
+	fprintf(file, "\t\t\t\tvar state2 = parseInt(state) + parseInt(number);\n");
+	fprintf(file, "\t\t\t\tvar min = $('#slider').slider('option', 'min');\n");
+	fprintf(file, "\t\t\t\tvar max = $('#slider').slider('option', 'max');\n");
+	fprintf(file, "\t\t\t\t\tdocument.getElementById('et' + document.getElementById('etape').value).style.display = 'none';\n");
+	fprintf(file, "\t\t\t\tif (state2 >= min && state2 <= max){\n");
+	fprintf(file, "\t\t\t\t\tdocument.getElementById('et' + state2).style.display = 'block';\n");
+	fprintf(file, "\t\t\t\t\t$('#etape').val(state2);\n");
+	fprintf(file, "\t\t\t\t\t$('#slider').slider('value', state2);\n");
+	fprintf(file, "\t\t\t\t}\n");
+	fprintf(file, "\t\t\t\telse if (state2 < min){\n");
+	fprintf(file, "\t\t\t\t\tdocument.getElementById('et' + min).style.display = 'block';\n");
+	fprintf(file, "\t\t\t\t\t$('#etape').val(min);\n");
+	fprintf(file, "\t\t\t\t\t$('#slider').slider('value', min);\n");
+	fprintf(file, "\t\t\t\t}\n");
+	fprintf(file, "\t\t\t\telse if (state2 > max){\n");
+	fprintf(file, "\t\t\t\t\tdocument.getElementById('et' + max).style.display = 'block';\n");
+	fprintf(file, "\t\t\t\t\t$('#etape').val(max);\n");
+	fprintf(file, "\t\t\t\t\t$('#slider').slider('value', max);\n");
+	fprintf(file, "\t\t\t\t}\n");
+	fprintf(file, "\t\t\t}\n");
+	fprintf(file, "\t\t</script>\n");
+
+	fprintf(file, "\t</head>\n");
+
+	fprintf(file, "\t<body>\n");
+}
+
+static void fxt_component_print_step(FILE *file, struct starpu_fxt_options *options, double timestamp, int workerid, unsigned push, struct component *from, struct component *to)
+{
+	fprintf(file, "\t\t<div id='et%d' style='display:%s;'><center><!-- Étape %d -->\n",
+			global_state, global_state > 1 ? "none":"block", global_state);
+	fprintf(file, "\t\t<p>Time %f, %d submitted %d ready, %s</p>\n", timestamp, nsubmitted, curq_size-nflowing, push?"push":"pull");
+	//fprintf(file, "\t\t\t<tt><pre>\n");
+	//_starpu_fxt_component_dump(file);
+	//fprintf(file, "\t\t\t</pre></tt>\n");
+	_starpu_fxt_component_print(file, options, workerid, from, to);
+	fprintf(file,"\t\t</center></div>");
+
+	global_state++;
+}
+
+void _starpu_fxt_component_connect(uint64_t parent, uint64_t child)
+{
+	struct component *parent_p, *child_p;
+	unsigned n;
+
+	COMPONENT_FIND(components, parent, parent_p);
+	COMPONENT_FIND(components, child, child_p);
+	STARPU_ASSERT(parent_p);
+	STARPU_ASSERT(child_p);
+
+	n = ++parent_p->nchildren;
+	parent_p->children = realloc(parent_p->children, n * sizeof(*parent_p->children));
+	parent_p->children[n-1] = child_p;
+	if (!child_p->parent)
+		child_p->parent = parent_p;
+}
+
+void _starpu_fxt_component_update_ntasks(unsigned _nsubmitted, unsigned _curq_size)
+{
+	nsubmitted = _nsubmitted;
+	curq_size = _curq_size;
+}
+
+void _starpu_fxt_component_push(FILE *output, struct starpu_fxt_options *options, double timestamp, int workerid, uint64_t from, uint64_t to, uint64_t task STARPU_ATTRIBUTE_UNUSED, unsigned prio)
+{
+	struct component *from_p = NULL, *to_p = NULL;
+
+	if (to == from)
+		return;
+
+	if (from)
+	{
+		COMPONENT_FIND(components, from, from_p);
+		STARPU_ASSERT(from_p);
+	}
+	if (to)
+	{
+		COMPONENT_FIND(components, to, to_p);
+		STARPU_ASSERT(to_p);
+	}
+	if (from_p)
+	{
+		if (prio)
+			from_p->npriotasks--;
+		else
+			from_p->ntasks--;
+	}
+	else
+		nflowing++;
+	if (prio)
+		to_p->npriotasks++;
+	else
+		to_p->ntasks++;
+
+	// fprintf(stderr,"push from %s to %s\n", from_p?from_p->name:"none", to_p?to_p->name:"none");
+	fxt_component_print_step(output, options, timestamp, workerid, 1, from_p, to_p);
+}
+
+void _starpu_fxt_component_pull(FILE *output, struct starpu_fxt_options *options, double timestamp, int workerid, uint64_t from, uint64_t to, uint64_t task STARPU_ATTRIBUTE_UNUSED, unsigned prio)
+{
+	struct component *from_p = NULL, *to_p = NULL;
+
+	if (to == from)
+		return;
+
+	if (from)
+	{
+		COMPONENT_FIND(components, from, from_p);
+		STARPU_ASSERT(from_p);
+	}
+	if (to)
+	{
+		COMPONENT_FIND(components, to, to_p);
+		STARPU_ASSERT(to_p);
+	}
+	if (prio)
+		from_p->npriotasks--;
+	else
+		from_p->ntasks--;
+	if (to_p)
+	{
+		if (prio)
+			to_p->npriotasks++;
+		else
+			to_p->ntasks++;
+	}
+	else
+		nflowing--;
+
+	// fprintf(stderr,"pull from %s to %s\n", from_p?from_p->name:"none", to_p?to_p->name:"none");
+	fxt_component_print_step(output, options, timestamp, workerid, 0, from_p, to_p);
+}
+
+void _starpu_fxt_component_finish(FILE *file)
+{
+	/* Javascript code from Anthony Simonet */
+	fprintf(file, "\t\t<script>\n");
+	fprintf(file, "\t\t\t$(function(){\n");
+	fprintf(file, "\t\t\t\tsliderDiv = $('#slider') <!-- Alias -->\n");
+	fprintf(file, "\t\t\t\tsliderDiv.slider({\n");
+	fprintf(file, "\t\t\t\t\tvalue: 1,\n");
+	fprintf(file, "\t\t\t\t\tmin: 1,\n");
+	fprintf(file, "\t\t\t\t\tmax: %d,\n", global_state-1);
+	fprintf(file, "\t\t\t\t\tstep: 1,\n");
+	fprintf(file, "\t\t\t\t\tanimate: 'fast',\n");
+	fprintf(file, "\t\t\t\t\tslide: function(event, ui){\n");
+	fprintf(file, "\t\t\t\t\t\tvar l_value = sliderDiv.slider('option', 'value');\n");
+	fprintf(file, "\t\t\t\t\t\t$('#etape').val(ui.value);\n");
+	fprintf(file, "\t\t\t\t\t\tdocument.getElementById('et' + l_value).style.display = 'none';\n");
+	fprintf(file, "\t\t\t\t\t\tdocument.getElementById('et' + ui.value).style.display = 'block';\n");
+	fprintf(file, "\t\t\t\t\t}\n");
+	fprintf(file, "\t\t\t\t});\n");
+	fprintf(file, "\t\t\t\t$('#etape').val(sliderDiv.slider('value')); <!-- Initialisation au lancement de la page -->\n");
+	fprintf(file, "\t\t\t\t$('#max').val(sliderDiv.slider('option', 'max'));\n");
+	fprintf(file, "\t\t\t});\n");
+	fprintf(file, "\t\t</script>\n");
+
+	fprintf(file, "\t\t<div id ='slider'></div>\n");
+	fprintf(file, "\t\t<center>\n");
+	fprintf(file, "\t\t\t<p>\n");
+	fprintf(file, "\t\t\t\t<input type='button' value='-100' onclick=\"changeState(-100);\"/>\n");
+	fprintf(file, "\t\t\t\t<input type='button' value='<<' onmousedown=\"myVar = setInterval('changeState(-1)', 50)\" onmouseup=\"clearInterval(myVar)\" onmouseout=\"clearInterval(myVar)\"/>\n");
+	fprintf(file, "\t\t\t\t<input type='button' value='<' onclick=\"changeState(-1);\"/>\n");
+	fprintf(file, "\t\t\t\t<label for='etape'>State</label>\n");
+	fprintf(file, "\t\t\t\t<input type='text' id='etape' size='3mm' readonly style='border:0;'>\n");
+	fprintf(file, "\t\t\t\t<label for='max'>in</label>\n");
+	fprintf(file, "\t\t\t\t<input type='text' id='max' size='3mm' readonly style='border:0;'>\n");
+	fprintf(file, "\t\t\t\t<input type='button' value='>' onclick=\"changeState(1);\" />\n");
+	fprintf(file, "\t\t\t\t<input type='button' value='>>' onmousedown=\"myVar = setInterval('changeState(1)', 50)\" onmouseup=\"clearInterval(myVar)\" onmouseout=\"clearInterval(myVar)\"/>\n");
+	fprintf(file, "\t\t\t\t<input type='button' value='+100' onclick=\"changeState(100);\"/>\n");
+	fprintf(file, "\t\t\t</p>\n");
+	fprintf(file, "\t\t\t\t<span id='range'>Auto speed (state/s): 4</span>\n");
+	fprintf(file, "\t\t\t\t<input type='range' id='autoRange' min='1' max='50' value='4' step='1' onchange=\"showValue(this.value); clearInterval(myVar);\"  />\n");
+	fprintf(file, "\t\t\t\t<script>\n");
+	fprintf(file, "\t\t\t\t\tdocument.getElementById('autoRange').value = 4;\n");
+	fprintf(file, "\t\t\t\t\tfunction showValue(newValue)\n");
+	fprintf(file, "\t\t\t\t\t{\n");
+	fprintf(file, "\t\t\t\t\t\tdocument.getElementById('range').innerHTML='Auto speed (state/s): '+ newValue;\n");
+	fprintf(file, "\t\t\t\t\t}\n");
+	fprintf(file, "\t\t\t\t</script>\n");
+	fprintf(file, "\t\t\t\t<input type='button' value='Auto' onclick=\"if(myVar){ clearInterval(myVar); myVar = null;}changeState(1); myVar = setInterval('changeState(1)', 1000/document.getElementById('autoRange').value);\"/>\n");
+	fprintf(file, "\t\t\t\t<input type='button' value='Stop' onclick=\"clearInterval(myVar);\"/>\n");
+	fprintf(file, "\t\t\t<p>\n");
+	fprintf(file, "\t\t\t</p>\n");
+	fprintf(file, "\t\t\t<FORM>\n");
+	fprintf(file, "\t\t\t\t<span>Go to state</span>\n");
+	fprintf(file, "\t\t\t\t<input type='text' name='setinput' id='input' value='' onKeyPress=\"if(event.keyCode == 13){ getInput(); javascript:this.value=''}\" onFocus=\"javascript:this.value=''\"/>\n");
+	fprintf(file, "\t\t\t\t<input type='text' name='message' id='' value='' style='display:none'>\n"); /* Dummy input preventing the page from being refreshed when enter is pressed. */
+	fprintf(file, "\t\t\t\t<input type='button' value='Go' onclick=\"getInput(); javascript:input.value=''\"/>\n");
+	fprintf(file, "\t\t\t</FORM>\n");
+	fprintf(file, "\t\t\t<br />\n");
+	fprintf(file, "\t\t</center>\n");
+	fprintf(file, "\t</body>\n");
+	fprintf(file, "</html>\n");
+}

+ 76 - 15
src/debug/traces/starpu_fxt.c

@@ -58,6 +58,7 @@ static unsigned other_index = 0;
 static FILE *out_paje_file;
 static FILE *out_paje_file;
 static FILE *distrib_time;
 static FILE *distrib_time;
 static FILE *activity_file;
 static FILE *activity_file;
+static FILE *anim_file;
 static FILE *tasks_file;
 static FILE *tasks_file;
 
 
 struct data_info {
 struct data_info {
@@ -256,7 +257,7 @@ static unsigned get_colour_symbol_blue(char *name)
 
 
 static double last_codelet_start[STARPU_NMAXWORKERS];
 static double last_codelet_start[STARPU_NMAXWORKERS];
 /* _STARPU_FUT_DO_PROBE4STR records only 4 longs */
 /* _STARPU_FUT_DO_PROBE4STR records only 4 longs */
-static char last_codelet_symbol[STARPU_NMAXWORKERS][4*sizeof(unsigned long)];
+char _starpu_last_codelet_symbol[STARPU_NMAXWORKERS][4*sizeof(unsigned long)];
 static int last_codelet_parameter[STARPU_NMAXWORKERS];
 static int last_codelet_parameter[STARPU_NMAXWORKERS];
 #define MAX_PARAMETERS 8
 #define MAX_PARAMETERS 8
 static char last_codelet_parameter_description[STARPU_NMAXWORKERS][MAX_PARAMETERS][FXT_MAX_PARAMS*sizeof(unsigned long)];
 static char last_codelet_parameter_description[STARPU_NMAXWORKERS][MAX_PARAMETERS][FXT_MAX_PARAMS*sizeof(unsigned long)];
@@ -869,7 +870,7 @@ static void handle_start_codelet_body(struct fxt_ev_64 *ev, struct starpu_fxt_op
 	unsigned long has_name = ev->param[3];
 	unsigned long has_name = ev->param[3];
 	char *name = has_name?(char *)&ev->param[4]:"unknown";
 	char *name = has_name?(char *)&ev->param[4]:"unknown";
 
 
-	snprintf(last_codelet_symbol[worker], sizeof(last_codelet_symbol[worker]), "%s", name);
+	snprintf(_starpu_last_codelet_symbol[worker], sizeof(_starpu_last_codelet_symbol[worker]), "%s", name);
 	last_codelet_parameter[worker] = 0;
 	last_codelet_parameter[worker] = 0;
 
 
 	double start_codelet_time = get_event_time_stamp(ev, options);
 	double start_codelet_time = get_event_time_stamp(ev, options);
@@ -971,7 +972,7 @@ static void handle_codelet_details(struct fxt_ev_64 *ev STARPU_ATTRIBUTE_UNUSED,
 		char *prefix = options->file_prefix;
 		char *prefix = options->file_prefix;
 		unsigned sched_ctx = ev->param[1];
 		unsigned sched_ctx = ev->param[1];
 
 
-		worker_set_detailed_state(last_codelet_start[worker], prefix, worker, last_codelet_symbol[worker], ev->param[2], parameters, ev->param[3], ev->param[4], job_id);
+		worker_set_detailed_state(last_codelet_start[worker], prefix, worker, _starpu_last_codelet_symbol[worker], ev->param[2], parameters, ev->param[3], ev->param[4], job_id);
 		if (sched_ctx != 0)
 		if (sched_ctx != 0)
 		{
 		{
 #ifdef STARPU_HAVE_POTI
 #ifdef STARPU_HAVE_POTI
@@ -979,9 +980,9 @@ static void handle_codelet_details(struct fxt_ev_64 *ev STARPU_ATTRIBUTE_UNUSED,
 			char ctx[6];
 			char ctx[6];
 			snprintf(ctx, sizeof(ctx), "Ctx%d", sched_ctx);
 			snprintf(ctx, sizeof(ctx), "Ctx%d", sched_ctx);
 			worker_container_alias(container, STARPU_POTI_STR_LEN, prefix, ev->param[5]);
 			worker_container_alias(container, STARPU_POTI_STR_LEN, prefix, ev->param[5]);
-			poti_SetState(last_codelet_start[worker], container, ctx, last_codelet_symbol[worker]);
+			poti_SetState(last_codelet_start[worker], container, ctx, _starpu_last_codelet_symbol[worker]);
 #else
 #else
-			fprintf(out_paje_file, "20	%.9f	%sw%"PRIu64"	Ctx%d	%s	%lu	%s	%08lx	%016llx	%lu\n", last_codelet_start[worker], prefix, ev->param[2], sched_ctx, last_codelet_symbol[worker], (unsigned long) ev->param[2], parameters, (unsigned long) ev->param[3], (unsigned long long) ev->param[4], job_id);
+			fprintf(out_paje_file, "20	%.9f	%sw%"PRIu64"	Ctx%d	%s	%lu	%s	%08lx	%016llx	%lu\n", last_codelet_start[worker], prefix, ev->param[2], sched_ctx, _starpu_last_codelet_symbol[worker], (unsigned long) ev->param[2], parameters, (unsigned long) ev->param[3], (unsigned long long) ev->param[4], job_id);
 #endif
 #endif
 		}
 		}
 #endif /* STARPU_ENABLE_PAJE_CODELET_DETAILS */
 #endif /* STARPU_ENABLE_PAJE_CODELET_DETAILS */
@@ -1013,7 +1014,7 @@ static void handle_end_codelet_body(struct fxt_ev_64 *ev, struct starpu_fxt_opti
 	update_accumulated_time(worker, 0.0, codelet_length, end_codelet_time, 0);
 	update_accumulated_time(worker, 0.0, codelet_length, end_codelet_time, 0);
 
 
 	if (distrib_time)
 	if (distrib_time)
-	     fprintf(distrib_time, "%s\t%s%d\t%ld\t%"PRIx32"\t%.9f\n", last_codelet_symbol[worker],
+	     fprintf(distrib_time, "%s\t%s%d\t%ld\t%"PRIx32"\t%.9f\n", _starpu_last_codelet_symbol[worker],
 		     prefix, worker, (unsigned long) codelet_size, codelet_hash, codelet_length);
 		     prefix, worker, (unsigned long) codelet_size, codelet_hash, codelet_length);
 
 
 	if (options->dumped_codelets)
 	if (options->dumped_codelets)
@@ -1021,13 +1022,14 @@ static void handle_end_codelet_body(struct fxt_ev_64 *ev, struct starpu_fxt_opti
 		dumped_codelets_count++;
 		dumped_codelets_count++;
 		dumped_codelets = realloc(dumped_codelets, dumped_codelets_count*sizeof(struct starpu_fxt_codelet_event));
 		dumped_codelets = realloc(dumped_codelets, dumped_codelets_count*sizeof(struct starpu_fxt_codelet_event));
 
 
-		snprintf(dumped_codelets[dumped_codelets_count - 1].symbol, 256, "%s", last_codelet_symbol[worker]);
+		snprintf(dumped_codelets[dumped_codelets_count - 1].symbol, 256, "%s", _starpu_last_codelet_symbol[worker]);
 		dumped_codelets[dumped_codelets_count - 1].workerid = worker;
 		dumped_codelets[dumped_codelets_count - 1].workerid = worker;
 		snprintf(dumped_codelets[dumped_codelets_count - 1].perfmodel_archname, 256, "%s", (char *)&ev->param[4]);
 		snprintf(dumped_codelets[dumped_codelets_count - 1].perfmodel_archname, 256, "%s", (char *)&ev->param[4]);
 		dumped_codelets[dumped_codelets_count - 1].size = codelet_size;
 		dumped_codelets[dumped_codelets_count - 1].size = codelet_size;
 		dumped_codelets[dumped_codelets_count - 1].hash = codelet_hash;
 		dumped_codelets[dumped_codelets_count - 1].hash = codelet_hash;
 		dumped_codelets[dumped_codelets_count - 1].time = codelet_length;
 		dumped_codelets[dumped_codelets_count - 1].time = codelet_length;
 	}
 	}
+	_starpu_last_codelet_symbol[worker][0] = 0;
 }
 }
 
 
 static void handle_start_executing(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
 static void handle_start_executing(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
@@ -1388,6 +1390,8 @@ static void handle_job_push(struct fxt_ev_64 *ev, struct starpu_fxt_options *opt
 
 
 	curq_size++;
 	curq_size++;
 
 
+	_starpu_fxt_component_update_ntasks(nsubmitted, curq_size);
+
 	if (!options->no_counter && out_paje_file)
 	if (!options->no_counter && out_paje_file)
 	{
 	{
 #ifdef STARPU_HAVE_POTI
 #ifdef STARPU_HAVE_POTI
@@ -1410,6 +1414,7 @@ static void handle_job_pop(struct fxt_ev_64 *ev, struct starpu_fxt_options *opti
 
 
 	curq_size--;
 	curq_size--;
 	nsubmitted--;
 	nsubmitted--;
+	_starpu_fxt_component_update_ntasks(nsubmitted, curq_size);
 
 
 	if (!options->no_counter && out_paje_file)
 	if (!options->no_counter && out_paje_file)
 	{
 	{
@@ -1431,12 +1436,37 @@ static void handle_job_pop(struct fxt_ev_64 *ev, struct starpu_fxt_options *opti
 	}
 	}
 }
 }
 
 
+static void handle_component_new(struct fxt_ev_64 *ev, struct starpu_fxt_options *options STARPU_ATTRIBUTE_UNUSED)
+{
+	_starpu_fxt_component_new(ev->param[0], (char *)&ev->param[1]);
+}
+
+static void handle_component_connect(struct fxt_ev_64 *ev, struct starpu_fxt_options *options STARPU_ATTRIBUTE_UNUSED)
+{
+	_starpu_fxt_component_connect(ev->param[0], ev->param[1]);
+}
+
+static void handle_component_push(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
+{
+	double current_timestamp = get_event_time_stamp(ev, options);
+	int workerid = find_worker_id(ev->param[0]);
+	_starpu_fxt_component_push(anim_file, options, current_timestamp, workerid, ev->param[1], ev->param[2], ev->param[3], ev->param[4]);
+}
+
+static void handle_component_pull(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
+{
+	double current_timestamp = get_event_time_stamp(ev, options);
+	int workerid = find_worker_id(ev->param[0]);
+	_starpu_fxt_component_pull(anim_file, options, current_timestamp, workerid, ev->param[1], ev->param[2], ev->param[3], ev->param[4]);
+}
+
 static
 static
 void handle_update_task_cnt(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
 void handle_update_task_cnt(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
 {
 {
 	double current_timestamp = get_event_time_stamp(ev, options);
 	double current_timestamp = get_event_time_stamp(ev, options);
 
 
 	nsubmitted++;
 	nsubmitted++;
+	_starpu_fxt_component_update_ntasks(nsubmitted, curq_size);
 	if (!options->no_counter && out_paje_file)
 	if (!options->no_counter && out_paje_file)
 	{
 	{
 #ifdef STARPU_HAVE_POTI
 #ifdef STARPU_HAVE_POTI
@@ -1985,6 +2015,19 @@ void _starpu_fxt_parse_new_file(char *filename_in, struct starpu_fxt_options *op
 				handle_job_pop(&ev, options);
 				handle_job_pop(&ev, options);
 				break;
 				break;
 
 
+			case _STARPU_FUT_SCHED_COMPONENT_NEW:
+				handle_component_new(&ev, options);
+				break;
+			case _STARPU_FUT_SCHED_COMPONENT_CONNECT:
+				handle_component_connect(&ev, options);
+				break;
+			case _STARPU_FUT_SCHED_COMPONENT_PUSH:
+				handle_component_push(&ev, options);
+				break;
+			case _STARPU_FUT_SCHED_COMPONENT_PULL:
+				handle_component_pull(&ev, options);
+				break;
+
 			/* check the memory transfer overhead */
 			/* check the memory transfer overhead */
 			case _STARPU_FUT_START_FETCH_INPUT:
 			case _STARPU_FUT_START_FETCH_INPUT:
 				handle_worker_status(&ev, options, "Fi");
 				handle_worker_status(&ev, options, "Fi");
@@ -2380,8 +2423,8 @@ void starpu_fxt_options_init(struct starpu_fxt_options *options)
 	options->ninputfiles = 0;
 	options->ninputfiles = 0;
 	options->out_paje_path = "paje.trace";
 	options->out_paje_path = "paje.trace";
 	options->dag_path = "dag.dot";
 	options->dag_path = "dag.dot";
-	/* TODO */
-	/* options->tasks_path = "tasks.rec"; */
+	options->tasks_path = "tasks.rec";
+	options->anim_path = "trace.html";
 	options->distrib_time_path = "distrib.data";
 	options->distrib_time_path = "distrib.data";
 	options->dumped_codelets = NULL;
 	options->dumped_codelets = NULL;
 	options->activity_path = "activity.data";
 	options->activity_path = "activity.data";
@@ -2426,17 +2469,24 @@ void _starpu_fxt_activity_file_init(struct starpu_fxt_options *options)
 }
 }
 
 
 static
 static
+void _starpu_fxt_anim_file_init(struct starpu_fxt_options *options)
+{
+	if (options->anim_path)
+	{
+		anim_file = fopen(options->anim_path, "w+");
+		_starpu_fxt_component_print_header(anim_file);
+	}
+	else
+		anim_file = NULL;
+}
+
+static
 void _starpu_fxt_tasks_file_init(struct starpu_fxt_options *options)
 void _starpu_fxt_tasks_file_init(struct starpu_fxt_options *options)
 {
 {
-#if 0
-	//TODO
-	if (options->activity_path)
+	if (options->tasks_path)
 		tasks_file = fopen(options->tasks_path, "w+");
 		tasks_file = fopen(options->tasks_path, "w+");
 	else
 	else
 		tasks_file = NULL;
 		tasks_file = NULL;
-#endif
-
-	tasks_file = fopen("tasks.rec", "w+");
 }
 }
 
 
 static
 static
@@ -2447,6 +2497,15 @@ void _starpu_fxt_activity_file_close(void)
 }
 }
 
 
 static
 static
+void _starpu_fxt_anim_file_close(void)
+{
+	//_starpu_fxt_component_dump(stderr);
+	_starpu_fxt_component_finish(anim_file);
+	if (anim_file)
+		fclose(anim_file);
+}
+
+static
 void _starpu_fxt_tasks_file_close(void)
 void _starpu_fxt_tasks_file_close(void)
 {
 {
 	if (tasks_file)
 	if (tasks_file)
@@ -2527,6 +2586,7 @@ void starpu_fxt_generate_trace(struct starpu_fxt_options *options)
 	_starpu_fxt_dag_init(options->dag_path);
 	_starpu_fxt_dag_init(options->dag_path);
 	_starpu_fxt_distrib_file_init(options);
 	_starpu_fxt_distrib_file_init(options);
 	_starpu_fxt_activity_file_init(options);
 	_starpu_fxt_activity_file_init(options);
+	_starpu_fxt_anim_file_init(options);
 	_starpu_fxt_tasks_file_init(options);
 	_starpu_fxt_tasks_file_init(options);
 
 
 	_starpu_fxt_paje_file_init(options);
 	_starpu_fxt_paje_file_init(options);
@@ -2655,6 +2715,7 @@ void starpu_fxt_generate_trace(struct starpu_fxt_options *options)
 	_starpu_fxt_paje_file_close();
 	_starpu_fxt_paje_file_close();
 	_starpu_fxt_activity_file_close();
 	_starpu_fxt_activity_file_close();
 	_starpu_fxt_distrib_file_close(options);
 	_starpu_fxt_distrib_file_close(options);
+	_starpu_fxt_anim_file_close();
 	_starpu_fxt_tasks_file_close();
 	_starpu_fxt_tasks_file_close();
 
 
 	_starpu_fxt_dag_terminate();
 	_starpu_fxt_dag_terminate();

+ 15 - 1
src/debug/traces/starpu_fxt.h

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
- * Copyright (C) 2009-2012  Université de Bordeaux
+ * Copyright (C) 2009-2012, 2015  Université de Bordeaux
  *
  *
  * StarPU is free software; you can redistribute it and/or modify
  * StarPU is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
  * it under the terms of the GNU Lesser General Public License as published by
@@ -38,6 +38,8 @@
 #include <starpu.h>
 #include <starpu.h>
 #include "../../../include/starpu_fxt.h"
 #include "../../../include/starpu_fxt.h"
 
 
+extern char _starpu_last_codelet_symbol[STARPU_NMAXWORKERS][4*sizeof(unsigned long)];
+
 void _starpu_fxt_dag_init(char *dag_filename);
 void _starpu_fxt_dag_init(char *dag_filename);
 void _starpu_fxt_dag_terminate(void);
 void _starpu_fxt_dag_terminate(void);
 void _starpu_fxt_dag_add_tag(uint64_t tag, unsigned long job_id);
 void _starpu_fxt_dag_add_tag(uint64_t tag, unsigned long job_id);
@@ -58,6 +60,18 @@ void _starpu_fxt_display_mpi_transfers(struct starpu_fxt_options *options, int *
 
 
 void _starpu_fxt_write_paje_header(FILE *file);
 void _starpu_fxt_write_paje_header(FILE *file);
 
 
+/*
+ * Animation
+ */
+void _starpu_fxt_component_print_header(FILE *output);
+void _starpu_fxt_component_new(uint64_t component, char *name);
+void _starpu_fxt_component_connect(uint64_t parent, uint64_t child);
+void _starpu_fxt_component_update_ntasks(unsigned nsubmitted, unsigned curq_size);
+void _starpu_fxt_component_push(FILE *output, struct starpu_fxt_options *options, double timestamp, int workerid, uint64_t from, uint64_t to, uint64_t task, unsigned prio);
+void _starpu_fxt_component_pull(FILE *output, struct starpu_fxt_options *options, double timestamp, int workerid, uint64_t from, uint64_t to, uint64_t task, unsigned prio);
+void _starpu_fxt_component_dump(FILE *output);
+void _starpu_fxt_component_finish(FILE *output);
+
 #endif // STARPU_USE_FXT
 #endif // STARPU_USE_FXT
 
 
 #endif // __STARPU__FXT_H__
 #endif // __STARPU__FXT_H__

+ 3 - 4
src/sched_policies/component_best_implementation.c

@@ -75,7 +75,7 @@ static int best_implementation_push_task(struct starpu_sched_component * compone
 {
 {
 	STARPU_ASSERT(component->nchildren == 1);
 	STARPU_ASSERT(component->nchildren == 1);
 	select_best_implementation_and_set_preds(component->tree->sched_ctx_id, component->workers_in_ctx, task);
 	select_best_implementation_and_set_preds(component->tree->sched_ctx_id, component->workers_in_ctx, task);
-	return starpu_sched_component_push_task(component->children[0],task);
+	return starpu_sched_component_push_task(component,component->children[0],task);
 }
 }
 
 
 int starpu_sched_component_is_best_implementation(struct starpu_sched_component * component)
 int starpu_sched_component_is_best_implementation(struct starpu_sched_component * component)
@@ -93,7 +93,7 @@ static struct starpu_task * best_implementation_pull_task(struct starpu_sched_co
 			continue;
 			continue;
 		else
 		else
 		{
 		{
-			task = starpu_sched_component_pull_task(component->parents[i]);
+			task = starpu_sched_component_pull_task(component->parents[i], component);
 			if(task)
 			if(task)
 				break;
 				break;
 		}
 		}
@@ -106,9 +106,8 @@ static struct starpu_task * best_implementation_pull_task(struct starpu_sched_co
 
 
 struct starpu_sched_component * starpu_sched_component_best_implementation_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 struct starpu_sched_component * starpu_sched_component_best_implementation_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "best_impl");
 	component->push_task = best_implementation_push_task;
 	component->push_task = best_implementation_push_task;
 	component->pull_task = best_implementation_pull_task;
 	component->pull_task = best_implementation_pull_task;
-	component->name = "best_implementation";
 	return component;
 	return component;
 }
 }

+ 4 - 5
src/sched_policies/component_composed.c

@@ -120,14 +120,14 @@ struct composed_component create_composed_component(struct starpu_sched_tree *tr
 static int composed_component_push_task(struct starpu_sched_component * component, struct starpu_task * task)
 static int composed_component_push_task(struct starpu_sched_component * component, struct starpu_task * task)
 {
 {
 	struct composed_component *c = component->data;
 	struct composed_component *c = component->data;
-	return starpu_sched_component_push_task(c->top,task);
+	return starpu_sched_component_push_task(component,c->top,task);
 }
 }
 struct starpu_task * composed_component_pull_task(struct starpu_sched_component *component)
 struct starpu_task * composed_component_pull_task(struct starpu_sched_component *component)
 {
 {
 	struct composed_component *c = component->data;
 	struct composed_component *c = component->data;
 	struct starpu_task * task = NULL;
 	struct starpu_task * task = NULL;
 	
 	
-	task = starpu_sched_component_pull_task(c->bottom);
+	task = starpu_sched_component_pull_task(c->bottom,component);
 	if(task)
 	if(task)
 		return task;
 		return task;
 
 
@@ -138,7 +138,7 @@ struct starpu_task * composed_component_pull_task(struct starpu_sched_component
 			continue;
 			continue;
 		else
 		else
 		{
 		{
-			task = starpu_sched_component_pull_task(component->parents[i]);
+			task = starpu_sched_component_pull_task(component->parents[i],component);
 			if(task)
 			if(task)
 				break;
 				break;
 		}
 		}
@@ -209,7 +209,7 @@ struct starpu_sched_component * starpu_sched_component_composed_component_create
 	struct fun_create_component_list * l = &recipe->list;
 	struct fun_create_component_list * l = &recipe->list;
 	if(l->_head == l->_tail)
 	if(l->_head == l->_tail)
 		return l->_head->create_component(tree, l->_head->arg);
 		return l->_head->create_component(tree, l->_head->arg);
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "composed");
 
 
 	struct composed_component * c = malloc(sizeof(struct composed_component));
 	struct composed_component * c = malloc(sizeof(struct composed_component));
 	*c = create_composed_component(tree, recipe
 	*c = create_composed_component(tree, recipe
@@ -229,6 +229,5 @@ struct starpu_sched_component * starpu_sched_component_composed_component_create
 	component->add_child = composed_component_add_child;
 	component->add_child = composed_component_add_child;
 	component->remove_child = composed_component_remove_child;
 	component->remove_child = composed_component_remove_child;
 	component->notify_change_workers = composed_component_notify_change_workers;
 	component->notify_change_workers = composed_component_notify_change_workers;
-	component->name = "composed";
 	return component;
 	return component;
 }
 }

+ 2 - 3
src/sched_policies/component_eager.c

@@ -49,7 +49,7 @@ static int eager_push_task(struct starpu_sched_component * component, struct sta
 								return 1;
 								return 1;
 							}
 							}
 							else
 							else
-								return starpu_sched_component_push_task(component->children[i],task);
+								return starpu_sched_component_push_task(component,component->children[i],task);
 						}
 						}
 					}
 					}
 				}
 				}
@@ -66,9 +66,8 @@ int starpu_sched_component_is_eager(struct starpu_sched_component * component)
 
 
 struct starpu_sched_component * starpu_sched_component_eager_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 struct starpu_sched_component * starpu_sched_component_eager_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "eager");
 	component->push_task = eager_push_task;
 	component->push_task = eager_push_task;
-	component->name = "eager";
 
 
 	return component;
 	return component;
 }
 }

+ 2 - 3
src/sched_policies/component_eager_calibration.c

@@ -61,7 +61,7 @@ static int eager_calibration_push_task(struct starpu_sched_component * component
 									return 1;
 									return 1;
 								}
 								}
 								else
 								else
-									return starpu_sched_component_push_task(component->children[i],task);
+									return starpu_sched_component_push_task(component,component->children[i],task);
 							}
 							}
 						}
 						}
 					}
 					}
@@ -79,9 +79,8 @@ int starpu_sched_component_is_eager_calibration(struct starpu_sched_component *
 
 
 struct starpu_sched_component * starpu_sched_component_eager_calibration_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 struct starpu_sched_component * starpu_sched_component_eager_calibration_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "eager_calibration");
 	component->push_task = eager_calibration_push_task;
 	component->push_task = eager_calibration_push_task;
-	component->name = "eager_calibration";
 
 
 	return component;
 	return component;
 }
 }

+ 5 - 6
src/sched_policies/component_fifo.c

@@ -214,17 +214,17 @@ static int fifo_can_push(struct starpu_sched_component * component)
 	STARPU_ASSERT(component->nchildren == 1);
 	STARPU_ASSERT(component->nchildren == 1);
 	struct starpu_sched_component * child = component->children[0];
 	struct starpu_sched_component * child = component->children[0];
 
 
-	struct starpu_task * task = starpu_sched_component_pull_task(component);
+	struct starpu_task * task = starpu_sched_component_pull_task(component,NULL);
 	if(task)
 	if(task)
-		ret = starpu_sched_component_push_task(child,task);	
+		ret = starpu_sched_component_push_task(NULL,child,task);	
 	while(task && !ret) 
 	while(task && !ret) 
 	{
 	{
 		if(!res)
 		if(!res)
 			res = 1;
 			res = 1;
 
 
-		task = starpu_sched_component_pull_task(component);
+		task = starpu_sched_component_pull_task(component,NULL);
 		if(task)
 		if(task)
-			ret = starpu_sched_component_push_task(child,task);	
+			ret = starpu_sched_component_push_task(NULL,child,task);	
 	}
 	}
 	if(task && ret)
 	if(task && ret)
 		fifo_push_local_task(component,task,1); 
 		fifo_push_local_task(component,task,1); 
@@ -239,7 +239,7 @@ int starpu_sched_component_is_fifo(struct starpu_sched_component * component)
 
 
 struct starpu_sched_component * starpu_sched_component_fifo_create(struct starpu_sched_tree *tree, struct starpu_sched_component_fifo_data * params)
 struct starpu_sched_component * starpu_sched_component_fifo_create(struct starpu_sched_tree *tree, struct starpu_sched_component_fifo_data * params)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "fifo");
 	struct _starpu_fifo_data * data = malloc(sizeof(*data));
 	struct _starpu_fifo_data * data = malloc(sizeof(*data));
 	data->fifo = _starpu_create_fifo();
 	data->fifo = _starpu_create_fifo();
 	STARPU_PTHREAD_MUTEX_INIT(&data->mutex,NULL);
 	STARPU_PTHREAD_MUTEX_INIT(&data->mutex,NULL);
@@ -250,7 +250,6 @@ struct starpu_sched_component * starpu_sched_component_fifo_create(struct starpu
 	component->pull_task = fifo_pull_task;
 	component->pull_task = fifo_pull_task;
 	component->can_push = fifo_can_push;
 	component->can_push = fifo_can_push;
 	component->deinit_data = fifo_component_deinit_data;
 	component->deinit_data = fifo_component_deinit_data;
-	component->name = "fifo";
 
 
 	if(params)
 	if(params)
 	{
 	{

+ 2 - 3
src/sched_policies/component_heft.c

@@ -153,7 +153,7 @@ static int heft_progress_one(struct starpu_sched_component *component)
 			return 1;
 			return 1;
 		}
 		}
 
 
-		int ret = starpu_sched_component_push_task(best_component, tasks[best_task]);
+		int ret = starpu_sched_component_push_task(component, best_component, tasks[best_task]);
 
 
 		if (ret)
 		if (ret)
 		{
 		{
@@ -226,7 +226,7 @@ int starpu_sched_component_is_heft(struct starpu_sched_component * component)
 
 
 struct starpu_sched_component * starpu_sched_component_heft_create(struct starpu_sched_tree *tree, struct starpu_sched_component_mct_data * params)
 struct starpu_sched_component * starpu_sched_component_heft_create(struct starpu_sched_tree *tree, struct starpu_sched_component_mct_data * params)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "heft");
 	struct _starpu_mct_data *mct_data = starpu_mct_init_parameters(params);
 	struct _starpu_mct_data *mct_data = starpu_mct_init_parameters(params);
 	struct _starpu_heft_data *data = malloc(sizeof(*data));
 	struct _starpu_heft_data *data = malloc(sizeof(*data));
 
 
@@ -238,7 +238,6 @@ struct starpu_sched_component * starpu_sched_component_heft_create(struct starpu
 	component->push_task = heft_push_task;
 	component->push_task = heft_push_task;
 	component->can_push = heft_can_push;
 	component->can_push = heft_can_push;
 	component->deinit_data = heft_component_deinit_data;
 	component->deinit_data = heft_component_deinit_data;
-	component->name = "heft";
 
 
 	return component;
 	return component;
 }
 }

+ 2 - 3
src/sched_policies/component_mct.c

@@ -99,7 +99,7 @@ static int mct_push_task(struct starpu_sched_component * component, struct starp
 		return 1;
 		return 1;
 	}
 	}
 
 
-	int ret = starpu_sched_component_push_task(best_component, task);
+	int ret = starpu_sched_component_push_task(component, best_component, task);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -117,14 +117,13 @@ int starpu_sched_component_is_mct(struct starpu_sched_component * component)
 
 
 struct starpu_sched_component * starpu_sched_component_mct_create(struct starpu_sched_tree *tree, struct starpu_sched_component_mct_data * params)
 struct starpu_sched_component * starpu_sched_component_mct_create(struct starpu_sched_tree *tree, struct starpu_sched_component_mct_data * params)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "mct");
 	struct _starpu_mct_data *data = starpu_mct_init_parameters(params);
 	struct _starpu_mct_data *data = starpu_mct_init_parameters(params);
 
 
 	component->data = data;
 	component->data = data;
 
 
 	component->push_task = mct_push_task;
 	component->push_task = mct_push_task;
 	component->deinit_data = mct_component_deinit_data;
 	component->deinit_data = mct_component_deinit_data;
-	component->name = "mct";
 
 
 	return component;
 	return component;
 }
 }

+ 4 - 5
src/sched_policies/component_perfmodel_select.c

@@ -44,10 +44,10 @@ static int perfmodel_select_push_task(struct starpu_sched_component * component,
 	if(can_execute)
 	if(can_execute)
 	{
 	{
 		if(isnan(length))
 		if(isnan(length))
-			return starpu_sched_component_push_task(data->calibrator_component,task);
+			return starpu_sched_component_push_task(component,data->calibrator_component,task);
 		if(_STARPU_IS_ZERO(length))
 		if(_STARPU_IS_ZERO(length))
-			return starpu_sched_component_push_task(data->no_perfmodel_component,task);
-		return starpu_sched_component_push_task(data->perfmodel_component,task);
+			return starpu_sched_component_push_task(component,data->no_perfmodel_component,task);
+		return starpu_sched_component_push_task(component,data->perfmodel_component,task);
 	}
 	}
 	else
 	else
 		return 1;
 		return 1;
@@ -70,7 +70,7 @@ struct starpu_sched_component * starpu_sched_component_perfmodel_select_create(s
 {
 {
 	STARPU_ASSERT(params);
 	STARPU_ASSERT(params);
 	STARPU_ASSERT(params->calibrator_component && params->no_perfmodel_component && params->perfmodel_component);
 	STARPU_ASSERT(params->calibrator_component && params->no_perfmodel_component && params->perfmodel_component);
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "perfmodel_selector");
 
 
 	struct _starpu_perfmodel_select_data * data = malloc(sizeof(*data));
 	struct _starpu_perfmodel_select_data * data = malloc(sizeof(*data));
 	data->calibrator_component = params->calibrator_component;
 	data->calibrator_component = params->calibrator_component;
@@ -80,7 +80,6 @@ struct starpu_sched_component * starpu_sched_component_perfmodel_select_create(s
 	component->data = data;
 	component->data = data;
 	component->push_task = perfmodel_select_push_task;
 	component->push_task = perfmodel_select_push_task;
 	component->deinit_data = perfmodel_select_component_deinit_data;
 	component->deinit_data = perfmodel_select_component_deinit_data;
-	component->name = "perfmodel_selector";
 
 
 	return component;
 	return component;
 }
 }

+ 5 - 6
src/sched_policies/component_prio.c

@@ -236,17 +236,17 @@ static int prio_can_push(struct starpu_sched_component * component)
 	STARPU_ASSERT(component->nchildren == 1);
 	STARPU_ASSERT(component->nchildren == 1);
 	struct starpu_sched_component * child = component->children[0];
 	struct starpu_sched_component * child = component->children[0];
 
 
-	struct starpu_task * task = starpu_sched_component_pull_task(component);
+	struct starpu_task * task = starpu_sched_component_pull_task(component, component);
 	if(task)
 	if(task)
-		ret = starpu_sched_component_push_task(child,task);	
+		ret = starpu_sched_component_push_task(component,child,task);	
 	while(task && !ret) 
 	while(task && !ret) 
 	{
 	{
 		if(!res)
 		if(!res)
 			res = 1;
 			res = 1;
 
 
-		task = starpu_sched_component_pull_task(component);
+		task = starpu_sched_component_pull_task(component,component);
 		if(task)
 		if(task)
-			ret = starpu_sched_component_push_task(child,task);	
+			ret = starpu_sched_component_push_task(component,child,task);	
 	}
 	}
 	if(task && ret)
 	if(task && ret)
 		prio_push_local_task(component,task,1); 
 		prio_push_local_task(component,task,1); 
@@ -261,7 +261,7 @@ int starpu_sched_component_is_prio(struct starpu_sched_component * component)
 
 
 struct starpu_sched_component * starpu_sched_component_prio_create(struct starpu_sched_tree *tree, struct starpu_sched_component_prio_data * params)
 struct starpu_sched_component * starpu_sched_component_prio_create(struct starpu_sched_tree *tree, struct starpu_sched_component_prio_data * params)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "prio");
 	struct _starpu_prio_data * data = malloc(sizeof(*data));
 	struct _starpu_prio_data * data = malloc(sizeof(*data));
 	_starpu_prio_deque_init(&data->prio);
 	_starpu_prio_deque_init(&data->prio);
 	STARPU_PTHREAD_MUTEX_INIT(&data->mutex,NULL);
 	STARPU_PTHREAD_MUTEX_INIT(&data->mutex,NULL);
@@ -273,7 +273,6 @@ struct starpu_sched_component * starpu_sched_component_prio_create(struct starpu
 	component->can_push = prio_can_push;
 	component->can_push = prio_can_push;
 	component->deinit_data = prio_component_deinit_data;
 	component->deinit_data = prio_component_deinit_data;
 
 
-	component->name = "prio";
 	if(params)
 	if(params)
 	{
 	{
 		data->ntasks_threshold=params->ntasks_threshold;
 		data->ntasks_threshold=params->ntasks_threshold;

+ 2 - 3
src/sched_policies/component_random.c

@@ -90,7 +90,7 @@ static int random_push_task(struct starpu_sched_component * component, struct st
 		return 1;
 		return 1;
 	}
 	}
 
 
-	int ret_val = starpu_sched_component_push_task(select,task);
+	int ret_val = starpu_sched_component_push_task(component,select,task);
 	return ret_val;
 	return ret_val;
 }
 }
 
 
@@ -113,9 +113,8 @@ int starpu_sched_component_is_random(struct starpu_sched_component *component)
 
 
 struct starpu_sched_component * starpu_sched_component_random_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 struct starpu_sched_component * starpu_sched_component_random_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "random");
 	component->estimated_end = random_estimated_end;
 	component->estimated_end = random_estimated_end;
 	component->push_task = random_push_task;
 	component->push_task = random_push_task;
-	component->name = "random";
 	return component;
 	return component;
 }
 }

+ 16 - 9
src/sched_policies/component_sched.c

@@ -192,6 +192,7 @@ void starpu_sched_component_destroy(struct starpu_sched_component *component)
 	component->deinit_data(component);
 	component->deinit_data(component);
 	free(component->children);
 	free(component->children);
 	free(component->parents);
 	free(component->parents);
+	free(component->name);
 	starpu_bitmap_destroy(component->workers);
 	starpu_bitmap_destroy(component->workers);
 	starpu_bitmap_destroy(component->workers_in_ctx);
 	starpu_bitmap_destroy(component->workers_in_ctx);
 	free(component);
 	free(component);
@@ -326,6 +327,7 @@ void starpu_sched_component_connect(struct starpu_sched_component *parent, struc
 {
 {
 	parent->add_child(parent, child);
 	parent->add_child(parent, child);
 	child->add_parent(child, parent);
 	child->add_parent(child, parent);
+	_STARPU_TRACE_SCHED_COMPONENT_CONNECT(parent,child);
 }
 }
 
 
 int starpu_sched_tree_push_task(struct starpu_task * task)
 int starpu_sched_tree_push_task(struct starpu_task * task)
@@ -334,14 +336,15 @@ int starpu_sched_tree_push_task(struct starpu_task * task)
 	unsigned sched_ctx_id = task->sched_ctx;
 	unsigned sched_ctx_id = task->sched_ctx;
 	struct starpu_sched_tree *tree = starpu_sched_ctx_get_policy_data(sched_ctx_id);
 	struct starpu_sched_tree *tree = starpu_sched_ctx_get_policy_data(sched_ctx_id);
 
 
-	int ret_val = starpu_sched_component_push_task(tree->root,task);
+	int ret_val = starpu_sched_component_push_task(NULL, tree->root,task);
 	
 	
 	return ret_val;
 	return ret_val;
 }
 }
 
 
-int starpu_sched_component_push_task(struct starpu_sched_component *component, struct starpu_task *task)
+int starpu_sched_component_push_task(struct starpu_sched_component *from STARPU_ATTRIBUTE_UNUSED, struct starpu_sched_component *to, struct starpu_task *task)
 {
 {
-	return component->push_task(component, task);
+	_STARPU_TRACE_SCHED_COMPONENT_PUSH(from, to, task);
+	return to->push_task(to, task);
 }
 }
 
 
 struct starpu_task * starpu_sched_tree_pop_task(unsigned sched_ctx)
 struct starpu_task * starpu_sched_tree_pop_task(unsigned sched_ctx)
@@ -351,13 +354,16 @@ struct starpu_task * starpu_sched_tree_pop_task(unsigned sched_ctx)
 
 
 	/* _starpu_sched_component_lock_worker(workerid) is called by component->pull_task()
 	/* _starpu_sched_component_lock_worker(workerid) is called by component->pull_task()
 	 */
 	 */
-	struct starpu_task * task = starpu_sched_component_pull_task(component);
+	struct starpu_task * task = starpu_sched_component_pull_task(component,NULL);
 	return task;
 	return task;
 }
 }
 
 
-struct starpu_task * starpu_sched_component_pull_task(struct starpu_sched_component *component)
+struct starpu_task * starpu_sched_component_pull_task(struct starpu_sched_component *from, struct starpu_sched_component *to STARPU_ATTRIBUTE_UNUSED)
 {
 {
-	return component->pull_task(component);
+	struct starpu_task *task = from->pull_task(from);
+	if (task)
+		_STARPU_TRACE_SCHED_COMPONENT_PULL(from, to, task);
+	return task;
 }
 }
 
 
 void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers)
 void starpu_sched_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers)
@@ -505,7 +511,7 @@ static struct starpu_task * starpu_sched_component_parents_pull_task(struct star
 			continue;
 			continue;
 		else
 		else
 		{
 		{
-			task = starpu_sched_component_pull_task(component->parents[i]);
+			task = starpu_sched_component_pull_task(component->parents[i], component);
 			if(task)
 			if(task)
 				break;
 				break;
 		}
 		}
@@ -579,7 +585,7 @@ static void take_component_and_does_nothing(struct starpu_sched_component * comp
 {
 {
 }
 }
 
 
-struct starpu_sched_component * starpu_sched_component_create(struct starpu_sched_tree *tree)
+struct starpu_sched_component * starpu_sched_component_create(struct starpu_sched_tree *tree, const char *name)
 {
 {
 	struct starpu_sched_component * component = malloc(sizeof(*component));
 	struct starpu_sched_component * component = malloc(sizeof(*component));
 	memset(component,0,sizeof(*component));
 	memset(component,0,sizeof(*component));
@@ -597,6 +603,7 @@ struct starpu_sched_component * starpu_sched_component_create(struct starpu_sche
 	component->estimated_end = starpu_sched_component_estimated_end_min;
 	component->estimated_end = starpu_sched_component_estimated_end_min;
 	component->deinit_data = take_component_and_does_nothing;
 	component->deinit_data = take_component_and_does_nothing;
 	component->notify_change_workers = take_component_and_does_nothing;
 	component->notify_change_workers = take_component_and_does_nothing;
-	component->name = "sched";
+	component->name = strdup(name);
+	_STARPU_TRACE_SCHED_COMPONENT_NEW(component);
 	return component;
 	return component;
 }
 }

+ 3 - 4
src/sched_policies/component_work_stealing.c

@@ -161,7 +161,7 @@ static struct starpu_task * pull_task(struct starpu_sched_component * component)
 			continue;
 			continue;
 		else
 		else
 		{
 		{
-			task = starpu_sched_component_pull_task(component->parents[i]);
+			task = starpu_sched_component_pull_task(component->parents[i],component);
 			if(task)
 			if(task)
 				break;
 				break;
 		}
 		}
@@ -319,7 +319,7 @@ void _ws_remove_child(struct starpu_sched_component * component, struct starpu_s
 	struct starpu_task * task;
 	struct starpu_task * task;
 	while((task = _starpu_prio_deque_pop_task(tmp_fifo)))
 	while((task = _starpu_prio_deque_pop_task(tmp_fifo)))
 	{
 	{
-		starpu_sched_component_push_task(component, task);
+		starpu_sched_component_push_task(NULL, component, task);
 	}
 	}
 	_starpu_prio_deque_destroy(tmp_fifo);
 	_starpu_prio_deque_destroy(tmp_fifo);
 	free(tmp_fifo);
 	free(tmp_fifo);
@@ -337,7 +337,7 @@ int starpu_sched_component_is_work_stealing(struct starpu_sched_component * comp
 
 
 struct starpu_sched_component * starpu_sched_component_work_stealing_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 struct starpu_sched_component * starpu_sched_component_work_stealing_create(struct starpu_sched_tree *tree, void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 {
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "work_stealing");
 	struct _starpu_work_stealing_data * wsd = malloc(sizeof(*wsd));
 	struct _starpu_work_stealing_data * wsd = malloc(sizeof(*wsd));
 	memset(wsd, 0, sizeof(*wsd));
 	memset(wsd, 0, sizeof(*wsd));
 	component->pull_task = pull_task;
 	component->pull_task = pull_task;
@@ -348,6 +348,5 @@ struct starpu_sched_component * starpu_sched_component_work_stealing_create(stru
 	component->estimated_load = _ws_estimated_load;
 	component->estimated_load = _ws_estimated_load;
 	component->deinit_data = _work_stealing_component_deinit_data;
 	component->deinit_data = _work_stealing_component_deinit_data;
 	component->data = wsd;
 	component->data = wsd;
-	component->name = "work_stealing";
 	return  component;
 	return  component;
 }
 }

+ 6 - 6
src/sched_policies/component_worker.c

@@ -501,7 +501,7 @@ static struct starpu_task * simple_worker_pull_task(struct starpu_sched_componen
 			else
 			else
 			{
 			{
 				_starpu_sched_component_worker_unlock_scheduling(component->tree->sched_ctx_id);
 				_starpu_sched_component_worker_unlock_scheduling(component->tree->sched_ctx_id);
-				task = starpu_sched_component_pull_task(component->parents[i]);
+				task = starpu_sched_component_pull_task(component->parents[i],component);
 				_starpu_sched_component_worker_lock_scheduling(component->tree->sched_ctx_id);
 				_starpu_sched_component_worker_lock_scheduling(component->tree->sched_ctx_id);
 				if(task)
 				if(task)
 					break;
 					break;
@@ -521,7 +521,7 @@ static struct starpu_task * simple_worker_pull_task(struct starpu_sched_componen
 			return task;
 			return task;
 		}
 		}
 		struct starpu_sched_component * combined_worker_component = starpu_sched_component_worker_get(component->tree->sched_ctx_id, workerid);
 		struct starpu_sched_component * combined_worker_component = starpu_sched_component_worker_get(component->tree->sched_ctx_id, workerid);
-		starpu_sched_component_push_task(combined_worker_component, task);
+		starpu_sched_component_push_task(component, combined_worker_component, task);
 		/* we have pushed a task in queue, so can make a recursive call */
 		/* we have pushed a task in queue, so can make a recursive call */
 		return simple_worker_pull_task(component);
 		return simple_worker_pull_task(component);
 
 
@@ -588,7 +588,9 @@ static struct starpu_sched_component * starpu_sched_component_worker_create(stru
 	struct _starpu_worker * worker = _starpu_get_worker_struct(workerid);
 	struct _starpu_worker * worker = _starpu_get_worker_struct(workerid);
 	if(worker == NULL)
 	if(worker == NULL)
 		return NULL;
 		return NULL;
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	char name[32];
+	snprintf(name, sizeof(name), "worker %u", workerid);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, name);
 	struct _starpu_worker_component_data * data = malloc(sizeof(*data));
 	struct _starpu_worker_component_data * data = malloc(sizeof(*data));
 	memset(data, 0, sizeof(*data));
 	memset(data, 0, sizeof(*data));
 
 
@@ -607,7 +609,6 @@ static struct starpu_sched_component * starpu_sched_component_worker_create(stru
 	starpu_bitmap_set(component->workers, workerid);
 	starpu_bitmap_set(component->workers, workerid);
 	starpu_bitmap_or(component->workers_in_ctx, component->workers);
 	starpu_bitmap_or(component->workers_in_ctx, component->workers);
 	_worker_components[tree->sched_ctx_id][workerid] = component;
 	_worker_components[tree->sched_ctx_id][workerid] = component;
-	component->name = "worker";
 
 
 	/*
 	/*
 #ifdef STARPU_HAVE_HWLOC
 #ifdef STARPU_HAVE_HWLOC
@@ -770,7 +771,7 @@ static struct starpu_sched_component  * starpu_sched_component_combined_worker_c
 	struct _starpu_combined_worker * combined_worker = _starpu_get_combined_worker_struct(workerid);
 	struct _starpu_combined_worker * combined_worker = _starpu_get_combined_worker_struct(workerid);
 	if(combined_worker == NULL)
 	if(combined_worker == NULL)
 		return NULL;
 		return NULL;
-	struct starpu_sched_component * component = starpu_sched_component_create(tree);
+	struct starpu_sched_component * component = starpu_sched_component_create(tree, "combined_worker");
 	struct _starpu_worker_component_data * data = malloc(sizeof(*data));
 	struct _starpu_worker_component_data * data = malloc(sizeof(*data));
 	memset(data, 0, sizeof(*data));
 	memset(data, 0, sizeof(*data));
 	data->combined_worker = combined_worker;
 	data->combined_worker = combined_worker;
@@ -786,7 +787,6 @@ static struct starpu_sched_component  * starpu_sched_component_combined_worker_c
 	starpu_bitmap_set(component->workers, workerid);
 	starpu_bitmap_set(component->workers, workerid);
 	starpu_bitmap_or(component->workers_in_ctx, component->workers);
 	starpu_bitmap_or(component->workers_in_ctx, component->workers);
 	_worker_components[tree->sched_ctx_id][workerid] = component;
 	_worker_components[tree->sched_ctx_id][workerid] = component;
-	component->name = "combined worker";
 
 
 #ifdef STARPU_HAVE_HWLOC
 #ifdef STARPU_HAVE_HWLOC
 	struct _starpu_machine_config *config = _starpu_get_machine_config();
 	struct _starpu_machine_config *config = _starpu_get_machine_config();

+ 2 - 2
src/sched_policies/modular_heft.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
- * Copyright (C) 2013-2014  Université de Bordeaux
+ * Copyright (C) 2013-2015  Université de Bordeaux
  * Copyright (C) 2013  INRIA
  * Copyright (C) 2013  INRIA
  * Copyright (C) 2013  Simon Archipoff
  * Copyright (C) 2013  Simon Archipoff
  *
  *
@@ -87,8 +87,8 @@ static void initialize_heft_center_policy(unsigned sched_ctx_id)
 	t->root = window_component;
 	t->root = window_component;
 	starpu_sched_component_connect(window_component, perfmodel_select_component);
 	starpu_sched_component_connect(window_component, perfmodel_select_component);
 
 
-	starpu_sched_component_connect(perfmodel_select_component, calibrator_component);
 	starpu_sched_component_connect(perfmodel_select_component, perfmodel_component);
 	starpu_sched_component_connect(perfmodel_select_component, perfmodel_component);
+	starpu_sched_component_connect(perfmodel_select_component, calibrator_component);
 	starpu_sched_component_connect(perfmodel_select_component, no_perfmodel_component);
 	starpu_sched_component_connect(perfmodel_select_component, no_perfmodel_component);
 
 
 	struct starpu_sched_component_prio_data prio_data =
 	struct starpu_sched_component_prio_data prio_data =

+ 2 - 2
src/sched_policies/modular_heft2.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
- * Copyright (C) 2013-2014  Université de Bordeaux
+ * Copyright (C) 2013-2015  Université de Bordeaux
  * Copyright (C) 2013  INRIA
  * Copyright (C) 2013  INRIA
  * Copyright (C) 2013  Simon Archipoff
  * Copyright (C) 2013  Simon Archipoff
  *
  *
@@ -61,8 +61,8 @@ static void initialize_heft2_center_policy(unsigned sched_ctx_id)
 	t->root = window_component;
 	t->root = window_component;
 	starpu_sched_component_connect(window_component, perfmodel_select_component);
 	starpu_sched_component_connect(window_component, perfmodel_select_component);
 
 
-	starpu_sched_component_connect(perfmodel_select_component, calibrator_component);
 	starpu_sched_component_connect(perfmodel_select_component, perfmodel_component);
 	starpu_sched_component_connect(perfmodel_select_component, perfmodel_component);
+	starpu_sched_component_connect(perfmodel_select_component, calibrator_component);
 	starpu_sched_component_connect(perfmodel_select_component, no_perfmodel_component);
 	starpu_sched_component_connect(perfmodel_select_component, no_perfmodel_component);
 
 
 	struct starpu_sched_component_prio_data prio_data =
 	struct starpu_sched_component_prio_data prio_data =