68 """Check environment is correct if we are in MPI mode, and setup dictionaries"""
70 if "RANK" not in os.environ:
72 "Running in MPI mode but the $RANK environment variable is not set!"
75 if not os.getcwd().endswith(
"rank-{}".format(
getMPIRank())):
77 "Running in MPI mode with rank {0} but working directory is not called rank-{0}".format(
83 mpiConfig[
"rank"] = rank
84 mpiConfig[
"type"] = mpiType
85 mpiConfig[
"outputs"] = {
86 dataType: deepcopy(dataDict[dataType])
for dataType
in output
89 output_proc_regex = re.compile(
r"(.+)\[(.*)](.*)")
90 for v
in mpiConfig[
"outputs"].values():
95 if (
"[" in fn)
and (
"]" in fn):
96 match = output_proc_regex.match(fn)
99 f
"{match.group(1)}{it}{match.group(3)}"
100 for it
in match.group(2).
split(
",")
103 list_to_remove.append(match.group(1))
106 list_to_remove.append(fn)
108 v.list_to_remove = list(
set(list_to_remove))
124 """Merge outputs into rank 0"""
125 if mpiConfig
is None:
126 msg.warning(
"trfMPITools.mergeOutputs called when we are not in MPI mode")
128 rank_dir_regex = re.compile(
"rank-([0-9]+)$")
130 int(m.group(1)): m.string
131 for m
in (rank_dir_regex.search(d.path)
for d
in os.scandir(
"..")
if d.is_dir())
132 if m
and int(m.group(1)) > 0
134 num_ranks = len(rank_dirs) + 1
136 open(
"athena_done",
"a").close()
138 (rank, f
"../rank-{rank}/athena_done")
for rank
in range(0, num_ranks)
141 files_to_check = list(
142 it.filterfalse(
lambda f: os.path.exists(f[1]), files_to_check)
144 while files_to_check:
147 f
"{count // 10 + 1}: Waiting for all ranks to finish athena: {list(map(lambda x: x[0], files_to_check))}"
151 files_to_check = list(
152 it.filterfalse(
lambda f: os.path.exists(f[1]), files_to_check)
156 import sqlite3
as sq3
157 from glob
import glob
160 conn = sq3.connect(
"mpilog.db")
162 tables = [
"ranks",
"files",
"event_log"]
163 for db
in glob(
"../rank-[1-9]*/mpilog.db"):
164 cur.execute(
"ATTACH DATABASE ? as db", (db,))
166 upsert =
"INSERT OR IGNORE" if table ==
"files" else "INSERT"
167 cur.execute(f
"{upsert} INTO {table} SELECT * from db.{table}")
169 cur.execute(
"DETACH DATABASE db")
172 msg.info(
"Rank output directories are:\n{}".format(pprint.pformat(rank_dirs)))
173 all_merge_inputs = list(
177 lambda f: f.is_file(),
178 it.chain.from_iterable(
map(os.scandir, rank_dirs.values())),
184 os.remove(
"PoolFileCatalog.xml")
185 except FileNotFoundError:
187 for dtype, defn
in mpiConfig[
"outputs"].items():
189 msg.info(f
"Output type is {dtype}")
190 merge_helper = deepcopy(defn)
191 merge_helper.multipleOK =
True
193 for fn
in defn.list_to_remove:
197 except FileNotFoundError:
200 for fn
in defn.value:
201 merge_inputs = sorted(filter(
lambda s: s.endswith(fn), all_merge_inputs))
203 merge_helper.value.extend(merge_inputs)
204 merge_lists.append((fn, merge_inputs))
206 defn.value = [x[0]
for x
in merge_lists
if len(x[1]) >= 1]
209 msg.info(f
"In rank {getMPIRank()}, not merging")
211 for idx
in range(
getMPIRank(), len(merge_lists), num_ranks):
212 my_merge = merge_lists[idx]
213 if len(my_merge[1]) < 1:
215 f
"In rank {getMPIRank()}, no inputs for ../rank-0/{my_merge[0]}"
219 f
"In rank {getMPIRank()}, merging into ../rank-0/{my_merge[0]}. Inputs are \n{pprint.pformat(my_merge[1])}"
222 merge_helper.selfMerge(f
"../rank-0/{my_merge[0]}", my_merge[1])
223 except Exception
as e:
225 f
"Merge failure in rank {getMPIRank()} merging into {my_merge[0]}: {e}"
227 with open(
"../rank-0/merge_failure",
"a")
as f:
229 f
"Merge failure in rank {getMPIRank()} merging into {my_merge[0]}: {e}\n"
232 open(
"done_merging",
"a").close()
236 (rank, f
"../rank-{rank}/done_merging")
for rank
in range(0, num_ranks)
239 files_to_check = list(
240 it.filterfalse(
lambda f: os.path.exists(f[1]), files_to_check)
242 while files_to_check:
245 f
"Waiting for all ranks to finish merging: {list(map(lambda x: x[0], files_to_check))}"
249 files_to_check = list(
250 it.filterfalse(
lambda f: os.path.exists(f[1]), files_to_check)
252 if not os.path.exists(
"merge_failure"):
253 msg.info(
"All ranks done merging")
255 msg.error(
"ERRORS WHILE MERGING")
256 raise RuntimeError(
"Output merging error")