/** @file options.cpp implementation of triplet finder options */ #include #include #include #include #include #include "options.h" /** prints usage and exits */ void print_usage_and_exit(int exit_code) { printf("Usage: triplets [OPTIONS]\n"); printf("Reconstructs STT tracks using Triplet Finder algorithm\n"); printf("expects input files ./data/stt-hits.csv and ./data/stt-tubes.csv, " "produces ./tracks-found.csv as output\n"); printf("\nOptions:\n"); const char *opt_fmt = " %-12s %s\n"; const char *opt_fmt2 = " %-14s %s\n"; printf(opt_fmt, "-b ", "single bunch time in ns, default 1000"); printf(opt_fmt, "-v", "be verbose, can be used multiple times"); printf(opt_fmt, "-n ", "number of hits to read from file, " "default all"); printf(opt_fmt, "-D ", "CUDA device to use, default 0"); printf(opt_fmt, "-G", "whether to group on device, default no"); printf(opt_fmt, "-B ", "bunch parallelization strategy, possible values:"); printf(opt_fmt2, "", "dyn: use dynamic parallelism to process " "multiple bunches; this is default"); printf(opt_fmt2, "", "tbunch: launch one kernel with 1 thread block" " per bunch"); printf(opt_fmt2, "", "hstream: launch from host with 1 stream per bunch"); printf(opt_fmt2, "", "hthread: launch from host with 1 stream per thread, " "multiple bunches per thread"); printf(opt_fmt, "-T ", "tube testing strategy, possible values:"); printf(opt_fmt2, "", "shared: check against all tubes with non-zero hits " "(default)"); printf(opt_fmt2, "", "raster: first check against sector-rows, then against tubes"); printf(opt_fmt, "-S ", "skewlet testing strategy, possible values:"); printf(opt_fmt2, "", "all: check against all skewlets (default)"); printf(opt_fmt2, "", "bins: use skewlet binning"); exit(exit_code); } // print_usage_and_exit int parse_int(int a = 0, int b = INT_MAX) { int r; if(sscanf(optarg, "%d", &r) < 1 || r < a || r > b) { fprintf(stderr, "%s is not an integer value between %d and %d\n", optarg, a, b); print_usage_and_exit(-1); } return r; } // parse_int double parse_double(double a = 0, double b = 1) { double r; if(sscanf(optarg, "%lf", &r) < 1 || r < a || r > b) { fprintf(stderr, "%s is not a double value between %lf and %lf\n", optarg, a, b); print_usage_and_exit(-1); } return r; } // parse_double /** parses the strings from one of the options @param strs possible strings, */ int parse_strings(const char **strs) { for(const char **pstr = strs; *pstr; pstr++) if(!strcmp(optarg, *pstr)) return (int)(pstr - strs); fprintf(stderr, "%s is not allowed as argument value\n", optarg); print_usage_and_exit(-1); return -1; } // parse_strings const char *bunch_strategy_strings[] = { "dyn", "tblock", "hstream", "hthread", 0 }; const char *tube_test_strategy_strings[] = { "raster", "shared", 0 }; const char *skewlet_test_strategy_strings[] = { "all", "bins", 0 }; void TripletFinderOptions::parse_cmdline(int argc, char **argv) { optind = 1; static const char *opt_str = ":hGn:b:B:T:D:S:"; int c, ndevices; while((c = getopt(argc, argv, opt_str)) != -1) { switch(c) { case 'h': print_usage_and_exit(0); break; case 'G': set_group_on_device(true); break; case 'n': nhits = parse_int(1); break; case 'b': tbunch = (float)parse_double(0, 1e6); break; case 'D': cucheck(cudaGetDeviceCount(&ndevices)); idevice = parse_int(0, ndevices - 1); cucheck(cudaSetDevice(idevice)); break; case 'B': set_bunch_strategy((BunchStrategy)parse_strings(bunch_strategy_strings)); #if !WITH_DYN_PAR if(bunch_strategy() == BunchDynamic) { fprintf(stderr, "dynamic parallelism is not supported in " "this version\n"); print_usage_and_exit(-1); } #endif break; case 'T': set_tube_strategy((TubeTestStrategy) parse_strings(tube_test_strategy_strings)); break; case 'S': set_skewlet_strategy((SkewletTestStrategy) parse_strings(skewlet_test_strategy_strings)); break; case ':': fprintf(stderr, "-%c option requires an argument\n", optopt); print_usage_and_exit(-1); break; case '?': fprintf(stderr, "-%c: unknown option\n", optopt); print_usage_and_exit(-1); break; default: // this should really not happen fprintf(stderr, "oops, this should really not happen\n"); print_usage_and_exit(-1); } // switch(c) } } // parse_cmdline