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