Skip to content

Commit 78c22c2

Browse files
Merge pull request #647 from E3SM-Project/jayeshkrishna/add_rm_after_conv
Adding a new command line argument in the ADIOS to NetCDF conversion tool to specify whether (and which) to delete input files (ADIOS BP) after converting to NetCDF Also including a simple README to document usage of the conversion tool
2 parents ec757e3 + e2ab41b commit 78c22c2

File tree

8 files changed

+203
-17
lines changed

8 files changed

+203
-17
lines changed

tools/adios2pio-nm/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ endif ()
8989
# DEFINE THE TARGET LIBRARY
9090
#==============================================================================
9191
SET(SRC ${SCORPIO_SOURCE_DIR}/tools/util/argparser.cxx adios2pio-nm.cxx)
92-
add_library(adios2pio-nm-lib adios2pio-nm-lib.cxx)
92+
add_library(adios2pio-nm-lib ${SCORPIO_SOURCE_DIR}/tools/util/spio_misc_tool_utils.cxx adios2pio-nm-lib.cxx)
9393
include_directories(
9494
"${PROJECT_SOURCE_DIR}" # to find foo/foo.h
9595
"${PROJECT_BINARY_DIR}") # to find foo/config.h
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
This file contains some basic information on how to use the ADIOS to NetCDF conversion tool for converting SCORPIO output files in the ADIOS BP file format to NetCDF. The conversion tool reads the ADIOS BP files in parallel (using SCORPIO and ADIOS) and converts the file using SCORPIO and PnetCDF or NetCDF libraries.
2+
3+
Running the application
4+
------------------------
5+
If SCORPIO is enabled with support for ADIOS (see the configure log of SCORPIO to see if ADIOS support is enabled), using PIO_IOTYPE_ADIOS (for uncompressed output) or PIO_IOTYPE_ADIOSC (for compressed output) will result in all SCORPIO output being written in the ADIOS BP file format. The output files in the ADIOS BP file format can be converted to NetCDF using the conversion tool in a separate batch job.
6+
7+
The conversion tool is an MPI program and can be run with different number (i.e., fewer) of MPI processes compared to the application that generated the output.
8+
9+
10+
---------------------------------------------------------------------------------------
11+
EXAMPLES:
12+
---------------------------------------------------------------------------------------
13+
14+
# Program options
15+
16+
jayesh@compute-386-03:~/scorpio_build2$ ./tools/adios2pio-nm/adios2pio-nm.exe
17+
Usage : ./tools/adios2pio-nm/adios2pio-nm.exe --[OPTIONAL ARG1 NAME]=[OPTIONAL ARG1 VALUE] --[OPTIONAL ARG2 NAME]=[OPTIONAL ARG2 VALUE] ...
18+
Optional Arguments :
19+
--bp-file: data produced by SCORPIO with ADIOS format
20+
--idir: Directory containing data output from SCORPIO (in ADIOS format)
21+
--nc-file: output file name after conversion
22+
--pio-format: output SCORPIO I/O type. Supported parameters: "pnetcdf", "netcdf", "netcdf4c", "netcdf4p", "nczarr"
23+
--rearr: SCORPIO rearranger. Supported parameters: "subset", "box", "any". Default "any".
24+
--rm-bp-file-after-conv: remove the ADIOS BP file after conversion
25+
--verbose: Turn on verbose info messages
26+
27+
28+
# Delete all ADIOS BP files after conversion
29+
jayesh@compute-386-03:~/scorpio_build2$ ./tools/adios2pio-nm/adios2pio-nm.exe --bp-file=/home/jayesh/scorpio_build2/tests/general/test_pio_file_simple_tests.testfile.bp --rm-bp-file-after-conv
30+
Converting BP file : "/home/jayesh/scorpio_build2/tests/general/test_pio_file_simple_tests.testfile.bp"
31+
Deleting BP file : /home/jayesh/scorpio_build2/tests/general/test_pio_file_simple_tests.testfile.bp
32+
33+
# Delete all ADIOS BP files with name "(.*)(test_pio_file_simple)(.*)" after conversion
34+
jayesh@compute-386-03:~/scorpio_build2$ ./tools/adios2pio-nm/adios2pio-nm.exe --bp-file=/home/jayesh/scorpio_build2/tests/general/test_pio_file_simple_tests.testfile.bp --rm-bp-file-after-conv="(.*)(test_pio_file_simple)(.*)"
35+
Converting BP file : "/home/jayesh/scorpio_build2/tests/general/test_pio_file_simple_tests.testfile.bp"
36+
Deleting BP file : /home/jayesh/scorpio_build2/tests/general/test_pio_file_simple_tests.testfile.bp
37+
38+
jayesh@compute-386-03:~/scorpio_build2$ ./tools/adios2pio-nm/adios2pio-nm.exe --bp-file=/home/jayesh/scorpio_build2/tests/general/test_pio_file_simple_tests.testfile.bp --rm-bp-file-after-conv="(.*)(DONT_DELETE_test_pio_file_simple)(.*)"
39+
Converting BP file : "/home/jayesh/scorpio_build2/tests/general/test_pio_file_simple_tests.testfile.bp"
40+
41+
# Convert ADIOS BP output files in directory, /scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run, and only delete the EAM ADIOS BP files after conversion
42+
jayesh@compute-386-03:~/scorpio_build2$ mpiexec -n 8 ./tools/adios2pio-nm/adios2pio-nm.exe --idir=/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run --rm-bp-file-after-conv="(.*)(.eam.)(.*)"
43+
Converting BP file : "/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.eam.rs.0001-01-02-00000.nc.bp"
44+
Deleting BP file : /scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.eam.rs.0001-01-02-00000.nc.bp
45+
Converting BP file : "/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.mosart.rh0.0001-01-02-00000.nc.bp"
46+
Converting BP file : "/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.elm.rh0.0001-01-02-00000.nc.bp"
47+
Converting BP file : "/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.cpl.r.0001-01-02-00000.nc.bp"
48+
Converting BP file : "/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.elm.r.0001-01-02-00000.nc.bp"
49+
Converting BP file : "/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.eam.h0.0001-01-01-00000.nc.bp"
50+
Deleting BP file : /scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.eam.h0.0001-01-01-00000.nc.bp
51+
Converting BP file : "/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.eam.r.0001-01-02-00000.nc.bp"
52+
Deleting BP file : /scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.eam.r.0001-01-02-00000.nc.bp
53+
Converting BP file : "/scratch/jayesh/e3sm/scratch/test_F2010_ne4_oQU240/run/test_F2010_ne4_oQU240.mosart.r.0001-01-02-00000.nc.bp"
54+

tools/adios2pio-nm/adios2pio-nm-lib.cxx

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "adios2pio-nm-lib.h"
2121
#include "adios2pio-nm-lib-c.h"
22+
#include "spio_misc_tool_utils.h"
2223

2324
using namespace std;
2425

@@ -2305,12 +2306,14 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
23052306
if(ierr != BP2PIO_NOERR)
23062307
{
23072308
fprintf(stderr, "ERROR: Checking BP file (%s) conversion status failed\n", infilepath.c_str());
2309+
GPTLstop("adios2pio:ConvertBPFile");
23082310
return BP2PIO_ERROR;
23092311
}
23102312

23112313
if(conv_done)
23122314
{
23132315
/* Avoid converting BP files that have already been converted */
2316+
GPTLstop("adios2pio:ConvertBPFile");
23142317
return BP2PIO_NOERR;
23152318
}
23162319

@@ -2325,6 +2328,7 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
23252328
ierr = OpenAdiosFile(adios, bpIO, bpReader, file0, err_msg);
23262329
if (ierr != PIO_NOERR)
23272330
{
2331+
GPTLstop("adios2pio:ConvertBPFile");
23282332
fprintf(stderr, "ERROR: Cannot open file: %s\n", file0.c_str());
23292333
fflush(stderr);
23302334
return ierr;
@@ -2343,6 +2347,7 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
23432347
else
23442348
{
23452349
fprintf(stderr, "ERROR: /__pio__/info/nproc is missing.\n");
2350+
GPTLstop("adios2pio:ConvertBPFile");
23462351
return BP2PIO_ERROR;
23472352
}
23482353

@@ -2396,12 +2401,14 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
23962401
if (mpierr != MPI_SUCCESS)
23972402
{
23982403
fprintf(stderr, "Bcasting /__pio__/info/block_nprocs failed, mpierr = %d\n", mpierr);
2404+
GPTLstop("adios2pio:ConvertBPFile");
23992405
return BP2PIO_ERROR;
24002406
}
24012407
}
24022408
else
24032409
{
24042410
fprintf(stderr, "ERROR: /__pio__/info/block_nprocs is missing.\n");
2411+
GPTLstop("adios2pio:ConvertBPFile");
24052412
return BP2PIO_ERROR;
24062413
}
24072414

@@ -2443,6 +2450,7 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
24432450
if (mpierr != MPI_SUCCESS)
24442451
{
24452452
fprintf(stderr, "Bcasting /__pio__/info/block_list failed, mpierr = %d\n", mpierr);
2453+
GPTLstop("adios2pio:ConvertBPFile");
24462454
return BP2PIO_ERROR;
24472455
}
24482456

@@ -2454,6 +2462,7 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
24542462
else
24552463
{
24562464
fprintf(stderr, "ERROR: /__pio__/info/block_list is missing.\n");
2465+
GPTLstop("adios2pio:ConvertBPFile");
24572466
return BP2PIO_ERROR;
24582467
}
24592468
bpReader[0].EndStep();
@@ -2464,7 +2473,10 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
24642473
ierr = CreateIOProcessGroup(w_comm, w_nproc, w_mpirank, block_procs, &comm, &mpirank, &nproc, &io_proc);
24652474
GPTLstop("adios2pio:ConvertBPFile:CreateIOProcessGroup");
24662475
if (ierr != BP2PIO_NOERR)
2476+
{
2477+
GPTLstop("adios2pio:ConvertBPFile");
24672478
return ierr;
2479+
}
24682480

24692481
/* Close files. Create a new ADIOS object, because the MPI processes are clustered into two groups */
24702482
bpReader[0].Close();
@@ -2479,6 +2491,7 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
24792491
/* Not I/O process */
24802492
MPI_Comm_free(&comm);
24812493
MPI_Barrier(w_comm);
2494+
GPTLstop("adios2pio:ConvertBPFile");
24822495
return BP2PIO_NOERR;
24832496
}
24842497

@@ -2660,6 +2673,7 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
26602673
{
26612674
cerr << "rank " << mpirank << ":ERROR in PIOc_finalize(), code = " << ret
26622675
<< " at " << __func__ << ":" << __LINE__ << endl;
2676+
GPTLstop("adios2pio:ConvertBPFile");
26632677
throw std::runtime_error("PIOc_finalize error.");
26642678
}
26652679
}
@@ -2683,7 +2697,9 @@ int ConvertBPFile(const string &infilepath, const string &outfilename,
26832697
GPTLstop("adios2pio:ConvertBPFile");
26842698

26852699
if (ierr != BP2PIO_NOERR)
2700+
{
26862701
return ierr;
2702+
}
26872703

26882704
return BP2PIO_NOERR;
26892705
}
@@ -2720,9 +2736,13 @@ enum PIO_IOTYPE GetIOType_nm(const string &t)
27202736
}
27212737

27222738
int ConvertBPToNC(const string &infilepath, const string &outfilename,
2723-
const string &piotype, const string &rearr, MPI_Comm comm_in)
2739+
const string &piotype, const string &rearr, MPI_Comm comm_in,
2740+
const std::string &rm_ifname_rgx)
27242741
{
27252742
int ierr = BP2PIO_NOERR;
2743+
int rank = -1;
2744+
2745+
MPI_Comm_rank(comm_in, &rank);
27262746

27272747
try
27282748
{
@@ -2732,6 +2752,23 @@ int ConvertBPToNC(const string &infilepath, const string &outfilename,
27322752
{
27332753
throw std::runtime_error("ConvertBPFile error.");
27342754
}
2755+
2756+
if ((rank == 0) && !rm_ifname_rgx.empty())
2757+
{
2758+
/* On root proc, delete the input BP file if its name matches the passed in regex */
2759+
#ifdef SPIO_NO_CXX_REGEX
2760+
/* Only "*" is supported for no regex case, and we assume its "*" if not empty() */
2761+
spio_tool_utils::rmdir_f(infilepath);
2762+
#else
2763+
std::smatch match;
2764+
std::regex rgx(rm_ifname_rgx);
2765+
if (std::regex_match(infilepath, match, rgx))
2766+
{
2767+
std::cout << "Deleting BP file : " << infilepath.c_str() << "\n";
2768+
spio_tool_utils::rmdir_f(infilepath);
2769+
}
2770+
#endif
2771+
}
27352772
}
27362773
catch (const std::exception &e)
27372774
{
@@ -2809,7 +2846,7 @@ static int FindBPDirs(const string &bppdir,
28092846
while ((pde = readdir(pdir)) != NULL)
28102847
{
28112848
assert(pde);
2812-
string dname(pde->d_name);
2849+
string dname(bppdir + "/" + pde->d_name);
28132850
/* Add dirs named "*.bp" to bpdirs */
28142851
string dname_prefix;
28152852
if ((pde->d_type == DT_DIR) &&
@@ -2838,7 +2875,7 @@ static int FindBPDirs(const string &bppdir,
28382875
* and converts them, one at a time, to NetCDF files
28392876
*/
28402877
int MConvertBPToNC(const string &bppdir, const string &piotype, const string &rearr,
2841-
MPI_Comm comm)
2878+
MPI_Comm comm, const std::string &rm_ifname_rgx)
28422879
{
28432880
int ierr = BP2PIO_NOERR;
28442881
vector<string> bpdirs;
@@ -2858,7 +2895,7 @@ int MConvertBPToNC(const string &bppdir, const string &piotype, const string &re
28582895
MPI_Barrier(comm);
28592896
ierr = ConvertBPToNC(bpdirs[i],
28602897
conv_fname_prefixes[i] + CONV_FNAME_SUFFIX,
2861-
piotype, rearr, comm);
2898+
piotype, rearr, comm, rm_ifname_rgx);
28622899
MPI_Barrier(comm);
28632900
if (ierr != BP2PIO_NOERR)
28642901
{
@@ -2884,8 +2921,10 @@ int C_API_ConvertBPToNC(const char *infilepath, const char *outfilename,
28842921
else
28852922
rearr = "subset";
28862923

2924+
/* FIXME: Currently we don't support regex deletes of BP input files */
2925+
std::string rm_ifname_rgx;
28872926
return ConvertBPToNC(string(infilepath), string(outfilename),
2888-
string(piotype), rearr, comm_in);
2927+
string(piotype), rearr, comm_in, rm_ifname_rgx);
28892928
}
28902929

28912930
#ifdef __cplusplus

tools/adios2pio-nm/adios2pio-nm-lib.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ using namespace std;
1717

1818
int ConvertBPToNC(const string &infilepath,
1919
const string &outfilename,
20-
const string &piotype, const string &rearr, MPI_Comm comm_in);
20+
const string &piotype, const string &rearr, MPI_Comm comm_in,
21+
const std::string &rm_ifname_rgx);
2122
int MConvertBPToNC(const string &bppdir, const string &piotype, const string &rearr,
22-
MPI_Comm comm);
23+
MPI_Comm comm, const std::string &rm_ifname_rgx);
2324
void SetDebugOutput(int val);
2425

2526
#endif /* #ifndef _ADIOS2PIO_NM_LIB_H_ */

tools/adios2pio-nm/adios2pio-nm.cxx

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99

1010
static void init_user_options(spio_tool_utils::ArgParser &ap)
1111
{
12-
ap.add_opt("bp-file", "data produced by PIO with ADIOS format")
13-
.add_opt("idir", "Directory containing data output from PIO (in ADIOS format)")
12+
ap.add_opt("bp-file", "data produced by SCORPIO with ADIOS format")
13+
.add_opt("rm-bp-file-after-conv", "remove the ADIOS BP file after conversion")
14+
.add_opt("idir", "Directory containing data output from SCORPIO (in ADIOS format)")
1415
.add_opt("nc-file", "output file name after conversion")
15-
.add_opt("pio-format", "output PIO_IO_TYPE. Supported parameters: \"pnetcdf\", \"netcdf\", \"netcdf4c\", \"netcdf4p\", \"nczarr\"")
16-
.add_opt("rearr", "PIO rearranger. Supported parameters: \"subset\", \"box\", \"any\". Default \"any\".")
16+
.add_opt("pio-format", "output SCORPIO I/O type. Supported parameters: \"pnetcdf\", \"netcdf\", \"netcdf4c\", \"netcdf4p\", \"nczarr\"")
17+
.add_opt("rearr", "SCORPIO rearranger. Supported parameters: \"subset\", \"box\", \"any\". Default \"any\".")
1718
.add_opt("verbose", "Turn on verbose info messages");
1819
}
1920

@@ -55,9 +56,10 @@ static int get_user_options(
5556
int argc, char *argv[],
5657
std::string &idir,
5758
std::string &ifile, std::string &ofile,
59+
std::string &rm_ifname_rgx,
5860
std::string &otype,
5961
std::string &rearr,
60-
int &debug_lvl)
62+
int &debug_lvl, int rank)
6163
{
6264
const std::string DEFAULT_PIO_FORMAT("pnetcdf");
6365
const std::string DEFAULT_REARRANGER("any");
@@ -96,6 +98,23 @@ static int get_user_options(
9698
idir = ap.get_arg<std::string>("idir");
9799
}
98100

101+
if (ap.has_arg("rm-bp-file-after-conv"))
102+
{
103+
try{
104+
/* Remove all input files matching the provided regex */
105+
rm_ifname_rgx = ap.get_arg<std::string>("rm-bp-file-after-conv");
106+
#ifdef SPIO_NO_CXX_REGEX
107+
if(rank == 0){
108+
std::cout << "WARNING: No C++ regex support. Ignoring specified regex for deleting files and deleting all input/BP files after conversion...\n";
109+
}
110+
rm_ifname_rgx = ".*";
111+
#endif
112+
} catch(...){
113+
/* Remove all input files */
114+
rm_ifname_rgx = ".*";
115+
}
116+
}
117+
99118
if (ap.has_arg("pio-format"))
100119
{
101120
otype = ap.get_arg<std::string>("pio-format");
@@ -143,10 +162,11 @@ int main(int argc, char *argv[])
143162

144163
/* Parse the user options */
145164
string idir, infilepath, outfilename, piotype, rearr;
165+
string rm_ifname_rgx;
146166
int debug_lvl = 0;
147167
ret = get_user_options(ap, argc, argv,
148168
idir, infilepath, outfilename,
149-
piotype, rearr, debug_lvl);
169+
rm_ifname_rgx, piotype, rearr, debug_lvl, rank);
150170

151171
if (ret != 0)
152172
{
@@ -165,11 +185,11 @@ int main(int argc, char *argv[])
165185
MPI_Barrier(comm_in);
166186
if (idir.size() == 0)
167187
{
168-
ret = ConvertBPToNC(infilepath, outfilename, piotype, rearr, comm_in);
188+
ret = ConvertBPToNC(infilepath, outfilename, piotype, rearr, comm_in, rm_ifname_rgx);
169189
}
170190
else
171191
{
172-
ret = MConvertBPToNC(idir, piotype, rearr, comm_in);
192+
ret = MConvertBPToNC(idir, piotype, rearr, comm_in, rm_ifname_rgx);
173193
}
174194
MPI_Barrier(comm_in);
175195

tools/util/argparser.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ template<>
8080
inline std::string ArgParser::get_arg<std::string>(const std::string &opt) const
8181
{
8282
assert(arg_map_.count(opt) == 1);
83-
return arg_map_.at(opt);
83+
std::string opt_val = arg_map_.at(opt);
84+
if(opt_val == NOVAL_OPT_STR){
85+
throw std::runtime_error("Requested value for argument with no value");
86+
}
87+
return opt_val;
8488
}
8589

8690
/* Get an int argument already parsed by the parser */

0 commit comments

Comments
 (0)