Skip to content

Commit 0a19f3d

Browse files
committed
TL: satisfying thomas's requests
1 parent 1dc21db commit 0a19f3d

File tree

3 files changed

+34
-13
lines changed

3 files changed

+34
-13
lines changed

pySDC/helpers/blocks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class BlockDecomposition(object):
99
gridSizes : list[int]
1010
Number of grid points in each dimension
1111
algo : str, optional
12-
Algorithm used for hte block decomposition :
12+
Algorithm used for the block decomposition :
1313
1414
- Hybrid : approach minimizing interface communication, inspired from
1515
the `[Hybrid CFD solver] <https://web.stanford.edu/group/ctr/ResBriefs07/5_larsson1_pp47_58.pdf>`_.

pySDC/helpers/fieldsIO.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
-----
3939
🚀 :class:`Cart1D` and :class:`Cart2D` are compatible with a MPI-based cartesian decomposition.
4040
See :class:`pySDC.tests.test_helpers.test_fieldsIO.writeFields_MPI` for an illustrative example.
41+
42+
Warning
43+
-------
44+
To use MPI collective writing, you need to call first the class methods :class:`Cart1D.initMPI`
45+
or :class:`Cart2D.initMPI` from the associated class (cf their docstring).
46+
Also, their associated `setHeader` methods **must be given the global grids coordinates**,
47+
wether code is run in parallel or not.
4148
"""
4249
import os
4350
import numpy as np
@@ -82,6 +89,8 @@ class FieldsIO:
8289

8390
tSize = T_DTYPE().itemsize
8491

92+
ALLOW_OVERWRITE = False
93+
8594
def __init__(self, dtype, fileName):
8695
"""
8796
Parameters
@@ -91,7 +100,7 @@ def __init__(self, dtype, fileName):
91100
fileName : str
92101
File.
93102
"""
94-
assert dtype in DTYPES_AVAIL, f"dtype not available ({dtype})"
103+
assert dtype in DTYPES_AVAIL, f"{dtype=} not available"
95104
self.dtype = dtype
96105
self.fileName = fileName
97106
self.initialized = False
@@ -170,6 +179,11 @@ def initialize(self):
170179
assert self.header is not None, "header must be set before initializing FieldsIO"
171180
assert not self.initialized, "FieldsIO already initialized"
172181

182+
if not self.ALLOW_OVERWRITE:
183+
assert not os.path.isfile(
184+
self.fileName
185+
), "file already exists, use FieldsIO.ALLOW_OVERWRITE = True to allow overwriting"
186+
173187
with open(self.fileName, "w+b") as f:
174188
self.hBase.tofile(f)
175189
for array in self.hInfos:
@@ -240,8 +254,8 @@ def nFields(self):
240254
"""Number of fields currently stored in the binary file"""
241255
return int((self.fileSize - self.hSize) // (self.tSize + self.fSize))
242256

243-
def check(self, idx):
244-
"""Utility method to check a positional index for a stored field"""
257+
def formatIndex(self, idx):
258+
"""Utility method to format a fields index to a positional integer (negative starts from last field index, like python lists)"""
245259
nFields = self.nFields
246260
if idx < 0:
247261
idx = nFields + idx
@@ -262,7 +276,7 @@ def times(self):
262276

263277
def time(self, idx):
264278
"""Time stored at a given field index"""
265-
idx = self.check(idx)
279+
idx = self.formatIndex(idx)
266280
offset = self.hSize + idx * (self.tSize + self.fSize)
267281
with open(self.fileName, "rb") as f:
268282
t = np.fromfile(f, dtype=T_DTYPE, count=1, offset=offset)[0]
@@ -285,7 +299,7 @@ def readField(self, idx):
285299
field : np.ndarray
286300
Read fields in a numpy array.
287301
"""
288-
idx = self.check(idx)
302+
idx = self.formatIndex(idx)
289303
offset = self.hSize + idx * (self.tSize + self.fSize)
290304
with open(self.fileName, "rb") as f:
291305
f.seek(offset)
@@ -494,15 +508,20 @@ def MPI_FILE_CLOSE(self):
494508
def initialize(self):
495509
"""Initialize the binary file (write header) in MPI mode"""
496510
if self.MPI_ROOT:
497-
super().initialize()
511+
try:
512+
super().initialize()
513+
except AssertionError as e:
514+
print(f"{type(e): {e}}")
515+
self.comm.Abort()
516+
498517
if self.MPI_ON:
499518
self.comm.Barrier() # Important, should not be removed !
500519
self.initialized = True
501520

502521
def addField(self, time, field):
503522
"""
504523
Append one field solution at the end of the file with one given time,
505-
eventually using MPI.
524+
possibly using MPI.
506525
507526
Parameters
508527
----------
@@ -538,7 +557,7 @@ def addField(self, time, field):
538557
def readField(self, idx):
539558
"""
540559
Read one field stored in the binary file, corresponding to the given
541-
time index, eventually in MPI mode.
560+
time index, possibly in MPI mode.
542561
543562
Parameters
544563
----------
@@ -558,7 +577,7 @@ def readField(self, idx):
558577
"""
559578
if not self.MPI_ON:
560579
return super().readField(idx)
561-
idx = self.check(idx)
580+
idx = self.formatIndex(idx)
562581

563582
offset0 = self.hSize + idx * (self.fSize + self.tSize)
564583
with open(self.fileName, "rb") as f:
@@ -651,7 +670,7 @@ def setupMPI(cls, comm: MPI.Intracomm, iLocX, nLocX, iLocY, nLocY):
651670
def addField(self, time, field):
652671
"""
653672
Append one field solution at the end of the file with one given time,
654-
eventually using MPI.
673+
possibly using MPI.
655674
656675
Parameters
657676
----------
@@ -712,7 +731,7 @@ def readField(self, idx):
712731
"""
713732
if not self.MPI_ON:
714733
return super().readField(idx)
715-
idx = self.check(idx)
734+
idx = self.formatIndex(idx)
716735

717736
offset0 = self.hSize + idx * (self.tSize + self.fSize)
718737
with open(self.fileName, "rb") as f:

pySDC/tests/test_helpers/test_fieldsIO.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import pytest
22
import numpy as np
33

4-
from pySDC.helpers.fieldsIO import DTYPES
4+
from pySDC.helpers.fieldsIO import DTYPES, FieldsIO
5+
6+
FieldsIO.ALLOW_OVERWRITE = True
57

68

79
@pytest.mark.parametrize("dtypeIdx", DTYPES.keys())

0 commit comments

Comments
 (0)