Skip to content

Commit 0d4d3aa

Browse files
committed
Have LocalPropertyOutput make a bit more data available to users for checkpointing
1 parent df7cef8 commit 0d4d3aa

File tree

2 files changed

+112
-95
lines changed

2 files changed

+112
-95
lines changed

Code/extraction/LocalPropertyOutput.cc

Lines changed: 99 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -222,111 +222,118 @@ namespace hemelb::extraction
222222
}
223223
}
224224

225-
void LocalPropertyOutput::Write(unsigned long timestepNumber, unsigned long totalSteps)
225+
std::optional<std::filesystem::path>
226+
LocalPropertyOutput::Write(unsigned long timestepNumber, unsigned long totalSteps)
226227
{
227228
// Don't write if we shouldn't this iteration.
228229
if (!ShouldWrite(timestepNumber))
229230
{
230-
return;
231+
return std::nullopt;
231232
}
232233

234+
std::filesystem::path ans;
233235
if (std::holds_alternative<single_timestep_files>(outputSpec.ts_mode)) {
234236
std::string fn = output_file_pattern.Format(timestepNumber, totalSteps);
235237
StartFile(fn);
238+
ans = fn;
239+
} else {
240+
ans = outputSpec.filename;
236241
}
237242

238243
// Don't write if this core doesn't do anything.
239-
if (local_data_write_length > 0)
240-
{
241-
// Create the buffer.
242-
auto xdrWriter = io::MakeXdrWriter(buffer.begin(), buffer.end());
243-
244-
// Firstly, the IO proc must write the iteration number.
245-
if (comms.OnIORank())
246-
{
247-
xdrWriter << (uint64_t) timestepNumber;
248-
}
249-
250-
dataSource->Reset();
251-
252-
while (dataSource->ReadNext())
253-
{
254-
const util::Vector3D<site_t>& position = dataSource->GetPosition();
255-
if (outputSpec.geometry->Include(*dataSource, position))
256-
{
257-
// Write the position
258-
xdrWriter << (uint32_t) position.x() << (uint32_t) position.y() << (uint32_t) position.z();
259-
260-
// Write for each field.
261-
for (auto& fieldSpec: outputSpec.fields)
262-
{
263-
overload_visit(
264-
fieldSpec.src,
265-
[&](source::Pressure) {
266-
write(xdrWriter, fieldSpec.typecode, dataSource->GetPressure() - fieldSpec.offset[0]);
267-
},
268-
[&](source::Velocity) {
269-
auto&& v = dataSource->GetVelocity();
270-
write(xdrWriter, fieldSpec.typecode, v.x(), v.y(), v.z());
271-
},
272-
//! @TODO: Work out how to handle the different stresses.
273-
[&](source::VonMisesStress) {
274-
write(xdrWriter, fieldSpec.typecode, dataSource->GetVonMisesStress());
275-
},
276-
[&](source::ShearStress) {
277-
write(xdrWriter, fieldSpec.typecode, dataSource->GetShearStress());
278-
},
279-
[&](source::ShearRate) {
280-
write(xdrWriter, fieldSpec.typecode, dataSource->GetShearRate());
281-
},
282-
[&](source::StressTensor) {
283-
util::Matrix3D tensor = dataSource->GetStressTensor();
284-
// Only the upper triangular part of the symmetric
285-
// tensor is stored. Storage is row-wise.
286-
write(xdrWriter, fieldSpec.typecode,
287-
tensor[0][0], tensor[0][1], tensor[0][2],
288-
tensor[1][1], tensor[1][2],
289-
tensor[2][2]);
290-
},
291-
[&](source::Traction) {
292-
auto&& t = dataSource->GetTraction();
293-
write(xdrWriter, fieldSpec.typecode, t.x(), t.y(), t.z());
294-
},
295-
[&](source::TangentialProjectionTraction) {
296-
auto&& t = dataSource->GetTangentialProjectionTraction();
297-
write(xdrWriter, fieldSpec.typecode, t.x(), t.y(), t.z());
298-
},
299-
[&](source::Distributions) {
300-
unsigned numComponents = dataSource->GetNumVectors();
301-
distribn_t const* d_ptr = dataSource->GetDistribution();
302-
for (auto i = 0U; i < numComponents; i++)
303-
{
304-
write(xdrWriter, fieldSpec.typecode, d_ptr[i]);
305-
}
306-
},
307-
[&](source::MpiRank) {
308-
write(xdrWriter, fieldSpec.typecode, comms.Rank());
309-
}
310-
);
311-
}
312-
}
313-
}
314-
315-
// Actually do the MPI writing.
316-
outputFile.WriteAt(local_write_start, buffer);
317-
}
244+
if (local_data_write_length > 0)
245+
{
246+
// Create the buffer.
247+
auto xdrWriter = io::MakeXdrWriter(buffer.begin(), buffer.end());
248+
249+
// Firstly, the IO proc must write the iteration number.
250+
if (comms.OnIORank())
251+
{
252+
xdrWriter << (uint64_t) timestepNumber;
253+
}
254+
255+
dataSource->Reset();
256+
257+
while (dataSource->ReadNext())
258+
{
259+
const util::Vector3D<site_t>& position = dataSource->GetPosition();
260+
if (outputSpec.geometry->Include(*dataSource, position))
261+
{
262+
// Write the position
263+
xdrWriter << (uint32_t) position.x() << (uint32_t) position.y() << (uint32_t) position.z();
264+
265+
// Write for each field.
266+
for (auto& fieldSpec: outputSpec.fields)
267+
{
268+
overload_visit(
269+
fieldSpec.src,
270+
[&](source::Pressure) {
271+
write(xdrWriter, fieldSpec.typecode, dataSource->GetPressure() - fieldSpec.offset[0]);
272+
},
273+
[&](source::Velocity) {
274+
auto&& v = dataSource->GetVelocity();
275+
write(xdrWriter, fieldSpec.typecode, v.x(), v.y(), v.z());
276+
},
277+
//! @TODO: Work out how to handle the different stresses.
278+
[&](source::VonMisesStress) {
279+
write(xdrWriter, fieldSpec.typecode, dataSource->GetVonMisesStress());
280+
},
281+
[&](source::ShearStress) {
282+
write(xdrWriter, fieldSpec.typecode, dataSource->GetShearStress());
283+
},
284+
[&](source::ShearRate) {
285+
write(xdrWriter, fieldSpec.typecode, dataSource->GetShearRate());
286+
},
287+
[&](source::StressTensor) {
288+
util::Matrix3D tensor = dataSource->GetStressTensor();
289+
// Only the upper triangular part of the symmetric
290+
// tensor is stored. Storage is row-wise.
291+
write(xdrWriter, fieldSpec.typecode,
292+
tensor[0][0], tensor[0][1], tensor[0][2],
293+
tensor[1][1], tensor[1][2],
294+
tensor[2][2]);
295+
},
296+
[&](source::Traction) {
297+
auto&& t = dataSource->GetTraction();
298+
write(xdrWriter, fieldSpec.typecode, t.x(), t.y(), t.z());
299+
},
300+
[&](source::TangentialProjectionTraction) {
301+
auto&& t = dataSource->GetTangentialProjectionTraction();
302+
write(xdrWriter, fieldSpec.typecode, t.x(), t.y(), t.z());
303+
},
304+
[&](source::Distributions) {
305+
unsigned numComponents = dataSource->GetNumVectors();
306+
distribn_t const* d_ptr = dataSource->GetDistribution();
307+
for (auto i = 0U; i < numComponents; i++)
308+
{
309+
write(xdrWriter, fieldSpec.typecode, d_ptr[i]);
310+
}
311+
},
312+
[&](source::MpiRank) {
313+
write(xdrWriter, fieldSpec.typecode, comms.Rank());
314+
}
315+
);
316+
}
317+
}
318+
}
319+
320+
// Actually do the MPI writing.
321+
outputFile.WriteAt(local_write_start, buffer);
322+
}
318323

319-
overload_visit(
320-
outputSpec.ts_mode,
321-
[this](multi_timestep_file) {
322-
// Set the offset to the right place for writing on the next
323-
// iteration.
324-
local_write_start += global_data_write_length;
325-
},
326-
[this](single_timestep_files) {
327-
outputFile.Close();
328-
}
329-
);
324+
overload_visit(
325+
outputSpec.ts_mode,
326+
[this](multi_timestep_file) {
327+
// Set the offset to the right place for writing on the next
328+
// iteration.
329+
local_write_start += global_data_write_length;
330+
},
331+
[this](single_timestep_files) {
332+
outputFile.Close();
333+
}
334+
);
335+
336+
return ans;
330337
}
331338

332339
// Write the offset file.

Code/extraction/LocalPropertyOutput.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,25 @@ namespace hemelb::extraction
3535
const PropertyOutputFile& GetOutputSpec() const;
3636

3737
// Write this core's section of the data file. Only writes if
38-
// appropriate for the current iteration number
39-
void Write(unsigned long timestepNumber, unsigned long totalSteps);
38+
// appropriate for the current iteration number.
39+
// Returns the path of the written file, iff writing occurred.
40+
std::optional<std::filesystem::path>
41+
Write(unsigned long timestepNumber, unsigned long totalSteps);
42+
43+
inline std::string const& GetOffsetFileName() const {
44+
return offset_file_name;
45+
}
4046

4147
// Write the offset file. Collective on the communicator.
4248
void WriteOffsetFile();
4349

4450
// Returns the number of items written for the field.
4551
unsigned GetFieldLength(source::Type) const;
4652

53+
auto OnIORank() const {
54+
return comms.OnIORank();
55+
}
56+
4757
private:
4858
// How many sites does this MPI process write?
4959
std::uint64_t CountWrittenSitesOnRank();
@@ -92,7 +102,7 @@ namespace hemelb::extraction
92102
// Buffer to serialise into before writing to disk.
93103
std::vector<char> buffer;
94104

95-
// The MPI file to write the offsets into.
105+
// The file to write the offsets into.
96106
std::string offset_file_name;
97107
};
98108
}

0 commit comments

Comments
 (0)