📄 setparams.c
字号:
/* * This utility configures a NPB to be built for a specific class. * It creates a file "npbparams.h" * in the source directory. This file keeps state information about * which size of benchmark is currently being built (so that nothing * if unnecessarily rebuilt) and defines (through PARAMETER statements) * the number of nodes and class for which a benchmark is being built. * The utility takes 3 arguments: * setparams benchmark-name class * benchmark-name is "sp", "bt", etc * class is the size of the benchmark * These parameters are checked for the current benchmark. If they * are invalid, this program prints a message and aborts. * If the parameters are ok, the current npbsize.h (actually just * the first line) is read in. If the new parameters are the same as * the old, nothing is done, but an exit code is returned to force the * user to specify (otherwise the make procedure succeeds but builds a * binary of the wrong name). Otherwise the file is rewritten. * Errors write a message (to stdout) and abort. * * This program makes use of two extra benchmark "classes" * class "X" means an invalid specification. It is returned if * there is an error parsing the config file. * class "U" is an external specification meaning "unknown class" * * Unfortunately everything has to be case sensitive. This is * because we can always convert lower to upper or v.v. but * can't feed this information back to the makefile, so typing * make CLASS=a and make CLASS=A will produce different binaries. * * */#include <sys/types.h>#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include <time.h>/* * This is the master version number for this set of * NPB benchmarks. It is in an obscure place so people * won't accidentally change it. */#define VERSION "2.3"/* controls verbose output from setparams *//* #define VERBOSE */#define FILENAME "npbparams.h"#define DESC_LINE "/* CLASS = %c */\n"#define DEF_CLASS_LINE "#define CLASS '%c'\n"#define FINDENT " "#define CONTINUE " > "void get_info(char *argv[], int *typep, char *classp);void check_info(int type, char class);void read_info(int type, char *classp);void write_info(int type, char class);void write_sp_info(FILE *fp, char class);void write_bt_info(FILE *fp, char class);void write_lu_info(FILE *fp, char class);void write_mg_info(FILE *fp, char class);void write_cg_info(FILE *fp, char class);void write_ft_info(FILE *fp, char class);void write_ep_info(FILE *fp, char class);void write_is_info(FILE *fp, char class);void write_compiler_info(int type, FILE *fp);void write_convertdouble_info(int type, FILE *fp);void check_line(char *line, char *label, char *val);int check_include_line(char *line, char *filename);void put_string(FILE *fp, char *name, char *val);void put_def_string(FILE *fp, char *name, char *val);void put_def_variable(FILE *fp, char *name, char *val);int ilog2(int i);enum benchmark_types {SP, BT, LU, MG, FT, IS, EP, CG};main(int argc, char *argv[]){ int type; char class, class_old; if (argc != 3) { printf("Usage: %s benchmark-name class\n", argv[0]); exit(1); } /* Get command line arguments. Make sure they're ok. */ get_info(argv, &type, &class); if (class != 'U') {#ifdef VERBOSE printf("setparams: For benchmark %s: class = %c\n", argv[1], class); #endif check_info(type, class); } /* Get old information. */ read_info(type, &class_old); if (class != 'U') { if (class_old != 'X') {#ifdef VERBOSE printf("setparams: old settings: class = %c\n", class_old); #endif } } else { printf("setparams:\n\ *********************************************************************\n\ * You must specify CLASS to build this benchmark *\n\ * For example, to build a class A benchmark, type *\n\ * make {benchmark-name} CLASS=A *\n\ *********************************************************************\n\n"); if (class_old != 'X') {#ifdef VERBOSE printf("setparams: Previous settings were CLASS=%c \n", class_old); #endif } exit(1); /* exit on class==U */ } /* Write out new information if it's different. */ if (class != class_old) {#ifdef VERBOSE printf("setparams: Writing %s\n", FILENAME); #endif write_info(type, class); } else {#ifdef VERBOSE printf("setparams: Settings unchanged. %s unmodified\n", FILENAME); #endif } exit(0);}/* * get_info(): Get parameters from command line */void get_info(char *argv[], int *typep, char *classp) { *classp = *argv[2]; if (!strcmp(argv[1], "sp") || !strcmp(argv[1], "SP")) *typep = SP; else if (!strcmp(argv[1], "bt") || !strcmp(argv[1], "BT")) *typep = BT; else if (!strcmp(argv[1], "ft") || !strcmp(argv[1], "FT")) *typep = FT; else if (!strcmp(argv[1], "lu") || !strcmp(argv[1], "LU")) *typep = LU; else if (!strcmp(argv[1], "mg") || !strcmp(argv[1], "MG")) *typep = MG; else if (!strcmp(argv[1], "is") || !strcmp(argv[1], "IS")) *typep = IS; else if (!strcmp(argv[1], "ep") || !strcmp(argv[1], "EP")) *typep = EP; else if (!strcmp(argv[1], "cg") || !strcmp(argv[1], "CG")) *typep = CG; else { printf("setparams: Error: unknown benchmark type %s\n", argv[1]); exit(1); }}/* * check_info(): Make sure command line data is ok for this benchmark */void check_info(int type, char class) { int tmplog; /* check class */ if (class != 'S' && class != 'A' && class != 'B' && class != 'R' && class != 'W' && class != 'C') { printf("setparams: Unknown benchmark class %c\n", class); printf("setparams: Allowed classes are \"S\", \"A\", \"B\" and \"C\"\n"); exit(1); }}/* * read_info(): Read previous information from file. * Not an error if file doesn't exist, because this * may be the first time we're running. * Assumes the first line of the file is in a special * format that we understand (since we wrote it). */void read_info(int type, char *classp){ int nread, gotem = 0; char line[200]; FILE *fp; fp = fopen(FILENAME, "r"); if (fp == NULL) {#ifdef VERBOSE printf("setparams: INFO: configuration file %s does not exist (yet)\n", FILENAME); #endif goto abort; } /* first line of file contains info (fortran), first two lines (C) */ switch(type) { case SP: case BT: case FT: case MG: case LU: case EP: case CG: nread = fscanf(fp, DESC_LINE, classp); if (nread != 1) { printf("setparams: Error parsing config file %s. Ignoring previous settings\n", FILENAME); goto abort; } break; case IS: nread = fscanf(fp, DEF_CLASS_LINE, classp); if (nread != 1) { printf("setparams: Error parsing config file %s. Ignoring previous settings\n", FILENAME); goto abort; } break; default: /* never should have gotten this far with a bad name */ printf("setparams: (Internal Error) Benchmark type %d unknown to this program\n", type); exit(1); } normal_return: *classp = *classp; fclose(fp); return; abort: *classp = 'X'; return;}/* * write_info(): Write new information to config file. * First line is in a special format so we can read * it in again. Then comes a warning. The rest is all * specific to a particular benchmark. */void write_info(int type, char class) { FILE *fp; fp = fopen(FILENAME, "w"); if (fp == NULL) { printf("setparams: Can't open file %d for writing\n", FILENAME); exit(1); } switch(type) { case SP: case BT: case FT: case MG: case LU: case EP: case CG: /* Write out the header */ fprintf(fp, DESC_LINE, class); /* Print out a warning so bozos don't mess with the file */ fprintf(fp, "\/*\n\c This file is generated automatically by the setparams utility.\n\c It sets the number of processors and the class of the NPB\n\c in this directory. Do not modify it by hand.\n\*/\n"); break; case IS: fprintf(fp, DEF_CLASS_LINE, class); fprintf(fp, "\/*\n\ This file is generated automatically by the setparams utility.\n\ It sets the number of processors and the class of the NPB\n\ in this directory. Do not modify it by hand. */\n\ \n"); break; default: printf("setparams: (Internal error): Unknown benchmark type %d\n", type); exit(1); } /* Now do benchmark-specific stuff */ switch(type) { case SP: write_sp_info(fp, class); break; case BT: write_bt_info(fp, class); break; case LU: write_lu_info(fp, class); break; case MG: write_mg_info(fp, class); break; case IS: write_is_info(fp, class); break; case FT: write_ft_info(fp, class); break; case EP: write_ep_info(fp, class); break; case CG: write_cg_info(fp, class); break; default: printf("setparams: (Internal error): Unknown benchmark type %d\n", type); exit(1); } write_convertdouble_info(type, fp); write_compiler_info(type, fp); fclose(fp); return;}/* * write_sp_info(): Write SP specific info to config file */void write_sp_info(FILE *fp, char class) { int problem_size, niter; char *dt; if (class == 'S') { problem_size = 12; dt = "0.015"; niter = 100; } else if (class == 'W') { problem_size = 36; dt = "0.0015"; niter = 400; } else if (class == 'A') { problem_size = 64; dt = "0.0015"; niter = 400; } else if (class == 'B') { problem_size = 102; dt = "0.001"; niter = 400; } else if (class == 'C') { problem_size = 162; dt = "0.00067"; niter = 400; } else { printf("setparams: Internal error: invalid class %c\n", class); exit(1); } fprintf(fp, "#define\tPROBLEM_SIZE\t%d\n", problem_size); fprintf(fp, "#define\tNITER_DEFAULT\t%d\n", niter); fprintf(fp, "#define\tDT_DEFAULT\t%s\n", dt);} /* * write_bt_info(): Write BT specific info to config file */void write_bt_info(FILE *fp, char class) { int problem_size, niter; char *dt; if (class == 'S') { problem_size = 12; dt = "0.010"; niter = 60; } else if (class == 'W') { problem_size = 24; dt = "0.0008"; niter = 200; } else if (class == 'A') { problem_size = 64; dt = "0.0008"; niter = 200; } else if (class == 'B') { problem_size = 102; dt = "0.0003"; niter = 200; } else if (class == 'C') { problem_size = 162; dt = "0.0001"; niter = 200; } else { printf("setparams: Internal error: invalid class %c\n", class); exit(1); } fprintf(fp, "#define\tPROBLEM_SIZE\t%d\n", problem_size); fprintf(fp, "#define\tNITER_DEFAULT\t%d\n", niter); fprintf(fp, "#define\tDT_DEFAULT\t%s\n", dt);} /* * write_lu_info(): Write SP specific info to config file */void write_lu_info(FILE *fp, char class) { int isiz1, isiz2, itmax, inorm, problem_size; int xdiv, ydiv; /* number of cells in x and y direction */ char *dt_default; if (class == 'S') { problem_size = 12; dt_default = "0.5"; itmax = 50; } else if (class == 'W') { problem_size = 33; dt_default = "1.5e-3"; itmax = 300; } else if (class == 'A') { problem_size = 64; dt_default = "2.0"; itmax = 250; } else if (class == 'B') { problem_size = 102; dt_default = "2.0"; itmax = 250; } else if (class == 'C') { problem_size = 162; dt_default = "2.0"; itmax = 250; } else { printf("setparams: Internal error: invalid class %c\n", class); exit(1); } inorm = itmax; isiz1 = problem_size; isiz2 = problem_size; fprintf(fp, "\n/* full problem size */\n"); fprintf(fp, "#define\tISIZ1\t%d\n", problem_size); fprintf(fp, "#define\tISIZ2\t%d\n", problem_size); fprintf(fp, "#define\tISIZ3\t%d\n", problem_size); fprintf(fp, "/* number of iterations and how often to print the norm */\n"); fprintf(fp, "#define\tITMAX_DEFAULT\t%d\n", itmax); fprintf(fp, "#define\tINORM_DEFAULT\t%d\n", inorm); fprintf(fp, "#define\tDT_DEFAULT\t%s\n", dt_default);}/* * write_mg_info(): Write MG specific info to config file */void write_mg_info(FILE *fp, char class) { int problem_size, nit, log2_size, lt_default, lm; int ndim1, ndim2, ndim3; if (class == 'S') { problem_size = 32; nit = 4; } else if (class == 'W') { problem_size = 64; nit = 40; } else if (class == 'A') { problem_size = 256; nit = 4; } else if (class == 'B') { problem_size = 256; nit = 20; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -