2 * This utility configures a NPB to be built for a specific number
3 * of nodes and a specific class. It creates a file "npbparams.h"
4 * in the source directory. This file keeps state information about
5 * which size of benchmark is currently being built (so that nothing
6 * if unnecessarily rebuilt) and defines (through PARAMETER statements)
7 * the number of nodes and class for which a benchmark is being built.
9 * The utility takes 3 arguments:
10 * setparams benchmark-name nprocs class
11 * benchmark-name is "sp", "bt", etc
12 * nprocs is the number of processors to run on
13 * class is the size of the benchmark
14 * These parameters are checked for the current benchmark. If they
15 * are invalid, this program prints a message and aborts.
16 * If the parameters are ok, the current npbsize.h (actually just
17 * the first line) is read in. If the new parameters are the same as
18 * the old, nothing is done, but an exit code is returned to force the
19 * user to specify (otherwise the make procedure succeeds but builds a
20 * binary of the wrong name). Otherwise the file is rewritten.
21 * Errors write a message (to stdout) and abort.
23 * This program makes use of two extra benchmark "classes"
24 * class "X" means an invalid specification. It is returned if
25 * there is an error parsing the config file.
26 * class "U" is an external specification meaning "unknown class"
28 * Unfortunately everything has to be case sensitive. This is
29 * because we can always convert lower to upper or v.v. but
30 * can't feed this information back to the makefile, so typing
31 * make CLASS=a and make CLASS=A will produce different binaries.
36 #include <sys/types.h>
44 * This is the master version number for this set of
45 * NPB benchmarks. It is in an obscure place so people
46 * won't accidentally change it.
51 /* controls verbose output from setparams */
54 #define FILENAME "npbparams.h"
55 #define DESC_LINE "c NPROCS = %d CLASS = %c\n"
56 #define BT_DESC_LINE "c NPROCS = %d CLASS = %c SUBTYPE = %s\n"
57 #define DEF_CLASS_LINE "#define CLASS '%c'\n"
58 #define DEF_NUM_PROCS_LINE "#define NUM_PROCS %d\n"
60 #define CONTINUE " > "
62 #ifdef FORTRAN_REC_SIZE
63 int fortran_rec_size = FORTRAN_REC_SIZE;
65 int fortran_rec_size = 4;
68 void get_info(int argc, char *argv[], int *typep, int *nprocsp, char *classp,
70 void check_info(int type, int nprocs, char class);
71 void read_info(int type, int *nprocsp, char *classp, int *subtypep);
72 void write_info(int type, int nprocs, char class, int subtype);
73 void write_sp_info(FILE *fp, int nprocs, char class);
74 void write_bt_info(FILE *fp, int nprocs, char class, int io);
75 void write_lu_info(FILE *fp, int nprocs, char class);
76 void write_mg_info(FILE *fp, int nprocs, char class);
77 void write_cg_info(FILE *fp, int nprocs, char class);
78 void write_ft_info(FILE *fp, int nprocs, char class);
79 void write_ep_info(FILE *fp, int nprocs, char class);
80 void write_ep_info_C(FILE *fp, int nprocs, char class); /* after C translation */
81 void write_is_info(FILE *fp, int nprocs, char class);
82 void write_dt_info(FILE *fp, int nprocs, char class);
83 void write_compiler_info(int type, FILE *fp);
84 void write_convertdouble_info(int type, FILE *fp);
85 void check_line(char *line, char *label, char *val);
86 int check_include_line(char *line, char *filename);
87 void put_string(FILE *fp, char *name, char *val);
88 void put_def_string(FILE *fp, char *name, char *val);
89 void put_def_variable(FILE *fp, char *name, char *val);
94 enum benchmark_types {SP, BT, LU, MG, FT, IS, DT, EP, CG};
95 enum iotypes { NONE = 0, FULL, SIMPLE, EPIO, FORTRAN};
97 int main(int argc, char *argv[])
99 int nprocs, nprocs_old, type;
100 char class, class_old;
101 int subtype = -1, old_subtype = -1;
103 /* Get command line arguments. Make sure they're ok. */
104 get_info(argc, argv, &type, &nprocs, &class, &subtype);
107 printf("setparams: For benchmark %s: number of processors = %d class = %c\n",
108 argv[1], nprocs, class);
110 check_info(type, nprocs, class);
113 /* Get old information. */
114 read_info(type, &nprocs_old, &class_old, &old_subtype);
116 if (class_old != 'X') {
118 printf("setparams: old settings: number of processors = %d class = %c\n",
119 nprocs_old, class_old);
123 printf("setparams:\n\
124 *********************************************************************\n\
125 * You must specify NPROCS and CLASS to build this benchmark *\n\
126 * For example, to build a class A benchmark for 4 processors, type *\n\
127 * make {benchmark-name} NPROCS=4 CLASS=A *\n\
128 *********************************************************************\n\n");
130 if (class_old != 'X') {
132 printf("setparams: Previous settings were CLASS=%c NPROCS=%d\n",
133 class_old, nprocs_old);
136 exit(1); /* exit on class==U */
139 /* Write out new information if it's different. */
140 if (nprocs != nprocs_old || class != class_old || subtype != old_subtype) {
142 printf("setparams: Writing %s\n", FILENAME);
144 write_info(type, nprocs, class, subtype);
147 printf("setparams: Settings unchanged. %s unmodified\n", FILENAME);
156 * get_info(): Get parameters from command line
159 void get_info(int argc, char *argv[], int *typep, int *nprocsp, char *classp,
164 printf("Usage: %s (%d) benchmark-name nprocs class\n", argv[0], argc);
168 *nprocsp = atoi(argv[2]);
172 if (!strcmp(argv[1], "sp") || !strcmp(argv[1], "SP")) *typep = SP;
173 else if (!strcmp(argv[1], "ft") || !strcmp(argv[1], "FT")) *typep = FT;
174 else if (!strcmp(argv[1], "lu") || !strcmp(argv[1], "LU")) *typep = LU;
175 else if (!strcmp(argv[1], "mg") || !strcmp(argv[1], "MG")) *typep = MG;
176 else if (!strcmp(argv[1], "is") || !strcmp(argv[1], "IS")) *typep = IS;
177 else if (!strcmp(argv[1], "dt") || !strcmp(argv[1], "DT")) *typep = DT;
178 else if (!strcmp(argv[1], "ep") || !strcmp(argv[1], "EP")) *typep = EP;
179 else if (!strcmp(argv[1], "cg") || !strcmp(argv[1], "CG")) *typep = CG;
180 else if (!strcmp(argv[1], "bt") || !strcmp(argv[1], "BT")) {
183 /* printf("Usage: %s (%d) benchmark-name nprocs class\n", argv[0], argc); */
187 if (!strcmp(argv[4], "full") || !strcmp(argv[4], "FULL")) {
189 } else if (!strcmp(argv[4], "simple") || !strcmp(argv[4], "SIMPLE")) {
191 } else if (!strcmp(argv[4], "epio") || !strcmp(argv[4], "EPIO")) {
193 } else if (!strcmp(argv[4], "fortran") || !strcmp(argv[4], "FORTRAN")) {
195 } else if (!strcmp(argv[4], "none") || !strcmp(argv[4], "NONE")) {
198 printf("setparams: Error: unknown btio type %s\n", argv[4]);
203 printf("setparams: Error: unknown benchmark type %s\n", argv[1]);
209 * check_info(): Make sure command line data is ok for this benchmark
212 void check_info(int type, int nprocs, char class)
214 int rootprocs, logprocs;
216 /* check number of processors */
218 printf("setparams: Number of processors must be greater than zero\n");
225 rootprocs = isqrt(nprocs);
227 printf("setparams: Number of processors %d must be a square (1,4,9,...) for this benchmark",
231 if (class == 'S' && nprocs > 16) {
232 printf("setparams: BT and SP sample sizes cannot be run on more\n");
233 printf(" than 16 processors because the cell size would be too small.\n");
243 logprocs = ilog2(nprocs);
245 printf("setparams: Number of processors must be a power of two (1,2,4,...) for this benchmark\n");
256 /* never should have gotten this far with a bad name */
257 printf("setparams: (Internal Error) Benchmark type %d unknown to this program\n", type);
269 printf("setparams: Unknown benchmark class %c\n", class);
270 printf("setparams: Allowed classes are \"S\", \"W\", and \"A\" through \"E\"\n");
274 if (class == 'E' && (type == IS || type == DT)) {
275 printf("setparams: Benchmark class %c not defined for IS or DT\n", class);
279 if (class == 'D' && type == IS && nprocs < 4) {
280 printf("setparams: IS class D size cannot be run on less than 4 processors\n");
287 * read_info(): Read previous information from file.
288 * Not an error if file doesn't exist, because this
289 * may be the first time we're running.
290 * Assumes the first line of the file is in a special
291 * format that we understand (since we wrote it).
294 void read_info(int type, int *nprocsp, char *classp, int *subtypep)
298 fp = fopen(FILENAME, "r");
301 printf("setparams: INFO: configuration file %s does not exist (yet)\n", FILENAME);
306 /* first line of file contains info (fortran), first two lines (C) */
310 char subtype_str[100];
311 nread = fscanf(fp, BT_DESC_LINE, nprocsp, classp, subtype_str);
314 printf("setparams: Error parsing config file %s. Ignoring previous settings\n", FILENAME);
320 if (!strcmp(subtype_str, "full") || !strcmp(subtype_str, "FULL")) {
322 } else if (!strcmp(subtype_str, "simple") ||
323 !strcmp(subtype_str, "SIMPLE")) {
325 } else if (!strcmp(subtype_str, "epio") || !strcmp(subtype_str, "EPIO")) {
327 } else if (!strcmp(subtype_str, "fortran") ||
328 !strcmp(subtype_str, "FORTRAN")) {
342 nread = fscanf(fp, DESC_LINE, nprocsp, classp);
344 printf("setparams: Error line %d parsing config file %s. Ignoring previous settings\n", __LINE__,FILENAME);
351 nread = fscanf(fp, DEF_CLASS_LINE, classp);
352 nread += fscanf(fp, DEF_NUM_PROCS_LINE, nprocsp);
354 printf("setparams: Error line %d parsing config file %s. Ignoring previous settings\n", __LINE__,FILENAME);
359 /* never should have gotten this far with a bad name */
360 printf("setparams: (Internal Error) Benchmark type %d unknown to this program\n", type);
378 * write_info(): Write new information to config file.
379 * First line is in a special format so we can read
380 * it in again. Then comes a warning. The rest is all
381 * specific to a particular benchmark.
384 void write_info(int type, int nprocs, char class, int subtype)
387 char *BT_TYPES[] = {"NONE", "FULL", "SIMPLE", "EPIO", "FORTRAN"};
389 fp = fopen(FILENAME, "w");
391 printf("setparams: Can't open file %s for writing\n", FILENAME);
397 /* Write out the header */
398 if (subtype == -1 || subtype == 0) {
399 fprintf(fp, DESC_LINE, nprocs, class);
401 fprintf(fp, BT_DESC_LINE, nprocs, class, BT_TYPES[subtype]);
403 /* Print out a warning so bozos don't mess with the file */
407 c This file is generated automatically by the setparams utility.\n\
408 c It sets the number of processors and the class of the NPB\n\
409 c in this directory. Do not modify it by hand.\n\
420 /* Write out the header */
421 fprintf(fp, DESC_LINE, nprocs, class);
422 /* Print out a warning so bozos don't mess with the file */
426 c This file is generated automatically by the setparams utility.\n\
427 c It sets the number of processors and the class of the NPB\n\
428 c in this directory. Do not modify it by hand.\n\
435 fprintf(fp, DEF_CLASS_LINE, class);
436 fprintf(fp, DEF_NUM_PROCS_LINE, nprocs);
439 This file is generated automatically by the setparams utility.\n\
440 It sets the number of processors and the class of the NPB\n\
441 in this directory. Do not modify it by hand. */\n\
445 printf("setparams: (Internal error): Unknown benchmark type %d\n",
450 /* Now do benchmark-specific stuff */
453 write_sp_info(fp, nprocs, class);
456 write_lu_info(fp, nprocs, class);
459 write_mg_info(fp, nprocs, class);
462 write_is_info(fp, nprocs, class);
465 write_dt_info(fp, nprocs, class);
468 write_ft_info(fp, nprocs, class);
471 //write_ep_info(fp, nprocs, class);
472 write_ep_info_C(fp, nprocs, class);
475 write_cg_info(fp, nprocs, class);
478 write_bt_info(fp, nprocs, class, subtype);
481 printf("setparams: (Internal error): Unknown benchmark type %d\n", type);
484 write_convertdouble_info(type, fp);
485 write_compiler_info(type, fp);
492 * write_sp_info(): Write SP specific info to config file
495 void write_sp_info(FILE *fp, int nprocs, char class)
497 int maxcells, problem_size, niter;
499 maxcells = isqrt(nprocs);
500 if (class == 'S') { problem_size = 12; dt = "0.015d0"; niter = 100; }
501 else if (class == 'W') { problem_size = 36; dt = "0.0015d0"; niter = 400; }
502 else if (class == 'A') { problem_size = 64; dt = "0.0015d0"; niter = 400; }
503 else if (class == 'B') { problem_size = 102; dt = "0.001d0"; niter = 400; }
504 else if (class == 'C') { problem_size = 162; dt = "0.00067d0"; niter = 400; }
505 else if (class == 'D') { problem_size = 408; dt = "0.00030d0"; niter = 500; }
506 else if (class == 'E') { problem_size = 1020; dt = "0.0001d0"; niter = 500; }
508 printf("setparams: Internal error: invalid class %c\n", class);
511 fprintf(fp, "%sinteger maxcells, problem_size, niter_default\n", FINDENT);
512 fprintf(fp, "%sparameter (maxcells=%d, problem_size=%d, niter_default=%d)\n",
513 FINDENT, maxcells, problem_size, niter);
514 fprintf(fp, "%sdouble precision dt_default\n", FINDENT);
515 fprintf(fp, "%sparameter (dt_default = %s)\n", FINDENT, dt);
519 * write_bt_info(): Write BT specific info to config file
522 void write_bt_info(FILE *fp, int nprocs, char class, int io)
524 int maxcells, problem_size, niter, wr_interval;
526 maxcells = isqrt(nprocs);
527 if (class == 'S') { problem_size = 12; dt = "0.010d0"; niter = 60; }
528 else if (class == 'W') { problem_size = 24; dt = "0.0008d0"; niter = 200; }
529 else if (class == 'A') { problem_size = 64; dt = "0.0008d0"; niter = 200; }
530 else if (class == 'B') { problem_size = 102; dt = "0.0003d0"; niter = 200; }
531 else if (class == 'C') { problem_size = 162; dt = "0.0001d0"; niter = 200; }
532 else if (class == 'D') { problem_size = 408; dt = "0.00002d0"; niter = 250; }
533 else if (class == 'E') { problem_size = 1020; dt = "0.4d-5"; niter = 250; }
535 printf("setparams: Internal error: invalid class %c\n", class);
539 fprintf(fp, "%sinteger maxcells, problem_size, niter_default\n", FINDENT);
540 fprintf(fp, "%sparameter (maxcells=%d, problem_size=%d, niter_default=%d)\n",
541 FINDENT, maxcells, problem_size, niter);
542 fprintf(fp, "%sdouble precision dt_default\n", FINDENT);
543 fprintf(fp, "%sparameter (dt_default = %s)\n", FINDENT, dt);
544 fprintf(fp, "%sinteger wr_default\n", FINDENT);
545 fprintf(fp, "%sparameter (wr_default = %d)\n", FINDENT, wr_interval);
546 fprintf(fp, "%sinteger iotype\n", FINDENT);
547 fprintf(fp, "%sparameter (iotype = %d)\n", FINDENT, io);
549 fprintf(fp, "%scharacter*(*) filenm\n", FINDENT);
552 fprintf(fp, "%sparameter (filenm = 'btio.full.out')\n", FINDENT);
555 fprintf(fp, "%sparameter (filenm = 'btio.simple.out')\n", FINDENT);
558 fprintf(fp, "%sparameter (filenm = 'btio.epio.out')\n", FINDENT);
561 fprintf(fp, "%sparameter (filenm = 'btio.fortran.out')\n", FINDENT);
562 fprintf(fp, "%sinteger fortran_rec_sz\n", FINDENT);
563 fprintf(fp, "%sparameter (fortran_rec_sz = %d)\n",
564 FINDENT, fortran_rec_size);
575 * write_lu_info(): Write SP specific info to config file
578 void write_lu_info(FILE *fp, int nprocs, char class)
580 int isiz1, isiz2, itmax, inorm, problem_size;
581 int xdiv, ydiv; /* number of cells in x and y direction */
584 if (class == 'S') { problem_size = 12; dt_default = "0.5d0"; itmax = 50; }
585 else if (class == 'W') { problem_size = 33; dt_default = "1.5d-3"; itmax = 300; }
586 else if (class == 'A') { problem_size = 64; dt_default = "2.0d0"; itmax = 250; }
587 else if (class == 'B') { problem_size = 102; dt_default = "2.0d0"; itmax = 250; }
588 else if (class == 'C') { problem_size = 162; dt_default = "2.0d0"; itmax = 250; }
589 else if (class == 'D') { problem_size = 408; dt_default = "1.0d0"; itmax = 300; }
590 else if (class == 'E') { problem_size = 1020; dt_default = "0.5d0"; itmax = 300; }
592 printf("setparams: Internal error: invalid class %c\n", class);
596 xdiv = ydiv = ilog2(nprocs)/2;
597 if (xdiv+ydiv != ilog2(nprocs)) xdiv += 1;
598 xdiv = ipow2(xdiv); ydiv = ipow2(ydiv);
599 isiz1 = problem_size/xdiv; if (isiz1*xdiv < problem_size) isiz1++;
600 isiz2 = problem_size/ydiv; if (isiz2*ydiv < problem_size) isiz2++;
603 fprintf(fp, "\nc number of nodes for which this version is compiled\n");
604 fprintf(fp, "%sinteger nnodes_compiled\n", FINDENT);
605 fprintf(fp, "%sparameter (nnodes_compiled = %d)\n", FINDENT, nprocs);
607 fprintf(fp, "\nc full problem size\n");
608 fprintf(fp, "%sinteger isiz01, isiz02, isiz03\n", FINDENT);
609 fprintf(fp, "%sparameter (isiz01=%d, isiz02=%d, isiz03=%d)\n",
610 FINDENT, problem_size, problem_size, problem_size);
612 fprintf(fp, "\nc sub-domain array size\n");
613 fprintf(fp, "%sinteger isiz1, isiz2, isiz3\n", FINDENT);
614 fprintf(fp, "%sparameter (isiz1=%d, isiz2=%d, isiz3=isiz03)\n",
615 FINDENT, isiz1, isiz2);
617 fprintf(fp, "\nc number of iterations and how often to print the norm\n");
618 fprintf(fp, "%sinteger itmax_default, inorm_default\n", FINDENT);
619 fprintf(fp, "%sparameter (itmax_default=%d, inorm_default=%d)\n",
620 FINDENT, itmax, inorm);
622 fprintf(fp, "%sdouble precision dt_default\n", FINDENT);
623 fprintf(fp, "%sparameter (dt_default = %s)\n", FINDENT, dt_default);
628 * write_mg_info(): Write MG specific info to config file
631 void write_mg_info(FILE *fp, int nprocs, char class)
633 int problem_size, nit, log2_size, log2_nprocs, lt_default, lm;
634 int ndim1, ndim2, ndim3;
635 if (class == 'S') { problem_size = 32; nit = 4; }
636 else if (class == 'W') { problem_size = 128; nit = 4; }
637 else if (class == 'A') { problem_size = 256; nit = 4; }
638 else if (class == 'B') { problem_size = 256; nit = 20; }
639 else if (class == 'C') { problem_size = 512; nit = 20; }
640 else if (class == 'D') { problem_size = 1024; nit = 50; }
641 else if (class == 'E') { problem_size = 2048; nit = 50; }
643 printf("setparams: Internal error: invalid class type %c\n", class);
646 log2_size = ilog2(problem_size);
647 log2_nprocs = ilog2(nprocs);
648 /* lt is log of largest total dimension */
649 lt_default = log2_size;
650 /* log of log of maximum dimension on a node */
651 lm = log2_size - log2_nprocs/3;
653 ndim3 = log2_size - (log2_nprocs+2)/3;
654 ndim2 = log2_size - (log2_nprocs+1)/3;
656 fprintf(fp, "%sinteger nprocs_compiled\n", FINDENT);
657 fprintf(fp, "%sparameter (nprocs_compiled = %d)\n", FINDENT, nprocs);
658 fprintf(fp, "%sinteger nx_default, ny_default, nz_default\n", FINDENT);
659 fprintf(fp, "%sparameter (nx_default=%d, ny_default=%d, nz_default=%d)\n",
660 FINDENT, problem_size, problem_size, problem_size);
661 fprintf(fp, "%sinteger nit_default, lm, lt_default\n", FINDENT);
662 fprintf(fp, "%sparameter (nit_default=%d, lm = %d, lt_default=%d)\n",
663 FINDENT, nit, lm, lt_default);
664 fprintf(fp, "%sinteger debug_default\n", FINDENT);
665 fprintf(fp, "%sparameter (debug_default=%d)\n", FINDENT, 0);
666 fprintf(fp, "%sinteger ndim1, ndim2, ndim3\n", FINDENT);
667 fprintf(fp, "%sparameter (ndim1 = %d, ndim2 = %d, ndim3 = %d)\n",
668 FINDENT, ndim1, ndim2, ndim3);
673 * write_dt_info(): Write DT specific info to config file
676 void write_dt_info(FILE *fp, int nprocs, char class)
678 int num_samples,deviation,num_sources;
679 if (class == 'S') { num_samples=1728; deviation=128; num_sources=4; }
680 else if (class == 'W') { num_samples=1728*8; deviation=128*2; num_sources=4*2; }
681 else if (class == 'A') { num_samples=1728*64; deviation=128*4; num_sources=4*4; }
682 else if (class == 'B') { num_samples=1728*512; deviation=128*8; num_sources=4*8; }
683 else if (class == 'C') { num_samples=1728*4096; deviation=128*16; num_sources=4*16; }
684 else if (class == 'D') { num_samples=1728*4096*8; deviation=128*32; num_sources=4*32; }
686 printf("setparams: Internal error: invalid class type %c\n", class);
689 fprintf(fp, "#define NUM_SAMPLES %d\n", num_samples);
690 fprintf(fp, "#define STD_DEVIATION %d\n", deviation);
691 fprintf(fp, "#define NUM_SOURCES %d\n", num_sources);
695 * write_is_info(): Write IS specific info to config file
698 void write_is_info(FILE *fp, int nprocs, char class)
707 printf("setparams: Internal error: invalid class type %c\n", class);
713 * write_cg_info(): Write CG specific info to config file
716 void write_cg_info(FILE *fp, int nprocs, char class)
719 char *shift,*rcond="1.0d-1";
728 int num_proc_cols, num_proc_rows;
732 { na=1400; nonzer=7; niter=15; shift=shiftS; }
733 else if( class == 'W' )
734 { na=7000; nonzer=8; niter=15; shift=shiftW; }
735 else if( class == 'A' )
736 { na=14000; nonzer=11; niter=15; shift=shiftA; }
737 else if( class == 'B' )
738 { na=75000; nonzer=13; niter=75; shift=shiftB; }
739 else if( class == 'C' )
740 { na=150000; nonzer=15; niter=75; shift=shiftC; }
741 else if( class == 'D' )
742 { na=1500000; nonzer=21; niter=100; shift=shiftD; }
743 else if( class == 'E' )
744 { na=9000000; nonzer=26; niter=100; shift=shiftE; }
747 printf("setparams: Internal error: invalid class type %c\n", class);
750 fprintf( fp, "%sinteger na, nonzer, niter\n", FINDENT );
751 fprintf( fp, "%sdouble precision shift, rcond\n", FINDENT );
752 fprintf( fp, "%sparameter( na=%d,\n", FINDENT, na );
753 fprintf( fp, "%s nonzer=%d,\n", CONTINUE, nonzer );
754 fprintf( fp, "%s niter=%d,\n", CONTINUE, niter );
755 fprintf( fp, "%s shift=%s,\n", CONTINUE, shift );
756 fprintf( fp, "%s rcond=%s )\n", CONTINUE, rcond );
759 num_proc_cols = num_proc_rows = ilog2(nprocs)/2;
760 if (num_proc_cols+num_proc_rows != ilog2(nprocs)) num_proc_cols += 1;
761 num_proc_cols = ipow2(num_proc_cols); num_proc_rows = ipow2(num_proc_rows);
763 fprintf( fp, "\nc number of nodes for which this version is compiled\n" );
764 fprintf( fp, "%sinteger nnodes_compiled\n", FINDENT );
765 fprintf( fp, "%sparameter( nnodes_compiled = %d)\n", FINDENT, nprocs );
766 fprintf( fp, "%sinteger num_proc_cols, num_proc_rows\n", FINDENT );
767 fprintf( fp, "%sparameter( num_proc_cols=%d, num_proc_rows=%d )\n",
775 * write_ft_info(): Write FT specific info to config file
778 void write_ft_info(FILE *fp, int nprocs, char class)
780 /* easiest way (given the way the benchmark is written)
781 * is to specify log of number of grid points in each
782 * direction m1, m2, m3. nt is the number of iterations
784 int nx, ny, nz, maxdim, niter;
785 if (class == 'S') { nx = 64; ny = 64; nz = 64; niter = 6;}
786 else if (class == 'W') { nx = 128; ny = 128; nz = 32; niter = 6;}
787 else if (class == 'A') { nx = 256; ny = 256; nz = 128; niter = 6;}
788 else if (class == 'B') { nx = 512; ny = 256; nz = 256; niter =20;}
789 else if (class == 'C') { nx = 512; ny = 512; nz = 512; niter =20;}
790 else if (class == 'D') { nx = 2048; ny = 1024; nz = 1024; niter =25;}
791 else if (class == 'E') { nx = 4096; ny = 2048; nz = 2048; niter =25;}
793 printf("setparams: Internal error: invalid class type %c\n", class);
797 if (ny > maxdim) maxdim = ny;
798 if (nz > maxdim) maxdim = nz;
799 fprintf(fp, "%sinteger nx, ny, nz, maxdim, niter_default, ntdivnp, np_min\n", FINDENT);
800 fprintf(fp, "%sparameter (nx=%d, ny=%d, nz=%d, maxdim=%d)\n",
801 FINDENT, nx, ny, nz, maxdim);
802 fprintf(fp, "%sparameter (niter_default=%d)\n", FINDENT, niter);
803 fprintf(fp, "%sparameter (np_min = %d)\n", FINDENT, nprocs);
804 fprintf(fp, "%sparameter (ntdivnp=((nx*ny)/np_min)*nz)\n", FINDENT);
805 fprintf(fp, "%sdouble precision ntotal_f\n", FINDENT);
806 fprintf(fp, "%sparameter (ntotal_f=1.d0*nx*ny*nz)\n", FINDENT);
810 * write_ep_info(): Write EP specific info to config file
813 void write_ep_info(FILE *fp, int nprocs, char class)
815 /* easiest way (given the way the benchmark is written)
816 * is to specify log of number of grid points in each
817 * direction m1, m2, m3. nt is the number of iterations
820 if (class == 'S') { m = 24; }
821 else if (class == 'W') { m = 25; }
822 else if (class == 'A') { m = 28; }
823 else if (class == 'B') { m = 30; }
824 else if (class == 'C') { m = 32; }
825 else if (class == 'D') { m = 36; }
826 else if (class == 'E') { m = 40; }
828 printf("setparams: Internal error: invalid class type %c\n", class);
831 /* number of processors given by "npm" */
834 fprintf(fp, "%scharacter class\n",FINDENT);
835 fprintf(fp, "%sparameter (class =\'%c\')\n",
837 fprintf(fp, "%sinteger m, npm\n", FINDENT);
838 fprintf(fp, "%sparameter (m=%d, npm=%d)\n",
842 * write_ep_info_C(): Write EP specific info to config file
846 void write_ep_info_C(FILE *fp, int nprocs, char class)
848 /* easiest way (given the way the benchmark is written)
849 * is to specify log of number of grid points in each
850 * direction m1, m2, m3. nt is the number of iterations
853 if (class == 'S') { m = 24; }
854 else if (class == 'W') { m = 25; }
855 else if (class == 'A') { m = 28; }
856 else if (class == 'B') { m = 30; }
857 else if (class == 'C') { m = 32; }
858 else if (class == 'D') { m = 36; }
859 else if (class == 'E') { m = 40; }
861 printf("setparams: Internal error: invalid class type %c\n", class);
864 /* number of processors given by "npm" */
867 fprintf(fp, "%schar *_class=\"%c\";\n",FINDENT,class);
868 fprintf(fp, "%sint m=%d;\n", FINDENT,m);
869 fprintf(fp, "%sint npm=%d;\n", FINDENT,nprocs);
872 * This is a gross hack to allow the benchmarks to
873 * print out how they were compiled. Various other ways
874 * of doing this have been tried and they all fail on
875 * some machine - due to a broken "make" program, or
876 * F77 limitations, of whatever. Hopefully this will
877 * always work because it uses very portable C. Unfortunately
878 * it relies on parsing the make.def file - YUK.
879 * If your machine doesn't have <string.h> or <ctype.h>, happy hacking!
886 #define DEFFILE "../config/make.def"
887 #define DEFAULT_MESSAGE "(none)"
889 void write_compiler_info(int type, FILE *fp)
892 char mpif77[LL], flink[LL], fmpi_lib[LL], fmpi_inc[LL], fflags[LL], flinkflags[LL];
893 char compiletime[LL], randfile[LL];
894 char mpicc[LL], cflags[LL], clink[LL], clinkflags[LL],
895 cmpi_lib[LL], cmpi_inc[LL];
898 deffile = fopen(DEFFILE, "r");
899 if (deffile == NULL) {
901 setparams: File %s doesn't exist. To build the NAS benchmarks\n\
902 you need to create is according to the instructions\n\
903 in the README in the main directory and comments in \n\
904 the file config/make.def.template\n", DEFFILE);
907 strcpy(mpif77, DEFAULT_MESSAGE);
908 strcpy(flink, DEFAULT_MESSAGE);
909 strcpy(fmpi_lib, DEFAULT_MESSAGE);
910 strcpy(fmpi_inc, DEFAULT_MESSAGE);
911 strcpy(fflags, DEFAULT_MESSAGE);
912 strcpy(flinkflags, DEFAULT_MESSAGE);
913 strcpy(randfile, DEFAULT_MESSAGE);
914 strcpy(mpicc, DEFAULT_MESSAGE);
915 strcpy(cflags, DEFAULT_MESSAGE);
916 strcpy(clink, DEFAULT_MESSAGE);
917 strcpy(clinkflags, DEFAULT_MESSAGE);
918 strcpy(cmpi_lib, DEFAULT_MESSAGE);
919 strcpy(cmpi_inc, DEFAULT_MESSAGE);
921 while (fgets(line, LL, deffile) != NULL) {
922 if (*line == '#') continue;
923 /* yes, this is inefficient. but it's simple! */
924 check_line(line, "MPIF77", mpif77);
925 check_line(line, "FLINK", flink);
926 check_line(line, "FMPI_LIB", fmpi_lib);
927 check_line(line, "FMPI_INC", fmpi_inc);
928 check_line(line, "FFLAGS", fflags);
929 check_line(line, "FLINKFLAGS", flinkflags);
930 check_line(line, "RAND", randfile);
931 check_line(line, "MPICC", mpicc);
932 check_line(line, "CFLAGS", cflags);
933 check_line(line, "CLINK", clink);
934 check_line(line, "CLINKFLAGS", clinkflags);
935 check_line(line, "CMPI_LIB", cmpi_lib);
936 check_line(line, "CMPI_INC", cmpi_inc);
937 /* if the dummy library is used by including make.dummy, we set the
938 Fortran and C paths to libraries and headers accordingly */
939 if(check_include_line(line, "../config/make.dummy")) {
940 strcpy(fmpi_lib, "-L../MPI_dummy -lmpi");
941 strcpy(fmpi_inc, "-I../MPI_dummy");
942 strcpy(cmpi_lib, "-L../MPI_dummy -lmpi");
943 strcpy(cmpi_inc, "-I../MPI_dummy");
950 (void) strftime(compiletime, (size_t)LL, "%d %b %Y", tmp);
961 put_string(fp, "compiletime", compiletime);
962 put_string(fp, "npbversion", VERSION);
963 put_string(fp, "cs1", mpif77);
964 put_string(fp, "cs2", flink);
965 put_string(fp, "cs3", fmpi_lib);
966 put_string(fp, "cs4", fmpi_inc);
967 put_string(fp, "cs5", fflags);
968 put_string(fp, "cs6", flinkflags);
969 put_string(fp, "cs7", randfile);
974 put_def_string(fp, "COMPILETIME", compiletime);
975 put_def_string(fp, "NPBVERSION", VERSION);
976 put_def_string(fp, "MPICC", mpicc);
977 put_def_string(fp, "CFLAGS", cflags);
978 put_def_string(fp, "CLINK", clink);
979 put_def_string(fp, "CLINKFLAGS", clinkflags);
980 put_def_string(fp, "CMPI_LIB", cmpi_lib);
981 put_def_string(fp, "CMPI_INC", cmpi_inc);
984 printf("setparams: (Internal error): Unknown benchmark type %d\n",
991 void check_line(char *line, char *label, char *val)
995 original_line = line;
996 /* compare beginning of line and label */
997 while (*label != '\0' && *line == *label) {
1000 /* if *label is not EOS, we must have had a mismatch */
1001 if (*label != '\0') return;
1002 /* if *line is not a space, actual label is longer than test label */
1003 if (!isspace(*line) && *line != '=') return ;
1004 /* skip over white space */
1005 while (isspace(*line)) line++;
1006 /* next char should be '=' */
1007 if (*line != '=') return;
1008 /* skip over white space */
1009 while (isspace(*++line));
1010 /* if EOS, nothing was specified */
1011 if (*line == '\0') return;
1012 /* finally we've come to the value */
1014 /* chop off the newline at the end */
1016 if (n >= 0 && val[n] == '\n')
1018 if (n >= 0 && val[n] == '\r')
1020 /* treat continuation */
1021 while (val[n] == '\\' && fgets(original_line, LL, deffile)) {
1022 line = original_line;
1023 while (isspace(*line)) line++;
1024 if (isspace(*original_line)) val[n++] = ' ';
1025 while (*line && *line != '\n' && *line != '\r' && n < LL-1)
1030 /* if (val[strlen(val) - 1] == '\\') {
1032 setparams: Error in file make.def. Because of the way in which\n\
1033 command line arguments are incorporated into the\n\
1034 executable benchmark, you can't have any continued\n\
1035 lines in the file make.def, that is, lines ending\n\
1036 with the character \"\\\". Although it may be ugly, \n\
1037 you should be able to reformat without continuation\n\
1038 lines. The offending line is\n\
1039 %s\n", original_line);
1044 int check_include_line(char *line, char *filename)
1046 char *include_string = "include";
1047 /* compare beginning of line and "include" */
1048 while (*include_string != '\0' && *line == *include_string) {
1049 line++; include_string++;
1051 /* if *include_string is not EOS, we must have had a mismatch */
1052 if (*include_string != '\0') return(0);
1053 /* if *line is not a space, first word is not "include" */
1054 if (!isspace(*line)) return(0);
1055 /* skip over white space */
1056 while (isspace(*++line));
1057 /* if EOS, nothing was specified */
1058 if (*line == '\0') return(0);
1059 /* next keyword should be name of include file in *filename */
1060 while (*filename != '\0' && *line == *filename) {
1063 if (*filename != '\0' ||
1064 (*line != ' ' && *line != '\0' && *line !='\n')) return(0);
1070 void put_string(FILE *fp, char *name, char *val)
1081 fprintf(fp, "%scharacter*%d %s\n", FINDENT, len, name);
1082 fprintf(fp, "%sparameter (%s=\'%s\')\n", FINDENT, name, val);
1085 /* NOTE: is the ... stuff necessary in C? */
1086 void put_def_string(FILE *fp, char *name, char *val)
1097 fprintf(fp, "#define %s \"%s\"\n", name, val);
1100 void put_def_variable(FILE *fp, char *name, char *val)
1111 fprintf(fp, "#define %s %s\n", name, val);
1118 /* this version allows arbitrarily long lines but
1119 * some compilers don't like that and they're rarely
1124 void put_string(FILE *fp, char *name, char *val)
1126 int len, nlines, pos, i;
1129 nlines = len/LINELEN;
1130 if (nlines*LINELEN < len) nlines++;
1131 fprintf(fp, "%scharacter*%d %s\n", FINDENT, nlines*LINELEN, name);
1132 fprintf(fp, "%sparameter (%s = \n", FINDENT, name);
1133 for (i = 0; i < nlines; i++) {
1135 if (i == 0) fprintf(fp, "%s\'", CONTINUE);
1136 else fprintf(fp, "%s", CONTINUE);
1137 /* number should be same as LINELEN */
1138 fprintf(fp, "%.65s", val+pos);
1139 if (i == nlines-1) fprintf(fp, "\')\n");
1140 else fprintf(fp, "\n");
1147 /* integer square root. Return error if argument isn't
1148 * a perfect square or is less than or equal to zero
1154 if (i <= 0) return(-1);
1156 for (root = 1; square <= i; root++) {
1158 if (square == i) return(root);
1164 /* integer log base two. Return error is argument isn't
1165 * a power of two or is less than or equal to zero
1172 if (i <= 0) return(-1);
1174 for (log2 = 0; log2 < 20; log2++) {
1175 if (exp2 == i) return(log2);
1184 if (i < 0) return(-1);
1185 if (i == 0) return(1);
1186 while(i--) pow2 *= 2;
1192 void write_convertdouble_info(int type, FILE *fp)
1202 fprintf(fp, "%slogical convertdouble\n", FINDENT);
1203 #ifdef CONVERTDOUBLE
1204 fprintf(fp, "%sparameter (convertdouble = .true.)\n", FINDENT);
1206 fprintf(fp, "%sparameter (convertdouble = .false.)\n", FINDENT);