@@ -178,6 +178,7 @@ typedef struct {
178
178
int global_dir_layout ;
179
179
#endif /* HAVE_LUSTRE_LUSTREAPI */
180
180
char * saveRankDetailsCSV ; /* save the details about the performance to a file */
181
+ char * savePerOpDataCSV ;
181
182
const char * prologue ;
182
183
const char * epilogue ;
183
184
@@ -197,6 +198,7 @@ static mdtest_options_t o;
197
198
198
199
/* This structure describes the processing status for stonewalling */
199
200
typedef struct {
201
+ OpTimer * ot ; /* Operation timer*/
200
202
double start_time ;
201
203
202
204
int stone_wall_timer_seconds ;
@@ -238,6 +240,7 @@ void VerboseMessage (int root_level, int any_level, int line, char * format, ...
238
240
fflush (out_logfile );
239
241
}
240
242
}
243
+ char const * mdtest_test_name (int i );
241
244
242
245
void parse_dirpath (char * dirpath_arg ) {
243
246
char * tmp , * token ;
@@ -443,11 +446,13 @@ void create_remove_items_helper(const int dirs, const int create, const char *pa
443
446
444
447
for (uint64_t i = progress -> items_start ; i < progress -> items_per_dir ; ++ i ) {
445
448
if (!dirs ) {
449
+ double start = GetTimeStamp ();
446
450
if (create ) {
447
451
create_file (path , itemNum + i );
448
452
} else {
449
453
remove_file (path , itemNum + i );
450
454
}
455
+ if (progress -> ot ) OpTimerValue (progress -> ot , start - progress -> start_time , GetTimeStamp () - start );
451
456
} else {
452
457
create_remove_dirs (path , create , itemNum + i );
453
458
}
@@ -644,14 +649,16 @@ void mdtest_stat(const int random, const int dirs, const long dir_iter, const ch
644
649
645
650
/* below temp used to be hiername */
646
651
VERBOSE (3 ,5 ,"mdtest_stat %4s: %s" , (dirs ? "dir" : "file" ), item );
652
+ double start = GetTimeStamp ();
647
653
if (-1 == o .backend -> stat (item , & buf , o .backend_options )) {
648
654
WARNF ("unable to stat %s %s" , dirs ? "directory" : "file" , item );
649
655
}
656
+ if (progress -> ot ) OpTimerValue (progress -> ot , start - progress -> start_time , GetTimeStamp () - start );
650
657
}
651
658
}
652
659
653
660
/* reads all of the items created as specified by the input parameters */
654
- void mdtest_read (int random , int dirs , const long dir_iter , char * path ) {
661
+ void mdtest_read (int random , int dirs , const long dir_iter , char * path , rank_progress_t * progress ) {
655
662
uint64_t parent_dir , item_num = 0 ;
656
663
char item [MAX_PATHLEN ], temp [MAX_PATHLEN ];
657
664
aiori_fd_t * aiori_fh ;
@@ -732,6 +739,7 @@ void mdtest_read(int random, int dirs, const long dir_iter, char *path) {
732
739
733
740
o .hints .filePerProc = ! o .shared_file ;
734
741
742
+ double start = GetTimeStamp ();
735
743
/* open file for reading */
736
744
aiori_fh = o .backend -> open (item , O_RDONLY , o .backend_options );
737
745
if (NULL == aiori_fh ) {
@@ -746,7 +754,7 @@ void mdtest_read(int random, int dirs, const long dir_iter, char *path) {
746
754
WARNF ("unable to read file %s" , item );
747
755
o .verification_error += 1 ;
748
756
continue ;
749
- }
757
+ }
750
758
int pretend_rank = (2 * o .nstride + rank ) % o .size ;
751
759
if (o .verify_read ){
752
760
if (o .shared_file ) {
@@ -759,6 +767,7 @@ void mdtest_read(int random, int dirs, const long dir_iter, char *path) {
759
767
}
760
768
}
761
769
}
770
+ if (progress -> ot ) OpTimerValue (progress -> ot , start - progress -> start_time , GetTimeStamp () - start );
762
771
763
772
/* close file */
764
773
o .backend -> close (aiori_fh , o .backend_options );
@@ -1200,7 +1209,7 @@ void file_test_create(const int iteration, const int ntasks, const char *path, r
1200
1209
}
1201
1210
MPI_Barrier (testComm );
1202
1211
}
1203
-
1212
+
1204
1213
/* create files */
1205
1214
create_remove_items (0 , 0 , 1 , 0 , temp_path , 0 , progress );
1206
1215
if (o .stone_wall_timer_seconds ){
@@ -1244,6 +1253,11 @@ void file_test(const int iteration, const int ntasks, const char *path, rank_pro
1244
1253
/* create phase */
1245
1254
if (o .create_only ) {
1246
1255
phase_prepare ();
1256
+ if (o .savePerOpDataCSV != NULL ) {
1257
+ char path [MAX_PATHLEN ];
1258
+ sprintf (path , "%s-%s-%05d.csv" , o .savePerOpDataCSV , mdtest_test_name (MDTEST_FILE_CREATE_NUM ), rank );
1259
+ progress -> ot = OpTimerInit (path , o .write_bytes > 0 ? o .write_bytes : 1 );
1260
+ }
1247
1261
t_start = GetTimeStamp ();
1248
1262
#ifdef HAVE_GPFSCREATESHARING_T
1249
1263
/* Enable createSharingHint */
@@ -1270,6 +1284,7 @@ void file_test(const int iteration, const int ntasks, const char *path, rank_pro
1270
1284
}
1271
1285
#endif /* HAVE_GPFSCREATESHARING_T */
1272
1286
t_end = GetTimeStamp ();
1287
+ OpTimerFree (& progress -> ot );
1273
1288
updateResult (res , MDTEST_FILE_CREATE_NUM , o .items , t_start , t_end , t_end_before_barrier );
1274
1289
}else {
1275
1290
if (o .stoneWallingStatusFile ){
@@ -1298,7 +1313,13 @@ void file_test(const int iteration, const int ntasks, const char *path, rank_pro
1298
1313
/* stat phase */
1299
1314
if (o .stat_only ) {
1300
1315
phase_prepare ();
1316
+ if (o .savePerOpDataCSV != NULL ) {
1317
+ char path [MAX_PATHLEN ];
1318
+ sprintf (path , "%s-%s-%05d.csv" , o .savePerOpDataCSV , mdtest_test_name (MDTEST_FILE_STAT_NUM ), rank );
1319
+ progress -> ot = OpTimerInit (path , 1 );
1320
+ }
1301
1321
t_start = GetTimeStamp ();
1322
+ progress -> start_time = t_start ;
1302
1323
for (int dir_iter = 0 ; dir_iter < o .directory_loops ; dir_iter ++ ){
1303
1324
prep_testdir (iteration , dir_iter );
1304
1325
if (o .unique_dir_per_task ) {
@@ -1318,13 +1339,20 @@ void file_test(const int iteration, const int ntasks, const char *path, rank_pro
1318
1339
t_end_before_barrier = GetTimeStamp ();
1319
1340
phase_end ();
1320
1341
t_end = GetTimeStamp ();
1342
+ OpTimerFree (& progress -> ot );
1321
1343
updateResult (res , MDTEST_FILE_STAT_NUM , o .items , t_start , t_end , t_end_before_barrier );
1322
1344
}
1323
1345
1324
1346
/* read phase */
1325
1347
if (o .read_only ) {
1326
1348
phase_prepare ();
1349
+ if (o .savePerOpDataCSV != NULL ) {
1350
+ char path [MAX_PATHLEN ];
1351
+ sprintf (path , "%s-%s-%05d.csv" , o .savePerOpDataCSV , mdtest_test_name (MDTEST_FILE_READ_NUM ), rank );
1352
+ progress -> ot = OpTimerInit (path , o .read_bytes > 0 ? o .read_bytes : 1 );
1353
+ }
1327
1354
t_start = GetTimeStamp ();
1355
+ progress -> start_time = t_start ;
1328
1356
for (int dir_iter = 0 ; dir_iter < o .directory_loops ; dir_iter ++ ){
1329
1357
prep_testdir (iteration , dir_iter );
1330
1358
if (o .unique_dir_per_task ) {
@@ -1340,23 +1368,28 @@ void file_test(const int iteration, const int ntasks, const char *path, rank_pro
1340
1368
1341
1369
/* read files */
1342
1370
if (o .random_seed > 0 ) {
1343
- mdtest_read (1 ,0 , dir_iter , temp_path );
1371
+ mdtest_read (1 , 0 , dir_iter , temp_path , progress );
1344
1372
} else {
1345
- mdtest_read (0 ,0 , dir_iter , temp_path );
1373
+ mdtest_read (0 , 0 , dir_iter , temp_path , progress );
1346
1374
}
1347
1375
}
1348
1376
t_end_before_barrier = GetTimeStamp ();
1349
1377
phase_end ();
1350
1378
t_end = GetTimeStamp ();
1379
+ OpTimerFree (& progress -> ot );
1351
1380
updateResult (res , MDTEST_FILE_READ_NUM , o .items , t_start , t_end , t_end_before_barrier );
1352
1381
}
1353
1382
1354
1383
/* remove phase */
1355
1384
if (o .remove_only ) {
1356
1385
phase_prepare ();
1386
+ if (o .savePerOpDataCSV != NULL ) {
1387
+ sprintf (temp_path , "%s-%s-%05d.csv" , o .savePerOpDataCSV , mdtest_test_name (MDTEST_FILE_REMOVE_NUM ), rank );
1388
+ progress -> ot = OpTimerInit (temp_path , o .write_bytes > 0 ? o .write_bytes : 1 );
1389
+ }
1357
1390
t_start = GetTimeStamp ();
1391
+ progress -> start_time = t_start ;
1358
1392
progress -> items_start = 0 ;
1359
-
1360
1393
for (int dir_iter = 0 ; dir_iter < o .directory_loops ; dir_iter ++ ){
1361
1394
prep_testdir (iteration , dir_iter );
1362
1395
if (o .unique_dir_per_task ) {
@@ -1369,19 +1402,19 @@ void file_test(const int iteration, const int ntasks, const char *path, rank_pro
1369
1402
}
1370
1403
1371
1404
VERBOSE (3 ,5 ,"file_test: rm directories path is '%s'" , temp_path );
1372
-
1373
1405
if (o .collective_creates ) {
1374
1406
if (rank == 0 ) {
1375
1407
collective_create_remove (0 , 0 , ntasks , temp_path , progress );
1376
1408
}
1377
1409
} else {
1378
- VERBOSE (3 ,5 ,"gonna create %s" , temp_path );
1410
+ VERBOSE (3 ,5 ,"gonna remove %s" , temp_path );
1379
1411
create_remove_items (0 , 0 , 0 , 0 , temp_path , 0 , progress );
1380
1412
}
1381
1413
}
1382
1414
t_end_before_barrier = GetTimeStamp ();
1383
1415
phase_end ();
1384
1416
t_end = GetTimeStamp ();
1417
+ OpTimerFree (& progress -> ot );
1385
1418
updateResult (res , MDTEST_FILE_REMOVE_NUM , o .items , t_start , t_end , t_end_before_barrier );
1386
1419
}
1387
1420
@@ -2322,8 +2355,8 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
2322
2355
#endif
2323
2356
{0 , "warningAsErrors" , "Any warning should lead to an error." , OPTION_FLAG , 'd' , & aiori_warning_as_errors },
2324
2357
{0 , "saveRankPerformanceDetails" , "Save the individual rank information into this CSV file." , OPTION_OPTIONAL_ARGUMENT , 's' , & o .saveRankDetailsCSV },
2358
+ {0 , "savePerOpDataCSV" , "Store the performance of each rank into an individual file prefixed with this option." , OPTION_OPTIONAL_ARGUMENT , 's' , & o .savePerOpDataCSV },
2325
2359
{0 , "showRankStatistics" , "Include statistics per rank" , OPTION_FLAG , 'd' , & o .show_perrank_statistics },
2326
-
2327
2360
LAST_OPTION
2328
2361
};
2329
2362
options_all_t * global_options = airoi_create_all_module_options (options );
@@ -2364,7 +2397,6 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
2364
2397
for (i = 1 ; i < argc ; i ++ ) {
2365
2398
snprintf (& cmd_buffer [strlen (cmd_buffer )], 4096 - strlen (cmd_buffer ), " '%s'" , argv [i ]);
2366
2399
}
2367
-
2368
2400
VERBOSE (0 ,-1 ,"-- started at %s --\n" , PrintTimestamp ());
2369
2401
VERBOSE (0 ,-1 ,"mdtest-%s was launched with %d total task(s) on %d node(s)" , RELEASE_VERS , o .size , numNodes );
2370
2402
VERBOSE (0 ,-1 ,"Command line used: %s" , cmd_buffer );
0 commit comments