瀏覽代碼

Cleanup the scheduling policy structure as well as the code to initialize the
scheduling policy.

Cédric Augonnet 15 年之前
父節點
當前提交
2050338dad

+ 2 - 1
include/starpu.h

@@ -38,7 +38,8 @@ extern "C" {
  * make future extensions not problematic */
 struct starpu_conf {
 	/* which scheduling policy should be used ? (NULL for default) */
-	const char *sched_policy;
+	const char *sched_policy_name;
+	struct sched_policy_s *sched_policy;
 
 	/* maximum number of CPUs (-1 for default) */
 	int ncpus;

+ 10 - 3
src/core/policies/deque-modeling-policy-data-aware.c

@@ -207,8 +207,8 @@ static struct jobq_s *init_dmda_fifo(void)
 	return q;
 }
 
-void initialize_dmda_policy(struct machine_config_s *config, 
- __attribute__ ((unused)) struct sched_policy_s *_policy) 
+static void initialize_dmda_policy(struct machine_config_s *config, 
+	 __attribute__ ((unused)) struct sched_policy_s *_policy) 
 {
 	nworkers = 0;
 
@@ -219,7 +219,7 @@ void initialize_dmda_policy(struct machine_config_s *config,
 	setup_queues(init_fifo_queues_mechanisms, init_dmda_fifo, config);
 }
 
-struct jobq_s *get_local_queue_dmda(struct sched_policy_s *policy __attribute__ ((unused)))
+static struct jobq_s *get_local_queue_dmda(struct sched_policy_s *policy __attribute__ ((unused)))
 {
 	struct jobq_s *queue;
 	queue = pthread_getspecific(policy->local_queue_key);
@@ -233,3 +233,10 @@ struct jobq_s *get_local_queue_dmda(struct sched_policy_s *policy __attribute__
 	return queue;
 }
 
+struct sched_policy_s sched_dmda_policy = {
+	.init_sched = initialize_dmda_policy,
+	.deinit_sched = NULL,
+	.get_local_queue = get_local_queue_dmda,
+	.policy_name = "dmda",
+	.policy_description = "data-aware performance model"
+};

+ 1 - 4
src/core/policies/deque-modeling-policy-data-aware.h

@@ -21,9 +21,6 @@
 #include <core/mechanisms/queues.h>
 #include <core/mechanisms/fifo_queues.h>
 
-void initialize_dmda_policy(struct machine_config_s *config,
- __attribute__ ((unused)) struct sched_policy_s *_policy);
-
-struct jobq_s *get_local_queue_dmda(struct sched_policy_s *policy __attribute__ ((unused)));
+extern struct sched_policy_s sched_dmda_policy;
 
 #endif // __DEQUE_MODELING_POLICY_DATA_AWARE_H__

+ 10 - 3
src/core/policies/deque-modeling-policy.c

@@ -169,8 +169,8 @@ static struct jobq_s *init_dm_fifo(void)
 	return q;
 }
 
-void initialize_dm_policy(struct machine_config_s *config, 
- __attribute__ ((unused)) struct sched_policy_s *_policy) 
+static void initialize_dm_policy(struct machine_config_s *config, 
+	 __attribute__ ((unused)) struct sched_policy_s *_policy) 
 {
 	nworkers = 0;
 
@@ -185,7 +185,7 @@ void initialize_dm_policy(struct machine_config_s *config,
 	setup_queues(init_fifo_queues_mechanisms, init_dm_fifo, config);
 }
 
-struct jobq_s *get_local_queue_dm(struct sched_policy_s *policy __attribute__ ((unused)))
+static struct jobq_s *get_local_queue_dm(struct sched_policy_s *policy __attribute__ ((unused)))
 {
 	struct jobq_s *queue;
 	queue = pthread_getspecific(policy->local_queue_key);
@@ -199,3 +199,10 @@ struct jobq_s *get_local_queue_dm(struct sched_policy_s *policy __attribute__ ((
 	return queue;
 }
 
+struct sched_policy_s sched_dm_policy = {
+	.init_sched = initialize_dm_policy,
+	.deinit_sched = NULL,
+	.get_local_queue = get_local_queue_dm,
+	.policy_name = "dm",
+	.policy_description = "performance model"
+};

+ 1 - 4
src/core/policies/deque-modeling-policy.h

@@ -21,9 +21,6 @@
 #include <core/mechanisms/queues.h>
 #include <core/mechanisms/fifo_queues.h>
 
-void initialize_dm_policy(struct machine_config_s *config,
- __attribute__ ((unused)) struct sched_policy_s *_policy);
-
-struct jobq_s *get_local_queue_dm(struct sched_policy_s *policy __attribute__ ((unused)));
+extern struct sched_policy_s sched_dm_policy;
 
 #endif // __DEQUE_MODELING_POLICY_H__

+ 12 - 4
src/core/policies/eager-central-policy.c

@@ -44,15 +44,23 @@ static struct jobq_s *func_init_central_queue(void)
 	return jobq;
 }
 
-void initialize_eager_center_policy(struct machine_config_s *config, 
-	   __attribute__ ((unused)) struct sched_policy_s *_policy) 
+static void initialize_eager_center_policy(struct machine_config_s *config, 
+		   __attribute__ ((unused)) struct sched_policy_s *_policy) 
 {
 	setup_queues(init_central_queue_design, func_init_central_queue, config);
 }
 
-struct jobq_s *get_local_queue_eager(struct sched_policy_s *policy 
-					__attribute__ ((unused)))
+static struct jobq_s *get_local_queue_eager(struct sched_policy_s *policy 
+						__attribute__ ((unused)))
 {
 	/* this is trivial for that strategy :) */
 	return jobq;
 }
+
+struct sched_policy_s sched_eager_policy = {
+	.init_sched = initialize_eager_center_policy,
+	.deinit_sched = NULL,
+	.get_local_queue = get_local_queue_eager,
+	.policy_name = "eager",
+	.policy_description = "greedy policy"
+};

+ 1 - 3
src/core/policies/eager-central-policy.h

@@ -20,8 +20,6 @@
 #include <core/workers.h>
 #include <core/mechanisms/fifo_queues.h>
 
-void initialize_eager_center_policy(struct machine_config_s *config, struct sched_policy_s *policy);
-//void set_local_queue_eager(struct jobq_s *jobq);
-struct jobq_s *get_local_queue_eager(struct sched_policy_s *policy);
+extern struct sched_policy_s sched_eager_policy;
 
 #endif // __EAGER_CENTRAL_POLICY_H__

+ 9 - 3
src/core/policies/eager-central-priority-policy.c

@@ -37,16 +37,22 @@ static struct jobq_s *func_init_priority_queue(void)
 	return jobq;
 }
 
-void initialize_eager_center_priority_policy(struct machine_config_s *config, 
+static void initialize_eager_center_priority_policy(struct machine_config_s *config, 
 			__attribute__ ((unused))	struct sched_policy_s *_policy) 
 {
 	setup_queues(init_priority_queue_design, func_init_priority_queue, config);
 }
 
-struct jobq_s *get_local_queue_eager_priority(struct sched_policy_s *policy __attribute__ ((unused)))
+static struct jobq_s *get_local_queue_eager_priority(struct sched_policy_s *policy __attribute__ ((unused)))
 {
 	/* this is trivial for that strategy */
 	return jobq;
 }
 
-
+struct sched_policy_s sched_prio_policy = {
+	.init_sched = initialize_eager_center_priority_policy,
+	.deinit_sched = NULL,
+	.get_local_queue = get_local_queue_eager_priority,
+	.policy_name = "prio",
+	.policy_description = "eager (with priorities)"
+};

+ 1 - 3
src/core/policies/eager-central-priority-policy.h

@@ -21,8 +21,6 @@
 #include <core/mechanisms/queues.h>
 #include <core/mechanisms/priority_queues.h>
 
-void initialize_eager_center_priority_policy(struct machine_config_s *config, struct sched_policy_s *policy);
-void set_local_queue_eager_priority(struct jobq_s *jobq);
-struct jobq_s *get_local_queue_eager_priority(struct sched_policy_s *policy);
+extern struct sched_policy_s sched_prio_policy;
 
 #endif // __EAGER_CENTRAL_PRIORITY_POLICY_H__

+ 8 - 0
src/core/policies/no-prio-policy.c

@@ -55,3 +55,11 @@ struct jobq_s *get_local_queue_no_prio(struct sched_policy_s *policy
 	/* this is trivial for that strategy :) */
 	return jobq;
 }
+
+struct sched_policy_s sched_no_prio_policy = {
+	.init_sched = initialize_no_prio_policy,
+	.deinit_sched = NULL,
+	.get_local_queue = get_local_queue_no_prio,
+	.policy_name = "no-prio",
+	.policy_description = "eager without priority"
+};

+ 1 - 3
src/core/policies/no-prio-policy.h

@@ -20,8 +20,6 @@
 #include <core/workers.h>
 #include <core/mechanisms/fifo_queues.h>
 
-void initialize_no_prio_policy(struct machine_config_s *config, struct sched_policy_s *policy);
-//void set_local_queue_eager(struct jobq_s *jobq);
-struct jobq_s *get_local_queue_no_prio(struct sched_policy_s *policy);
+extern struct sched_policy_s sched_no_prio_policy;
 
 #endif // __NO_PRIO_POLICY_H__

+ 10 - 3
src/core/policies/random-policy.c

@@ -95,8 +95,8 @@ static struct jobq_s *init_random_fifo(void)
 	return q;
 }
 
-void initialize_random_policy(struct machine_config_s *config, 
- __attribute__ ((unused)) struct sched_policy_s *_policy) 
+static void initialize_random_policy(struct machine_config_s *config, 
+	 __attribute__ ((unused)) struct sched_policy_s *_policy) 
 {
 	nworkers = 0;
 
@@ -105,7 +105,7 @@ void initialize_random_policy(struct machine_config_s *config,
 	setup_queues(init_fifo_queues_mechanisms, init_random_fifo, config);
 }
 
-struct jobq_s *get_local_queue_random(struct sched_policy_s *policy __attribute__ ((unused)))
+static struct jobq_s *get_local_queue_random(struct sched_policy_s *policy __attribute__ ((unused)))
 {
 	struct jobq_s *queue;
 	queue = pthread_getspecific(policy->local_queue_key);
@@ -119,3 +119,10 @@ struct jobq_s *get_local_queue_random(struct sched_policy_s *policy __attribute_
 	return queue;
 }
 
+struct sched_policy_s sched_random_policy = {
+	.init_sched = initialize_random_policy,
+	.deinit_sched = NULL,
+	.get_local_queue = get_local_queue_random,
+	.policy_name = "random",
+	.policy_description = "weighted random"
+};

+ 1 - 4
src/core/policies/random-policy.h

@@ -21,9 +21,6 @@
 #include <core/mechanisms/queues.h>
 #include <core/mechanisms/fifo_queues.h>
 
-void initialize_random_policy(struct machine_config_s *config,
- __attribute__ ((unused)) struct sched_policy_s *_policy);
-
-struct jobq_s *get_local_queue_random(struct sched_policy_s *policy __attribute__ ((unused)));
+extern struct sched_policy_s sched_random_policy;
 
 #endif // __RANDOM_POLICY_H__

+ 96 - 89
src/core/policies/sched_policy.c

@@ -36,106 +36,113 @@ struct sched_policy_s *get_sched_policy(void)
 	return &policy;
 }
 
-void init_sched_policy(struct machine_config_s *config)
+static void load_sched_policy(struct sched_policy_s *sched_policy)
 {
-	struct starpu_conf *user_conf = config->user_conf;
+	STARPU_ASSERT(sched_policy);
 
-	/* eager policy is taken by default */
-	const char *sched_pol;
-	if (user_conf && (user_conf->sched_policy))
+#ifdef VERBOSE
+	if (sched_policy->policy_name)
 	{
-		sched_pol = user_conf->sched_policy;
-	}
-	else {
-		sched_pol = getenv("SCHED");
-	}
+		fprintf(stderr, "Use %s scheduler", sched_policy->policy_name);
 
-	if (sched_pol) {
-		 if (strcmp(sched_pol, "help") == 0) {
-			fprintf(stderr, "SCHED can be either of\n");
-			fprintf(stderr, "ws\twork stealing\n");
-			fprintf(stderr, "prio\tprio eager\n");
-			fprintf(stderr, "no-prio\teager (without prio)\n");
-			fprintf(stderr, "dm\tperformance model\n");
-			fprintf(stderr, "dmda\tdata-aware performance model\n");
-			fprintf(stderr, "random\trandom\n");
-			fprintf(stderr, "else the eager scheduler will be used\n");
-		 }
-		 if (strcmp(sched_pol, "ws") == 0) {
-#ifdef VERBOSE
-		 	fprintf(stderr, "USE WS SCHEDULER !! \n");
-#endif
-			policy.init_sched = initialize_ws_policy;
-			policy.deinit_sched = NULL;
-			policy.get_local_queue = get_local_queue_ws;
-		 }
-		 else if (strcmp(sched_pol, "prio") == 0) {
-#ifdef VERBOSE
-		 	fprintf(stderr, "USE PRIO EAGER SCHEDULER !! \n");
-#endif
-			policy.init_sched = initialize_eager_center_priority_policy;
-			policy.deinit_sched = NULL;
-			policy.get_local_queue = get_local_queue_eager_priority;
-		 }
-		 else if (strcmp(sched_pol, "no-prio") == 0) {
-#ifdef VERBOSE
-		 	fprintf(stderr, "USE _NO_ PRIO EAGER SCHEDULER !! \n");
-#endif
-			policy.init_sched = initialize_no_prio_policy;
-			policy.deinit_sched = NULL;
-			policy.get_local_queue = get_local_queue_no_prio;
-		 }
-		 else if (strcmp(sched_pol, "dm") == 0) {
-#ifdef VERBOSE
-		 	fprintf(stderr, "USE MODEL SCHEDULER !! \n");
-#endif
-			policy.init_sched = initialize_dm_policy;
-			policy.deinit_sched = NULL;
-			policy.get_local_queue = get_local_queue_dm;
-		 }
-		 else if (strcmp(sched_pol, "dmda") == 0) {
-#ifdef VERBOSE
-		 	fprintf(stderr, "USE DATA AWARE MODEL SCHEDULER !! \n");
-#endif
-			policy.init_sched = initialize_dmda_policy;
-			policy.deinit_sched = NULL;
-			policy.get_local_queue = get_local_queue_dmda;
-		 }
-		 else if (strcmp(sched_pol, "random") == 0) {
-#ifdef VERBOSE
-		 	fprintf(stderr, "USE RANDOM SCHEDULER !! \n");
-#endif
-			policy.init_sched = initialize_random_policy;
-			policy.deinit_sched = NULL;
-			policy.get_local_queue = get_local_queue_random;
-		 }
-		 else {
-#ifdef VERBOSE
-		 	fprintf(stderr, "USE EAGER SCHEDULER !! \n");
-#endif
-			/* default scheduler is the eager one */
-			policy.init_sched = initialize_eager_center_policy;
-			policy.deinit_sched = NULL;
-			policy.get_local_queue = get_local_queue_eager;
-		 }
+		if (sched_policy->policy_description)
+		{
+			fprintf(stderr, " (%s)", sched_policy->policy_description);
+		}
+
+		fprintf(stderr, "\n");
 	}
-	else {
-#ifdef VERBOSE
-	 	fprintf(stderr, "USE EAGER SCHEDULER !! \n");
 #endif
-		/* default scheduler is the eager one */
-		policy.init_sched = initialize_eager_center_policy;
-		policy.deinit_sched = NULL;
-		policy.get_local_queue = get_local_queue_eager;
-	}
+
+	policy.init_sched = sched_policy->init_sched;
+	policy.deinit_sched = sched_policy->deinit_sched;
+	policy.get_local_queue = sched_policy->get_local_queue;
 
 	pthread_cond_init(&policy.sched_activity_cond, NULL);
 	pthread_mutex_init(&policy.sched_activity_mutex, NULL);
 	pthread_key_create(&policy.local_queue_key, NULL);
+}
+
+static struct sched_policy_s *find_sched_policy_from_name(const char *policy_name)
+{
+
+	if (!policy_name)
+		return NULL;
+
+	if (strcmp(policy_name, "ws") == 0) {
+		return &sched_ws_policy;
+	}
+	else if (strcmp(policy_name, "prio") == 0) {
+		return &sched_prio_policy;
+	}
+	else if (strcmp(policy_name, "no-prio") == 0) {
+		return &sched_no_prio_policy;
+	}
+	else if (strcmp(policy_name, "dm") == 0) {
+		return &sched_dm_policy;
+	}
+	else if (strcmp(policy_name, "dmda") == 0) {
+		return &sched_dmda_policy;
+	}
+	else if (strcmp(policy_name, "random") == 0) {
+		return &sched_random_policy;
+	}
+	else if (strcmp(policy_name, "eager") == 0) {
+		return &sched_eager_policy;
+	}
+
+	return NULL;
+}
+
+static void display_sched_help_message(void)
+{
+	const char *sched_env = getenv("SCHED");
+	if (sched_env && (strcmp(sched_env, "help") == 0)) {
+		fprintf(stderr, "SCHED can be either of\n");
+		fprintf(stderr, "ws\twork stealing\n");
+		fprintf(stderr, "prio\tprio eager\n");
+		fprintf(stderr, "no-prio\teager (without prio)\n");
+		fprintf(stderr, "dm\tperformance model\n");
+		fprintf(stderr, "dmda\tdata-aware performance model\n");
+		fprintf(stderr, "random\trandom\n");
+		fprintf(stderr, "else the eager scheduler will be used\n");
+	 }
+}
+
+static struct sched_policy_s *select_sched_policy(struct machine_config_s *config)
+{
+	struct starpu_conf *user_conf = config->user_conf;
+
+	/* First, we check whether the application explicitely gave a scheduling policy or not */
+	if (user_conf && (user_conf->sched_policy))
+		return user_conf->sched_policy;
+
+	/* Otherwise, we look if the application specified the name of a policy to load */
+	const char *sched_pol_name;
+	if (user_conf && (user_conf->sched_policy_name))
+	{
+		sched_pol_name = user_conf->sched_policy_name;
+	}
+	else {
+		sched_pol_name = getenv("SCHED");
+	}
+
+	if (sched_pol_name)
+		return find_sched_policy_from_name(sched_pol_name);
+
+	/* If no policy was specified, we use the greedy policy as a default */
+	return &sched_eager_policy;
+}
+
+void init_sched_policy(struct machine_config_s *config)
+{
+	/* Perhaps we have to display some help */
+	display_sched_help_message();
+
+	struct sched_policy_s *selected_policy;
+	selected_policy = select_sched_policy(config);
 
-	mem_node_descr * const descr = get_memory_node_description();
-	pthread_rwlock_init(&descr->attached_queues_rwlock, NULL);
-	descr->total_queues_count = 0;
+	load_sched_policy(selected_policy);
 
 	policy.init_sched(config, &policy);
 }

+ 6 - 0
src/core/policies/sched_policy.h

@@ -37,6 +37,12 @@ struct sched_policy_s {
 	/* anyone can request which queue it is associated to */
 	struct jobq_s *(*get_local_queue)(struct sched_policy_s *);
 
+	/* name of the policy (optionnal) */
+	const char *policy_name;
+
+	/* description of the policy (optionnal) */
+	const char *policy_description;
+
 	/* some worker may block until some activity happens in the machine */
 	pthread_cond_t sched_activity_cond;
 	pthread_mutex_t sched_activity_mutex;

+ 10 - 3
src/core/policies/work-stealing-policy.c

@@ -174,8 +174,8 @@ static struct jobq_s *init_ws_deque(void)
 	return q;
 }
 
-void initialize_ws_policy(struct machine_config_s *config, 
-			__attribute__ ((unused))	struct sched_policy_s *_policy) 
+static void initialize_ws_policy(struct machine_config_s *config, 
+				__attribute__ ((unused)) struct sched_policy_s *_policy) 
 {
 	nworkers = 0;
 	rr_worker = 0;
@@ -185,7 +185,7 @@ void initialize_ws_policy(struct machine_config_s *config,
 	setup_queues(init_deque_queues_mechanisms, init_ws_deque, config);
 }
 
-struct jobq_s *get_local_queue_ws(struct sched_policy_s *policy __attribute__ ((unused)))
+static struct jobq_s *get_local_queue_ws(struct sched_policy_s *policy __attribute__ ((unused)))
 {
 	struct jobq_s *queue;
 	queue = pthread_getspecific(policy->local_queue_key);
@@ -199,3 +199,10 @@ struct jobq_s *get_local_queue_ws(struct sched_policy_s *policy __attribute__ ((
 	return queue;
 }
 
+struct sched_policy_s sched_ws_policy = {
+	.init_sched = initialize_ws_policy,
+	.deinit_sched = NULL,
+	.get_local_queue = get_local_queue_ws,
+	.policy_name = "ws",
+	.policy_description = "work stealing"
+};

+ 1 - 2
src/core/policies/work-stealing-policy.h

@@ -20,7 +20,6 @@
 #include <core/workers.h>
 #include <core/mechanisms/deque_queues.h>
 
-void initialize_ws_policy(struct machine_config_s *config, struct sched_policy_s *policy);
-struct jobq_s *get_local_queue_ws(struct sched_policy_s *policy);
+extern struct sched_policy_s sched_ws_policy;
 
 #endif // __WORK_STEALING_POLICY_H__

+ 3 - 2
src/datawizard/memory_nodes.c

@@ -35,12 +35,13 @@ void init_memory_nodes(void)
 
 	unsigned i;
 	for (i = 0; i < MAXNODES; i++) 
-	{
 		descr.nodes[i] = UNUSED; 
-	}
 
 	init_mem_chunk_lists();
 	init_data_request_lists();
+
+	pthread_rwlock_init(&descr.attached_queues_rwlock, NULL);
+	descr.total_queues_count = 0;
 }
 
 void deinit_memory_nodes(void)

+ 2 - 2
tests/core/starpu_wait_all_tasks.c

@@ -67,7 +67,7 @@ static void inject_one_task(void)
 }
 
 static struct starpu_conf conf = {
-	.sched_policy = NULL,
+	.sched_policy_name = NULL,
 	.ncpus = -1,
 	.ncuda = -1,
 	.nspus = -1,
@@ -91,7 +91,7 @@ static void parse_args(int argc, char **argv)
 			ntasks = atoi(optarg);
 			break;
 		case 'p':
-			conf.sched_policy = optarg;
+			conf.sched_policy_name = optarg;
 			break;
 		case 'h':
 			usage(argv);

+ 1 - 1
tests/errorcheck/starpu_init_noworker.c

@@ -26,7 +26,7 @@ int main(int argc, char **argv)
 
 	/* We try to initialize StarPU without any worker */
 	struct starpu_conf conf = {
-		.sched_policy = NULL, /* default */
+		.sched_policy_name = NULL, /* default */
 		.ncpus = 0,
 		.ncuda = 0,
 		.nspus = 0,

+ 2 - 2
tests/microbenchs/async-tasks-overhead.c

@@ -88,7 +88,7 @@ static void inject_one_task(void)
 }
 
 static struct starpu_conf conf = {
-	.sched_policy = NULL,
+	.sched_policy_name = NULL,
 	.ncpus = -1,
 	.ncuda = -1,
 	.nspus = -1,
@@ -112,7 +112,7 @@ static void parse_args(int argc, char **argv)
 			ntasks = atoi(optarg);
 			break;
 		case 'p':
-			conf.sched_policy = optarg;
+			conf.sched_policy_name = optarg;
 			break;
 		case 'h':
 			usage(argv);