IOR
parse_options.c
Go to the documentation of this file.
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4 /******************************************************************************\
5 * *
6 * Copyright (c) 2003, The Regents of the University of California *
7 * See the file COPYRIGHT for a complete copyright notice and license. *
8 * *
9 ********************************************************************************
10 *
11 * Parse commandline functions.
12 *
13 \******************************************************************************/
14 
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include <string.h>
23 
24 #if defined(HAVE_STRINGS_H)
25 #include <strings.h>
26 #endif
27 
28 #include "utilities.h"
29 #include "ior.h"
30 #include "aiori.h"
31 #include "parse_options.h"
32 #include "option.h"
33 #include "aiori.h"
34 
36 
38 
39 
42 
43 
44 /*
45  * Check and correct all settings of each test in queue for correctness.
46  */
47 static void CheckRunSettings(IOR_test_t *tests)
48 {
49  IOR_test_t *ptr;
50  IOR_param_t *params;
51 
52  for (ptr = tests; ptr != NULL; ptr = ptr->next) {
53  params = &ptr->params;
54 
55  /* If no write/read/check action requested, set both write and read */
56  if (params->writeFile == FALSE
57  && params->readFile == FALSE
58  && params->checkWrite == FALSE
59  && params->checkRead == FALSE) {
60  params->readFile = TRUE;
61  params->writeFile = TRUE;
62  }
63 
64  if(params->dualMount && !params->filePerProc) {
65  ERR("Dual Mount can only be used with File Per Process");
66  }
67  }
68 }
69 
70 /*
71  * Set flags from commandline string/value pairs.
72  */
73 void DecodeDirective(char *line, IOR_param_t *params, options_all_t * module_options)
74 {
75  char option[MAX_STR];
76  char value[MAX_STR];
77  int rc;
78  int initialized;
79 
80  rc = sscanf(line, " %[^=# \t\r\n] = %[^# \t\r\n] ", option, value);
81  if (rc != 2 && rank == 0) {
82  fprintf(out_logfile, "Syntax error in configuration options: %s\n",
83  line);
84  MPI_CHECK(MPI_Initialized(&initialized), "MPI_Initialized() error");
85  if (initialized)
86  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
87  else
88  exit(EXIT_FAILURE);
89  }
90  if (strcasecmp(option, "api") == 0) {
91  params->api = strdup(value);
92 
93  params->backend = aiori_select(params->api);
94  if (params->backend == NULL){
95  fprintf(out_logfile, "Could not load backend API %s\n", params->api);
96  exit(EXIT_FAILURE);
97  }
98  } else if (strcasecmp(option, "summaryFile") == 0) {
99  if (rank == 0){
100  out_resultfile = fopen(value, "w");
101  if (out_resultfile == NULL){
102  FAIL("Cannot open output file for writes!");
103  }
104  printf("Writing output to %s\n", value);
105  }
106  } else if (strcasecmp(option, "saveRankPerformanceDetailsCSV") == 0){
107  if (rank == 0){
108  // check that the file is writeable, truncate it and add header
109  FILE* fd = fopen(value, "w");
110  if (fd == NULL){
111  FAIL("Cannot open saveRankPerformanceDetailsCSV file for write!");
112  }
113  char buff[] = "access,rank,runtime-with-openclose,runtime,throughput-withopenclose,throughput\n";
114  int ret = fwrite(buff, strlen(buff), 1, fd);
115  if(ret != 1){
116  FAIL("Cannot write header to saveRankPerformanceDetailsCSV file");
117  }
118  fclose(fd);
119  }
120  params->saveRankDetailsCSV = strdup(value);
121  } else if (strcasecmp(option, "summaryFormat") == 0) {
122  if(strcasecmp(value, "default") == 0){
124  }else if(strcasecmp(value, "JSON") == 0){
126  }else if(strcasecmp(value, "CSV") == 0){
128  }else{
129  FAIL("Unknown summaryFormat");
130  }
131  } else if (strcasecmp(option, "refnum") == 0) {
132  params->referenceNumber = atoi(value);
133  } else if (strcasecmp(option, "debug") == 0) {
134  params->debug = strdup(value);
135  } else if (strcasecmp(option, "platform") == 0) {
136  params->platform = strdup(value);
137  } else if (strcasecmp(option, "testfile") == 0) {
138  params->testFileName = strdup(value);
139  } else if (strcasecmp(option, "dualmount") == 0){
140  params->dualMount = atoi(value);
141  } else if (strcasecmp(option, "allocateBufferOnGPU") == 0) {
142  params->gpuMemoryFlags = atoi(value);
143  } else if (strcasecmp(option, "GPUid") == 0) {
144  params->gpuID = atoi(value);
145  } else if (strcasecmp(option, "GPUDirect") == 0) {
146  params->gpuDirect = atoi(value);
147  } else if (strcasecmp(option, "deadlineforstonewalling") == 0) {
148  params->deadlineForStonewalling = atoi(value);
149  } else if (strcasecmp(option, "stoneWallingWearOut") == 0) {
150  params->stoneWallingWearOut = atoi(value);
151  } else if (strcasecmp(option, "stoneWallingWearOutIterations") == 0) {
152  params->stoneWallingWearOutIterations = atoll(value);
153  } else if (strcasecmp(option, "stoneWallingStatusFile") == 0) {
154  params->stoneWallingStatusFile = strdup(value);
155  } else if (strcasecmp(option, "maxtimeduration") == 0) {
156  params->maxTimeDuration = atoi(value);
157  } else if (strcasecmp(option, "mintimeduration") == 0) {
158  params->minTimeDuration = atoi(value);
159  } else if (strcasecmp(option, "outlierthreshold") == 0) {
160  params->outlierThreshold = atoi(value);
161  } else if (strcasecmp(option, "numnodes") == 0) {
162  params->numNodes = atoi(value);
163  } else if (strcasecmp(option, "numtasks") == 0) {
164  params->numTasks = atoi(value);
165  } else if (strcasecmp(option, "numtasksonnode0") == 0) {
166  params->numTasksOnNode0 = atoi(value);
167  } else if (strcasecmp(option, "repetitions") == 0) {
168  params->repetitions = atoi(value);
169  } else if (strcasecmp(option, "intertestdelay") == 0) {
170  params->interTestDelay = atoi(value);
171  } else if (strcasecmp(option, "interiodelay") == 0) {
172  params->interIODelay = atoi(value);
173  } else if (strcasecmp(option, "readfile") == 0) {
174  params->readFile = atoi(value);
175  } else if (strcasecmp(option, "writefile") == 0) {
176  params->writeFile = atoi(value);
177  } else if (strcasecmp(option, "fileperproc") == 0) {
178  params->filePerProc = atoi(value);
179  } else if (strcasecmp(option, "taskpernodeoffset") == 0) {
180  params->taskPerNodeOffset = atoi(value);
181  } else if (strcasecmp(option, "reordertasksconstant") == 0) {
182  params->reorderTasks = atoi(value);
183  } else if (strcasecmp(option, "reordertasksrandom") == 0) {
184  params->reorderTasksRandom = atoi(value);
185  } else if (strcasecmp(option, "reordertasksrandomSeed") == 0) {
186  params->reorderTasksRandomSeed = atoi(value);
187  } else if (strcasecmp(option, "reordertasks") == 0) {
188  /* Backwards compatibility for the "reorderTasks" option.
189  MUST follow the other longer reordertasks checks. */
190  params->reorderTasks = atoi(value);
191  } else if (strcasecmp(option, "checkwrite") == 0) {
192  params->checkWrite = atoi(value);
193  } else if (strcasecmp(option, "checkread") == 0) {
194  params->checkRead = atoi(value);
195  } else if (strcasecmp(option, "keepfile") == 0) {
196  params->keepFile = atoi(value);
197  } else if (strcasecmp(option, "keepfilewitherror") == 0) {
198  params->keepFileWithError = atoi(value);
199  } else if (strcasecmp(option, "multiFile") == 0) {
200  params->multiFile = atoi(value);
201  } else if (strcasecmp(option, "warningAsErrors") == 0) {
202  params->warningAsErrors = atoi(value);
203  } else if (strcasecmp(option, "segmentcount") == 0) {
204  params->segmentCount = string_to_bytes(value);
205  } else if (strcasecmp(option, "blocksize") == 0) {
206  params->blockSize = string_to_bytes(value);
207  } else if (strcasecmp(option, "transfersize") == 0) {
208  params->transferSize = string_to_bytes(value);
209  } else if (strcasecmp(option, "singlexferattempt") == 0) {
210  params->singleXferAttempt = atoi(value);
211  } else if (strcasecmp(option, "intraTestBarriers") == 0) {
212  params->intraTestBarriers = atoi(value);
213  } else if (strcasecmp(option, "verbose") == 0) {
214  params->verbose = atoi(value);
215  } else if (strcasecmp(option, "collective") == 0) {
216  params->collective = atoi(value);
217  } else if (strcasecmp(option, "settimestampsignature") == 0) {
218  params->setTimeStampSignature = atoi(value);
219  } else if (strcasecmp(option, "dataPacketType") == 0) {
220  params->dataPacketType = parsePacketType(value[0]);
221  } else if (strcasecmp(option, "uniqueDir") == 0) {
222  params->uniqueDir = atoi(value);
223  } else if (strcasecmp(option, "useexistingtestfile") == 0) {
224  params->useExistingTestFile = atoi(value);
225  } else if (strcasecmp(option, "fsyncperwrite") == 0) {
226  params->fsyncPerWrite = atoi(value);
227  } else if (strcasecmp(option, "fsync") == 0) {
228  params->fsync = atoi(value);
229  } else if (strcasecmp(option, "randomoffset") == 0) {
230  params->randomOffset = atoi(value);
231  } else if (strcasecmp(option, "memoryPerTask") == 0) {
232  params->memoryPerTask = string_to_bytes(value);
233  params->memoryPerNode = 0;
234  } else if (strcasecmp(option, "memoryPerNode") == 0) {
235  params->memoryPerNode = NodeMemoryStringToBytes(value);
236  params->memoryPerTask = 0;
237  } else if (strcasecmp(option, "summaryalways") == 0) {
238  params->summary_every_test = atoi(value);
239  } else {
240  // backward compatibility for now
241  if (strcasecmp(option, "useo_direct") == 0) {
242  strcpy(option, "--posix.odirect");
243  }
244  int parsing_error = option_parse_key_value(option, value, module_options);
245  if(parsing_error){
246  if (rank == 0)
247  fprintf(out_logfile, "Unrecognized parameter \"%s\"\n",
248  option);
249  MPI_CHECK(MPI_Initialized(&initialized), "MPI_Initialized() error");
250  if (initialized)
251  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
252  else
253  exit(EXIT_FAILURE);
254  }
255  }
256 }
257 
258 
259 /*
260  * Parse a single line, which may contain multiple comma-seperated directives
261  */
262 void ParseLine(char *line, IOR_param_t * test, options_all_t * module_options)
263 {
264  char *start, *end;
265 
266  char * newline = strdup(line);
267  start = newline;
268  do {
269  end = strchr(start, '#');
270  if (end != NULL){
271  *end = '\0';
272  end = NULL; // stop parsing after comment
273  }
274  end = strchr(start, ',');
275  if (end != NULL){
276  *end = '\0';
277  }
278  if(strlen(start) < 3){
279  fprintf(out_logfile, "Invalid option substring string: \"%s\" in \"%s\"\n", start, line);
280  exit(EXIT_FAILURE);
281  }
282  DecodeDirective(start, test, module_options);
283  start = end + 1;
284  } while (end != NULL);
285  free(newline);
286 }
287 
288 
289 static void decodeDirectiveWrapper(char *line){
290  ParseLine(line, parameters, global_options);
291 }
292 
293 /*
294  * Determines if the string "haystack" contains only the string "needle", and
295  * possibly whitespace before and after needle. Function is case insensitive.
296  */
297 int contains_only(char *haystack, char *needle)
298 {
299  char *ptr, *end;
300 
301  end = haystack + strlen(haystack);
302  /* skip over leading shitspace */
303  for (ptr = haystack; ptr < end; ptr++) {
304  if (!isspace(*ptr))
305  break;
306  }
307  /* check for "needle" */
308  if (strncasecmp(ptr, needle, strlen(needle)) != 0)
309  return 0;
310  /* make sure the rest of the line is only whitespace as well */
311  for (ptr += strlen(needle); ptr < end; ptr++) {
312  if (!isspace(*ptr))
313  return 0;
314  }
315 
316  return 1;
317 }
318 
319 /*
320  * Read the configuration script, allocating and filling in the structure of
321  * global parameters.
322  */
323 IOR_test_t *ReadConfigScript(char *scriptName)
324 {
325  int test_num = 0;
326  int runflag = 0;
327  char linebuf[MAX_STR];
328  char empty[MAX_STR];
329  char *ptr;
330  FILE *file;
331  IOR_test_t *head = NULL;
332  IOR_test_t *tail = NULL;
333 
334  option_help ** option_p = & global_options->modules[0].options;
335 
336  /* Initialize the first test */
337  head = CreateTest(& initialTestParams, test_num++);
338  tail = head;
339  *option_p = createGlobalOptions(& ((IOR_test_t*) head)->params); /* The current options */
340 
341  /* open the script */
342  file = fopen(scriptName, "r");
343  if (file == NULL)
344  ERR("fopen() failed");
345 
346  /* search for the "IOR START" line */
347  while (fgets(linebuf, MAX_STR, file) != NULL) {
348  if (contains_only(linebuf, "ior start")) {
349  break;
350  }
351  }
352 
353  /* Iterate over a block of IOR commands */
354  while (fgets(linebuf, MAX_STR, file) != NULL) {
355  /* skip over leading whitespace */
356  ptr = linebuf;
357  while (isspace(*ptr))
358  ptr++;
359 
360  /* skip empty lines */
361  if (sscanf(ptr, "%s", empty) == -1)
362  continue;
363 
364  /* skip lines containing only comments */
365  if (sscanf(ptr, " #%c", empty) == 1)
366  continue;
367 
368  if (contains_only(ptr, "ior stop")) {
369  break;
370  } else if (contains_only(ptr, "run")) {
371  if (runflag) {
372  /* previous line was a "run" as well
373  create duplicate test */
374  tail->next = CreateTest(&tail->params, test_num++);
375  AllocResults(tail);
376  ((IOR_test_t*) tail)->params.backend_options = airoi_update_module_options(((IOR_test_t*) tail)->params.backend, global_options);
377 
378  tail = tail->next;
379  *option_p = createGlobalOptions(& ((IOR_test_t*) tail->next)->params);
380  }
381  runflag = 1;
382  } else if (runflag) {
383  /* If this directive was preceded by a "run" line, then
384  create and initialize a new test structure */
385  runflag = 0;
386  tail->next = CreateTest(&tail->params, test_num++);
387  *option_p = createGlobalOptions(& ((IOR_test_t*) tail->next)->params);
388  AllocResults(tail);
389  ((IOR_test_t*) tail)->params.backend_options = airoi_update_module_options(((IOR_test_t*) tail)->params.backend, global_options);
390 
391  tail = tail->next;
392  ParseLine(ptr, &tail->params, global_options);
393  } else {
394  ParseLine(ptr, &tail->params, global_options);
395  }
396  }
397 
398  /* close the script */
399  if (fclose(file) != 0)
400  ERR("fclose() of script file failed");
401  AllocResults(tail); /* copy the actual module options into the test */
402  ((IOR_test_t*) tail)->params.backend_options = airoi_update_module_options(((IOR_test_t*) tail)->params.backend, global_options);
403 
404  return head;
405 }
406 
407 
409  char APIs[1024];
410  char APIs_legacy[1024];
411  aiori_supported_apis(APIs, APIs_legacy, IOR);
412  char * apiStr = safeMalloc(1024);
413  sprintf(apiStr, "API for I/O [%s]", APIs);
414 
415  option_help o [] = {
416  {'a', NULL, apiStr, OPTION_OPTIONAL_ARGUMENT, 's', & params->api},
417  {'A', NULL, "refNum -- user supplied reference number to include in the summary", OPTION_OPTIONAL_ARGUMENT, 'd', & params->referenceNumber},
418  {'b', NULL, "blockSize -- contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'l', & params->blockSize},
419  {'c', "collective", "Use collective I/O", OPTION_FLAG, 'd', & params->collective},
420  {'C', NULL, "reorderTasks -- changes task ordering for readback (useful to avoid client cache)", OPTION_FLAG, 'd', & params->reorderTasks},
421  {'d', NULL, "interTestDelay -- delay between reps in seconds", OPTION_OPTIONAL_ARGUMENT, 'd', & params->interTestDelay},
422  {'D', NULL, "deadlineForStonewalling -- seconds before stopping write or read phase", OPTION_OPTIONAL_ARGUMENT, 'd', & params->deadlineForStonewalling},
423  {.help=" -O stoneWallingWearOut=1 -- once the stonewalling timeout is over, all process finish to access the amount of data", .arg = OPTION_OPTIONAL_ARGUMENT},
424  {.help=" -O stoneWallingWearOutIterations=N -- stop after processing this number of iterations, needed for reading data back written with stoneWallingWearOut", .arg = OPTION_OPTIONAL_ARGUMENT},
425  {.help=" -O stoneWallingStatusFile=FILE -- this file keeps the number of iterations from stonewalling during write and allows to use them for read", .arg = OPTION_OPTIONAL_ARGUMENT},
426  {.help=" -O minTimeDuration=0 -- minimum Runtime for the run (will repeat from beginning of the file if time is not yet over)", .arg = OPTION_OPTIONAL_ARGUMENT},
427 #ifdef HAVE_CUDA
428  {.help=" -O allocateBufferOnGPU=X -- allocate I/O buffers on the GPU: X=1 uses managed memory - verifications are run on CPU; X=2 managed memory - verifications on GPU; X=3 device memory with verifications on GPU.", .arg = OPTION_OPTIONAL_ARGUMENT},
429  {.help=" -O GPUid=X -- select the GPU to use, use -1 for round-robin among local procs.", .arg = OPTION_OPTIONAL_ARGUMENT},
430 #ifdef HAVE_GPU_DIRECT
431  {0, "gpuDirect", "allocate I/O buffers on the GPU and use gpuDirect to store data; this option is incompatible with any option requiring CPU access to data.", OPTION_FLAG, 'd', & params->gpuDirect},
432 #endif
433 #endif
434  {'e', NULL, "fsync -- perform a fsync() operation at the end of each read/write phase", OPTION_FLAG, 'd', & params->fsync},
435  {'E', NULL, "useExistingTestFile -- do not remove test file before write access", OPTION_FLAG, 'd', & params->useExistingTestFile},
436  {'f', NULL, "scriptFile -- test script name", OPTION_OPTIONAL_ARGUMENT, 's', & params->testscripts},
437  {'F', NULL, "filePerProc -- file-per-process", OPTION_FLAG, 'd', & params->filePerProc},
438  {'g', NULL, "intraTestBarriers -- use barriers between open, write/read, and close", OPTION_FLAG, 'd', & params->intraTestBarriers},
439  /* This option toggles between Incompressible Seed and Time stamp sig based on -l,
440  * so we'll toss the value in both for now, and sort it out in initialization
441  * after all the arguments are in and we know which it keep.
442  */
443  {'G', NULL, "setTimeStampSignature -- set value for time stamp signature/random seed", OPTION_OPTIONAL_ARGUMENT, 'd', & params->setTimeStampSignature},
444  {'i', NULL, "repetitions -- number of repetitions of test", OPTION_OPTIONAL_ARGUMENT, 'd', & params->repetitions},
445  {'j', NULL, "outlierThreshold -- warn on outlier N seconds from mean", OPTION_OPTIONAL_ARGUMENT, 'd', & params->outlierThreshold},
446  {'k', NULL, "keepFile -- don't remove the test file(s) on program exit", OPTION_FLAG, 'd', & params->keepFile},
447  {'K', NULL, "keepFileWithError -- keep error-filled file(s) after data-checking", OPTION_FLAG, 'd', & params->keepFileWithError},
448  {'l', "dataPacketType", "datapacket type-- type of packet that will be created [offset|incompressible|timestamp|random|o|i|t|r]", OPTION_OPTIONAL_ARGUMENT, 's', & params->buffer_type},
449  {'m', NULL, "multiFile -- use number of reps (-i) for multiple file count", OPTION_FLAG, 'd', & params->multiFile},
450  {'M', NULL, "memoryPerNode -- hog memory on the node (e.g.: 2g, 75%)", OPTION_OPTIONAL_ARGUMENT, 's', & params->memoryPerNodeStr},
451  {'N', NULL, "numTasks -- number of tasks that are participating in the test (overrides MPI)", OPTION_OPTIONAL_ARGUMENT, 'd', & params->numTasks},
452  {'o', NULL, "testFile -- full name for test", OPTION_OPTIONAL_ARGUMENT, 's', & params->testFileName},
453  {'O', NULL, "string of IOR directives (e.g. -O checkRead=1,GPUid=2)", OPTION_OPTIONAL_ARGUMENT, 'p', & decodeDirectiveWrapper},
454  {'Q', NULL, "taskPerNodeOffset for read tests use with -C & -Z options (-C constant N, -Z at least N)", OPTION_OPTIONAL_ARGUMENT, 'd', & params->taskPerNodeOffset},
455  {'r', NULL, "readFile -- read existing file", OPTION_FLAG, 'd', & params->readFile},
456  {'R', NULL, "checkRead -- verify that the output of read matches the expected signature (used with -G)", OPTION_FLAG, 'd', & params->checkRead},
457  {'s', NULL, "segmentCount -- number of segments", OPTION_OPTIONAL_ARGUMENT, 'd', & params->segmentCount},
458  {'t', NULL, "transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'l', & params->transferSize},
459  {'T', NULL, "maxTimeDuration -- max time in minutes executing repeated test; it aborts only between iterations and not within a test!", OPTION_OPTIONAL_ARGUMENT, 'd', & params->maxTimeDuration},
460  {'u', NULL, "uniqueDir -- use unique directory name for each file-per-process", OPTION_FLAG, 'd', & params->uniqueDir},
461  {'v', NULL, "verbose -- output information (repeating flag increases level)", OPTION_FLAG, 'd', & params->verbose},
462  {'w', NULL, "writeFile -- write file", OPTION_FLAG, 'd', & params->writeFile},
463  {'W', NULL, "checkWrite -- check read after write", OPTION_FLAG, 'd', & params->checkWrite},
464  {'x', NULL, "singleXferAttempt -- do not retry transfer if incomplete", OPTION_FLAG, 'd', & params->singleXferAttempt},
465  {'X', NULL, "reorderTasksRandomSeed -- random seed for -Z option", OPTION_OPTIONAL_ARGUMENT, 'd', & params->reorderTasksRandomSeed},
466  {'y', NULL, "dualMount -- use dual mount points for a filesystem", OPTION_FLAG, 'd', & params->dualMount},
467  {'Y', NULL, "fsyncPerWrite -- perform sync operation after every write operation", OPTION_FLAG, 'd', & params->fsyncPerWrite},
468  {'z', NULL, "randomOffset -- access is to random, not sequential, offsets within a file", OPTION_FLAG, 'd', & params->randomOffset},
469  {0, "randomPrefill", "For random -z access only: Prefill the file with this blocksize, e.g., 2m", OPTION_OPTIONAL_ARGUMENT, 'l', & params->randomPrefillBlocksize},
470  {0, "random-offset-seed", "The seed for -z", OPTION_OPTIONAL_ARGUMENT, 'd', & params->randomSeed},
471  {'Z', NULL, "reorderTasksRandom -- changes task ordering to random ordering for readback", OPTION_FLAG, 'd', & params->reorderTasksRandom},
472  {0, "warningAsErrors", "Any warning should lead to an error.", OPTION_FLAG, 'd', & params->warningAsErrors},
473  {.help=" -O summaryFile=FILE -- store result data into this file", .arg = OPTION_OPTIONAL_ARGUMENT},
474  {.help=" -O summaryFormat=[default,JSON,CSV] -- use the format for outputting the summary", .arg = OPTION_OPTIONAL_ARGUMENT},
475  {.help=" -O saveRankPerformanceDetailsCSV=<FILE> -- store the performance of each rank into the named CSV file.", .arg = OPTION_OPTIONAL_ARGUMENT},
476  {0, "dryRun", "do not perform any I/Os just run evtl. inputs print dummy output", OPTION_FLAG, 'd', & params->dryRun},
477  LAST_OPTION,
478  };
479  option_help * options = malloc(sizeof(o));
480  memcpy(options, & o, sizeof(o));
481  return options;
482 }
483 
484 
485 /*
486  * Parse Commandline.
487  */
488 IOR_test_t *ParseCommandLine(int argc, char **argv, MPI_Comm com)
489 {
490  init_IOR_Param_t(& initialTestParams, com);
491 
492  IOR_test_t *tests = NULL;
493 
494  initialTestParams.platform = GetPlatformName();
495 
496  option_help * options = createGlobalOptions( & initialTestParams);
497  parameters = & initialTestParams;
498  global_options = airoi_create_all_module_options(options);
499  option_parse(argc, argv, global_options);
500  updateParsedOptions(& initialTestParams, global_options);
501 
502  if (initialTestParams.testscripts){
503  tests = ReadConfigScript(initialTestParams.testscripts);
504  }else{
505  tests = CreateTest(&initialTestParams, 0);
506  AllocResults(tests);
507  }
508 
509  CheckRunSettings(tests);
510 
511  return (tests);
512 }
option_module * modules
Definition: option.h:36
int reorderTasks
Definition: ior.h:103
int uniqueDir
Definition: ior.h:120
void init_IOR_Param_t(IOR_param_t *p, MPI_Comm com)
Definition: ior.c:254
IOR_test_t * ParseCommandLine(int argc, char **argv, MPI_Comm com)
int reorderTasksRandomSeed
Definition: ior.h:106
int warningAsErrors
Definition: ior.h:154
static void CheckRunSettings(IOR_test_t *tests)
Definition: parse_options.c:47
int multiFile
Definition: ior.h:96
#define LAST_OPTION
Definition: option.h:39
char * GetPlatformName()
Definition: ior.c:551
void * airoi_update_module_options(const ior_aiori_t *backend, options_all_t *opt)
Definition: aiori.c:96
CURLcode rc
Definition: aiori-S3-4c.c:111
int filePerProc
Definition: ior.h:102
FILE * out_logfile
Definition: utilities.c:74
int gpuID
Definition: ior.h:89
int option_parse(int argc, char **argv, options_all_t *opt_all)
Definition: option.c:414
int repetitions
Definition: ior.h:94
struct benchmark_options o
Definition: md-workbench.c:133
IOR_offset_t segmentCount
Definition: ior.h:112
int keepFile
Definition: ior.h:109
int contains_only(char *haystack, char *needle)
int checkRead
Definition: ior.h:108
enum OutputFormat_t outputFormat
Definition: utilities.c:76
int numTasksOnNode0
Definition: ior.h:92
IOR_offset_t transferSize
Definition: ior.h:114
size_t memoryPerNode
Definition: ior.h:137
IOR_param_t params
Definition: ior.h:182
ior_memory_flags gpuMemoryFlags
Definition: ior.h:87
static IOR_param_t initialTestParams
Definition: parse_options.c:35
#define FAIL(...)
Definition: aiori-debug.h:16
int summary_every_test
Definition: ior.h:119
int numNodes
Definition: ior.h:91
int setTimeStampSignature
Definition: ior.h:131
int fsyncPerWrite
Definition: ior.h:147
int interTestDelay
Definition: ior.h:97
#define MPI_CHECK(MPI_STATUS, MSG)
Definition: aiori-debug.h:97
int maxTimeDuration
Definition: ior.h:128
char * testFileName
Definition: ior.h:79
char * stoneWallingStatusFile
Definition: ior.h:126
option_help * createGlobalOptions(IOR_param_t *params)
int taskPerNodeOffset
Definition: ior.h:104
const ior_aiori_t * aiori_select(const char *api)
Definition: aiori.c:240
int fsync
Definition: ior.h:148
struct IOR_test_t * next
Definition: ior.h:184
ior_dataPacketType_e dataPacketType
Definition: ior.h:141
char * testscripts
Definition: ior.h:139
ior_dataPacketType_e parsePacketType(char t)
Definition: utilities.c:291
int outlierThreshold
Definition: ior.h:129
int intraTestBarriers
Definition: ior.h:153
int reorderTasksRandom
Definition: ior.h:105
static option_help options[]
Definition: aiori-CEPHFS.c:59
int checkWrite
Definition: ior.h:107
Definition: aiori.h:119
int verbose
Definition: ior.h:130
void updateParsedOptions(IOR_param_t *options, options_all_t *global_options)
Definition: utilities.c:308
int dryRun
Definition: ior.h:85
char * platform
Definition: ior.h:78
int gpuDirect
Definition: ior.h:88
int singleXferAttempt
Definition: ior.h:146
int interIODelay
Definition: ior.h:98
char * saveRankDetailsCSV
Definition: ior.h:118
FILE * out_resultfile
Definition: utilities.c:75
options_all_t * airoi_create_all_module_options(option_help *global_options)
Definition: aiori.c:110
int option_parse_key_value(char *key, char *val, options_all_t *opt_all)
Definition: option.c:402
void aiori_supported_apis(char *APIs, char *APIs_legacy, enum bench_type type)
Definition: aiori.c:130
int stoneWallingWearOut
Definition: ior.h:123
IOR_test_t * CreateTest(IOR_param_t *init_params, int test_num)
Definition: ior.c:477
void ParseLine(char *line, IOR_param_t *test, options_all_t *module_options)
int keepFileWithError
Definition: ior.h:110
int randomSeed
Definition: ior.h:133
#define FALSE
Definition: iordef.h:76
int useExistingTestFile
Definition: ior.h:121
static options_all_t * global_options
Definition: parse_options.c:41
int readFile
Definition: ior.h:100
int randomOffset
Definition: ior.h:135
char * buffer_type
Definition: ior.h:140
int numTasks
Definition: ior.h:90
size_t memoryPerTask
Definition: ior.h:136
int referenceNumber
Definition: ior.h:75
int writeFile
Definition: ior.h:101
int64_t string_to_bytes(char *size_str)
Definition: option.c:30
void DecodeDirective(char *line, IOR_param_t *params, options_all_t *module_options)
Definition: parse_options.c:73
uint64_t stoneWallingWearOutIterations
Definition: ior.h:125
#define MAX_STR
Definition: iordef.h:113
int collective
Definition: ior.h:82
static void decodeDirectiveWrapper(char *line)
option_help * options
Definition: option.h:30
IOR_offset_t randomPrefillBlocksize
Definition: ior.h:116
IOR_test_t * ReadConfigScript(char *scriptName)
const struct ior_aiori * backend
Definition: ior.h:73
int dualMount
Definition: ior.h:86
static IOR_param_t * parameters
Definition: parse_options.c:40
#define ERR(MSG)
Definition: aiori-debug.h:75
char * debug
Definition: ior.h:74
int deadlineForStonewalling
Definition: ior.h:122
char * api
Definition: ior.h:76
size_t NodeMemoryStringToBytes(char *size_str)
Definition: utilities.c:259
char * memoryPerNodeStr
Definition: ior.h:138
int rank
Definition: utilities.c:70
IOR_offset_t blockSize
Definition: ior.h:113
#define TRUE
Definition: iordef.h:80
int minTimeDuration
Definition: ior.h:124
void * safeMalloc(uint64_t size)
Definition: utilities.c:238
#define NULL
Definition: iordef.h:84
void AllocResults(IOR_test_t *test)
Definition: ior.c:456