Browse Source

clean lp2paje, make it a real documented starpu tool

Samuel Thibault 12 years ago
parent
commit
e850b08c6c

+ 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
 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
 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
 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 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
 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
 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
 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
 tasks before less prioritized tasks, to check to which extend this results
 to a less optimal solution. This increases even more computation time.
 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
 @node Insert Task Utility
 @section 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 = 0;
 static unsigned bound_deps = 0;
 static unsigned bound_deps = 0;
 static unsigned bound_lp = 0;
 static unsigned bound_lp = 0;
+static unsigned bound_mps = 0;
 static unsigned with_ctxs = 0;
 static unsigned with_ctxs = 0;
 static unsigned with_noctxs = 0;
 static unsigned with_noctxs = 0;
 static unsigned chole1 = 0;
 static unsigned chole1 = 0;
@@ -150,77 +151,83 @@ static void __attribute__((unused)) parse_args(int argc, char **argv)
 		{
 		{
 			with_ctxs = 1;
 			with_ctxs = 1;
 			break;
 			break;
-		}
+		} else
 		if (strcmp(argv[i], "-with_noctxs") == 0) 
 		if (strcmp(argv[i], "-with_noctxs") == 0) 
 		{
 		{
 			with_noctxs = 1;
 			with_noctxs = 1;
 			break;
 			break;
-		}
+		} else
 		
 		
 		if (strcmp(argv[i], "-chole1") == 0) 
 		if (strcmp(argv[i], "-chole1") == 0) 
 		{
 		{
 			chole1 = 1;
 			chole1 = 1;
 			break;
 			break;
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-chole2") == 0) 
 		if (strcmp(argv[i], "-chole2") == 0) 
 		{
 		{
 			chole2 = 1;
 			chole2 = 1;
 			break;
 			break;
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-size") == 0)
 		if (strcmp(argv[i], "-size") == 0)
 		{
 		{
 		        char *argptr;
 		        char *argptr;
 			size = strtol(argv[++i], &argptr, 10);
 			size = strtol(argv[++i], &argptr, 10);
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-nblocks") == 0)
 		if (strcmp(argv[i], "-nblocks") == 0)
 		{
 		{
 		        char *argptr;
 		        char *argptr;
 			nblocks = strtol(argv[++i], &argptr, 10);
 			nblocks = strtol(argv[++i], &argptr, 10);
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-nbigblocks") == 0)
 		if (strcmp(argv[i], "-nbigblocks") == 0)
 		{
 		{
 		        char *argptr;
 		        char *argptr;
 			nbigblocks = strtol(argv[++i], &argptr, 10);
 			nbigblocks = strtol(argv[++i], &argptr, 10);
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-no-pin") == 0)
 		if (strcmp(argv[i], "-no-pin") == 0)
 		{
 		{
 			pinned = 0;
 			pinned = 0;
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-no-prio") == 0)
 		if (strcmp(argv[i], "-no-prio") == 0)
 		{
 		{
 			noprio = 1;
 			noprio = 1;
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-bound") == 0)
 		if (strcmp(argv[i], "-bound") == 0)
 		{
 		{
 			bound = 1;
 			bound = 1;
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-bound-lp") == 0)
 		if (strcmp(argv[i], "-bound-lp") == 0)
 		{
 		{
 			bound_lp = 1;
 			bound_lp = 1;
-		}
+		} else
+
+		if (strcmp(argv[i], "-bound-mps") == 0)
+		{
+			bound_mps = 1;
+		} else
 
 
 		if (strcmp(argv[i], "-bound-deps") == 0)
 		if (strcmp(argv[i], "-bound-deps") == 0)
 		{
 		{
 			bound_deps = 1;
 			bound_deps = 1;
-		}
+		} else
 
 
 		if (strcmp(argv[i], "-check") == 0)
 		if (strcmp(argv[i], "-check") == 0)
 		{
 		{
 			check = 1;
 			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,"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);
 			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();
 	start = starpu_timing_now();
 
 
-	if (bound || bound_lp)
+	if (bound || bound_lp || bound_mps)
 		starpu_bound_start(bound_deps, 0);
 		starpu_bound_start(bound_deps, 0);
 	/* create all the DAG nodes */
 	/* create all the DAG nodes */
 	for (k = 0; k < nblocks; k++)
 	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();
 	starpu_task_wait_for_all();
-	if (bound || bound_lp)
+	if (bound || bound_lp || bound_mps)
 		starpu_bound_stop();
 		starpu_bound_stop();
 
 
 	end = starpu_timing_now();
 	end = starpu_timing_now();
@@ -162,6 +162,11 @@ static int _cholesky(starpu_data_handle_t dataA, unsigned nblocks)
 			FILE *f = fopen("cholesky.lp", "w");
 			FILE *f = fopen("cholesky.lp", "w");
 			starpu_bound_print_lp(f);
 			starpu_bound_print_lp(f);
 		}
 		}
+		if (bound_mps)
+		{
+			FILE *f = fopen("cholesky.mps", "w");
+			starpu_bound_print_mps(f);
+		}
 		if (bound)
 		if (bound)
 		{
 		{
 			double res;
 			double res;

+ 21 - 15
src/profiling/bound.c

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
  * Copyright (C) 2010, 2011, 2012, 2013  Centre National de la Recherche Scientifique
  * 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
  * Copyright (C) 2011  Télécom-SudParis
  *
  *
  * StarPU is free software; you can redistribute it and/or modify
  * 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, "/* 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, "/* !! 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, "/* We want to minimize total execution time (ms) */\n");
 		fprintf(output, "min: tmax;\n\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)
 		for (t1 = tasks; t1; t1 = t1->next)
 			fprintf(output, "c%lu <= tmax;\n", t1->id);
 			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, "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, "* We want to minimize total execution time (ms)\n");
 		fprintf(output, " N  TMAX\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++)
 		for (w = 0; w < nw; w++)
 		{
 		{
 			char name[32];
 			char name[32];
@@ -850,36 +856,36 @@ void starpu_bound_print_mps(FILE *output)
 			fprintf(output, " L  W%d\n", w);
 			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)
 		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, "* task %s key %x\n", _starpu_codelet_get_model_name(tp->cl), (unsigned) tp->footprint);
 			fprintf(output, " E  T%d\n", t);
 			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 (w = 0; w < nw; w++)
 			for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
 			for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
 				if (!isnan(times[w*nt+t]))
 				if (!isnan(times[w*nt+t]))
 				{
 				{
 					char name[9];
 					char name[9];
 					snprintf(name, sizeof(name), "W%dT%d", w, t);
 					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++)
 		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)
 		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");
 		fprintf(output, "ENDATA\n");
 	}
 	}

+ 5 - 3
tools/Makefile.am

@@ -86,7 +86,8 @@ bin_PROGRAMS += 			\
 	starpu_perfmodel_display	\
 	starpu_perfmodel_display	\
 	starpu_perfmodel_plot 		\
 	starpu_perfmodel_plot 		\
 	starpu_calibrate_bus		\
 	starpu_calibrate_bus		\
-	starpu_machine_display
+	starpu_machine_display		\
+	starpu_lp2paje
 
 
 starpu_perfmodel_plot_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(FXT_CFLAGS)
 starpu_perfmodel_plot_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(FXT_CFLAGS)
 
 
@@ -104,8 +105,6 @@ STARPU_TOOLS	+=			\
 	starpu_perfmodel_plot
 	starpu_perfmodel_plot
 endif
 endif
 
 
-noinst_PROGRAMS =	cbc2paje lp2paje
-
 dist_bin_SCRIPTS +=			\
 dist_bin_SCRIPTS +=			\
 	starpu_workers_activity		\
 	starpu_workers_activity		\
 	starpu_codelet_histo_profile	\
 	starpu_codelet_histo_profile	\
@@ -129,6 +128,8 @@ starpu_perfmodel_display.1: starpu_perfmodel_display$(EXEEXT)
 	help2man --no-discard-stderr -N --output=$@ ./$<
 	help2man --no-discard-stderr -N --output=$@ ./$<
 starpu_perfmodel_plot.1: starpu_perfmodel_plot$(EXEEXT)
 starpu_perfmodel_plot.1: starpu_perfmodel_plot$(EXEEXT)
 	help2man --no-discard-stderr -N --output=$@ ./$<
 	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)
 starpu_workers_activity.1: starpu_workers_activity$(EXEEXT)
 	chmod +x $<
 	chmod +x $<
 	help2man --no-discard-stderr -N --output=$@ ./$<
 	help2man --no-discard-stderr -N --output=$@ ./$<
@@ -153,6 +154,7 @@ dist_man1_MANS =\
 	starpu_machine_display.1 \
 	starpu_machine_display.1 \
 	starpu_perfmodel_display.1 \
 	starpu_perfmodel_display.1 \
 	starpu_perfmodel_plot.1	\
 	starpu_perfmodel_plot.1	\
+	starpu_lp2paje.1	\
 	starpu_workers_activity.1 \
 	starpu_workers_activity.1 \
 	starpu_codelet_profile.1 \
 	starpu_codelet_profile.1 \
 	starpu_codelet_histo_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.
 /* 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
  * StarPU is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
  * it under the terms of the GNU Lesser General Public License as published by
@@ -14,34 +14,48 @@
  * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  */
  */
 
 
+#include <config.h>
 #include <assert.h>
 #include <assert.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
 
 
+#define PROGNAME "starpu_lp2paje"
+
 struct task {
 struct task {
 	double start;
 	double start;
 	double stop;
 	double stop;
+	int num;
 	int worker;
 	int worker;
 };
 };
 
 
 int main(int argc, char *argv[]) {
 int main(int argc, char *argv[]) {
 	int nw, nt;
 	int nw, nt;
 	double tmax;
 	double tmax;
-	int i, w, t, t2;
+	int i, w, ww, t, tt, t2;
 	int foo;
 	int foo;
 	double bar;
 	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("\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(
 	printf(
 "%%EventDef PajeDefineContainerType 1\n"
 "%%EventDef PajeDefineContainerType 1\n"
 "%%  Alias         string\n"
 "%%  Alias         string\n"
@@ -80,7 +94,8 @@ int main(int argc, char *argv[]) {
 "1 W 0 Worker\n"
 "1 W 0 Worker\n"
 );
 );
 	printf("3 S W \"Worker State\"\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");
 	printf("5 F S Idle \"1.0 0.0 0.0\"\n");
 	for (i = 0; i < nw; i++)
 	for (i = 0; i < nw; i++)
 		printf("2 0 W%d W 0 \"%d\"\n", i, 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++)
 	for (w = 0; w < nw; w++)
 		printf("4 %f W%d W\n", tmax, 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];
 		struct task task[nt];
 		memset(&task, 0, sizeof(task));
 		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);
 			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++) {
 		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);
 			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 (t != t2 && task[t].worker == task[t2].worker) {
 					if (!(task[t].start >= task[t2].stop
 					if (!(task[t].start >= task[t2].stop
 					    || task[t2].start >= task[t].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);
 					}
 					}
 				}
 				}
 			}
 			}