FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_part_get_control.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2019 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <math.h>
10 #include <errno.h>
11 
12 #include "hecmw_util.h"
13 #include "hecmw_io.h"
14 
15 #include "hecmw_partlex.h"
16 #include "hecmw_part_define.h"
17 #include "hecmw_part_struct.h"
18 #include "hecmw_part_get_control.h"
19 
20 static char ctrl_file_name[HECMW_FILENAME_LEN] = "\0";
21 static int args_subdomain = 0;
22 
23 /*================================================================================================*/
24 
25 extern int HECMW_part_set_subdomains(int n_domain) {
26  args_subdomain = n_domain;
27  return 0;
28 }
29 
30 extern int HECMW_part_set_ctrl_file_name(char *fname) {
31  if (fname == NULL) {
32  HECMW_set_error(HECMW_PART_E_INV_ARG, "'fname' is NULL");
33  goto error;
34  }
35  if (strlen(fname) > HECMW_FILENAME_LEN) {
37  "control file for partitioner");
38  goto error;
39  }
40 
41  snprintf(ctrl_file_name, sizeof(ctrl_file_name), "%s", fname);
42 
43  return 0;
44 
45 error:
46  return -1;
47 }
48 
49 /*============================================================================*/
50 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
51 /* partitioning type < TYPE={ NODE-BASED | ELEMENT-BASED } > */
52 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
53 static int part_cont_type(void) {
54  int token;
55 
56  /* '=' */
57  token = HECMW_partlex_next_token();
58  if (token != '=') {
60  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
61  "part_cont_type", HECMW_partlex_get_text());
62  return -1;
63  }
64 
65  /* { NODE-BASED | ELEMENT-BASED } */
66  token = HECMW_partlex_next_token();
67  switch (token) {
68  case HECMW_PARTLEX_V_NODE_BASED: /* TYPE=NODE-BASED */
70 
71  case HECMW_PARTLEX_V_ELEMENT_BASED: /* TYPE=ELEMENT-BASED */
73 
74  default:
76  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
77  "part_cont_type", HECMW_partlex_get_text());
78  return -1;
79  }
80 }
81 
82 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
83 /* partitioning method < METHOD={ RCB | KMETIS | PMETIS | USER } > */
84 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
85 static int part_cont_method(void) {
86  int token;
87 
88  /* '=' */
89  token = HECMW_partlex_next_token();
90  if (token != '=') {
92  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
93  "part_cont_method", HECMW_partlex_get_text());
94  return -1;
95  }
96 
97  /* { RCB | KMETIS | PMETIS | USER } */
98  token = HECMW_partlex_next_token();
99  switch (token) {
100  case HECMW_PARTLEX_V_RCB: /* METHOD=RCB */
101  return HECMW_PART_METHOD_RCB;
102 
103  case HECMW_PARTLEX_V_KMETIS: /* METHOD=KMETIS */
105 
106  case HECMW_PARTLEX_V_PMETIS: /* METHOD=PMETIS */
108 
109  case HECMW_PARTLEX_V_USER: /* METHOD=USER */
110  return HECMW_PART_METHOD_USER;
111 
112  default:
114  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
115  "part_cont_method", HECMW_partlex_get_text());
116  return -1;
117  }
118 }
119 
120 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
121 /* number of sub-domains < DOMAIN=n > */
122 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
123 static int part_cont_domain(void) {
124  int token, domain;
125 
126  /* '=' */
127  token = HECMW_partlex_next_token();
128  if (token != '=') {
130  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
131  "part_cont_domain", HECMW_partlex_get_text());
132  return -1;
133  }
134 
135  /* n */
136  token = HECMW_partlex_next_token();
137  switch (token) {
138  case HECMW_PARTLEX_INT: /* DOMAIN=n */
139  domain = (int)HECMW_partlex_get_number();
140  if (domain < 1) {
143  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
144  "part_cont_domain", HECMW_partlex_get_text());
145  return -1;
146  }
147  return domain;
148 
149  default:
151  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
152  "part_cont_domain", HECMW_partlex_get_text());
153  return -1;
154  }
155 }
156 
157 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
158 /* depth of overlapping zone < DEPTH=n > */
159 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
160 static int part_cont_depth(void) {
161  int token, depth;
162 
163  /* '=' */
164  token = HECMW_partlex_next_token();
165  if (token != '=') {
167  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
168  "part_cont_depth", HECMW_partlex_get_text());
169  return -1;
170  }
171 
172  /* n */
173  token = HECMW_partlex_next_token();
174  switch (token) {
175  case HECMW_PARTLEX_INT: /* DEPTH=n */
176  depth = (int)HECMW_partlex_get_number();
177  if (depth < 1) {
179  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
180  "part_cont_depth", HECMW_partlex_get_text());
181  return -1;
182  }
183  return depth;
184 
185  default:
187  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
188  "part_cont_depth", HECMW_partlex_get_text());
189  return -1;
190  }
191 }
192 
193 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
194 /* ucd file name < UCD=filename > */
195 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
196 static int part_cont_ucd(char *name, size_t name_len) {
197  char *p;
198  int token, is_print_ucd = 0;
199 
200  /* '=' */
201  token = HECMW_partlex_next_token();
202  if (token != '=') {
204  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
205  "part_cont_ucd", HECMW_partlex_get_text());
206  return -1;
207  }
208 
209  /* filename */
210  token = HECMW_partlex_next_token();
211  switch (token) {
212  case HECMW_PARTLEX_NAME: /* UCD=filename */
213  case HECMW_PARTLEX_FILENAME: /* UCD=filename */
215  if (strlen(p) > HECMW_FILENAME_LEN) {
218  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
219  "part_cont_ucd", HECMW_partlex_get_text());
220  return -1;
221  }
222  snprintf(name, name_len, "%s", p);
223  is_print_ucd = 1;
224 
225  return is_print_ucd;
226 
227  default:
229  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
230  "part_cont_ucd", HECMW_partlex_get_text());
231  return -1;
232  }
233 
234  HECMW_assert(0);
235 
236  return -1;
237 }
238 
239 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
240 /* partitioning contact < CONTACT={ DEFAULT | AGGREGATE | DISTRIBUTE | SIMPLE }
241  * > */
242 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
243 static int part_cont_contact(void) {
244  int token;
245 
246  /* '=' */
247  token = HECMW_partlex_next_token();
248  if (token != '=') {
250  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
251  "part_cont_method", HECMW_partlex_get_text());
252  return -1;
253  }
254 
255  /* { DEFAULT | AGGREGATE | DISTRIBUTE | SIMPLE } */
256  token = HECMW_partlex_next_token();
257  switch (token) {
258  case HECMW_PARTLEX_V_DEFAULT: /* CONTACT=DEFAULT */
260 
261  case HECMW_PARTLEX_V_AGGREGATE: /* CONTACT=AGGREGATE */
263 
264  case HECMW_PARTLEX_V_DISTRIBUTE: /* CONTACT=DISTRIBUTE */
266 
267  case HECMW_PARTLEX_V_SIMPLE: /* CONTACT=SIMPLE */
269 
270  default:
272  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
273  "part_cont_method", HECMW_partlex_get_text());
274  return -1;
275  }
276 }
277 
278 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
279 /* contact ownership scheme < CONTACT_OWNER={ MASTER | SLAVE } > */
280 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
281 /* Needs no rule in hecmw_partlex.l: flex takes the longest match, so {name}
282  * beats the 7-character CONTACT rule and the keyword arrives as
283  * HECMW_PARTLEX_NAME. Compared as a string here, which is why
284  * hecmw_partlex.c stays untouched. */
285 static int part_cont_contact_owner(void) {
286  int token;
287  char *p;
288 
289  /* '=' */
290  token = HECMW_partlex_next_token();
291  if (token != '=') {
292  HECMW_log(HECMW_LOG_ERROR, "%s %s (%s)",
294  "'=' required after 'CONTACT_OWNER'",
296  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
297  "part_cont_contact_owner", HECMW_partlex_get_text());
298  return -1;
299  }
300 
301  /* { MASTER | SLAVE } */
302  token = HECMW_partlex_next_token();
303  if (token == HECMW_PARTLEX_NAME) {
305 
306  if (strcmp(p, "MASTER") == 0) { /* CONTACT_OWNER=MASTER */
308  }
309  if (strcmp(p, "SLAVE") == 0) { /* CONTACT_OWNER=SLAVE */
311  }
312  }
313 
314  HECMW_log(HECMW_LOG_ERROR, "%s %s (%s)",
316  "'CONTACT_OWNER' must be 'MASTER' or 'SLAVE'",
318  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
319  "part_cont_contact_owner", HECMW_partlex_get_text());
320  return -1;
321 }
322 
323 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
324 /* part file name < PART=filename > */
325 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
326 static int part_cont_part(char *name, size_t name_len) {
327  char *p;
328  int token, is_print_part = 0;
329 
330  /* '=' */
331  token = HECMW_partlex_next_token();
332  if (token != '=') {
334  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
335  "part_cont_part", HECMW_partlex_get_text());
336  return -1;
337  }
338 
339  /* filename */
340  token = HECMW_partlex_next_token();
341  switch (token) {
342  case HECMW_PARTLEX_NAME: /* PART=filename */
343  case HECMW_PARTLEX_FILENAME: /* PART=filename */
345  if (strlen(p) > HECMW_FILENAME_LEN) {
348  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
349  "part_cont_part", HECMW_partlex_get_text());
350  return -1;
351  }
352  snprintf(name, name_len, "%s", p);
353  is_print_part = 1;
354 
355  return is_print_part;
356 
357  default:
359  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
360  "part_cont_part", HECMW_partlex_get_text());
361  return -1;
362  }
363 
364  HECMW_assert(0);
365 
366  return -1;
367 }
368 
369 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
370 /* partitioning directions for RCB partitioning < x, y, z > */
371 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
372 static int part_cont_rcb_divs(int n_domain) {
373  int base, rest, n;
374  int i;
375 
376  for (i = 0; i < n_domain; i++) {
377  n = (int)pow(2, i);
378  base = n_domain / n;
379  rest = n_domain % n;
380 
381  if ((base == 1) && (rest == 0)) return i;
382  if ((base == 0) && (rest == 1)) return 0;
383  if ((base == 1) && (rest > 0)) return -1;
384  }
385 
386  HECMW_assert(0);
387 
388  return 0;
389 }
390 
391 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
392 static int part_cont_rcb_opt(struct hecmw_part_cont_data *cont_data) {
393  int token;
394  int i;
395 
396  if (cont_data->n_domain == 1) {
397  cont_data->n_rcb_div = 0;
398  cont_data->rcb_axis = NULL;
399  return 0;
400  }
401 
402  /* number of decompositions */
403  cont_data->n_rcb_div = part_cont_rcb_divs(cont_data->n_domain);
404  if (cont_data->n_rcb_div < -1) {
406  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%d)", __FILE__, __LINE__,
407  "part_cont_rcb_opt", cont_data->n_domain);
408  return -1;
409  }
410 
411  /* partitioning directions */
412  cont_data->rcb_axis = (int *)HECMW_malloc(sizeof(int) * cont_data->n_rcb_div);
413  if (cont_data->rcb_axis == NULL) {
415  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
416  "part_cont_rcb_opt", "cont_data->rcb_axis");
417  return -1;
418  }
419 
420  for (i = 0; i < cont_data->n_rcb_div; i++) {
421  token = HECMW_partlex_next_token();
422 
423  switch (token) {
424  case 'x':
425  cont_data->rcb_axis[i] = HECMW_PART_RCB_X_AXIS;
426  break;
427 
428  case 'y':
429  cont_data->rcb_axis[i] = HECMW_PART_RCB_Y_AXIS;
430  break;
431 
432  case 'z':
433  cont_data->rcb_axis[i] = HECMW_PART_RCB_Z_AXIS;
434  break;
435 
436  default:
438  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
439  "part_cont_rcb_opt", HECMW_partlex_get_text());
440  HECMW_free(cont_data->rcb_axis);
441  return -1;
442  }
443 
444  token = HECMW_partlex_next_token();
445  if (token != ',' && token != HECMW_PARTLEX_NL && token) {
446  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
447  "part_cont_rcb_opt", HECMW_partlex_get_text());
448  HECMW_free(cont_data->rcb_axis);
449  return -1;
450  }
451 
452  if (i + 1 == cont_data->n_rcb_div) {
453  if (token == ',') {
455  while ((token = HECMW_partlex_next_token()) != HECMW_PARTLEX_NL) {
456  }
457  }
458  break;
459  } else {
460  if (token == HECMW_PARTLEX_NL || !token) {
462  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
463  "part_cont_rcb_opt");
464  HECMW_free(cont_data->rcb_axis);
465  return -1;
466  }
467  }
468  }
469 
470  return 0;
471 }
472 
473 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
474 /* control data for partitioner < !PARTITION > */
475 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
476 static int part_cont_partition(struct hecmw_part_cont_data *cont_data) {
477  int token;
478 
479  cont_data->type = -1;
480  cont_data->method = -1;
481  cont_data->n_domain = -1;
482  cont_data->depth = -1;
483  cont_data->is_print_ucd = -1;
484  cont_data->contact = -1;
485  cont_data->contact_owner= -1;
486  cont_data->is_print_part= -1;
487  cont_data->ucd_file_name[0] = '\0';
488  cont_data->part_file_name[0] = '\0';
489 
490  while ((token = HECMW_partlex_next_token()) != HECMW_PARTLEX_NL ||
491  (token = HECMW_partlex_next_token())) {
492  switch (token) {
493  case HECMW_PARTLEX_K_TYPE: /* TYPE */
494  cont_data->type = part_cont_type();
495  if (cont_data->type < 0) return -1;
496  break;
497 
498  case HECMW_PARTLEX_K_METHOD: /* METHOD */
499  cont_data->method = part_cont_method();
500  if (cont_data->method < 0) return -1;
501  break;
502 
503  case HECMW_PARTLEX_K_DOMAIN: /* DOMAIN */
504  cont_data->n_domain = part_cont_domain();
505  if (cont_data->n_domain < 0) return -1;
506  break;
507 
508  case HECMW_PARTLEX_K_DEPTH: /* DEPTH */
509  cont_data->depth = part_cont_depth();
510  if (cont_data->depth < 0) return -1;
511  break;
512 
513  case HECMW_PARTLEX_K_UCD: /* UCD */
514  cont_data->is_print_ucd = part_cont_ucd(cont_data->ucd_file_name,
515  sizeof(cont_data->ucd_file_name));
516  if (cont_data->is_print_ucd < 0) return -1;
517  break;
518 
519  case HECMW_PARTLEX_K_CONTACT: /* CONTACT */
520  cont_data->contact = part_cont_contact();
521  if (cont_data->contact < 0) return -1;
522  break;
523 
524  case HECMW_PARTLEX_K_PART: /* PART */
525  cont_data->is_print_part = part_cont_part(cont_data->part_file_name,
526  sizeof(cont_data->part_file_name));
527  if (cont_data->is_print_part < 0) return -1;
528  break;
529 
530  case HECMW_PARTLEX_NAME: /* CONTACT_OWNER (see part_cont_contact_owner) */
531  if (strcmp(HECMW_partlex_get_text(), "CONTACT_OWNER") == 0) {
532  cont_data->contact_owner = part_cont_contact_owner();
533  if (cont_data->contact_owner < 0) return -1;
534  break;
535  }
536  /* fall through: any other name is an unknown keyword */
537 
538  default:
539  HECMW_log(HECMW_LOG_ERROR, "%s %s (%s)",
541  "in control data for partitioner", HECMW_partlex_get_text());
542  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
543  "part_cont_partition", HECMW_partlex_get_text());
544  return -1;
545  }
546 
547  token = HECMW_partlex_next_token();
548  if (token != ',' && token != HECMW_PARTLEX_NL && token != EOF) {
549  HECMW_log(HECMW_LOG_ERROR, "%s %s (%s)",
551  "in control file for partitioner", HECMW_partlex_get_text());
552  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
553  "part_cont_partition", HECMW_partlex_get_text());
554  return -1;
555  } else {
556  if (token == HECMW_PARTLEX_NL || token == EOF) break;
557  }
558  }
559 
560  /* check data */
561  if (cont_data->type < 0) {
563  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
564  "part_cont_partition");
565  return -1;
566  }
567 
568 #ifndef HECMW_PART_WITH_METIS
569  if (cont_data->method == HECMW_PART_METHOD_PMETIS) {
571  HECMW_log(HECMW_LOG_DEBUG, "%s:%d", __FILE__, __LINE__);
572  return -1;
573  }
574 
575  if (cont_data->method == HECMW_PART_METHOD_KMETIS) {
577  HECMW_log(HECMW_LOG_DEBUG, "%s:%d", __FILE__, __LINE__);
578  return -1;
579  }
580 #endif
581 
584 
585  if (cont_data->method < 0) {
587  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
588  "part_cont_partition");
589  return -1;
590  }
592  cont_data->method == HECMW_PART_METHOD_KMETIS ||
594 
595  if (cont_data->n_domain <= 0) {
597  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
598  "part_cont_partition");
599  return -1;
600  }
601 
602  if (cont_data->depth < 0) {
603  cont_data->depth = 1;
604  }
605 
606  if (cont_data->is_print_ucd < 0) {
607  cont_data->is_print_ucd = 0;
608  }
609 
610  if (cont_data->is_print_part < 0) {
611  cont_data->is_print_part = 0;
612  }
613 
614  if (cont_data->contact_owner < 0) {
616  }
617 
618  /* the slave-owner scheme decides the responsible domain from node ownership,
619  * which element-based partitioning does not establish */
620  if (cont_data->contact_owner == HECMW_PART_CONTACT_OWNER_SLAVE &&
622  HECMW_log(HECMW_LOG_ERROR, "%s %s",
624  "'CONTACT_OWNER=SLAVE' requires 'TYPE=NODE-BASED'");
625  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
626  "part_cont_partition");
627  return -1;
628  }
629 
630  if (cont_data->method == HECMW_PART_METHOD_USER) {
631  cont_data->is_print_part = 0;
632  }
633 
634  /* partitioning directions ( option for RCB ) */
635  if (cont_data->method == HECMW_PART_METHOD_RCB) {
636  if (token == EOF) {
638  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
639  "part_cont_partition");
640  return -1;
641  }
642  part_cont_rcb_opt(cont_data);
643  }
644 
645  if (token == EOF) {
646  HECMW_log(HECMW_LOG_ERROR, "%s (%s)",
648  "control file for partitioner");
649  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
650  "part_cont_partition");
651  return -1;
652  } else {
653  return 0;
654  }
655 }
656 
657 /*----------------------------------------------------------------------------*/
658 /* get control data */
659 /*----------------------------------------------------------------------------*/
660 static int part_get_control(struct hecmw_part_cont_data *cont_data) {
661  int token, stat;
662  FILE *fp;
663 
664  if (args_subdomain){
666  cont_data->method = HECMW_PART_METHOD_KMETIS; /*HECMW_PART_METHOD_RCB; HECMW_PART_METHOD_PMETIS;*/
667  cont_data->n_domain = args_subdomain;
668  cont_data->depth = 1;
669  cont_data->is_print_ucd = 0;
672  cont_data->is_print_part= 0;
673  return 0;
674  }
675 
676  /* open file */
677  if (strlen(ctrl_file_name) == 0) {
678  HECMW_log(HECMW_LOG_ERROR, "%s (%s)",
680  "control file name for partitioner is not set");
681  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
682  "part_get_control");
683  return -1;
684  }
685  if ((fp = fopen(ctrl_file_name, "r")) == NULL) {
686  HECMW_log(HECMW_LOG_ERROR, "%s (%s)", HECMW_strmsg(errno),
687  "control file for partitioner");
688  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
689  "part_get_control");
690  return -1;
691  }
692 
693  /* initialize lex */
694  stat = HECMW_partlex_set_input(fp);
695  if (stat) {
696  return -1;
697  }
698 
699  /* get control data */
700  while ((token = HECMW_partlex_next_token())) {
701  switch (token) {
702  case HECMW_PARTLEX_H_PARTITION: /* !PARTITION */
703  token = HECMW_partlex_next_token();
704  switch (token) {
705  case ',': /* normal */
706  if (part_cont_partition(cont_data)) return -1;
707  break;
708 
709  case HECMW_PARTLEX_NL: /* no option */
715  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s", __FILE__, __LINE__,
716  "part_cont_partition");
717  return -1;
718 
719  default: /* invalid delimiter */
720  HECMW_log(HECMW_LOG_ERROR, "%s (%s)",
723  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
724  "part_cont_partition", HECMW_partlex_get_text());
725  return -1;
726  }
727  break;
728 
729  case HECMW_PARTLEX_NL: /* new line */
730  break;
731 
732  case 'x':
733  case 'y':
734  case 'z':
735  switch (cont_data->method) {
737  if (cont_data->n_domain > 1) {
740  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
741  "part_cont_partition", HECMW_partlex_get_text());
742  return -1;
743  } else {
744  break;
745  }
746 
752  break;
753 
754  default:
757  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
758  "part_cont_partition", HECMW_partlex_get_text());
759  return -1;
760  }
761  while ((token = HECMW_partlex_next_token()) &&
762  token != HECMW_PARTLEX_NL) {
763  }
764  goto finalize;
765 
766  default:
768  HECMW_log(HECMW_LOG_DEBUG, "%s:%d:%s (%s)", __FILE__, __LINE__,
769  "part_cont_partition", HECMW_partlex_get_text());
770  return -1;
771  }
772  }
773 
774 /* close file */
775 finalize:
776  if (fclose(fp)) {
778  "control file for partitioner");
779  return -1;
780  }
781 
782  return 0;
783 }
784 
785 /*============================================================================*/
786 
789 
790  /* allocate structure for control data */
792  sizeof(struct hecmw_part_cont_data));
793  if (cont_data == NULL) {
795  return NULL;
796  }
797  cont_data->rcb_axis = NULL;
798 
799  /* get control data via file */
800  if (part_get_control(cont_data)) {
802  return NULL;
803  }
804 
805  return cont_data;
806 }
807 
808 /*================================================================================================*/
809 
811  if (cont_data->rcb_axis) {
812  HECMW_free(cont_data->rcb_axis);
813  }
815 }
#define HECMW_FILENAME_LEN
Definition: hecmw_config.h:74
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:33
#define NULL
int HECMW_log(int loglv, const char *fmt,...)
Definition: hecmw_log.c:260
#define HECMW_LOG_ERROR
Definition: hecmw_log.h:15
#define HECMW_LOG_WARN
Definition: hecmw_log.h:17
#define HECMW_LOG_DEBUG
Definition: hecmw_log.h:21
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
char * HECMW_strmsg(int msgno)
Definition: hecmw_msg.c:31
#define HECMW_PART_E_CTRL_DEPTH_NOEQ
#define HECMW_PART_E_FILE_CLOSE
#define HECMW_PART_E_CTRL_UCD_INVAL
#define HECMW_PART_METHOD_PMETIS
#define HECMW_PART_E_CTRL_UCD_NOEQ
#define HECMW_PART_E_CTRL_DOMAIN_POW
#define HECMW_PART_W_CTRL_RCB_MANY_DIR
#define HECMW_PART_RCB_Z_AXIS
#define HECMW_PART_RCB_Y_AXIS
#define HECMW_PART_E_CTRL_NODEF_KMETIS
#define HECMW_PART_E_CTRL_TYPE_INVAL
#define HECMW_PART_CONTACT_OWNER_MASTER
#define HECMW_PART_RCB_X_AXIS
#define HECMW_PART_E_CTRL_PART_TOO_LONG
#define HECMW_PART_E_TOO_LONG_FNAME
#define HECMW_PART_E_CTRL_RCB_FEW_DIR
#define HECMW_PART_E_CTRL_NO_METHOD
#define HECMW_PART_E_CTRL_PART_NOEQ
#define HECMW_PART_METHOD_RCB
#define HECMW_PART_E_CTRL_METHOD_NOEQ
#define HECMW_PART_E_CTRL_METHOD_INVAL
#define HECMW_PART_CONTACT_DEFAULT
#define HECMW_PART_E_INV_ARG
#define HECMW_PART_E_CTRL_NO_TYPE
#define HECMW_PART_E_CTRL_TYPE_NOEQ
#define HECMW_PART_E_CTRL_DOMAIN_NOEQ
#define HECMW_PART_TYPE_NODE_BASED
#define HECMW_PART_E_CTRL_RCB_NODIR
#define HECMW_PART_E_CTRL_RCB_INVAL
#define HECMW_PART_METHOD_KMETIS
#define HECMW_PART_E_CTRL_DOMAIN_INVAL
#define HECMW_PART_E_CTRL_DEPTH_INVAL
#define HECMW_PART_E_INVALID_TOKEN
#define HECMW_PART_E_CTRL_PART_INVAL
#define HECMW_PART_E_CTRL_NODEF_PMETIS
#define HECMW_PART_E_CTRL_CONTACT_INVAL
#define HECMW_PART_CONTACT_DISTRIBUTE
#define HECMW_PART_CONTACT_SIMPLE
#define HECMW_PART_E_INVALID_EOF
#define HECMW_PART_CONTACT_AGGREGATE
#define HECMW_PART_E_CTRL_UCD_TOO_LONG
#define HECMW_PART_METHOD_USER
#define HECMW_PART_E_CTRL_NO_DOMAIN
#define HECMW_PART_E_NULL_POINTER
#define HECMW_PART_W_CTRL_DIR_WORCB
#define HECMW_PART_CONTACT_OWNER_SLAVE
#define HECMW_PART_TYPE_ELEMENT_BASED
void HECMW_part_free_control(struct hecmw_part_cont_data *cont_data)
int HECMW_part_set_ctrl_file_name(char *fname)
struct hecmw_part_cont_data * HECMW_part_get_control(void)
int HECMW_part_set_subdomains(int n_domain)
#define HECMW_PARTLEX_V_DEFAULT
Definition: hecmw_partlex.h:51
#define HECMW_PARTLEX_V_DISTRIBUTE
Definition: hecmw_partlex.h:55
#define HECMW_PARTLEX_FILENAME
Definition: hecmw_partlex.h:19
#define HECMW_PARTLEX_K_TYPE
Definition: hecmw_partlex.h:23
#define HECMW_PARTLEX_K_DOMAIN
Definition: hecmw_partlex.h:27
#define HECMW_PARTLEX_K_METHOD
Definition: hecmw_partlex.h:25
#define HECMW_PARTLEX_V_RCB
Definition: hecmw_partlex.h:41
#define HECMW_PARTLEX_K_UCD
Definition: hecmw_partlex.h:31
#define HECMW_PARTLEX_V_PMETIS
Definition: hecmw_partlex.h:45
#define HECMW_PARTLEX_INT
Definition: hecmw_partlex.h:13
char * HECMW_partlex_get_text(void)
#define HECMW_PARTLEX_V_SIMPLE
Definition: hecmw_partlex.h:57
#define HECMW_PARTLEX_K_PART
Definition: hecmw_partlex.h:35
#define HECMW_PARTLEX_NL
Definition: hecmw_partlex.h:11
int HECMW_partlex_set_input(FILE *fp)
#define HECMW_PARTLEX_V_AGGREGATE
Definition: hecmw_partlex.h:53
double HECMW_partlex_get_number(void)
#define HECMW_PARTLEX_V_NODE_BASED
Definition: hecmw_partlex.h:37
#define HECMW_PARTLEX_NAME
Definition: hecmw_partlex.h:17
#define HECMW_PARTLEX_K_CONTACT
Definition: hecmw_partlex.h:33
#define HECMW_PARTLEX_K_DEPTH
Definition: hecmw_partlex.h:29
#define HECMW_PARTLEX_H_PARTITION
Definition: hecmw_partlex.h:21
#define HECMW_PARTLEX_V_KMETIS
Definition: hecmw_partlex.h:43
int HECMW_partlex_next_token(void)
#define HECMW_PARTLEX_V_ELEMENT_BASED
Definition: hecmw_partlex.h:39
#define HECMW_PARTLEX_V_USER
Definition: hecmw_partlex.h:49
#define HECMW_assert(cond)
Definition: hecmw_util.h:40