Beispiel #1
0
int main(int argc, char ** argv){
  MPI_Init(&argc, &argv);



	// Default values
	struct args args;
	args.procs.nn = 0;
	args.procs.ppn = 0;
	args.dgeom_size = 0;
	args.dgeom = NULL;
	args.bgeom_size = 0;
  args.bgeom = NULL;
	args.cgeom_size = 0;
  args.cgeom = NULL;
  args.testfn = NULL;
  args.write_test = 0;
  args.read_test = 0;
	args.report_type = REPORT_HUMAN;
  args.par_access = NC_INDEPENDENT;
  args.is_unlimited = 0;
	args.verify = 0;
	args.fill_value = 0;

	char * dg = NULL, * bg  = NULL, *cg = NULL, *iot = "ind", *xf = "human";

	option_help options [] = {
		{'n' , "nn"             , "Number of nodes"                         , OPTION_OPTIONAL_ARGUMENT , 'd' , & args.procs.nn}     ,
		{'p' , "ppn"            , "Number of processes"                     , OPTION_OPTIONAL_ARGUMENT , 'd' , & args.procs.ppn}    ,
		{'d' , "data-geometry"  , "Data geometry (t:x:y:z)"                 , OPTION_OPTIONAL_ARGUMENT , 's' , & dg}                ,
		{'b' , "block-geometry" , "Block geometry (t:x:y:z)"                , OPTION_OPTIONAL_ARGUMENT , 's' , & bg}                ,
		{'c' , "chunk-geometry" , "Chunk geometry (t:x:y:z|auto)"           , OPTION_OPTIONAL_ARGUMENT , 's' , & cg}                ,
		{'r' , "read"           , "Enable read benchmark"                   , OPTION_FLAG              , 'd' , & args.read_test}    ,
		{'w' , "write"          , "Enable write benchmark"                  , OPTION_FLAG              , 'd' , & args.write_test}   ,
		{'t' , "io-type"        , "Independent / Collective I/O (ind|coll)" , OPTION_OPTIONAL_ARGUMENT , 's' , & iot}               ,
		{'u' , "unlimited"      , "Enable unlimited time dimension"         , OPTION_FLAG              , 'd' , & args.is_unlimited} ,
		{'f' , "testfile"       , "Filename of the testfile"                , OPTION_OPTIONAL_ARGUMENT , 's' , & args.testfn}       ,
		{'x' , "output-format"  , "Output-Format (parser|human)"            , OPTION_OPTIONAL_ARGUMENT , 's' , & xf}                ,
		{'F' , "use-fill-value" , "Write a fill value"                      , OPTION_FLAG              , 'd', & args.fill_value}    ,
		{0 , 	 "verify"  				, "Verify that the data read is correct (reads the data again)", OPTION_FLAG ,						   'd' , & args.verify}                ,
	  LAST_OPTION
	  };
	int rank;
	MPI_Comm_rank(MPI_COMM_WORLD, & rank);
	// check the correctness of the options only for rank 0
	if (rank == 0){
		printf("Benchtool (datatype: %s) \n", xstr(DATATYPE));
		parseOptions(argc, argv, options);
	}
	MPI_Barrier(MPI_COMM_WORLD);
	if (rank != 0){
		parseOptions(argc, argv, options);
	}

	parse_dims(dg, &args.dgeom, &args.dgeom_size);
	parse_dims(bg, &args.bgeom, &args.bgeom_size);

  if ((0 == strcmp(iot, "c")) | (0 == strcmp(iot, "coll")) | (0 == strcmp(iot,"collective"))) {
    args.par_access = NC_COLLECTIVE;
  }
  else if  ((0 == strcmp(iot, "i")) | (0 == strcmp(iot, "ind")) | (0 == strcmp(iot, "independent"))) {
    args.par_access = NC_INDEPENDENT;
  }
  else {
    FATAL_ERR("Unsupported parallel access type %s\n", xf);
  }

	if (0 == strcmp(xf, "parser")) {
		args.report_type = REPORT_PARSER;
	}else	if (0 == strcmp(xf, "human")) {
		args.report_type = REPORT_HUMAN;
	}else{
		FATAL_ERR("Unsupported report type %s\n", xf);
	}

	if (0 == args.procs.nn) {
		char *end = NULL;
		const char* env = getenv("SLURM_NNODES");
		if (NULL != env) {
			args.procs.nn = strtol(env, &end, 10);
		}
		if (0 == args.procs.nn) {
			args.procs.nn = 1;
		}
	}

	if (0 == args.procs.ppn) {
		char *end = NULL;
		const char* env = getenv("SLURM_NTASKS_PER_NODE");
		if (NULL != env) {
			args.procs.ppn = strtol(env, &end, 10);
		}
		if (0 == args.procs.ppn) {
			args.procs.ppn = 1;
		}
	}

	if (NULL == args.testfn) {
		const char* testfn = "./testfn.nc";
		args.testfn = (char*)malloc(sizeof(*args.testfn) * strlen(testfn) + 1);
		strcpy(args.testfn, testfn);
	}

	if (NULL == args.dgeom) {
		args.dgeom_size = NDIMS;
		args.dgeom = (size_t*)malloc(sizeof(*args.dgeom) * args.dgeom_size);
		args.dgeom[DT] = 100;
		args.dgeom[DX] = args.procs.nn * 100;
		args.dgeom[DY] = args.procs.ppn * 100;
		args.dgeom[DZ] = 10;
	}

	if (NDIMS != args.dgeom_size) {
		FATAL_ERR("Found %zu dimensions (expected %d).\n", args.dgeom_size, NDIMS);
	}

	// Automatic block layout
	if (NULL == args.bgeom) {
		args.bgeom_size = args.dgeom_size;
		args.bgeom = (size_t*)malloc(sizeof(*args.bgeom) * args.bgeom_size);
		args.bgeom[DT] = 1;
		args.bgeom[DX] = args.dgeom[DX] / args.procs.nn;
		args.bgeom[DY] = args.dgeom[DY] / args.procs.ppn;
		args.bgeom[DZ] = args.dgeom[DZ];
	}

	if (cg != NULL && 0 == strcmp(cg, "auto")) {
		args.cgeom_size = args.bgeom_size;
		args.cgeom = (size_t*)malloc(sizeof(*args.cgeom) * args.cgeom_size);
		args.cgeom[DT] = 1;
		args.cgeom[DX] = args.bgeom[DX];
		args.cgeom[DY] = args.bgeom[DY];
		args.cgeom[DZ] = args.bgeom[DZ];
	}
	else {
		parse_dims(cg, &args.cgeom, &args.cgeom_size);
	}

	if (NDIMS != args.bgeom_size) {
		FATAL_ERR("Found %zu dimensions (expected %d).\n", args.bgeom_size, NDIMS);
	}

  if (NULL != args.cgeom) {
    if (NDIMS != args.cgeom_size) {
      FATAL_ERR("Found %zu dimensions (expected %d).\n", args.cgeom_size, NDIMS);
    }
  }

  DEBUG_MESSAGE("dgeom (%zu:%zu:%zu:%zu)\n", args.dgeom[DT], args.dgeom[DX], args.dgeom[DY], args.dgeom[DZ]);
  DEBUG_MESSAGE("bgeom (%zu:%zu:%zu:%zu)\n", args.bgeom[DT], args.bgeom[DX], args.bgeom[DY], args.bgeom[DZ]);
  if (NULL != args.cgeom) {
    DEBUG_MESSAGE("cgeom (%zu:%zu:%zu:%zu)\n", args.cgeom[DT], args.cgeom[DX], args.cgeom[DY], args.cgeom[DZ]);
  }
  DEBUG_MESSAGE("(nn %zu, ppn %zu)\n", args.procs.nn, args.procs.ppn);
  DEBUG_MESSAGE("test filename %s\n", args.testfn);

  if (args.dgeom[DX] % args.procs.nn != 0) {
    FATAL_ERR("x must be a multiple of number of nodes.\n");
  }

  if (args.dgeom[DY] % args.procs.ppn != 0) {
    FATAL_ERR("y must be a multiple of number of processes.\n");
  }

  if (NULL != args.cgeom) {
    if (args.dgeom[DT] % args.cgeom[DT] != 0) {
      FATAL_ERR("Time range must be a multiple of time slice (range=%zu; slice=%zu)\n", args.dgeom[DT], args.cgeom[DT]);
    }
  }

	int nranks = 0;
	MPI_Comm_size(MPI_COMM_WORLD, &nranks);

	if (nranks != args.procs.nn * args.procs.ppn){
		FATAL_ERR("Bad environment: np != nn * ppn; np(size of MPI_COMM_WORLD)=%d, nodes(nn)=%zu, ppn(procs per node)=%zu\n",
				nranks, args.procs.nn, args.procs.ppn);
	}


	if ((args.read_test == false) & (args.write_test == false) & (args.verify == false)) {
		args.write_test = true;
	}

	benchmark_t wbm;
	benchmark_init(&wbm);

	int header_printed = 0;

	benchmark_t rbm;
	benchmark_init(&rbm);
	if (args.write_test || args.verify) {
		benchmark_setup(&wbm, args.procs, NDIMS, args.dgeom, args.bgeom, args.cgeom, args.testfn, IO_MODE_WRITE, args.par_access, args.is_unlimited, args.fill_value);
		if(rank == 0){
			print_header(& wbm);
			header_printed = 1;
		}
	}
	if (args.write_test) {
		benchmark_run(&wbm, NULL);
		report_t report;
		report_init(&report);
		report_setup(&report, &wbm);
		report_print(&report, args.report_type);
		report_destroy(&report);
	}
	if (args.read_test) {
		int ret;
		benchmark_setup(&rbm, args.procs, NDIMS, args.dgeom, args.bgeom, args.cgeom, args.testfn, IO_MODE_READ, args.par_access, args.is_unlimited, 0);
		if(rank == 0 && ! header_printed){
			print_header(& rbm);
			header_printed = 1;
		}
		ret = benchmark_run(&rbm, args.verify ? wbm.block : NULL );
		report_t report;
		report_init(&report);
		report_setup(&report, &rbm);
		report_print(&report, args.report_type);
		report_destroy(&report);

	}else if (args.verify) {

		int ret;
		benchmark_setup(& rbm, args.procs, NDIMS, args.dgeom, args.bgeom, args.cgeom, args.testfn, IO_MODE_READ, args.par_access, args.is_unlimited, 0);
		if(rank == 0 && ! header_printed){
			print_header(& rbm);
			header_printed = 1;
		}
		ret = benchmark_run(& rbm, wbm.block);
		if (args.verify){
			if (ret) {
				printf("TEST PASSED [%u]\n", wbm.rank);
			}
			else {
				printf("TEST FAILED [%u]\n", wbm.rank);
			}
		}
	}


	MPI_Finalize();
	benchmark_destroy(&wbm);
	benchmark_destroy(&rbm);
  free(args.dgeom);
	free(args.bgeom);
  free(args.cgeom);
  free(args.testfn);
  return 0;
}
Beispiel #2
0
void args_handle(config *cfg, int argc, char **argv) {
    int fl;
    while ((fl = getopt(argc, argv, "Acd:fhl:m:rsSx")) != -1) {
        switch (fl) {
        case 'A':               /* no axis */
            cfg->axis = false;
            break;
        case 'c':               /* use colorblind-safe default colors */
            cfg->colorblind = true;
            break;
        case 'd':               /* dimensions */
            parse_dims(cfg, optarg);
            break;
        case 'f':               /* flip x/y */
            cfg->flip_xy = true;
            break;
        case 'h':               /* help */
            usage(NULL);
            break;
        case 'l':               /* log */
            if (strchr(optarg, 'x')) {
                cfg->log_x = true;
            }
            if (strchr(optarg, 'y')) {
                cfg->log_y = true;
            }
            if (strchr(optarg, 'c')) {
                cfg->log_count = true;
            }
            break;
        case 'm':               /* mode */
            switch (optarg[0]) {
            case 'c':
                cfg->mode = MODE_COUNT;
                break;
            case 'd':
                cfg->mode = MODE_DOT;
                break;
            case 'l':
                cfg->mode = MODE_LINE;
                break;
            default:
                usage("Bad argument to -m: must be 'count', 'dot', or 'line'.");
            }
            break;
        case 'r':               /* linear regression */
            cfg->regression = true;
            break;
        case 's':               /* SVG */
            cfg->plot_type = PLOT_SVG;
            break;
        case 'S':               /* disable stream mode */
            cfg->stream_mode = false;
            break;
        case 'x':               /* col 0 is X value */
            cfg->x_column = true;
            break;
        case '?':
        default:
            usage(NULL);
        }
    }

    argc -= (optind - 1);
    argv += (optind - 1);
    if (argc > 1) {
        cfg->in_path = argv[1];
        if (0 != strcmp("-", cfg->in_path)) {
            cfg->in = fopen(cfg->in_path, "r");
            if (cfg->in == NULL) {
                err(1, "fopen");
            }
        }
    }

    if (cfg->plot_type == PLOT_SVG) {
        init_svg(cfg);
    } else {
        init_ascii(cfg);
    }
}