Explorar o código

Some functions from starpu_task_bundle.h moved to where they rightfully belong.

Nicolas Collin %!s(int64=13) %!d(string=hai) anos
pai
achega
616f8b48f0

+ 0 - 23
include/starpu_task_bundle.h

@@ -19,8 +19,6 @@
 #ifndef __STARPU_TASK_BUNDLE_H__
 #define __STARPU_TASK_BUNDLE_H__
 
-#include <starpu_perfmodel.h>
-
 #ifdef __cplusplus
 extern "C"
 {
@@ -53,20 +51,6 @@ typedef struct _starpu_task_bundle *starpu_task_bundle_t;
  */
 void starpu_task_bundle_create(starpu_task_bundle_t *bundle);
 
-/* starpu_task_bundle_destroy
- * ==========================
- * Purpose
- * =======
- * Destroy and deinitialize a bundle,
- * memory previoulsy allocated is freed.
- *
- * Arguments
- * =========
- * bundle		(input)
- * 			Bundle to destroy.
- */
-void starpu_task_bundle_destroy(starpu_task_bundle_t bundle);
-
 /* starpu_task_bundle_insert
  * =========================
  * Purpose
@@ -134,13 +118,6 @@ int starpu_task_bundle_remove(starpu_task_bundle_t bundle, struct starpu_task *t
  */
 void starpu_task_bundle_close(starpu_task_bundle_t bundle);
 
-/* Return the expected duration of the entire task bundle in µs. */
-double starpu_task_bundle_expected_length(starpu_task_bundle_t bundle, enum starpu_perf_archtype arch, unsigned nimpl);
-/* Return the time (in µs) expected to transfer all data used within the bundle */
-double starpu_task_bundle_expected_data_transfer_time(starpu_task_bundle_t bundle, unsigned memory_node);
-/* Return the expected power consumption of the entire task bundle in J. */
-double starpu_task_bundle_expected_power(starpu_task_bundle_t bundle, enum starpu_perf_archtype arch, unsigned nimpl);
-
 #ifdef __cplusplus
 }
 #endif

+ 113 - 0
src/core/perfmodel/perfmodel.c

@@ -336,6 +336,119 @@ double starpu_task_expected_data_transfer_time(uint32_t memory_node, struct star
 	return penalty;
 }
 
+/* Return the expected duration of the entire task bundle in µs */
+double _starpu_task_bundle_expected_length(starpu_task_bundle_t bundle, enum starpu_perf_archtype arch, unsigned nimpl)
+{
+	double expected_length = 0.0;
+
+	/* We expect the length of the bundle the be the sum of the different tasks length. */
+	_STARPU_PTHREAD_MUTEX_LOCK(&bundle->mutex);
+
+	struct _starpu_task_bundle_entry *entry;
+	entry = bundle->list;
+
+	while (entry)
+	{
+		double task_length = starpu_task_expected_length(entry->task, arch, nimpl);
+
+		/* In case the task is not calibrated, we consider the task
+		 * ends immediately. */
+		if (task_length > 0.0)
+			expected_length += task_length;
+
+		entry = entry->next;
+	}
+
+	_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
+
+	return expected_length;
+}
+
+/* Return the expected power consumption of the entire task bundle in J */
+double _starpu_task_bundle_expected_power(starpu_task_bundle_t bundle, enum starpu_perf_archtype arch, unsigned nimpl)
+{
+	double expected_power = 0.0;
+
+	/* We expect total consumption of the bundle the be the sum of the different tasks consumption. */
+	_STARPU_PTHREAD_MUTEX_LOCK(&bundle->mutex);
+
+	struct _starpu_task_bundle_entry *entry;
+	entry = bundle->list;
+
+	while (entry)
+	{
+		double task_power = starpu_task_expected_power(entry->task, arch, nimpl);
+
+		/* In case the task is not calibrated, we consider the task
+		 * ends immediately. */
+		if (task_power > 0.0)
+			expected_power += task_power;
+
+		entry = entry->next;
+	}
+
+	_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
+
+	return expected_power;
+}
+
+/* Return the time (in µs) expected to transfer all data used within the bundle */
+double _starpu_task_bundle_expected_data_transfer_time(starpu_task_bundle_t bundle, unsigned memory_node)
+{
+	_STARPU_PTHREAD_MUTEX_LOCK(&bundle->mutex);
+
+	struct _starpu_handle_list *handles = NULL;
+
+	/* We list all the handle that are accessed within the bundle. */
+
+	/* For each task in the bundle */
+	struct _starpu_task_bundle_entry *entry = bundle->list;
+	while (entry)
+	{
+		struct starpu_task *task = entry->task;
+
+		if (task->cl)
+		{
+			unsigned b;
+			for (b = 0; b < task->cl->nbuffers; b++)
+			{
+				starpu_data_handle_t handle = task->handles[b];
+				enum starpu_access_mode mode = task->cl->modes[b];
+
+				if (!(mode & STARPU_R))
+					continue;
+
+				/* Insert the handle in the sorted list in case
+				 * it's not already in that list. */
+				_insertion_handle_sorted(&handles, handle, mode);
+			}
+		}
+
+		entry = entry->next;
+	}
+
+	_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
+
+	/* Compute the sum of data transfer time, and destroy the list */
+
+	double total_exp = 0.0;
+
+	while (handles)
+	{
+		struct _starpu_handle_list *current = handles;
+		handles = handles->next;
+
+		double exp;
+		exp = starpu_data_expected_transfer_time(current->handle, memory_node, current->mode);
+
+		total_exp += exp;
+
+		free(current);
+	}
+
+	return total_exp;
+}
+
 static int directory_existence_was_tested = 0;
 
 void _starpu_get_perf_model_dir(char *path, size_t maxlen)

+ 8 - 0
src/core/perfmodel/perfmodel.h

@@ -24,6 +24,7 @@
 #include <starpu_perfmodel.h>
 //#include <core/jobs.h>
 #include <common/htable32.h>
+#include <core/task_bundle.h>
 //#include <core/workers.h>
 #include <pthread.h>
 #include <stdio.h>
@@ -65,6 +66,13 @@ void _starpu_create_sampling_directory_if_needed(void);
 void _starpu_load_bus_performance_files(void);
 double _starpu_predict_transfer_time(unsigned src_node, unsigned dst_node, size_t size);
 
+/* Return the expected duration of the entire task bundle in µs. */
+double _starpu_task_bundle_expected_length(starpu_task_bundle_t bundle, enum starpu_perf_archtype arch, unsigned nimpl);
+/* Return the time (in µs) expected to transfer all data used within the bundle */
+double _starpu_task_bundle_expected_data_transfer_time(starpu_task_bundle_t bundle, unsigned memory_node);
+/* Return the expected power consumption of the entire task bundle in J. */
+double _starpu_task_bundle_expected_power(starpu_task_bundle_t bundle, enum starpu_perf_archtype arch, unsigned nimpl);
+
 void _starpu_set_calibrate_flag(unsigned val);
 unsigned _starpu_get_calibrate_flag(void);
 

+ 34 - 151
src/core/task_bundle.c

@@ -2,6 +2,7 @@
  *
  * Copyright (C) 2011  Université de Bordeaux 1
  * Copyright (C) 2011  Télécom-SudParis
+ * Copyright (C) 2012  Inria
  *
  * 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
@@ -30,6 +31,8 @@ void starpu_task_bundle_create(starpu_task_bundle_t *bundle)
 	STARPU_ASSERT(*bundle);
 
 	_STARPU_PTHREAD_MUTEX_INIT(&(*bundle)->mutex, NULL);
+	/* Of course at the beginning a bundle is open,
+	 * user can insert and remove tasks from it */
 	(*bundle)->closed = 0;
 
 	/* Start with an empty list */
@@ -37,38 +40,20 @@ void starpu_task_bundle_create(starpu_task_bundle_t *bundle)
 
 }
 
-/* Deinitialize a bundle. In case the destroy flag is set, the bundle structure
- * is freed too. */
-void starpu_task_bundle_destroy(starpu_task_bundle_t bundle)
-{
-	/* Remove all entries from the bundle (which is likely to be empty) */
-	while (bundle->list)
-	{
-		struct _starpu_task_bundle_entry *entry = bundle->list;
-		bundle->list = bundle->list->next;
-		free(entry);
-	}
-
-	_STARPU_PTHREAD_MUTEX_DESTROY(&bundle->mutex);
-
-	free(bundle);
-}
-
-/* Insert a task into a bundle. */
 int starpu_task_bundle_insert(starpu_task_bundle_t bundle, struct starpu_task *task)
 {
 	_STARPU_PTHREAD_MUTEX_LOCK(&bundle->mutex);
 
 	if (bundle->closed)
 	{
-		/* The bundle is closed, we cannot add tasks anymore */
+		/* The bundle is closed, we cannot add task anymore */
 		_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
 		return -EPERM;
 	}
 
 	if (task->status != STARPU_TASK_INVALID)
 	{
-		/* the task has already been submitted, it's too late to put it
+		/* The task has already been submitted, it's too late to put it
 		 * into a bundle now. */
 		_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
 		return -EINVAL;
@@ -95,16 +80,13 @@ int starpu_task_bundle_insert(starpu_task_bundle_t bundle, struct starpu_task *t
 		item->next = entry;
 	}
 
+	/* Mark the task as belonging the bundle */
 	task->bundle = bundle;
 
 	_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
 	return 0;
 }
 
-/* Remove a task from a bundle. This method must be called with bundle->mutex
- * hold. This function returns 0 if the task was found, -ENOENT if the element
- * was not found, 1 if the element is found and if the list was deinitialized
- * because it was locked and became empty. */
 int starpu_task_bundle_remove(starpu_task_bundle_t bundle, struct starpu_task *task)
 {
 	struct _starpu_task_bundle_entry *item;
@@ -113,6 +95,8 @@ int starpu_task_bundle_remove(starpu_task_bundle_t bundle, struct starpu_task *t
 
 	item = bundle->list;
 
+	/* List is empty, there is no way the task
+	 * belong to it */
 	if (!item)
 	{
 		_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
@@ -132,7 +116,7 @@ int starpu_task_bundle_remove(starpu_task_bundle_t bundle, struct starpu_task *t
 		if (bundle->closed && bundle->list == NULL)
 		{
 			_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
-			starpu_task_bundle_destroy(bundle);
+			_starpu_task_bundle_destroy(bundle);
 			return 0;
 		}
 
@@ -140,6 +124,8 @@ int starpu_task_bundle_remove(starpu_task_bundle_t bundle, struct starpu_task *t
 		return 0;
 	}
 
+	/* Go through the list until we find the right task,
+	 * then we delete it */
 	while (item->next)
 	{
 		struct _starpu_task_bundle_entry *next;
@@ -170,11 +156,12 @@ void starpu_task_bundle_close(starpu_task_bundle_t bundle)
 {
 	_STARPU_PTHREAD_MUTEX_LOCK(&bundle->mutex);
 
-	/* If the bundle is already empty, we deinitialize it now. */
+	/* If the bundle is already empty, we deinitialize it now as the
+	 * user closed it and thus don't intend to insert new tasks in it. */
 	if (bundle->list == NULL)
 	{
 		_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
-		starpu_task_bundle_destroy(bundle);
+		_starpu_task_bundle_destroy(bundle);
 		return;
 	}
 
@@ -185,79 +172,32 @@ void starpu_task_bundle_close(starpu_task_bundle_t bundle)
 
 }
 
-/* Return the expected duration of the entire task bundle in µs */
-double starpu_task_bundle_expected_length(starpu_task_bundle_t bundle, enum starpu_perf_archtype arch, unsigned nimpl)
-{
-	double expected_length = 0.0;
-
-	/* We expect the length of the bundle the be the sum of the different tasks length. */
-	_STARPU_PTHREAD_MUTEX_LOCK(&bundle->mutex);
-
-	struct _starpu_task_bundle_entry *entry;
-	entry = bundle->list;
-
-	while (entry)
-	{
-		double task_length = starpu_task_expected_length(entry->task, arch, nimpl);
-
-		/* In case the task is not calibrated, we consider the task
-		 * ends immediately. */
-		if (task_length > 0.0)
-			expected_length += task_length;
-
-		entry = entry->next;
-	}
-
-	_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
-
-	return expected_length;
-}
-
-/* Return the expected power consumption of the entire task bundle in J */
-double starpu_task_bundle_expected_power(starpu_task_bundle_t bundle, enum starpu_perf_archtype arch, unsigned nimpl)
+void _starpu_task_bundle_destroy(starpu_task_bundle_t bundle)
 {
-	double expected_power = 0.0;
-
-	/* We expect total consumption of the bundle the be the sum of the different tasks consumption. */
-	_STARPU_PTHREAD_MUTEX_LOCK(&bundle->mutex);
-
-	struct _starpu_task_bundle_entry *entry;
-	entry = bundle->list;
-
-	while (entry)
+	/* Remove all entries from the bundle (which is likely to be empty) */
+	while (bundle->list)
 	{
-		double task_power = starpu_task_expected_power(entry->task, arch, nimpl);
-
-		/* In case the task is not calibrated, we consider the task
-		 * ends immediately. */
-		if (task_power > 0.0)
-			expected_power += task_power;
-
-		entry = entry->next;
+		struct _starpu_task_bundle_entry *entry = bundle->list;
+		bundle->list = bundle->list->next;
+		free(entry);
 	}
 
-	_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
+	_STARPU_PTHREAD_MUTEX_DESTROY(&bundle->mutex);
 
-	return expected_power;
+	free(bundle);
 }
 
-struct handle_list
-{
-	starpu_data_handle_t handle;
-	enum starpu_access_mode mode;
-	struct handle_list *next;
-};
-
-static void insertion_handle_sorted(struct handle_list **listp, starpu_data_handle_t handle, enum starpu_access_mode mode)
+void _insertion_handle_sorted(struct _starpu_handle_list **listp, starpu_data_handle_t handle, enum starpu_access_mode mode)
 {
 	STARPU_ASSERT(listp);
 
-	struct handle_list *list = *listp;
+	struct _starpu_handle_list *list = *listp;
 
+	/* If the list is empty or the handle's address the smallest among the
+	 * list, we insert it as first element */
 	if (!list || list->handle > handle)
 	{
-		/* We insert the first element of the list */
-		struct handle_list *link = (struct handle_list *) malloc(sizeof(struct handle_list));
+		struct _starpu_handle_list *link = (struct _starpu_handle_list *) malloc(sizeof(struct _starpu_handle_list));
 		STARPU_ASSERT(link);
 		link->handle = handle;
 		link->mode = mode;
@@ -266,26 +206,26 @@ static void insertion_handle_sorted(struct handle_list **listp, starpu_data_hand
 		return;
 	}
 
-	/* Look for the element or a place to insert it. */
-	struct handle_list *prev = list;
+	struct _starpu_handle_list *prev = list;
 
+	/* Look for the same handle if already present in the list.
+	 * Else place it right before the smallest following handle */
 	while (list && (handle >= list->handle))
 	{
 		prev = list;
 		list = list->next;
 	}
 
-	/* The element should be in prev or not in the list */
-
 	if (prev->handle == handle)
 	{
-		/* The handle is already in the list */
+		/* The handle is already in the list, the merge both the access modes */
 		prev->mode = (enum starpu_access_mode) ((int) prev->mode | (int) mode);
 	}
 	else
 	{
-		/* The handle was not in the list, we insert it after prev */
-		struct handle_list *link = (struct handle_list *) malloc(sizeof(struct handle_list));
+		/* The handle was not in the list, we insert it after 'prev', thus right before
+		 * 'list' which is the smallest following handle */
+		struct _starpu_handle_list *link = (struct _starpu_handle_list *) malloc(sizeof(struct _starpu_handle_list));
 		STARPU_ASSERT(link);
 		link->handle = handle;
 		link->mode = mode;
@@ -293,60 +233,3 @@ static void insertion_handle_sorted(struct handle_list **listp, starpu_data_hand
 		prev->next = link;
 	}
 }
-
-/* Return the time (in µs) expected to transfer all data used within the bundle */
-double starpu_task_bundle_expected_data_transfer_time(starpu_task_bundle_t bundle, unsigned memory_node)
-{
-	_STARPU_PTHREAD_MUTEX_LOCK(&bundle->mutex);
-
-	struct handle_list *handles = NULL;
-
-	/* We list all the handle that are accessed within the bundle. */
-
-	/* For each task in the bundle */
-	struct _starpu_task_bundle_entry *entry = bundle->list;
-	while (entry)
-	{
-		struct starpu_task *task = entry->task;
-
-		if (task->cl)
-		{
-			unsigned b;
-			for (b = 0; b < task->cl->nbuffers; b++)
-			{
-				starpu_data_handle_t handle = task->handles[b];
-				enum starpu_access_mode mode = task->cl->modes[b];
-
-				if (!(mode & STARPU_R))
-					continue;
-
-				/* Insert the handle in the sorted list in case
-				 * it's not already in that list. */
-				insertion_handle_sorted(&handles, handle, mode);
-			}
-		}
-
-		entry = entry->next;
-	}
-
-	_STARPU_PTHREAD_MUTEX_UNLOCK(&bundle->mutex);
-
-	/* Compute the sum of data transfer time, and destroy the list */
-
-	double total_exp = 0.0;
-
-	while (handles)
-	{
-		struct handle_list *current = handles;
-		handles = handles->next;
-
-		double exp;
-		exp = starpu_data_expected_transfer_time(current->handle, memory_node, current->mode);
-
-		total_exp += exp;
-
-		free(current);
-	}
-
-	return total_exp;
-}

+ 39 - 0
src/core/task_bundle.h

@@ -100,4 +100,43 @@ struct _starpu_handle_list
 	struct _starpu_handle_list *next;
 };
 
+/* _starpu_task_bundle_destroy
+ * ==========================
+ * Purpose
+ * =======
+ * Destroy and deinitialize a bundle,
+ * memory previoulsy allocated is freed.
+ *
+ * Arguments
+ * =========
+ * bundle		(input)
+ * 			Bundle to destroy.
+ */
+void _starpu_task_bundle_destroy(starpu_task_bundle_t bundle);
+
+/* _insertion_handle_sorted
+ * ========================
+ * Purpose
+ * =======
+ * Insert an handle in a _starpu_handle_list, elements are sorted
+ * in increasing order, considering their physical address.
+ * As the list doesn't accept duplicate elements, a handle with the
+ * same address as an handle contained in the list is not inserted, but
+ * its mode access is merged with the one of the latter.
+ *
+ * Arguments
+ * =========
+ * listp		(input, output)
+ * 			Pointer to the first element of the list.
+ * 			In the case of an empty list or an inserted handle with small address,
+ * 			it should have changed when the call returns.
+ *
+ * handle		(input)
+ * 			Handle to insert in the list.
+ *
+ * mode			(input)
+ * 			Access mode of the handle.
+ */
+void _insertion_handle_sorted(struct _starpu_handle_list **listp, starpu_data_handle_t handle, enum starpu_access_mode mode);
+
 #endif // __CORE_TASK_BUNDLE_H__

+ 3 - 3
src/sched_policies/heft.c

@@ -267,9 +267,9 @@ static void compute_all_performance_predictions(struct starpu_task *task,
 			if (bundle)
 			{
 				/* TODO : conversion time */
-				local_task_length[worker][nimpl] = starpu_task_bundle_expected_length(bundle, perf_arch, nimpl);
-				local_data_penalty[worker][nimpl] = starpu_task_bundle_expected_data_transfer_time(bundle, memory_node);
-				local_power[worker][nimpl] = starpu_task_bundle_expected_power(bundle, perf_arch,nimpl);
+				local_task_length[worker][nimpl] = _starpu_task_bundle_expected_length(bundle, perf_arch, nimpl);
+				local_data_penalty[worker][nimpl] = _starpu_task_bundle_expected_data_transfer_time(bundle, memory_node);
+				local_power[worker][nimpl] = _starpu_task_bundle_expected_power(bundle, perf_arch,nimpl);
 				//_STARPU_DEBUG("Scheduler heft bundle: task length (%lf) local power (%lf) worker (%u) kernel (%u) \n", local_task_length[worker],local_power[worker],worker,nimpl);
 
 			}