drake
1.0.0
|
00001 /* 00002 Copyright 2015 Nicolas Melot, Christoph Kessler 00003 00004 This file is part of Drake. 00005 00006 Drake is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 Drake is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with Drake. If not, see <http://www.gnu.org/licenses/>. 00018 00019 */ 00020 00021 00022 // drawgraph.c JK May 23, 2008 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 #include <stdlib.h> 00028 00029 #include <drake/mapping.h> 00030 #include <drake/platform.h> 00031 #include "drawgraph-2.h" 00032 00033 FILE *input, *output, *error; 00034 00035 // left upper corner of image 00036 double xref = 0.0; 00037 double yref = 0.0; 00038 00039 // radius of a circle 00040 double yrad = 225.0; 00041 00042 // distances between nodes 00043 double xdiff; 00044 double ydiff; 00045 00046 // max no of proc and nodes +1 00047 // x[i][j] == 1 iff node i is mapped onto proc j 00048 int x[NMAX][PMAX]; 00049 int num_procs = 0; 00050 int num_tasks = 0; 00051 00052 typedef struct prel 00053 { 00054 int proc; 00055 int index; 00056 } Prel; 00057 00058 // order in which processors are drawn 00059 Prel ranklist[PMAX]; 00060 00061 // actual no of processors and nodes 1..p 1..n 00062 int p, n, logn; 00063 00064 typedef struct pt 00065 { 00066 double x; 00067 double y; 00068 } Pt; 00069 00070 // 00071 Pt pos[NMAX]; 00072 00073 // routines to draw 00074 00075 void 00076 initimage(void) 00077 { 00078 fprintf( 00079 output, 00080 "\ 00081 #FIG 3.2\n\ 00082 Portrait\n\ 00083 Center\n\ 00084 Metric\n\ 00085 A4 \n\ 00086 100.0\n\ 00087 Single\n\ 00088 -2\n\ 00089 1200 2\n"); 00090 } 00091 00092 void 00093 dashline(double x1, double y1, double x2, double y2) 00094 { 00095 fprintf(output, "2 1 1 4 0 0 100 1 -1 6.40 0 0 12 0 0 2\n"); 00096 fprintf(output, " %d %d %d %d\n", (int) x1, (int) y1, (int) x2, 00097 (int) y2); 00098 } 00099 00100 void 00101 circle(double xcenter, double ycenter, double radius) 00102 { 00103 // fprintf(output, "circle %lf %lf %lf\n",xcenter,ycenter,radius); 00104 fprintf(output, "1 1 0 2 0 0 100 1 -1 6.40 1 0.0 %d %d %d %d %d %d %d %d\n", 00105 00106 (int) xcenter, (int) ycenter, (int) radius, (int) radius, (int) (xcenter 00107 - radius), (int) (ycenter - radius), (int) (xcenter + radius), 00108 (int) (ycenter + radius)); 00109 } 00110 00111 void 00112 arc(double x1, double y1, double x2, double y2) 00113 { 00114 // fprintf(output, "arc %lf %lf %lf %lf\n",x1,y1,x2,y2); 00115 fprintf(output, "2 1 0 2 0 0 100 1 -1 6.40 0 0 12 1 0 2\n"); 00116 fprintf(output, " 2 1 1.0 144.00 200.00\n"); 00117 fprintf(output, " %d %d %d %d\n", (int) x1, (int) y1, (int) x2, 00118 (int) y2); 00119 00120 } 00121 00122 void 00123 textout(double x1, double y1, char* str, int size) 00124 { 00125 // fprintf(output, "text %lf %lf %s\n",x1,y1,str); 00126 fprintf(output, "4 1 0 100 1 0 %d.0 0.0 4 267.0 %lf %d %d %s\\001\n", size, 00127 (double) strlen(str) * 100.0, (int) x1, (int) (y1 + yrad / 2.0), str); 00128 00129 } 00130 00131 #define STRL 255 00132 00133 int 00134 inputstructure(void) 00135 { 00136 char instr[STRL], *endstr; 00137 int flag = 0; 00138 int i, j; 00139 int tmp; 00140 char str[2], *end; 00141 00142 while (!feof(input)) 00143 { 00144 char *res = fgets(instr, STRL, input); 00145 if(res == NULL) 00146 { 00147 fprintf(stderr, "[%s:%s:%d][ERROR] Cannot read character from input.\n", __FILE__, __FUNCTION__, __LINE__); 00148 abort(); 00149 } 00150 00151 if (!strncmp(instr, "k =", 3)) 00152 { 00153 flag = 1; 00154 sscanf(instr + 4, "%d", &p); 00155 break; 00156 } 00157 } 00158 if (flag == 0) 00159 { 00160 fprintf(output, "could not find line beginning with k =\n"); 00161 return 0; 00162 } 00163 n = (1 << p) - 1; 00164 logn = p; 00165 00166 flag = 0; 00167 while (!feof(input)) 00168 { 00169 char *res = fgets(instr, STRL, input); 00170 if(res == NULL) 00171 { 00172 fprintf(stderr, "[%s:%s:%d][ERROR] Cannot read character from input.\n", __FILE__, __FUNCTION__, __LINE__); 00173 abort(); 00174 } 00175 00176 if (!strncmp(instr, "x [", 3)) 00177 { 00178 flag = 1; 00179 break; 00180 } 00181 } 00182 if (flag == 0) 00183 { 00184 fprintf(output, "could not find line beginning with x [\n"); 00185 return 0; 00186 } 00187 00188 char *res = fgets(instr, STRL, input); 00189 if(res == NULL) 00190 { 00191 fprintf(stderr, "[%s:%s:%d][ERROR] Cannot read character from input.\n", __FILE__, __FUNCTION__, __LINE__); 00192 abort(); 00193 } 00194 00195 00196 str[1] = '\0'; 00197 i = 1; 00198 while (1) 00199 { 00200 flag = fscanf(input, "%s", (char*) &instr); 00201 tmp = strtol(instr, &endstr, 10); 00202 00203 j = 1; 00204 int n = fscanf(input, "%c", &str[0]); 00205 if(n < 1 || n == EOF) 00206 { 00207 fprintf(stderr, "[%s:%s:%d][ERROR] Could not read input file.\n", __FILE__, __FUNCTION__, __LINE__); 00208 abort(); 00209 } 00210 00211 while (str[0] != '\n') 00212 { 00213 tmp = strtol(str, &end, 2); 00214 if (end - str > 0) 00215 { 00216 x[i][j] = tmp; 00217 num_procs = j; 00218 j++; 00219 } 00220 n = fscanf(input, "%c", str); 00221 if(n < 1 || n == EOF) 00222 { 00223 fprintf(stderr, "[%s:%s:%d][ERROR] Could not read input file.\n", __FILE__, __FUNCTION__, __LINE__); 00224 abort(); 00225 } 00226 } 00227 00228 if (flag == 0 || flag == EOF || endstr != instr + strlen(instr)) 00229 { 00230 break; 00231 } 00232 i++; 00233 num_tasks = i; 00234 } 00235 00236 return 1; 00237 } 00238 00239 int 00240 prelcmp(const void *p1, const void *p2) 00241 { 00242 int index1, index2; 00243 00244 index1 = ((Prel*) p1)->index; 00245 index2 = ((Prel*) p2)->index; 00246 00247 if (index1 < index2) 00248 return 1; 00249 else if (index1 > index2) 00250 return -1; 00251 00252 return 0; 00253 } 00254 00255 void 00256 rankprocessors(void) 00257 { 00258 int i, j; 00259 00260 // fill ranklist first with minimum numbers of nodes placed 00261 for (j = 1; j <= p; j++) 00262 { 00263 ranklist[j].index = n + 1; // no element placed 00264 ranklist[j].proc = j; // proc j 00265 for (i = 1; i <= n; i++) 00266 { 00267 if (x[i][j] == 1) 00268 { 00269 ranklist[j].index = i; 00270 break; 00271 } 00272 } 00273 } 00274 qsort((void*) (&(ranklist[1])), p, sizeof(Prel), prelcmp); 00275 } 00276 00277 int 00278 drawproc(int proc, int line) 00279 { 00280 int i, level; 00281 int incline; 00282 int flag; 00283 char str[100]; 00284 00285 incline = 0; 00286 for (level = logn - 1; level >= 0; level--) 00287 { 00288 flag = 0; 00289 for (i = 1 << level; i < (1 << (level + 1)); i++) 00290 { 00291 if (x[i][proc] == 1) 00292 { 00293 flag = 1; // node in this level placed 00294 pos[i].x = xref + ((double) ((i - (1 << level)) * (1 << (logn - level)) 00295 + (1 << (logn - 1 - level))) + 0.5) * xdiff; 00296 pos[i].y = yref + ((double) line + 0.5) * ydiff; 00297 circle(pos[i].x, pos[i].y, yrad); 00298 sprintf(str, "%d", i); 00299 textout(pos[i].x, pos[i].y, str, 20); 00300 } 00301 } 00302 if (flag) 00303 { 00304 incline++; 00305 line++; 00306 } 00307 } 00308 00309 if (incline == 0) 00310 incline++; 00311 00312 sprintf(str, "SPE%d", proc); 00313 textout(480.0, yref + ((double) line - 0.25) * ydiff, str, 24); 00314 00315 return incline; 00316 } 00317 00318 void 00319 drawline(int line) 00320 { 00321 dashline(xref, yref + ((double) line) * ydiff, xref + xdiff 00322 * (double) (n + 1), yref + ((double) line) * ydiff); 00323 } 00324 00325 void 00326 drawedges(void) 00327 { 00328 int i; 00329 00330 for (i = n; i >= 2; i--) 00331 { 00332 if (pos[i].y < pos[i / 2].y) // normal case, edges going from top to bottom 00333 // leaves node at bottom, hits node at top 00334 arc(pos[i].x, pos[i].y + yrad, pos[i / 2].x, pos[i / 2].y - yrad); 00335 else 00336 { // leaves and hits nodes at appropriate sides 00337 if (pos[i].x <= pos[i / 2].x) // edge going left to right 00338 arc(pos[i].x + yrad, pos[i].y, pos[i / 2].x - yrad, pos[i / 2].y); 00339 else 00340 // edge going right to left 00341 arc(pos[i].x, pos[i].y - yrad, pos[i / 2].x + yrad, pos[i / 2].y); 00342 } 00343 } 00344 } 00345 00346 void 00347 drawallprocessors(void) 00348 { 00349 int j; 00350 int line = 0; 00351 00352 initimage(); 00353 for (j = 1; j <= p; j++) 00354 { 00355 // draw proc ranklist[j].proc starting from line line 00356 line += drawproc(ranklist[j].proc, line); 00357 // if j!=p draw horizontal dashline 00358 if (j < p) 00359 drawline(line); 00360 } 00361 drawedges(); 00362 } 00363 00364 void 00365 pelib_drawgraph2_draw(FILE * read_from, FILE * print_to, FILE * err_to) 00366 { 00367 input = read_from; 00368 output = print_to; 00369 error = err_to; 00370 00371 if (input == NULL) 00372 { 00373 input = stdin; 00374 } 00375 if (output == NULL) 00376 { 00377 output = stdout; 00378 } 00379 if (error == NULL) 00380 { 00381 error = stderr; 00382 } 00383 00384 xdiff = 1.1 * yrad; 00385 ydiff = 4 * yrad; 00386 00387 if (inputstructure()) 00388 { 00389 rankprocessors(); 00390 drawallprocessors(); 00391 } 00392 } 00393 00394 mapping_t* 00395 pelib_drawgraph2_load(FILE* read_from, mapping_t* mapping, int 00396 ( filter)(task_t*)) 00397 { 00398 int i, j; 00399 processor_t *processor = NULL; 00400 task_t task; 00401 00402 input = read_from; 00403 output = fopen("std-bitbucket.txt", "w"); 00404 error = fopen("err-bitbucket.txt", "w"); 00405 num_procs = 0; 00406 num_tasks = 0; 00407 inputstructure(); 00408 00409 fprintf(stderr, "[%s:%s:%d] mapping = pelib_alloc_collection(mapping_t)(%d);\n", __FILE__, __FUNCTION__, __LINE__, DRAKE_MAPPING_MAX_PROCESSOR_COUNT); 00410 mapping = pelib_alloc_collection(mapping_t)(DRAKE_MAPPING_MAX_PROCESSOR_COUNT); 00411 00412 // Fills mapping with processors and processors with tasks 00413 for (j = 1; j <= num_procs; j++) 00414 { 00415 fprintf(stderr, "[%s:%s:%d] processor = pelib_alloc_collection(processor_t)(%d);\n", __FILE__, __FUNCTION__, __LINE__, DRAKE_MAPPING_MAX_TASK_COUNT); 00416 processor = pelib_alloc_collection(processor_t)(DRAKE_MAPPING_MAX_TASK_COUNT); 00417 fprintf(stderr, "[%s:%s:%d] processor->id = %d - 1;\n", __FILE__, __FUNCTION__, __LINE__, j); 00418 processor->id = j - 1; 00419 fprintf(stderr, "[%s:%s:%d] processor->source = pelib_alloc_collection(array_t(cross_link_tp))(%d);\n", __FILE__, __FUNCTION__, __LINE__, num_tasks); 00420 processor->source = pelib_alloc_collection(array_t(cross_link_tp))(num_tasks); 00421 fprintf(stderr, "[%s:%s:%d] processor->sink = pelib_alloc_collection(array_t(cross_link_tp))(%d);\n", __FILE__, __FUNCTION__, __LINE__, num_tasks); 00422 processor->sink = pelib_alloc_collection(array_t(cross_link_tp))(num_tasks); 00423 fprintf(stderr, "[%s:%s:%d] nb_mapping_insert_processor(mapping, processor);\n", __FILE__, __FUNCTION__, __LINE__); 00424 drake_mapping_insert_processor(mapping, processor); 00425 00426 for (i = 1; i < num_tasks; i++) 00427 { 00428 if (x[i][j] == 1) 00429 { 00430 task.id = i; 00431 if (filter(&task) != 0) 00432 { 00433 fprintf(stderr, "[%s:%s:%d] task.id = %d\n", __FILE__, __FUNCTION__, __LINE__, i); 00434 00435 fprintf(stderr, "[%s:%s:%d] task.pred = pelib_alloc_collection(array_t(link_tp))(%d);\n", __FILE__, __FUNCTION__, __LINE__, num_tasks); 00436 task.pred = pelib_alloc(map_t(string, link_tp))(); 00437 pelib_init(map_t(string, link_tp))(task.pred); 00438 fprintf(stderr, "[%s:%s:%d] task.succ = pelib_alloc_collection(array_t(link_tp))(%d);\n", __FILE__, __FUNCTION__, __LINE__, num_tasks); 00439 task.succ = pelib_alloc(map_t(string, link_tp))(); 00440 pelib_init(map_t(string, link_tp))(task.succ); 00441 fprintf(stderr, "[%s:%s:%d] task.source = pelib_alloc_collection(array_t(cross_link_tp))(%d);\n", __FILE__, __FUNCTION__, __LINE__, num_tasks); 00442 task.source = pelib_alloc_collection(array_t(cross_link_tp))(num_tasks); 00443 fprintf(stderr, "[%s:%s:%d] task.sink = pelib_alloc_collection(array_t(cross_link_tp))(%d);\n", __FILE__, __FUNCTION__, __LINE__, num_tasks); 00444 task.sink = pelib_alloc_collection(array_t(cross_link_tp))(num_tasks); 00445 00446 fprintf(stderr, "[%s:%s:%d] task.status = TASK_INIT;\n", __FILE__, __FUNCTION__, __LINE__); 00447 task.status = TASK_INIT; 00448 00449 fprintf(stderr, "[%s:%s:%d] drake_mapping_insert_task(mapping, %d - 1, &task);\n", __FILE__, __FUNCTION__, __LINE__, j); 00450 drake_mapping_insert_task(mapping, j - 1, &task); 00451 } 00452 continue; 00453 } 00454 } 00455 } 00456 00457 fflush(stdin); 00458 fflush(stdout); 00459 fflush(stderr); 00460 00461 input = stdin; 00462 output = stdout; 00463 error = stderr; 00464 00465 return mapping; 00466 } 00467