@@ -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