Skip to content

Commit d21bbab

Browse files
committed
fix: make non-root workers print to devnull
The MPI-aware versions of the `writeheaders_data` and `writeheaders_ranks` methods call `open(..., "w")` on every rank, not just root, even though only root actually uses to the handles to print data. All four ranks independently opening the same file path like this (without any synchronisation) might lead to race conditions. Moreover, only root's handles get closed at the end. Fix this by assigning `devnull` to the handles for non-root workers, so that the writing functions called later on still work (this is why `nothing` is not acceptable) but they do not need to actually open the true output files.
1 parent 138eb2d commit d21bbab

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

ext/MPSTimeEvolutionMPIExt/mpi_utils.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,21 @@ function MPSTimeEvolution.simulationinfo(
252252
end
253253

254254
function MPSTimeEvolution.writeheaders_data(io_file, comm::MPI.Comm, cb; root, kwargs...)
255+
# This function needs to be called by all workers, not just root, so that
256+
# `printoutput_data` and `printoutput_ranks` can work correctly with their internal
257+
# calls to MPI methods --- we need all workers to have `io_handle` and `ranks_handle`
258+
# not to be nothing. However we also don't want every worker to actually open the
259+
# output files, since that can lead to race conditions. As a compromise, set the
260+
# non-root handles to `devnull`: this way the handle is never `nothing`, but only root
261+
# actually manages the output file. Moreover, `devnull` doesn't need to be closed at
262+
# the end of the main function.
263+
# (The actual printing is unaffected since it happens only if `isroot` is true, so
264+
# nothing gets actually printed to `devnull`, but it wouldn't be an issue since calling
265+
# `println` or `flush` on `devnull` doesn't do anything.)
255266
io_handle = nothing
256267
isroot=(MPI.Comm_rank(comm) == root)
257268
if !isnothing(io_file)
258-
io_handle = open(io_file, "w")
269+
io_handle = isroot ? open(io_file, "w") : devnull
259270

260271
columnheaders = ["time"]
261272

@@ -281,10 +292,11 @@ function MPSTimeEvolution.writeheaders_data(io_file, comm::MPI.Comm, cb; root, k
281292
end
282293

283294
function MPSTimeEvolution.writeheaders_ranks(ranks_file, comm::MPI.Comm, Ns::Int...; root)
295+
# (See `writeheaders_data` above.)
284296
ranks_handle = nothing
285297
isroot=(MPI.Comm_rank(comm) == root)
286298
if !isnothing(ranks_file)
287-
ranks_handle = open(ranks_file, "w")
299+
ranks_handle = isroot ? open(ranks_file, "w") : devnull
288300

289301
columnheaders = ["time"]
290302

0 commit comments

Comments
 (0)