Skip to content

Commit 2324a8e

Browse files
committed
Allow skipping some metadata in save_grid_data.
Allows writing smaller files e.g. in case another file already has required grid metadata.
1 parent 503a462 commit 2324a8e

File tree

1 file changed

+82
-31
lines changed

1 file changed

+82
-31
lines changed

dccrg.hpp

Lines changed: 82 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,21 +1086,29 @@ template <
10861086
Writes grid data into given file starting at given offset in bytes.
10871087
10881088
All processes write the data necessary for restoring the
1089-
internal state of the grid with load_grid_data().
1090-
This includes the geometry of the grid, the list of cells
1091-
which exist and their Cell_Data.
1089+
internal state of the grid with load_grid_data() if
1090+
default arguments are not changed.
1091+
If write_grid_info is false, info needed when initializing
1092+
grid is not written.
1093+
If write_cell_ids is false, ids of cells whose data will be
1094+
saved to file are not written.
1095+
If write_data_offsets if false, offsets of cells' data
1096+
will not be written.
10921097
All data is written in native endian format.
10931098
10941099
The data saved from each cells' user data class Cell_Data is
10951100
defined by the get_mpi_datatype method of that class.
10961101
Unless you know what you're doing the method should return
10971102
the same datatype information both when saving and loading the grid.
10981103
1104+
If cells_to_write is not empty, only given cells that must exist
1105+
and be owned by current process are written.
10991106
Process 0 writes the data represented by the given header to the
11001107
file at given offset. The header does not have to be defined
11011108
on other processes.
11021109
1103-
Must be called by all processes with identical arguments.
1110+
Filename, offset and write_* arguments must be identical on all
1111+
processes. Header is ignored by ranks other than 0.
11041112
Returns true on success, false otherwise (one one or more processes).
11051113
11061114
During this function the receiving process given to the cells'
@@ -1109,7 +1117,11 @@ template <
11091117
bool save_grid_data(
11101118
const std::string& name,
11111119
MPI_Offset offset,
1112-
std::tuple<void*, int, MPI_Datatype> header
1120+
std::tuple<void*, int, MPI_Datatype> header,
1121+
const std::vector<uint64_t>& cells_to_write = std::vector<uint64_t>(),
1122+
const bool write_grid_info = true,
1123+
const bool write_cell_ids = true,
1124+
const bool write_data_offsets = true
11131125
) {
11141126
#ifdef DEBUG
11151127
if (not this->grid_initialized) {
@@ -1237,6 +1249,7 @@ template <
12371249
offset += (MPI_Offset) header_size;
12381250
}
12391251

1252+
if (write_grid_info) {
12401253
// write endianness check
12411254
if (this->rank == 0) {
12421255

@@ -1322,38 +1335,47 @@ template <
13221335
}
13231336
}
13241337
offset += this->geometry.data_size();
1338+
} // if (write_grid_info)
13251339

13261340
// write the total number of cells that will be written
13271341
uint64_t number_of_cells = this->cell_data.size();
1342+
if (cells_to_write.size() > 0) {
1343+
number_of_cells = cells_to_write.size();
1344+
}
13281345
const uint64_t total_number_of_cells
13291346
= All_Reduce()(number_of_cells, this->comm);
13301347

1331-
if (this->rank == 0) {
1332-
ret_val = MPI_File_write_at(
1333-
outfile,
1334-
offset,
1335-
(void*) &total_number_of_cells,
1336-
1,
1337-
MPI_UINT64_T,
1338-
MPI_STATUS_IGNORE
1339-
);
1340-
if (ret_val != MPI_SUCCESS) {
1341-
std::cerr << __FILE__ << ":" << __LINE__
1342-
<< " Process " << this->rank
1343-
<< " Couldn't write cell list to file " << name
1344-
<< ": " << Error_String()(ret_val)
1345-
<< std::endl;
1346-
return false;
1348+
if (write_grid_info) {
1349+
if (this->rank == 0) {
1350+
ret_val = MPI_File_write_at(
1351+
outfile,
1352+
offset,
1353+
(void*) &total_number_of_cells,
1354+
1,
1355+
MPI_UINT64_T,
1356+
MPI_STATUS_IGNORE
1357+
);
1358+
if (ret_val != MPI_SUCCESS) {
1359+
std::cerr << __FILE__ << ":" << __LINE__
1360+
<< " Process " << this->rank
1361+
<< " Couldn't write cell list to file " << name
1362+
<< ": " << Error_String()(ret_val)
1363+
<< std::endl;
1364+
return false;
1365+
}
13471366
}
1367+
offset += sizeof(uint64_t);
13481368
}
1349-
offset += sizeof(uint64_t);
13501369

13511370
// contiguous memory version of cell list needed by MPI_Write_...
1352-
std::vector<uint64_t> cells_to_write = this->get_cells();
1353-
if (cells_to_write.size() != number_of_cells) {
1371+
auto cells_to_write_ = cells_to_write;
1372+
if (cells_to_write_.size() == 0) {
1373+
cells_to_write_ = this->get_cells();
1374+
}
1375+
if (cells_to_write_.size() != number_of_cells) {
13541376
std::cerr << __FILE__ << ":" << __LINE__
13551377
<< " Number of cells is inconsistent: " << number_of_cells
1356-
<< ", should be " << cells_to_write.size()
1378+
<< ", should be " << cells_to_write_.size()
13571379
<< std::endl;
13581380
abort();
13591381
}
@@ -1369,7 +1391,7 @@ template <
13691391

13701392
// get intermediate datatypes from user
13711393
for (size_t i = 0; i < number_of_cells; i++) {
1372-
const uint64_t cell = cells_to_write[i];
1394+
const uint64_t cell = cells_to_write_[i];
13731395

13741396
std::tie(
13751397
addresses[i],
@@ -1481,7 +1503,11 @@ template <
14811503
abort();
14821504
}
14831505

1484-
current_byte_offset += (uint64_t) current_bytes;
1506+
if (Is_Named_Datatype()(file_datatypes[i])) {
1507+
current_byte_offset += counts[i] * (uint64_t) current_bytes;
1508+
} else {
1509+
current_byte_offset += (uint64_t) current_bytes;
1510+
}
14851511
}
14861512

14871513
// tell everyone how many bytes everyone will write
@@ -1508,6 +1534,12 @@ template <
15081534
uint64_t cell_data_start
15091535
= (uint64_t) offset
15101536
+ 2 * total_number_of_cells * sizeof(uint64_t);
1537+
if (not write_cell_ids) {
1538+
cell_data_start -= total_number_of_cells * sizeof(uint64_t);
1539+
}
1540+
if (not write_data_offsets) {
1541+
cell_data_start -= total_number_of_cells * sizeof(uint64_t);
1542+
}
15111543

15121544
for (size_t i = 0; i < (size_t) this->rank; i++) {
15131545
cell_data_start += all_number_of_bytes[i];
@@ -1550,9 +1582,25 @@ template <
15501582

15511583
// write cell + data displacement list
15521584
std::vector<uint64_t> cells_and_data_displacements(2 * number_of_cells, 0);
1553-
for (size_t i = 0; i < number_of_cells; i++) {
1554-
cells_and_data_displacements[2 * i] = cells_to_write[i];
1555-
cells_and_data_displacements[2 * i + 1] = file_displacements[i];
1585+
uint64_t cell_and_disp_len = 0;
1586+
if (write_cell_ids and write_data_offsets) {
1587+
cell_and_disp_len = 2 * number_of_cells;
1588+
for (size_t i = 0; i < number_of_cells; i++) {
1589+
cells_and_data_displacements[2 * i] = cells_to_write_[i];
1590+
cells_and_data_displacements[2 * i + 1] = file_displacements[i];
1591+
}
1592+
} else if (write_cell_ids) {
1593+
cell_and_disp_len = number_of_cells;
1594+
for (size_t i = 0; i < number_of_cells; i++) {
1595+
cells_and_data_displacements[i] = cells_to_write_[i];
1596+
}
1597+
} else if (write_data_offsets) {
1598+
cell_and_disp_len = number_of_cells;
1599+
for (size_t i = 0; i < number_of_cells; i++) {
1600+
cells_and_data_displacements[i] = file_displacements[i];
1601+
}
1602+
} else {
1603+
cell_and_disp_len = 0;
15561604
}
15571605

15581606
// give a valid buffer to ...write_at_all even if no cells to write
@@ -1564,7 +1612,7 @@ template <
15641612
outfile,
15651613
(MPI_Offset) cell_list_start,
15661614
(void*) &cells_and_data_displacements[0],
1567-
2 * number_of_cells,
1615+
cell_and_disp_len,
15681616
MPI_UINT64_T,
15691617
MPI_STATUS_IGNORE
15701618
);
@@ -1744,6 +1792,9 @@ template <
17441792
sfc_caching_bathces. TODO: Reads at most number_of_cells number of cell data
17451793
offsets at a time, give a smaller number if all cell ids won't fit into memory at once.
17461794
1795+
Only supports files that were written with default arguments
1796+
given to save_grid_data.
1797+
17471798
All processes read the same data defined by the given header starting at
17481799
given file offset in bytes. The header does not have to be defined on
17491800
other processes.

0 commit comments

Comments
 (0)