Browse Source

Factorize modular scheduler creation. Add example of modular scheduling policy

Samuel Thibault 7 years ago
parent
commit
82900d839f

+ 55 - 1
doc/doxygen/chapters/api/modularized_scheduler.doxy

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2014                                Inria
  * Copyright (C) 2014-2017                                CNRS
- * Copyright (C) 2009-2011,2014-2015,2017                 Université de Bordeaux
+ * Copyright (C) 2009-2011,2014-2015,2017-2018                 Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -475,6 +475,60 @@ todo
 \ingroup API_Modularized_Scheduler
 	 this function build a scheduler for \p sched_ctx_id according to \p s and the hwloc topology of the machine.
 
+\def STARPU_SCHED_SIMPLE_DECIDE_WORKERS
+\ingroup API_Modularized_Scheduler
+Request to create downstream queues per worker, i.e. the scheduling decision-making component will choose exactly which workers tasks should got to.
+
+\def STARPU_SCHED_SIMPLE_DECIDE_MEMNODES
+\ingroup API_Modularized_Scheduler
+Request to create downstream queues per memory nodes, i.e. the scheduling decision-making component will choose which memory node tasks will go to.
+
+\def STARPU_SCHED_SIMPLE_DECIDE_ARCHS
+\ingroup API_Modularized_Scheduler
+Request to create downstream queues per computation arch, i.e. the scheduling decision-making component will choose whether tasks go to CPUs, or CUDA, or OpenCL, etc.
+
+\def STARPU_SCHED_SIMPLE_PERFMODEL
+\ingroup API_Modularized_Scheduler
+Request to add a perfmodel selector above the scheduling decision-making component. That way, only tasks with a calibrated performance model will be given to the component, other tasks will go to an eager branch that will distributed tasks so that their performance models will get calibrated.
+
+In other words, this is needed when using a component which needs performance models for tasks.
+
+\def STARPU_SCHED_SIMPLE_FIFO_ABOVE
+\ingroup API_Modularized_Scheduler
+Request to create a fifo above the scheduling decision-making component, otherwise tasks will be pushed directly to the component.
+
+This is useful to store tasks if there is a fifo below which limits the number of tasks to be scheduld in advance. The scheduling decision-making component can also store tasks itself, in which case this flag is not useful.
+
+\def STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO
+\ingroup API_Modularized_Scheduler
+Request that the fifo above be sorted by priorities
+
+\def STARPU_SCHED_SIMPLE_FIFOS_BELOW
+\ingroup API_Modularized_Scheduler
+Request to create fifos below the scheduling decision-making component, otherwise tasks will be pulled directly from workers.
+
+This is useful to be able to schedule a (tunable) small number of tasks in advance only.
+
+\def STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO
+\ingroup API_Modularized_Scheduler
+Request that the fifos below be sorted by priorities
+
+\def STARPU_SCHED_SIMPLE_WS_BELOW
+\ingroup API_Modularized_Scheduler
+Request that work between workers using the same fifo below be distributed using a work stealing component.
+
+\def STARPU_SCHED_SIMPLE_IMPL
+\ingroup API_Modularized_Scheduler
+Request that a component be added just above workers, that chooses the best task implementation.
+
+\fn void starpu_sched_component_initialize_simple_scheduler(starpu_sched_component_create_t create_decision_component, void *data, unsigned flags, unsigned sched_ctx_id)
+\ingroup API_Modularized_Scheduler
+This creates a simple modular scheduler tree around a scheduling decision-making
+component \p component. The details of what should be built around \p component
+is described by \p flags. The different STARPU_SCHED_SIMPL_DECIDE_* flags are
+mutually exclusive. \p data is passed to the \p create_decision_component
+function when creating the decision component.
+
 \fn int starpu_sched_component_push_task(struct starpu_sched_component *from, struct starpu_sched_component *to, struct starpu_task *task)
 \ingroup API_Modularized_Scheduler
 Push a task to a component. This is a helper for <c>component->push_task(component, task)</c> plus tracing.

+ 1 - 0
examples/Makefile.am

@@ -203,6 +203,7 @@ STARPU_EXAMPLES =
 STARPU_EXAMPLES +=				\
 	sched_ctx/prio				\
 	scheduler/dummy_sched			\
+	scheduler/dummy_modular_sched		\
 	worker_collections/worker_list_example
 
 if !STARPU_SIMGRID

+ 264 - 0
examples/scheduler/dummy_modular_sched.c

@@ -0,0 +1,264 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2012-2013,2015                           Inria
+ * Copyright (C) 2010-2018                                Université de Bordeaux
+ * Copyright (C) 2010-2013,2015-2017                      CNRS
+ *
+ * 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.
+ */
+
+/*
+ * This is an example of an application-defined scheduler.
+ * This is a mere eager scheduler with a centralized list of tasks to schedule:
+ * when a task becomes ready (push) it is put on the list. When a device
+ * becomes ready (pop), a task is taken from the list.
+ */
+#include <starpu.h>
+#include <starpu_scheduler.h>
+#include <starpu_sched_component.h>
+
+#ifdef STARPU_QUICK_CHECK
+#define NTASKS	320
+#elif !defined(STARPU_LONG_CHECK)
+#define NTASKS	3200
+#else
+#define NTASKS	32000
+#endif
+#define FPRINTF(ofile, fmt, ...) do { if (!getenv("STARPU_SSILENT")) {fprintf(ofile, fmt, ## __VA_ARGS__); }} while(0)
+
+struct dummy_sched_params
+{
+	int verbose;
+};
+
+struct dummy_sched_data
+{
+	int verbose;
+	struct starpu_task_list sched_list;
+     	starpu_pthread_mutex_t policy_mutex;
+};
+
+static void dummy_deinit_data(struct starpu_sched_component * component)
+{
+	struct dummy_sched_data *data = component->data;
+
+	STARPU_ASSERT(starpu_task_list_empty(&data->sched_list));
+
+	if (data->verbose)
+		fprintf(stderr, "Destroying Dummy scheduler\n");
+
+	STARPU_PTHREAD_MUTEX_DESTROY(&data->policy_mutex);
+	free(data);
+}
+
+static int dummy_push_task(struct starpu_sched_component *component, struct starpu_task *task)
+{
+	struct dummy_sched_data *data = component->data;
+	if (data->verbose)
+		fprintf(stderr, "pushing task %p\n", task);
+
+	/* NB: In this simplistic strategy, we assume that the context in which
+	   we push task has at least one worker*/
+
+	/* lock all workers when pushing tasks on a list where all
+	   of them would pop for tasks */
+        STARPU_PTHREAD_MUTEX_LOCK(&data->policy_mutex);
+
+	starpu_task_list_push_front(&data->sched_list, task);
+
+	starpu_push_task_end(task);
+	STARPU_PTHREAD_MUTEX_UNLOCK(&data->policy_mutex);
+
+	/* Tell below that they can now pull */
+	component->can_pull(component);
+
+	return 0;
+}
+
+static struct starpu_task *dummy_pull_task(struct starpu_sched_component *component, struct starpu_sched_component *to)
+{
+	struct dummy_sched_data *data = component->data;
+	if (data->verbose)
+		fprintf(stderr, "%p pulling for a task\n", to);
+
+#ifdef STARPU_NON_BLOCKING_DRIVERS
+	if (starpu_task_list_empty(&data->sched_list))
+		return NULL;
+#endif
+	STARPU_PTHREAD_MUTEX_LOCK(&data->policy_mutex);
+	struct starpu_task *task = NULL;
+	if (!starpu_task_list_empty(&data->sched_list))
+		task = starpu_task_list_pop_back(&data->sched_list);
+	STARPU_PTHREAD_MUTEX_UNLOCK(&data->policy_mutex);
+
+	return task;
+}
+
+static int dummy_can_push(struct starpu_sched_component * component, struct starpu_sched_component * to)
+{
+	struct dummy_sched_data *data = component->data;
+	int didwork = 0;
+
+	if (data->verbose)
+		fprintf(stderr, "%p tells me I can push to him\n", to);
+
+	struct starpu_task *task;
+	task = starpu_sched_component_pump_to(component, to, &didwork);
+
+	if (task)
+	{
+		if (data->verbose)
+			fprintf(stderr, "oops, %p couldn't take our task\n", to);
+		/* Oops, we couldn't push everything, put back this task */
+		STARPU_PTHREAD_MUTEX_LOCK(&data->policy_mutex);
+		starpu_task_list_push_back(&data->sched_list, task);
+		STARPU_PTHREAD_MUTEX_UNLOCK(&data->policy_mutex);
+	}
+	else
+	{
+		if (data->verbose)
+		{
+			if (didwork)
+				fprintf(stderr, "pushed some tasks to %p\n", to);
+			else
+				fprintf(stderr, "I didn't have anything for %p\n", to);
+		}
+	}
+
+	/* There is room now */
+	return didwork || starpu_sched_component_can_push(component, to);
+}
+
+static int dummy_can_pull(struct starpu_sched_component * component)
+{
+	struct dummy_sched_data *data = component->data;
+
+	if (data->verbose)
+		fprintf(stderr,"telling below they can pull\n");
+
+	return starpu_sched_component_can_pull(component);
+}
+
+struct starpu_sched_component *dummy_create(struct starpu_sched_tree *tree, struct dummy_sched_params *params)
+{
+	struct starpu_sched_component *component = starpu_sched_component_create(tree, "dummy");
+	struct dummy_sched_data *data = malloc(sizeof(*data));
+
+	STARPU_PTHREAD_MUTEX_INIT(&data->policy_mutex, NULL);
+	/* Create a linked-list of tasks and a condition variable to protect it */
+	starpu_task_list_init(&data->sched_list);
+	data->verbose = params->verbose;
+
+	component->data = data;
+	component->push_task = dummy_push_task;
+	component->pull_task = dummy_pull_task;
+	component->can_push = dummy_can_push;
+	component->can_pull = dummy_can_pull;
+	component->deinit_data = dummy_deinit_data;
+
+	return component;
+}
+
+static void init_dummy_sched(unsigned sched_ctx_id)
+{
+	FPRINTF(stderr, "Initialising Dummy scheduler\n");
+
+	struct dummy_sched_params params = {
+		.verbose = 1,
+	};
+
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) dummy_create, &params,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO,
+			sched_ctx_id);
+}
+
+static void deinit_dummy_sched(unsigned sched_ctx_id)
+{
+	struct starpu_sched_tree *t = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	starpu_sched_tree_destroy(t);
+}
+
+static struct starpu_sched_policy dummy_sched_policy =
+{
+	.init_sched = init_dummy_sched,
+	.deinit_sched = deinit_dummy_sched,
+	.add_workers = starpu_sched_tree_add_workers,
+	.remove_workers = starpu_sched_tree_remove_workers,
+	.push_task = starpu_sched_tree_push_task,
+	.pop_task = starpu_sched_tree_pop_task,
+	.pre_exec_hook = starpu_sched_component_worker_pre_exec_hook,
+	.post_exec_hook = starpu_sched_component_worker_post_exec_hook,
+	.pop_every_task = NULL,
+	.policy_name = "dummy",
+	.policy_description = "dummy modular scheduling strategy",
+	.worker_type = STARPU_WORKER_LIST,
+};
+
+void dummy_func(void *descr[], void *arg)
+{
+	(void)descr;
+	(void)arg;
+}
+
+static struct starpu_codelet dummy_codelet =
+{
+	.cpu_funcs = {dummy_func},
+	.cpu_funcs_name = {"dummy_func"},
+	.cuda_funcs = {dummy_func},
+        .opencl_funcs = {dummy_func},
+	.model = &starpu_perfmodel_nop,
+	.nbuffers = 0,
+	.name = "dummy",
+};
+
+
+int main(void)
+{
+	int ntasks = 4;
+	int ret;
+	struct starpu_conf conf;
+
+#ifdef STARPU_HAVE_UNSETENV
+	unsetenv("STARPU_SCHED");
+#endif
+
+	starpu_conf_init(&conf);
+	conf.sched_policy = &dummy_sched_policy,
+	ret = starpu_init(&conf);
+	if (ret == -ENODEV)
+		return 77;
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+
+#ifdef STARPU_QUICK_CHECK
+	ntasks /= 100;
+#endif
+
+	int i;
+	for (i = 0; i < ntasks; i++)
+	{
+		struct starpu_task *task = starpu_task_create();
+
+		task->cl = &dummy_codelet;
+		task->cl_arg = NULL;
+
+		ret = starpu_task_submit(task);
+		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+	}
+
+	starpu_task_wait_for_all();
+
+	starpu_shutdown();
+
+	return 0;
+}

+ 16 - 0
include/starpu_sched_component.h

@@ -101,6 +101,7 @@ int starpu_sched_component_send_can_push_to_parents(struct starpu_sched_componen
 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);
 
+typedef struct starpu_sched_component * (*starpu_sched_component_create_t)(struct starpu_sched_tree *tree, void *data);
 struct starpu_sched_component *starpu_sched_component_create(struct starpu_sched_tree *tree, const char *name) STARPU_ATTRIBUTE_MALLOC;
 void starpu_sched_component_add_child(struct starpu_sched_component* component, struct starpu_sched_component * child);
 void starpu_sched_component_destroy(struct starpu_sched_component *component);
@@ -205,6 +206,21 @@ struct starpu_sched_component_specs
 struct starpu_sched_tree *starpu_sched_component_make_scheduler(unsigned sched_ctx_id, struct starpu_sched_component_specs s);
 #endif /* STARPU_HAVE_HWLOC */
 
+#define STARPU_SCHED_SIMPLE_DECIDE_MASK		(3<<0)
+#define STARPU_SCHED_SIMPLE_DECIDE_WORKERS	(1<<0)
+#define STARPU_SCHED_SIMPLE_DECIDE_MEMNODES	(2<<0)
+#define STARPU_SCHED_SIMPLE_DECIDE_ARCHS	(3<<0)
+
+#define STARPU_SCHED_SIMPLE_PERFMODEL		(1<<4)
+#define STARPU_SCHED_SIMPLE_IMPL		(1<<5)
+#define STARPU_SCHED_SIMPLE_FIFO_ABOVE		(1<<6)
+#define STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO	(1<<7)
+#define STARPU_SCHED_SIMPLE_FIFOS_BELOW		(1<<8)
+#define STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO	(1<<9)
+#define STARPU_SCHED_SIMPLE_WS_BELOW		(1<<10)
+
+void starpu_sched_component_initialize_simple_scheduler(starpu_sched_component_create_t create_decision_component, void *data, unsigned flags, unsigned sched_ctx_id);
+
 #define STARPU_COMPONENT_MUTEX_LOCK(m) \
 do \
 { \

+ 3 - 2
src/Makefile.am

@@ -1,7 +1,7 @@
 # StarPU --- Runtime system for heterogeneous multicore architectures.
 #
 # Copyright (C) 2011-2017                                Inria
-# Copyright (C) 2009-2017                                Université de Bordeaux
+# Copyright (C) 2009-2018                                Université de Bordeaux
 # Copyright (C) 2010-2015,2017                           CNRS
 #
 # StarPU is free software; you can redistribute it and/or modify
@@ -298,7 +298,8 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 		\
 	sched_policies/modular_heft.c				\
 	sched_policies/modular_heft_prio.c			\
 	sched_policies/modular_heft2.c				\
-	sched_policies/modular_ws.c
+	sched_policies/modular_ws.c				\
+	sched_policies/modular_ez.c
 
 
 if STARPU_HAVE_LEVELDB

+ 5 - 16
src/sched_policies/modular_eager.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2017                                     CNRS
- * Copyright (C) 2014,2016-2017                           Université de Bordeaux
+ * Copyright (C) 2014,2016-2018                           Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -22,21 +22,10 @@
 
 static void initialize_eager_center_policy(unsigned sched_ctx_id)
 {
-	struct starpu_sched_tree *t;
-	struct starpu_sched_component * eager_component;
-
-	t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_component_fifo_create(t, NULL);
-	eager_component = starpu_sched_component_eager_create(t, NULL);
-
-	starpu_sched_component_connect(t->root, eager_component);
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-		starpu_sched_component_connect(eager_component, starpu_sched_component_worker_new(sched_ctx_id, i));
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_eager_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_eager_center_policy(unsigned sched_ctx_id)

+ 6 - 30
src/sched_policies/modular_eager_prefetching.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2014,2017                                CNRS
- * Copyright (C) 2014,2016-2017                           Université de Bordeaux
+ * Copyright (C) 2014,2016-2018                           Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -20,37 +20,13 @@
 #include <starpu_sched_component.h>
 #include <starpu_scheduler.h>
 
-#define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 2
-#define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
-
 static void initialize_eager_prefetching_center_policy(unsigned sched_ctx_id)
 {
-	struct starpu_sched_tree *t;
-	struct starpu_sched_component * eager_component;
-
-	t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_component_fifo_create(t, NULL);
-	eager_component = starpu_sched_component_eager_create(t, NULL);
-
-	starpu_sched_component_connect(t->root, eager_component);
-
-	struct starpu_sched_component_fifo_data fifo_data =
-		{
-			.ntasks_threshold = starpu_get_env_number_default("STARPU_NTASKS_THRESHOLD", _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT),
-			.exp_len_threshold = starpu_get_env_float_default("STARPU_EXP_LEN_THRESHOLD", _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT),
-		};
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-	{
-		struct starpu_sched_component * worker_component = starpu_sched_component_worker_new(sched_ctx_id, i);
-		struct starpu_sched_component * fifo_component = starpu_sched_component_fifo_create(t, &fifo_data);
-
-		starpu_sched_component_connect(fifo_component, worker_component);
-		starpu_sched_component_connect(eager_component, fifo_component);
-	}
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_eager_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_eager_prefetching_center_policy(unsigned sched_ctx_id)

+ 304 - 0
src/sched_policies/modular_ez.c

@@ -0,0 +1,304 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013-2015,2017                           Inria
+ * Copyright (C) 2014-2015,2017                           CNRS
+ * Copyright (C) 2013-2015,2017-2018                           Université de Bordeaux
+ * Copyright (C) 2013                                     Simon Archipoff
+ *
+ * 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 <starpu_sched_component.h>
+#include <starpu_scheduler.h>
+
+/* The scheduling strategy may look like this :
+ *
+ *                                    |
+ *                                fifo_above
+ *                                    |
+ *  decision_component <--push-- perfmodel_select_component --push--> eager_component
+ *  |     |     |                                                  |
+ * fifo  fifo  fifo                                                |
+ *  |     |     |                                                  |
+ * eager eager eager                                               |
+ *  |     |     |                                                  |
+ *  >--------------------------------------------------------------<
+ *                    |                                |
+ *              best_impl_component              best_impl_component
+ *                    |                               |
+ *               worker_component                   worker_component
+ */
+
+/* The two thresolds concerns the fifo components below, which contains queues
+ * who can handle the priority of StarPU tasks. You can tune your
+ * scheduling by benching those values and choose which one is the
+ * best for your current application.
+ * The current value of the ntasks_threshold is the best we found
+ * so far across several types of applications (cholesky, LU, stencil).
+ */
+#define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 30
+#define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
+
+void starpu_sched_component_initialize_simple_scheduler(starpu_sched_component_create_t create_decision_component, void *data, unsigned flags, unsigned sched_ctx_id)
+{
+	struct starpu_sched_tree * t;
+	struct starpu_sched_component *last = NULL;	/* Stores the last created component, from top to bottom */
+	unsigned i, j, n;
+	struct starpu_sched_component *decision_component = NULL;
+	struct starpu_sched_component *no_perfmodel_component = NULL;
+	struct starpu_sched_component *calibrator_component = NULL;
+
+	/* Components parameters */
+
+	if (flags & STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO || flags & STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO)
+	{
+		/* The application may use any integer */
+		if (starpu_sched_ctx_min_priority_is_set(sched_ctx_id) == 0)
+			starpu_sched_ctx_set_min_priority(sched_ctx_id, INT_MIN);
+		if (starpu_sched_ctx_max_priority_is_set(sched_ctx_id) == 0)
+			starpu_sched_ctx_set_max_priority(sched_ctx_id, INT_MAX);
+	}
+
+	struct starpu_sched_component_prio_data prio_data =
+		{
+			.ntasks_threshold = starpu_get_env_number_default("STARPU_NTASKS_THRESHOLD", _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT),
+			.exp_len_threshold = starpu_get_env_float_default("STARPU_EXP_LEN_THRESHOLD", _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT),
+		};
+
+
+	/* See what the component will decide */
+	unsigned nbelow;
+	unsigned nummaxids;
+	nummaxids = starpu_worker_get_count() + starpu_combined_worker_get_count();
+	if (starpu_memory_nodes_get_count() > nummaxids)
+		nummaxids = starpu_memory_nodes_get_count();
+	if (STARPU_ANY_WORKER > nummaxids)
+		nummaxids = STARPU_ANY_WORKER;
+	unsigned below_id[nummaxids];
+
+	switch (flags & STARPU_SCHED_SIMPLE_DECIDE_MASK)
+	{
+		case STARPU_SCHED_SIMPLE_DECIDE_WORKERS:
+			/* Count workers */
+			nbelow = starpu_worker_get_count() + starpu_combined_worker_get_count();
+			/* and no need for IDs */
+			break;
+		case STARPU_SCHED_SIMPLE_DECIDE_MEMNODES:
+		{
+			/* Count memory nodes */
+			n = starpu_memory_nodes_get_count();
+			nbelow = 0;
+			for(i = 0; i < n; i++)
+			{
+				for(j = 0; j < starpu_worker_get_count() + starpu_combined_worker_get_count(); j++)
+					if (starpu_worker_get_memory_node(j) == i)
+						break;
+				if (j >= starpu_worker_get_count() + starpu_combined_worker_get_count())
+					/* Don't create a component string for this memory node with no worker */
+					continue;
+				below_id[nbelow] = i;
+				nbelow++;
+			}
+			break;
+		}
+		case STARPU_SCHED_SIMPLE_DECIDE_ARCHS:
+		{
+			/* Count available architecture types */
+			enum starpu_worker_archtype type;
+			nbelow = 0;
+			for (type = STARPU_CPU_WORKER; type < STARPU_ANY_WORKER; type++)
+			{
+				if (starpu_worker_get_count_by_type(type))
+				{
+					below_id[nbelow] = type;
+					nbelow++;
+				}
+			}
+			break;
+		}
+		default:
+			STARPU_ABORT();
+	}
+	STARPU_ASSERT(nbelow > 0);
+
+	/* Start building the tree */
+	t = starpu_sched_tree_create(sched_ctx_id);
+
+	if (nbelow == 1)
+	{
+		/* Oh, no choice, we don't actually need to decide, just
+		 * use an eager scheduler */
+		decision_component = starpu_sched_component_eager_create(t, NULL);
+	}
+	else
+	{
+		decision_component = create_decision_component(t, data);
+	}
+
+	/* First, a fifo if requested */
+	if (flags & STARPU_SCHED_SIMPLE_FIFO_ABOVE)
+	{
+		struct starpu_sched_component *fifo_above;
+		if (flags & STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO)
+		{
+			fifo_above = starpu_sched_component_prio_create(t, NULL);
+		}
+		else
+		{
+			fifo_above = starpu_sched_component_fifo_create(t, NULL);
+		}
+		last = t->root = fifo_above;
+	}
+
+	/* Then, perfmodel calibration if requested, and plug the scheduling decision-making component to it */
+	if (flags & STARPU_SCHED_SIMPLE_PERFMODEL)
+	{
+		no_perfmodel_component = starpu_sched_component_eager_create(t, NULL);
+		calibrator_component = starpu_sched_component_eager_calibration_create(t, NULL);
+
+		struct starpu_sched_component_perfmodel_select_data perfmodel_select_data =
+			{
+				.calibrator_component = calibrator_component,
+				.no_perfmodel_component = no_perfmodel_component,
+				.perfmodel_component = decision_component,
+			};
+
+		struct starpu_sched_component * perfmodel_select_component = starpu_sched_component_perfmodel_select_create(t, &perfmodel_select_data);
+
+		if (!t->root)
+			t->root = perfmodel_select_component;
+		else
+			starpu_sched_component_connect(last, perfmodel_select_component);
+
+		starpu_sched_component_connect(perfmodel_select_component, decision_component);
+		starpu_sched_component_connect(perfmodel_select_component, calibrator_component);
+		starpu_sched_component_connect(perfmodel_select_component, no_perfmodel_component);
+	}
+	else
+	{
+		/* No perfmodel calibration */
+		if (!t->root)
+			/* Plug decision_component directly */
+			t->root = decision_component;
+		else
+			/* Plug decision_component to fifo */
+			starpu_sched_component_connect(last, decision_component);
+	}
+
+	/* Create one fifo+eager component pair per choice, below scheduling decision */
+	struct starpu_sched_component *last_below[nbelow];
+	memset(&last_below, 0, sizeof(last_below));
+	for(i = 0; i < nbelow; i++)
+	{
+		last = decision_component;
+		if (flags & STARPU_SCHED_SIMPLE_FIFOS_BELOW)
+		{
+			struct starpu_sched_component *fifo_below;
+			if (flags & STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO)
+			{
+				fifo_below = starpu_sched_component_prio_create(t, &prio_data);
+			}
+			else
+			{
+				fifo_below = starpu_sched_component_fifo_create(t, NULL);
+			}
+			starpu_sched_component_connect(last, fifo_below);
+			last = fifo_below;
+		}
+		switch (flags & STARPU_SCHED_SIMPLE_DECIDE_MASK)
+		{
+			case STARPU_SCHED_SIMPLE_DECIDE_WORKERS:
+				/* 1-1 mapping between choice and worker, no need for an eager component */
+				n = 1;
+				break;
+			case STARPU_SCHED_SIMPLE_DECIDE_MEMNODES:
+				n = 0;
+				for (j = 0; j < starpu_worker_get_count() + starpu_combined_worker_get_count(); j++)
+					if (starpu_worker_get_memory_node(j) == below_id[i])
+						n++;
+				break;
+			case STARPU_SCHED_SIMPLE_DECIDE_ARCHS:
+				n = starpu_worker_get_count_by_type(i);
+				break;
+			default:
+				STARPU_ABORT();
+		}
+		STARPU_ASSERT(n >= 1);
+		if (n > 1) {
+			/* Several workers for this choice, need to introduce
+			 * a component to distribute the work */
+			struct starpu_sched_component *distribute;
+			if (flags & STARPU_SCHED_SIMPLE_WS_BELOW)
+			{
+				distribute = starpu_sched_component_work_stealing_create(t, NULL);
+			}
+			else
+			{
+				distribute = starpu_sched_component_eager_create(t, NULL);
+			}
+
+			starpu_sched_component_connect(last, distribute);
+			last = distribute;
+		}
+		last_below[i] = last;
+	}
+
+	/* Finish by creating components per worker */
+	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
+	{
+		/* Start from the bottom */
+		struct starpu_sched_component * worker_component = starpu_sched_component_worker_new(sched_ctx_id, i);
+		struct starpu_sched_component * worker = worker_component;
+		unsigned id;
+
+		/* Create implementation chooser if requested */
+		if (flags & STARPU_SCHED_SIMPLE_IMPL)
+		{
+			struct starpu_sched_component * impl_component = starpu_sched_component_best_implementation_create(t, NULL);
+			starpu_sched_component_connect(impl_component, worker_component);
+			/* Reroute components above through it */
+			worker = impl_component;
+		}
+
+		switch (flags & STARPU_SCHED_SIMPLE_DECIDE_MASK)
+		{
+			case STARPU_SCHED_SIMPLE_DECIDE_WORKERS:
+				id = i;
+				break;
+			case STARPU_SCHED_SIMPLE_DECIDE_MEMNODES:
+				id = below_id[starpu_worker_get_memory_node(i)];
+				break;
+			case STARPU_SCHED_SIMPLE_DECIDE_ARCHS:
+				id = below_id[starpu_worker_get_type(i)];
+				break;
+			default:
+				STARPU_ABORT();
+		}
+		STARPU_ASSERT(id < nbelow);
+		last = last_below[id];
+		if (!last)
+			last = decision_component;
+
+		starpu_sched_component_connect(last, worker);
+
+		/* Plug perfmodel calibrator if requested */
+		if (flags & STARPU_SCHED_SIMPLE_PERFMODEL)
+		{
+			starpu_sched_component_connect(no_perfmodel_component, worker);
+			/* Calibrator needs to choose the implementation */
+			starpu_sched_component_connect(calibrator_component, worker_component);
+		}
+	}
+
+	starpu_sched_tree_update_workers(t);
+	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+}

+ 11 - 65
src/sched_policies/modular_heft.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2014-2015,2017                           CNRS
- * Copyright (C) 2013-2015,2017                           Université de Bordeaux
+ * Copyright (C) 2013-2015,2017-2018                           Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -22,24 +22,6 @@
 #include <float.h>
 #include <limits.h>
 
-/* The two thresolds concerns the prio components, which contains queues
- * who can handle the priority of StarPU tasks. You can tune your
- * scheduling by benching those values and choose which one is the
- * best for your current application. 
- * The current value of the ntasks_threshold is the best we found
- * so far across several types of applications (cholesky, LU, stencil).
- */
-#define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 30
-#define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
-
-static void initialize_heft_center_policy(unsigned sched_ctx_id)
-{
-	/* The application may use any integer */
-	if (starpu_sched_ctx_min_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_min_priority(sched_ctx_id, INT_MIN);
-	if (starpu_sched_ctx_max_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_max_priority(sched_ctx_id, INT_MAX);
-
 /* The scheduling strategy look like this :
  *
  *                                    |
@@ -66,53 +48,17 @@ static void initialize_heft_center_policy(unsigned sched_ctx_id)
  * component will push the task on its local queue if no one of the two thresholds
  * have been reached for it, or send a push_error signal to its parent.
  */
-	struct starpu_sched_tree * t = starpu_sched_tree_create(sched_ctx_id);
-
-	struct starpu_sched_component * window_component = starpu_sched_component_prio_create(t, NULL);
-
-	struct starpu_sched_component * perfmodel_component = starpu_sched_component_mct_create(t, NULL);
-	struct starpu_sched_component * no_perfmodel_component = starpu_sched_component_eager_create(t, NULL);
-	struct starpu_sched_component * calibrator_component = starpu_sched_component_eager_calibration_create(t, NULL);
-	
-	struct starpu_sched_component_perfmodel_select_data perfmodel_select_data =
-		{
-			.calibrator_component = calibrator_component,
-			.no_perfmodel_component = no_perfmodel_component,
-			.perfmodel_component = perfmodel_component,
-		};
-
-	struct starpu_sched_component * perfmodel_select_component = starpu_sched_component_perfmodel_select_create(t, &perfmodel_select_data);
 
-	t->root = window_component;
-	starpu_sched_component_connect(window_component, perfmodel_select_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);
-
-	struct starpu_sched_component_prio_data prio_data =
-		{
-			.ntasks_threshold = starpu_get_env_number_default("STARPU_NTASKS_THRESHOLD", _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT),
-			.exp_len_threshold = starpu_get_env_float_default("STARPU_EXP_LEN_THRESHOLD", _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT),
-		};
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-	{
-		struct starpu_sched_component * worker_component = starpu_sched_component_worker_new(sched_ctx_id, i);
-		struct starpu_sched_component * prio_component = starpu_sched_component_prio_create(t, &prio_data);
-		struct starpu_sched_component * impl_component = starpu_sched_component_best_implementation_create(t, NULL);
-
-		starpu_sched_component_connect(prio_component, worker_component);
-		starpu_sched_component_connect(impl_component, prio_component);
-
-		starpu_sched_component_connect(perfmodel_component, impl_component);
-		starpu_sched_component_connect(no_perfmodel_component, impl_component);
-		starpu_sched_component_connect(calibrator_component, impl_component);
-	}
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+static void initialize_heft_center_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_mct_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_PERFMODEL |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_heft_center_policy(unsigned sched_ctx_id)

+ 11 - 65
src/sched_policies/modular_heft2.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2014-2015,2017                           CNRS
- * Copyright (C) 2013-2015,2017                           Université de Bordeaux
+ * Copyright (C) 2013-2015,2017-2018                           Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -22,24 +22,6 @@
 #include <float.h>
 #include <limits.h>
 
-/* The two thresolds concerns the prio components, which contains queues
- * who can handle the priority of StarPU tasks. You can tune your
- * scheduling by benching those values and choose which one is the
- * best for your current application. 
- * The current value of the ntasks_threshold is the best we found
- * so far across several types of applications (cholesky, LU, stencil).
- */
-#define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 30
-#define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
-
-static void initialize_heft2_center_policy(unsigned sched_ctx_id)
-{
-	/* The application may use any integer */
-	if (starpu_sched_ctx_min_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_min_priority(sched_ctx_id, INT_MIN);
-	if (starpu_sched_ctx_max_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_max_priority(sched_ctx_id, INT_MAX);
-
 /* The scheduling strategy look like this :
  *
  *                                    |
@@ -66,53 +48,17 @@ static void initialize_heft2_center_policy(unsigned sched_ctx_id)
  * component will push the task on its local queue if no one of the two thresholds
  * have been reached for it, or send a push_error signal to its parent.
  */
-	struct starpu_sched_tree * t = starpu_sched_tree_create(sched_ctx_id);
-
-	struct starpu_sched_component * window_component = starpu_sched_component_prio_create(t, NULL);
-
-	struct starpu_sched_component * perfmodel_component = starpu_sched_component_heft_create(t, NULL);
-	struct starpu_sched_component * no_perfmodel_component = starpu_sched_component_eager_create(t, NULL);
-	struct starpu_sched_component * calibrator_component = starpu_sched_component_eager_calibration_create(t, NULL);
-	
-	struct starpu_sched_component_perfmodel_select_data perfmodel_select_data =
-		{
-			.calibrator_component = calibrator_component,
-			.no_perfmodel_component = no_perfmodel_component,
-			.perfmodel_component = perfmodel_component,
-		};
-
-	struct starpu_sched_component * perfmodel_select_component = starpu_sched_component_perfmodel_select_create(t, &perfmodel_select_data);
 
-	t->root = window_component;
-	starpu_sched_component_connect(window_component, perfmodel_select_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);
-
-	struct starpu_sched_component_prio_data prio_data =
-		{
-			.ntasks_threshold = starpu_get_env_number_default("STARPU_NTASKS_THRESHOLD", _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT),
-			.exp_len_threshold = starpu_get_env_float_default("STARPU_EXP_LEN_THRESHOLD", _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT),
-		};
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-	{
-		struct starpu_sched_component * worker_component = starpu_sched_component_worker_new(sched_ctx_id, i);
-		struct starpu_sched_component * prio_component = starpu_sched_component_prio_create(t, &prio_data);
-		struct starpu_sched_component * impl_component = starpu_sched_component_best_implementation_create(t, NULL);
-
-		starpu_sched_component_connect(prio_component, worker_component);
-		starpu_sched_component_connect(impl_component, prio_component);
-
-		starpu_sched_component_connect(perfmodel_component, impl_component);
-		starpu_sched_component_connect(no_perfmodel_component, impl_component);
-		starpu_sched_component_connect(calibrator_component, impl_component);
-	}
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+static void initialize_heft2_center_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_heft_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_PERFMODEL |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_heft2_center_policy(unsigned sched_ctx_id)

+ 11 - 103
src/sched_policies/modular_heft_prio.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2014-2015,2017                           CNRS
- * Copyright (C) 2013-2015,2017                           Université de Bordeaux
+ * Copyright (C) 2013-2015,2017-2018                           Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -22,47 +22,6 @@
 #include <float.h>
 #include <limits.h>
 
-/* The two thresolds concerns the prio components, which contains queues
- * who can handle the priority of StarPU tasks. You can tune your
- * scheduling by benching those values and choose which one is the
- * best for your current application. 
- * The current value of the ntasks_threshold is the best we found
- * so far across several types of applications (cholesky, LU, stencil).
- */
-#define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 30
-#define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
-
-static void initialize_heft_prio_policy(unsigned sched_ctx_id)
-{
-	unsigned i, j, n, nnodes;
-
-	/* First count how many memory nodes really have workers */
-	n = starpu_memory_nodes_get_count();
-	nnodes = 0;
-	for(i = 0; i < n; i++)
-	{
-		for(j = 0; j < starpu_worker_get_count() + starpu_combined_worker_get_count(); j++)
-			if (starpu_worker_get_memory_node(j) == i)
-				break;
-		if (j >= starpu_worker_get_count() + starpu_combined_worker_get_count())
-			/* Don't create a component for this memory node with no worker */
-			continue;
-		nnodes++;
-	}
-
-	if (nnodes == 1)
-	{
-		/* Just one memory node, we don't actually need MCT etc., just
-		 * initialize a prio scheduler */
-		return starpu_initialize_prio_center_policy(sched_ctx_id);
-	}
-
-	/* The application may use any integer */
-	if (starpu_sched_ctx_min_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_min_priority(sched_ctx_id, INT_MIN);
-	if (starpu_sched_ctx_max_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_max_priority(sched_ctx_id, INT_MAX);
-
 /* The scheduling strategy look like this :
  *
  *                                    |
@@ -90,68 +49,17 @@ static void initialize_heft_prio_policy(unsigned sched_ctx_id)
  * component will push the task on its local queue if no one of the two thresholds
  * have been reached for it, or send a push_error signal to its parent.
  */
-	struct starpu_sched_tree * t = starpu_sched_tree_create(sched_ctx_id);
-
-	struct starpu_sched_component * window_component = starpu_sched_component_prio_create(t, NULL);
-
-	struct starpu_sched_component * perfmodel_component = starpu_sched_component_mct_create(t, NULL);
-	struct starpu_sched_component * no_perfmodel_component = starpu_sched_component_eager_create(t, NULL);
-	struct starpu_sched_component * calibrator_component = starpu_sched_component_eager_calibration_create(t, NULL);
-	
-	struct starpu_sched_component_perfmodel_select_data perfmodel_select_data =
-		{
-			.calibrator_component = calibrator_component,
-			.no_perfmodel_component = no_perfmodel_component,
-			.perfmodel_component = perfmodel_component,
-		};
 
-	struct starpu_sched_component * perfmodel_select_component = starpu_sched_component_perfmodel_select_create(t, &perfmodel_select_data);
-
-	t->root = window_component;
-	starpu_sched_component_connect(window_component, perfmodel_select_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);
-
-	struct starpu_sched_component_prio_data prio_data =
-		{
-			.ntasks_threshold = starpu_get_env_number_default("STARPU_NTASKS_THRESHOLD", _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT),
-			.exp_len_threshold = starpu_get_env_float_default("STARPU_EXP_LEN_THRESHOLD", _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT),
-		};
-
-	n = starpu_memory_nodes_get_count();
-	STARPU_ASSERT(n >= 1);
-	struct starpu_sched_component * eagers[n];
-
-	/* Create one fifo+eager component pair per memory node, below mct */
-	for(i = 0; i < n; i++)
-	{
-		for(j = 0; j < starpu_worker_get_count() + starpu_combined_worker_get_count(); j++)
-			if (starpu_worker_get_memory_node(j) == i)
-				break;
-		if (j == starpu_worker_get_count() + starpu_combined_worker_get_count())
-			/* Don't create a component for this memory node with no worker */
-			continue;
-		struct starpu_sched_component * prio_component = starpu_sched_component_prio_create(t, &prio_data);
-		eagers[i] = starpu_sched_component_eager_create(t, NULL);
-		starpu_sched_component_connect(perfmodel_component, prio_component);
-		starpu_sched_component_connect(prio_component, eagers[i]);
-	}
-
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-	{
-		struct starpu_sched_component * worker_component = starpu_sched_component_worker_new(sched_ctx_id, i);
-		struct starpu_sched_component * impl_component = starpu_sched_component_best_implementation_create(t, NULL);
-
-		starpu_sched_component_connect(eagers[starpu_worker_get_memory_node(i)], impl_component);
-		starpu_sched_component_connect(no_perfmodel_component, impl_component);
-		starpu_sched_component_connect(calibrator_component, impl_component);
-		starpu_sched_component_connect(impl_component, worker_component);
-	}
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+static void initialize_heft_prio_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_mct_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_MEMNODES |
+			STARPU_SCHED_SIMPLE_PERFMODEL |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_heft_prio_policy(unsigned sched_ctx_id)

+ 6 - 22
src/sched_policies/modular_prio.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2017                                     CNRS
- * Copyright (C) 2014,2017                                Université de Bordeaux
+ * Copyright (C) 2014,2017-2018                                Université de Bordeaux
  *
  * 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
@@ -22,27 +22,11 @@
 
 void starpu_initialize_prio_center_policy(unsigned sched_ctx_id)
 {
-	struct starpu_sched_tree *t;
-	struct starpu_sched_component * eager_component;
-
-	t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_component_prio_create(t, NULL);
-	eager_component = starpu_sched_component_eager_create(t, NULL);
-
-	starpu_sched_component_connect(t->root, eager_component);
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-		starpu_sched_component_connect(eager_component, starpu_sched_component_worker_new(sched_ctx_id, i));
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
-
-	/* The application may use any integer */
-	if (starpu_sched_ctx_min_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_min_priority(sched_ctx_id, INT_MIN);
-	if (starpu_sched_ctx_max_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_max_priority(sched_ctx_id, INT_MAX);
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_eager_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_prio_center_policy(unsigned sched_ctx_id)

+ 15 - 4
src/sched_policies/modular_prio_prefetching.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2014,2017                                CNRS
- * Copyright (C) 2014,2017                                Université de Bordeaux
+ * Copyright (C) 2014,2017-2018                                Université de Bordeaux
  *
  * 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
@@ -20,9 +20,9 @@
 #include <starpu_scheduler.h>
 #include <limits.h>
 
-#define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 4
-#define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
-
+/* Just as documentation example, here is the detailed equivalent of the
+ * starpu_sched_component_initialize_simple_scheduler call below */
+#if 0
 static void initialize_prio_prefetching_center_policy(unsigned sched_ctx_id)
 {
 	struct starpu_sched_tree *t;
@@ -58,6 +58,17 @@ static void initialize_prio_prefetching_center_policy(unsigned sched_ctx_id)
 	if (starpu_sched_ctx_max_priority_is_set(sched_ctx_id) == 0)
 		starpu_sched_ctx_set_max_priority(sched_ctx_id, INT_MAX);
 }
+#endif
+
+static void initialize_prio_prefetching_center_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_eager_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
+}
 
 static void deinitialize_prio_prefetching_center_policy(unsigned sched_ctx_id)
 {

+ 10 - 37
src/sched_policies/modular_random.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2017                                     CNRS
- * Copyright (C) 2014,2017                                Université de Bordeaux
+ * Copyright (C) 2014,2017-2018                                Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -25,21 +25,10 @@
 
 static void initialize_random_fifo_center_policy(unsigned sched_ctx_id)
 {
-	struct starpu_sched_tree *t;
-	struct starpu_sched_component * random_component;
-
-	t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_component_fifo_create(t, NULL);
-	random_component = starpu_sched_component_random_create(t, NULL);
-
-	starpu_sched_component_connect(t->root, random_component);
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-		starpu_sched_component_connect(random_component, starpu_sched_component_worker_new(sched_ctx_id, i));
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_random_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_random_fifo_center_policy(unsigned sched_ctx_id)
@@ -68,27 +57,11 @@ struct starpu_sched_policy _starpu_sched_modular_random_policy =
 
 static void initialize_random_prio_center_policy(unsigned sched_ctx_id)
 {
-	struct starpu_sched_tree *t;
-	struct starpu_sched_component * random_component;
-
-	t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_component_prio_create(t, NULL);
-	random_component = starpu_sched_component_random_create(t, NULL);
-
-	starpu_sched_component_connect(t->root, random_component);
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-		starpu_sched_component_connect(random_component, starpu_sched_component_worker_new(sched_ctx_id, i));
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
-
-	/* The application may use any integer */
-	if (starpu_sched_ctx_min_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_min_priority(sched_ctx_id, INT_MIN);
-	if (starpu_sched_ctx_max_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_max_priority(sched_ctx_id, INT_MAX);
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_random_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_random_prio_center_policy(unsigned sched_ctx_id)

+ 13 - 59
src/sched_policies/modular_random_prefetching.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2014,2017                                CNRS
- * Copyright (C) 2014,2017                                Université de Bordeaux
+ * Copyright (C) 2014,2017-2018                                Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -28,32 +28,11 @@
 
 static void initialize_random_fifo_prefetching_center_policy(unsigned sched_ctx_id)
 {
-	struct starpu_sched_tree *t;
-	struct starpu_sched_component * random_component;
-
-	t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_component_fifo_create(t, NULL);
-	random_component = starpu_sched_component_random_create(t, NULL);
-
-	starpu_sched_component_connect(t->root, random_component);
-
-	struct starpu_sched_component_fifo_data fifo_data =
-		{
-			.ntasks_threshold = starpu_get_env_number_default("STARPU_NTASKS_THRESHOLD", _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT),
-			.exp_len_threshold = starpu_get_env_float_default("STARPU_EXP_LEN_THRESHOLD", _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT),
-		};
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-	{
-		struct starpu_sched_component * worker_component = starpu_sched_component_worker_new(sched_ctx_id, i);
-		struct starpu_sched_component * fifo_component = starpu_sched_component_fifo_create(t, &fifo_data);
-
-		starpu_sched_component_connect(fifo_component, worker_component);
-		starpu_sched_component_connect(random_component, fifo_component);
-	}
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_random_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_random_fifo_prefetching_center_policy(unsigned sched_ctx_id)
@@ -82,38 +61,13 @@ struct starpu_sched_policy _starpu_sched_modular_random_prefetching_policy =
 
 static void initialize_random_prio_prefetching_center_policy(unsigned sched_ctx_id)
 {
-	struct starpu_sched_tree *t;
-	struct starpu_sched_component *random_component;
-
-	t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_component_prio_create(t, NULL);
-	random_component = starpu_sched_component_random_create(t, NULL);
-
-	starpu_sched_component_connect(t->root, random_component);
-
-	struct starpu_sched_component_prio_data prio_data =
-		{
-			.ntasks_threshold = starpu_get_env_number_default("STARPU_NTASKS_THRESHOLD", _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT),
-			.exp_len_threshold = starpu_get_env_float_default("STARPU_EXP_LEN_THRESHOLD", _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT),
-		};
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-	{
-		struct starpu_sched_component * worker_component = starpu_sched_component_worker_new(sched_ctx_id, i);
-		struct starpu_sched_component * prio_component = starpu_sched_component_prio_create(t, &prio_data);
-
-		starpu_sched_component_connect(prio_component, worker_component);
-		starpu_sched_component_connect(random_component, prio_component);
-	}
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
-
-	/* The application may use any integer */
-	if (starpu_sched_ctx_min_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_min_priority(sched_ctx_id, INT_MIN);
-	if (starpu_sched_ctx_max_priority_is_set(sched_ctx_id) == 0)
-		starpu_sched_ctx_set_max_priority(sched_ctx_id, INT_MAX);
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_random_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE |
+			STARPU_SCHED_SIMPLE_FIFO_ABOVE_PRIO |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW |
+			STARPU_SCHED_SIMPLE_FIFOS_BELOW_PRIO |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_random_prio_prefetching_center_policy(unsigned sched_ctx_id)

+ 5 - 12
src/sched_policies/modular_ws.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2013-2015,2017                           Inria
  * Copyright (C) 2017                                     CNRS
- * Copyright (C) 2014                                     Université de Bordeaux
+ * Copyright (C) 2014, 2018                                     Université de Bordeaux
  * Copyright (C) 2013                                     Simon Archipoff
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -23,17 +23,10 @@
 
 static void initialize_ws_center_policy(unsigned sched_ctx_id)
 {
-	struct starpu_sched_tree *t;
-
-	t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_component_work_stealing_create(t, NULL);
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-		starpu_sched_component_connect(t->root, starpu_sched_component_worker_new(sched_ctx_id, i));
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+	starpu_sched_component_initialize_simple_scheduler((starpu_sched_component_create_t) starpu_sched_component_work_stealing_create, NULL,
+			STARPU_SCHED_SIMPLE_DECIDE_WORKERS |
+			STARPU_SCHED_SIMPLE_WS_BELOW |
+			STARPU_SCHED_SIMPLE_IMPL, sched_ctx_id);
 }
 
 static void deinitialize_ws_center_policy(unsigned sched_ctx_id)