소스 검색

clean lp2paje, make it a real documented starpu tool

Samuel Thibault 12 년 전
부모
커밋
e850b08c6c
7개의 변경된 파일102개의 추가작업 그리고 245개의 파일을 삭제
  1. 6 8
      doc/chapters/advanced-examples.texi
  2. 21 14
      examples/cholesky/cholesky.h
  3. 7 2
      examples/cholesky/cholesky_implicit.c
  4. 21 15
      src/profiling/bound.c
  5. 5 3
      tools/Makefile.am
  6. 0 156
      tools/cbc2paje.c
  7. 42 47
      tools/lp2paje.c

+ 6 - 8
doc/chapters/advanced-examples.texi

@@ -474,14 +474,15 @@ probably use @code{lp_solve -timeout 1 test.pl -wmps test.mps} to convert the
 problem to MPS format and then use a better solver, @code{glpsol} might be
 better than @code{lp_solve} for instance (the @code{--pcost} option may be
 useful), but sometimes doesn't manage to converge. @code{cbc} might look
-slower, but it is parallel. Be sure to try at least all the @code{-B} options
-of @code{lp_solve}. For instance, we often just use
-@code{lp_solve -cc -B1 -Bb -Bg -Bp -Bf -Br -BG -Bd -Bs -BB -Bo -Bc -Bi} , and
-the @code{-gr} option can also be quite useful.
+slower, but it is parallel. For @code{lp_solve}, be sure to try at least all the
+@code{-B} options. For instance, we often just use @code{lp_solve -cc -B1 -Bb
+-Bg -Bp -Bf -Br -BG -Bd -Bs -BB -Bo -Bc -Bi} , and the @code{-gr} option can
+also be quite useful. The resulting schedule can be observed by using the
+@code{starpu_lp2paje} tool, which converts it into the Paje format.
 
 Data transfer time can only be taken into account when @code{deps} is set. Only
 data transfers inferred from implicit data dependencies between tasks are taken
-into account.
+into account. Other data transfers are assumed to be completely overlapped.
 
 Setting @code{deps} to 0 will only take into account the actual computations
 on processing units. It however still properly takes into account the varying
@@ -493,9 +494,6 @@ the priorities as the StarPU scheduler would, i.e. schedule prioritized
 tasks before less prioritized tasks, to check to which extend this results
 to a less optimal solution. This increases even more computation time.
 
-Note that for simplicity, all this however doesn't take into account data
-transfers, which are assumed to be completely overlapped.
-
 @node Insert Task Utility
 @section Insert Task Utility
 

+ 21 - 14
examples/cholesky/cholesky.h

@@ -122,6 +122,7 @@ static unsigned check = 0;
 static unsigned bound = 0;
 static unsigned bound_deps = 0;
 static unsigned bound_lp = 0;
+static unsigned bound_mps = 0;
 static unsigned with_ctxs = 0;
 static unsigned with_noctxs = 0;
 static unsigned chole1 = 0;
@@ -150,77 +151,83 @@ static void __attribute__((unused)) parse_args(int argc, char **argv)
 		{
 			with_ctxs = 1;
 			break;
-		}
+		} else
 		if (strcmp(argv[i], "-with_noctxs") == 0) 
 		{
 			with_noctxs = 1;
 			break;
-		}
+		} else
 		
 		if (strcmp(argv[i], "-chole1") == 0) 
 		{
 			chole1 = 1;
 			break;
-		}
+		} else
 
 		if (strcmp(argv[i], "-chole2") == 0) 
 		{
 			chole2 = 1;
 			break;
-		}
+		} else
 
 		if (strcmp(argv[i], "-size") == 0)
 		{
 		        char *argptr;
 			size = strtol(argv[++i], &argptr, 10);
-		}
+		} else
 
 		if (strcmp(argv[i], "-nblocks") == 0)
 		{
 		        char *argptr;
 			nblocks = strtol(argv[++i], &argptr, 10);
-		}
+		} else
 
 		if (strcmp(argv[i], "-nbigblocks") == 0)
 		{
 		        char *argptr;
 			nbigblocks = strtol(argv[++i], &argptr, 10);
-		}
+		} else
 
 		if (strcmp(argv[i], "-no-pin") == 0)
 		{
 			pinned = 0;
-		}
+		} else
 
 		if (strcmp(argv[i], "-no-prio") == 0)
 		{
 			noprio = 1;
-		}
+		} else
 
 		if (strcmp(argv[i], "-bound") == 0)
 		{
 			bound = 1;
-		}
+		} else
 
 		if (strcmp(argv[i], "-bound-lp") == 0)
 		{
 			bound_lp = 1;
-		}
+		} else
+
+		if (strcmp(argv[i], "-bound-mps") == 0)
+		{
+			bound_mps = 1;
+		} else
 
 		if (strcmp(argv[i], "-bound-deps") == 0)
 		{
 			bound_deps = 1;
-		}
+		} else
 
 		if (strcmp(argv[i], "-check") == 0)
 		{
 			check = 1;
-		}
+		} else
 
-		if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i],"--help") == 0)
+		/* if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i],"--help") == 0) */
 		{
 			fprintf(stderr,"usage : %s [-size size] [-nblocks nblocks] [-no-pin] [-no-prio] [-bound] [-bound-deps] [-bound-lp] [-check]\n", argv[0]);
 			fprintf(stderr,"Currently selected: %ux%u and %ux%u blocks\n", size, size, nblocks, nblocks);
+			exit(0);
 		}
 	}
 }

+ 7 - 2
examples/cholesky/cholesky_implicit.c

@@ -89,7 +89,7 @@ static int _cholesky(starpu_data_handle_t dataA, unsigned nblocks)
 
 	start = starpu_timing_now();
 
-	if (bound || bound_lp)
+	if (bound || bound_lp || bound_mps)
 		starpu_bound_start(bound_deps, 0);
 	/* create all the DAG nodes */
 	for (k = 0; k < nblocks; k++)
@@ -140,7 +140,7 @@ static int _cholesky(starpu_data_handle_t dataA, unsigned nblocks)
 	}
 
 	starpu_task_wait_for_all();
-	if (bound || bound_lp)
+	if (bound || bound_lp || bound_mps)
 		starpu_bound_stop();
 
 	end = starpu_timing_now();
@@ -162,6 +162,11 @@ static int _cholesky(starpu_data_handle_t dataA, unsigned nblocks)
 			FILE *f = fopen("cholesky.lp", "w");
 			starpu_bound_print_lp(f);
 		}
+		if (bound_mps)
+		{
+			FILE *f = fopen("cholesky.mps", "w");
+			starpu_bound_print_mps(f);
+		}
 		if (bound)
 		{
 			double res;

+ 21 - 15
src/profiling/bound.c

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  * Copyright (C) 2010, 2011, 2012, 2013  Centre National de la Recherche Scientifique
- * Copyright (C) 2010-2012  Université de Bordeaux 1
+ * Copyright (C) 2010-2013  Université de Bordeaux 1
  * Copyright (C) 2011  Télécom-SudParis
  *
  * StarPU is free software; you can redistribute it and/or modify
@@ -501,10 +501,16 @@ void starpu_bound_print_lp(FILE *output)
 		}
 		fprintf(output, "/* StarPU upper bound linear programming problem, to be run in lp_solve. */\n\n");
 		fprintf(output, "/* !! This is a big system, it will be long to solve !! */\n\n");
+
 		fprintf(output, "/* We want to minimize total execution time (ms) */\n");
 		fprintf(output, "min: tmax;\n\n");
 
-		fprintf(output, "/* Which is the maximum of all task completion times (ms) */\n");
+		fprintf(output, "/* Number of tasks */\n");
+		fprintf(output, "nt = %d;\n", nt);
+		fprintf(output, "/* Number of workers */\n");
+		fprintf(output, "nw = %d;\n", nw);
+
+		fprintf(output, "/* The total execution time is the maximum of all task completion times (ms) */\n");
 		for (t1 = tasks; t1; t1 = t1->next)
 			fprintf(output, "c%lu <= tmax;\n", t1->id);
 
@@ -836,12 +842,12 @@ void starpu_bound_print_mps(FILE *output)
 
 		fprintf(output, "NAME           StarPU theoretical bound\n");
 
-		fprintf(output, "\nROWS\n");
+		fprintf(output, "*\nROWS\n");
 
 		fprintf(output, "* We want to minimize total execution time (ms)\n");
 		fprintf(output, " N  TMAX\n");
 
-		fprintf(output, "\n* Which is the maximum of all worker execution times (ms)\n");
+		fprintf(output, "* Which is the maximum of all worker execution times (ms)\n");
 		for (w = 0; w < nw; w++)
 		{
 			char name[32];
@@ -850,36 +856,36 @@ void starpu_bound_print_mps(FILE *output)
 			fprintf(output, " L  W%d\n", w);
 		}
 
-		fprintf(output, "\n* And we have to have computed exactly all tasks\n");
+		fprintf(output, "*\n* And we have to have computed exactly all tasks\n*\n");
 		for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
 		{
 			fprintf(output, "* task %s key %x\n", _starpu_codelet_get_model_name(tp->cl), (unsigned) tp->footprint);
 			fprintf(output, " E  T%d\n", t);
 		}
 
-		fprintf(output, "\nCOLUMNS\n");
+		fprintf(output, "*\nCOLUMNS\n*\n");
 
-		fprintf(output, "\n* Execution times and completion of all tasks\n");
+		fprintf(output, "*\n* Execution times and completion of all tasks\n*\n");
 		for (w = 0; w < nw; w++)
 			for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
 				if (!isnan(times[w*nt+t]))
 				{
 					char name[9];
 					snprintf(name, sizeof(name), "W%dT%d", w, t);
-					fprintf(stderr,"    %-8s  W%-7d  %12f\n", name, w, times[w*nt+t]);
-					fprintf(stderr,"    %-8s  T%-7d  %12d\n", name, t, 1);
+					fprintf(output,"    %-8s  W%-7d  %12f\n", name, w, times[w*nt+t]);
+					fprintf(output,"    %-8s  T%-7d  %12d\n", name, t, 1);
 				}
 
-		fprintf(output, "\n* Total execution time\n");
+		fprintf(output, "*\n* Total execution time\n*\n");
 		for (w = 0; w < nw; w++)
-			fprintf(stderr,"    TMAX      W%-2d       %12d\n", w, -1);
-		fprintf(stderr,"    TMAX      TMAX      %12d\n", 1);
+			fprintf(output,"    TMAX      W%-2d       %12d\n", w, -1);
+		fprintf(output,"    TMAX      TMAX      %12d\n", 1);
 
-		fprintf(output, "\nRHS\n");
+		fprintf(output, "*\nRHS\n*\n");
 
-		fprintf(output, "\n* Total number of tasks\n");
+		fprintf(output, "*\n* Total number of tasks\n*\n");
 		for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
-			fprintf(stderr,"    NT%-2d      T%-7d  %12lu\n", t, t, tp->n);
+			fprintf(output,"    NT%-2d      T%-7d  %12lu\n", t, t, tp->n);
 
 		fprintf(output, "ENDATA\n");
 	}

+ 5 - 3
tools/Makefile.am

@@ -86,7 +86,8 @@ bin_PROGRAMS += 			\
 	starpu_perfmodel_display	\
 	starpu_perfmodel_plot 		\
 	starpu_calibrate_bus		\
-	starpu_machine_display
+	starpu_machine_display		\
+	starpu_lp2paje
 
 starpu_perfmodel_plot_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(FXT_CFLAGS)
 
@@ -104,8 +105,6 @@ STARPU_TOOLS	+=			\
 	starpu_perfmodel_plot
 endif
 
-noinst_PROGRAMS =	cbc2paje lp2paje
-
 dist_bin_SCRIPTS +=			\
 	starpu_workers_activity		\
 	starpu_codelet_histo_profile	\
@@ -129,6 +128,8 @@ starpu_perfmodel_display.1: starpu_perfmodel_display$(EXEEXT)
 	help2man --no-discard-stderr -N --output=$@ ./$<
 starpu_perfmodel_plot.1: starpu_perfmodel_plot$(EXEEXT)
 	help2man --no-discard-stderr -N --output=$@ ./$<
+starpu_lp2paje.1: starpu_lp2paje$(EXEEXT)
+	help2man --no-discard-stderr -N --output=$@ ./$<
 starpu_workers_activity.1: starpu_workers_activity$(EXEEXT)
 	chmod +x $<
 	help2man --no-discard-stderr -N --output=$@ ./$<
@@ -153,6 +154,7 @@ dist_man1_MANS =\
 	starpu_machine_display.1 \
 	starpu_perfmodel_display.1 \
 	starpu_perfmodel_plot.1	\
+	starpu_lp2paje.1	\
 	starpu_workers_activity.1 \
 	starpu_codelet_profile.1 \
 	starpu_codelet_histo_profile.1

+ 0 - 156
tools/cbc2paje.c

@@ -1,156 +0,0 @@
-/* StarPU --- Runtime system for heterogeneous multicore architectures.
- *
- * Copyright (C) 2010  Université de Bordeaux 1
- *
- * 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 <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct task {
-	double start;
-	double stop;
-	int worker;
-};
-
-int main(int argc, char *argv[]) {
-	int nw, nt;
-	double tmax;
-	int i, w, t, t2;
-	int foo;
-	double bar;
-	unsigned long num;
-	int b;
-	unsigned long next = 1;
-
-	if (argc != 3) {
-		fprintf(stderr,"usage: %s nb_workers nb_tasks\n", argv[0]);
-		exit(1);
-	}
-	nw = atoi(argv[1]);
-	nt = atoi(argv[2]);
-	fprintf(stderr,"%d workers, %d tasks\n", nw, nt);
-	assert(scanf("Optimal - objective value       %lf", &tmax) == 1);
-	printf(
-"%%EventDef PajeDefineContainerType 1\n"
-"%%  Alias         string\n"
-"%%  ContainerType string\n"
-"%%  Name          string\n"
-"%%EndEventDef\n"
-"%%EventDef PajeCreateContainer     2\n"
-"%%  Time          date\n"
-"%%  Alias         string\n"
-"%%  Type          string\n"
-"%%  Container     string\n"
-"%%  Name          string\n"
-"%%EndEventDef\n"
-"%%EventDef PajeDefineStateType     3\n"
-"%%  Alias         string\n"
-"%%  ContainerType string\n"
-"%%  Name          string\n"
-"%%EndEventDef\n"
-"%%EventDef PajeDestroyContainer    4\n"
-"%%  Time          date\n"
-"%%  Name          string\n"
-"%%  Type          string\n"
-"%%EndEventDef\n"
-"%%EventDef PajeDefineEntityValue 5\n"
-"%%  Alias         string\n"
-"%%  EntityType    string\n"
-"%%  Name          string\n"
-"%%  Color         color\n"
-"%%EndEventDef\n"
-"%%EventDef PajeSetState 6\n"
-"%%  Time          date\n"
-"%%  Type          string\n"
-"%%  Container     string\n"
-"%%  Value         string\n"
-"%%EndEventDef\n"
-"1 W 0 Worker\n"
-);
-	printf("3 S W \"Worker State\"\n");
-	printf("5 S S Running \"0.0 1.0 0.0\"\n");
-	printf("5 F S Idle \"1.0 0.0 0.0\"\n");
-	for (i = 0; i < nw; i++)
-		printf("2 0 W%d W 0 \"%d\"\n", i, i);
-
-	for (w = 0; w < nw; w++)
-		printf("4 %f W%d W\n", tmax, w);
-
-	assert(scanf("%d C%d %lf %lf", &foo, &foo, &tmax, &bar) == 4);
-	next++;
-	{
-		struct task task[nt];
-		memset(&task, 0, sizeof(task));
-		for (t = 0; t < nt; t++) {
-			assert(scanf("%d C%d %lf %lf", &foo, &foo, &task[t].stop, &bar) == 4);
-			next++;
-		}
-
-		while (1) {
-			assert(scanf("%d C%lu", &foo, &num) == 2);
-			if (num >= next +
-
-				/* FIXME */
-				//nw*nt
-				8*20 + 5*16
-
-				) {
-				next+= 8*20+5*16;
-				break;
-			}
-			/* FIXME */
-			if (num-next < 8*20) {
-				t = (num - next) / nw;
-				w = (num - next) % nw;
-			} else {
-				unsigned long nnum = (num-next)-8*20;
-				t = (nnum / 5) + 20;
-				w = (nnum % 5)+3;
-			}
-
-			assert(scanf("%d %lf", &b, &bar) == 2);
-			if (b) {
-				task[t].worker = w;
-				fprintf(stderr,"%lu: task %d on %d: %f\n", num, t, w, task[t].stop);
-			}
-		}
-		while(1) {
-			t = num - next;
-			if (t > nt)
-				break;
-			assert(scanf("%lf %lf", &task[t].start, &bar) == 2);
-			assert(scanf("%d C%lu", &foo, &num) == 2);
-		}
-
-		for (t = 0; t < nt; t++) {
-			printf("6 %f S W%d S\n", task[t].start, task[t].worker);
-			printf("6 %f S W%d F\n", task[t].stop, task[t].worker);
-		}
-
-		for (t = 0; t < nt; t++) {
-			for (t2 = 0; t2 < nt; t2++) {
-				if (t != t2 && task[t].worker == task[t2].worker) {
-					if (!(task[t].start >= task[t2].stop
-					    || task[t2].start >= task[t].stop)) {
-						fprintf(stderr,"oops, %d and %d sharing worker %d !!\n", t, t2, task[t].worker);
-					}
-				}
-			}
-		}
-	}
-
-	return 0;
-}

+ 42 - 47
tools/lp2paje.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2010-2011  Université de Bordeaux 1
+ * Copyright (C) 2010-2011, 2013  Université de Bordeaux 1
  *
  * 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
@@ -14,34 +14,48 @@
  * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  */
 
+#include <config.h>
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#define PROGNAME "starpu_lp2paje"
+
 struct task {
 	double start;
 	double stop;
+	int num;
 	int worker;
 };
 
 int main(int argc, char *argv[]) {
 	int nw, nt;
 	double tmax;
-	int i, w, t, t2;
+	int i, w, ww, t, tt, t2;
 	int foo;
 	double bar;
-	unsigned long num;
-	unsigned long next = 1;
 
-	if (argc != 3) {
-		fprintf(stderr,"usage: %s nb_workers nb_tasks\n", argv[0]);
-		exit(1);
+	if (argc != 1) {
+		if (strcmp(argv[1], "-v") == 0
+		 || strcmp(argv[1], "--version") == 0)
+		{
+			fprintf(stderr, PROGNAME " (" PACKAGE_NAME ") " PACKAGE_VERSION "\n");
+			exit(EXIT_SUCCESS);
+		}
+		fprintf(stderr, "Convert schedule optimized by lp into the Paje format\n\n");
+		fprintf(stderr, "Usage: lp_solve file.lp | %s > paje.trace\n", PROGNAME);
+		fprintf(stderr, "Reports bugs to <"PACKAGE_BUGREPORT">.");
+		fprintf(stderr, "\n");
+		exit(EXIT_SUCCESS);
 	}
-	nw = atoi(argv[1]);
-	nt = atoi(argv[2]);
-	fprintf(stderr,"%d workers, %d tasks\n", nw, nt);
+	scanf("Suboptimal solution\n");
 	assert(scanf("\nValue of objective function: %lf\n", &tmax) == 1);
+
+	assert(scanf("Actual values of the variables:\n") == 0);
+	assert(scanf("tmax %lf\n", &tmax) == 1);
+	assert(scanf("nt %d\n", &nt) == 1);
+	assert(scanf("nw %d\n", &nw) == 1);
 	printf(
 "%%EventDef PajeDefineContainerType 1\n"
 "%%  Alias         string\n"
@@ -80,7 +94,8 @@ int main(int argc, char *argv[]) {
 "1 W 0 Worker\n"
 );
 	printf("3 S W \"Worker State\"\n");
-	printf("5 S S Running \"0.0 1.0 0.0\"\n");
+	for (t = 0; t < nt; t++)
+		printf("5 R%d S Running_%d \"0.0 1.0 0.0\"\n", t, t);
 	printf("5 F S Idle \"1.0 0.0 0.0\"\n");
 	for (i = 0; i < nw; i++)
 		printf("2 0 W%d W 0 \"%d\"\n", i, i);
@@ -88,52 +103,32 @@ int main(int argc, char *argv[]) {
 	for (w = 0; w < nw; w++)
 		printf("4 %f W%d W\n", tmax, w);
 
-	assert(scanf("Actual values of the variables:\n") == 0);
-	assert(scanf("tmax %lf\n", &tmax) == 1);
-	next++;
+	fprintf(stderr,"%d workers, %d tasks\n", nw, nt);
 	{
 		struct task task[nt];
 		memset(&task, 0, sizeof(task));
-		for (t = 0; t < nt; t++) {
+		for (t = nt-1; t >= 0; t--) {
 			assert(scanf("c%d %lf\n", &foo, &task[t].stop) == 2);
-			next++;
 		}
 
-		num = next;
-		while (1) {
-			if (num >= next +
-
-				/* FIXME */
-				//nw*nt
-				8*84 + 5*49
-
-				) {
-				next+= 8*84+5*49;
-				break;
-			}
-			assert(scanf("t%dw%d %lf\n", &foo, &foo, &bar) == 3);
-			/* FIXME */
-			if (num-next < 8*84) {
-				t = (num - next) / nw;
-				w = (num - next) % nw;
-			} else {
-				unsigned long nnum = (num-next)-8*84;
-				t = (nnum / 5) + 84;
-				w = (nnum % 5)+3;
-			}
+		for (t = nt-1; t >= 0; t--)
+			for (w = 0; w < nw; w++) {
+				assert(scanf("t%dw%d %lf\n", &tt, &ww, &bar) == 3);
+				assert(ww == w);
 
-			if (bar > 0.5) {
-				task[t].worker = w;
-				fprintf(stderr,"%lu: task %d on %d: %f\n", num, t, w, task[t].stop);
-			}
-			num++;
+				if (bar > 0.5) {
+					task[t].num = tt;
+					task[t].worker = w;
+				}
 		}
-		for (t = 0; t < nt; t++) {
-			assert(scanf("s%d %lf\n", &foo, &task[t].start) == 2);
+		for (t = nt-1; t >= 0; t--) {
+			assert(scanf("s%d %lf\n", &tt, &task[t].start) == 2);
+			fprintf(stderr,"%d: task %d on %d: %f - %f\n", nt-1-t, tt, task[t].worker, task[t].start, task[t].stop);
+			assert(tt == task[t].num);
 		}
 
 		for (t = 0; t < nt; t++) {
-			printf("6 %f S W%d S\n", task[t].start, task[t].worker);
+			printf("6 %f S W%d R%d\n", task[t].start, task[t].worker, t);
 			printf("6 %f S W%d F\n", task[t].stop, task[t].worker);
 		}
 
@@ -142,7 +137,7 @@ int main(int argc, char *argv[]) {
 				if (t != t2 && task[t].worker == task[t2].worker) {
 					if (!(task[t].start >= task[t2].stop
 					    || task[t2].start >= task[t].stop)) {
-						fprintf(stderr,"oops, %d and %d sharing worker %d !!\n", t, t2, task[t].worker);
+						fprintf(stderr,"oops, %d and %d sharing worker %d !!\n", task[t].num, task[t2].num, task[t].worker);
 					}
 				}
 			}