Skip to content

Commit

Permalink
Ensures that any directories specifed as part of outdir exist.
Browse files Browse the repository at this point in the history
This is accomplished through the new ``Ensure_Outdir_Exists`` function. Along the way, I introduced a helper function ``Is_Root_Proc()``, local to ``io.cpp`` so that we can reduce some of the ``ifdef`` statements.
  • Loading branch information
mabruzzo committed Sep 7, 2023
1 parent 257b216 commit b441372
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 13 deletions.
68 changes: 55 additions & 13 deletions src/io/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

#include <algorithm>
#include <ctime>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#ifdef HDF5
#include <hdf5.h>
#endif // HDF5
Expand All @@ -32,13 +34,22 @@
* output routine */
void rotate_point(Real x, Real y, Real z, Real delta, Real phi, Real theta, Real *xp, Real *yp, Real *zp);

void Create_Log_File(struct parameters P)
/* local function that designates whether we are using a root-process. It gives
* gives a sensible result regardless of whether we are using MPI */
static inline bool Is_Root_Proc()
{
#ifdef MPI_CHOLLA
if (procID != 0) {
return procID == root;
#else
return true;
#endif
}

void Create_Log_File(struct parameters P)
{
if (!Is_Root_Proc()) {
return;
}
#endif

std::string file_name(LOG_FILE_NAME);
chprintf("\nCreating Log File: %s \n\n", file_name.c_str());
Expand All @@ -64,11 +75,9 @@ void Create_Log_File(struct parameters P)

void Write_Message_To_Log_File(const char *message)
{
#ifdef MPI_CHOLLA
if (procID != 0) {
if (!!Is_Root_Proc()) {
return;
}
#endif

std::string file_name(LOG_FILE_NAME);
std::ofstream out_file;
Expand Down Expand Up @@ -2587,20 +2596,14 @@ void Grid3D::Read_Grid_HDF5(hid_t file_id, struct parameters P)
int chprintf(const char *__restrict sdata, ...) // NOLINT(cert-dcl50-cpp)
{
int code = 0;
#ifdef MPI_CHOLLA
/*limit printf to root process only*/
if (procID == root) {
#endif /*MPI_CHOLLA*/

if (!Is_Root_Proc()) {
va_list ap;
va_start(ap, sdata);
code = vfprintf(stdout, sdata, ap); // NOLINT(clang-analyzer-valist.Uninitialized)
va_end(ap);
fflush(stdout);

#ifdef MPI_CHOLLA
}
#endif /*MPI_CHOLLA*/

return code;
}
Expand Down Expand Up @@ -2661,3 +2664,42 @@ void write_debug(Real *Value, const char *fname, int nValues, int iProc)

fclose(fp);
}

void Ensure_Outdir_Exists(std::string outdir)
{
if (outdir == "") {
return;
} else if (Is_Root_Proc()) {
// if the last character of outdir is not a '/', then the substring of
// characters after the final '/' (or entire string if there isn't any '/')
// is treated as a file-prefix
//
// this is accomplished here:
std::filesystem::path without_file_prefix = std::filesystem::path(outdir).parent_path();

if (!without_file_prefix.empty()) {
// try to create all directories specified within outdir (does nothing if
// the directories already exist)
std::error_code err_code;
std::filesystem::create_directories(without_file_prefix, err_code);

// confirm that an error-code wasn't set & that the path actually refers
// to a directory (it's unclear from docs whether err-code is set in that
// case)
if (err_code || !std::filesystem::is_directory(without_file_prefix)) {
chprintf(
"something went wrong while trying to create the path to the "
"output-dir: %s\n",
outdir.c_str());
chexit(1);
}
}
}

// this barrier ensures we won't ever encounter a scenario when 1 process
// tries to write a file to a non-existent directory before the root process
// has a chance to create it
#ifdef MPI_CHOLLA
MPI_Barrier(world);
#endif
}
6 changes: 6 additions & 0 deletions src/io/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ void Write_Message_To_Log_File(const char* message);

void write_debug(Real* Value, const char* fname, int nValues, int iProc);

/* Checks whether the directories referred to within outdir exist. Creates them
* if they don't. It gracefully handles cases where outdir contains a prefix
* for the output files.
*/
void Ensure_Outdir_Exists(std::string outdir);

#ifdef HDF5
// From io/io.cpp

Expand Down
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ int main(int argc, char *argv[])
chprintf("Input directory: %s\n", P.indir);
}
chprintf("Output directory: %s\n", P.outdir);
Ensure_Outdir_Exists(P.outdir);

// Check the configuration
Check_Configuration(P);
Expand Down

0 comments on commit b441372

Please sign in to comment.