23 #include <unordered_map> 26 #if defined WASH_CSTONE || defined WASH_WONE 32 #include "particle_data.hpp" 34 #if SIZE_MAX == UCHAR_MAX 35 #define MPI_SIZE_T MPI_UNSIGNED_CHAR 36 #elif SIZE_MAX == USHRT_MAX 37 #define MPI_SIZE_T MPI_UNSIGNED_SHORT 38 #elif SIZE_MAX == UINT_MAX 39 #define MPI_SIZE_T MPI_UNSIGNED 40 #elif SIZE_MAX == ULONG_MAX 41 #define MPI_SIZE_T MPI_UNSIGNED_LONG 42 #elif SIZE_MAX == ULLONG_MAX 43 #define MPI_SIZE_T MPI_UNSIGNED_LONG_LONG 45 #error "Unknown size_t size" 48 namespace fs = std::filesystem;
54 const std::string get_simulation_name();
56 const std::string get_output_name();
60 size_t particle_count;
63 std::vector<double> data;
65 std::vector<std::string> labels;
67 std::vector<unsigned short> dim;
69 friend std::ostream& operator<<(std::ostream& os,
const SimulationData& data) {
70 os <<
"SimulationData[ count=" << data.particle_count <<
", data=" << data.data.size() <<
", ";
72 for (
int i = 0; i < data.labels.size(); i++) {
73 os <<
"(" << data.labels.at(i) <<
"," << data.dim.at(i) <<
"),";
89 using WriterFuncT = std::function<int(const io::IOManager&, const SimulationData&, const size_t)>;
90 static const std::unordered_map<std::string, std::string> label_map;
105 IOManager(
const std::string format, WriterFuncT writer,
const size_t nth,
const size_t rank = 0,
const size_t size = 1,
const bool timings =
true) : writer(writer), output_nth(nth), rank(rank), size(size), do_timings(timings) {
106 path =
"./out/" + get_simulation_name() + std::string(
"/");
107 std::cout <<
"IO Manager: Output Path: " << path <<
"; Type: " << format <<
"; Rank " << rank <<
"; of " << size <<
";" << std::endl;
109 if (!fs::exists(path)) {
111 fs::create_directories(path);
112 }
catch (
const std::exception& e) {
113 std::cerr <<
"Error creating directory: " << e.what() << std::endl;
114 throw std::runtime_error(
"Error initialising IO manager: Creating Output directory");
123 IOManager(
const std::string format, WriterFuncT writer) :
IOManager(format, writer, 1) {}
125 IOManager(
const std::string format, WriterFuncT writer,
const size_t rank,
const size_t size) :
IOManager(format, writer, 1, rank, size) {}
129 const std::string get_path()
const {
133 size_t get_rank()
const {
137 size_t get_size()
const {
141 void set_gather(
bool value =
true) {
142 this->gather = value;
149 auto find = label_map.find(label);
150 if (find != label_map.end()) {
165 data = copy_simulation_data();
166 #if defined WASH_WSER || defined WASH_WISB || defined WASH_WEST 169 #elif defined WASH_CSTONE || defined WASH_WONE 171 if (size == 1 || !gather) {
175 std::vector<int> recv_counts(size, 1);
176 std::vector<int> displs (size);
177 for (
size_t i = 0 ; i < size; i++) {
181 size_t particle_counts[size];
182 MPI_Gatherv(&data.particle_count, 1, MPI_SIZE_T, particle_counts, recv_counts.data(), displs.data(), MPI_SIZE_T, 0, MPI_COMM_WORLD);
185 int int_particle_counts[size];
186 unsigned sim_particle_count = 0;
187 for (
size_t idx = 0; idx < size; idx++) {
188 int_particle_counts[idx] = particle_counts[idx];
189 sim_particle_count += particle_counts[idx];
193 for (
size_t idx = 0; idx < data.labels.size(); idx++) {
194 total_width += data.dim[idx];
198 std::vector<double> sim_data(sim_particle_count * total_width);
200 std::vector<int> send_sizes(size);
201 for (
size_t i = 0; i < size; i++) {
202 send_sizes[i] = total_width * int_particle_counts[i];
205 std::vector<int> displs_2(size);
207 for (
size_t i = 1; i < size; i++) {
208 displs_2[i] = displs_2[i-1] + send_sizes[i];
211 MPI_Gatherv(data.data.data(), data.data.size(), MPI_DOUBLE, sim_data.data(), send_sizes.data(), displs_2.data(), MPI_DOUBLE, 0, MPI_COMM_WORLD );
214 return SimulationData { .particle_count = sim_particle_count, .data = sim_data, .labels = data.labels, .dim = data.dim };
228 if (writer && iteration % this->output_nth == 0 && this->path !=
"") {
230 if (gather && rank != 0) {
234 writer(*
this, sim_data, iteration);
244 void write_timings(
const std::string& event_name,
const int tag,
const int64_t time_taken)
const {
246 std::string fpath = (
new std::string(this->path))->append(get_output_name() +
".timings.csv");
248 std::ios_base::openmode mode = std::ofstream::app;
249 std::ofstream outputFile(fpath, mode);
251 outputFile << event_name <<
"," << tag <<
"," << time_taken <<
"," << rank <<
"," << size << std::endl;
262 #if defined WASH_CSTONE || defined WASH_WONE 267 std::string fpath = (
new std::string(this->path))->append(get_output_name() +
".timings.csv");
269 if (fs::exists(fpath)) {
270 fs::path old_fpath = this->path + get_output_name() +
".old.timings.csv";
271 fs::rename(fpath, old_fpath);
273 }
catch (
const std::exception& ex) {
274 std::cerr <<
"Error trying to create timings output " << ex.what() << std::endl;
280 IOManager::WriterFuncT return_writer(
const std::string format);
294 io::IOManager
create_io(
const std::string format,
const size_t output_nth,
const bool use_gather =
false,
const size_t rank = 0,
const size_t size = 1,
const bool timings =
true);
307 std::vector<std::string> get_variables_names();
void new_timings()
Clear the timings output file.
Definition: io.hpp:260
Manages the IO options for the simulation.
Definition: io.hpp:87
std::vector< double > copy_variables()
Copy the variables of the simulation.
Definition: wash.cpp:399
const SimulationData get_simulation_data()
Copies the simulation data at the current point of the simulation.
Definition: io.hpp:164
void write_iteration(const size_t iteration)
Dispatches an iteration call to the writer based on the iteration number.
Definition: io.hpp:227
TODO: Consider having this as a private header in WISB/WS2ST/etc implementations. ...
Definition: ascii.hpp:5
const std::string & expand_label(const std::string &label) const
Helper function to expand a label if an expansion exists.
Definition: io.hpp:148
The public facing API for all Wash programs to be written with.
io::IOManager create_io(const std::string format, const size_t output_nth, const bool use_gather=false, const size_t rank=0, const size_t size=1, const bool timings=true)
Set-up the IO options for the simulation.
Definition: io.cpp:59
void write_timings(const std::string &event_name, const int tag, const int64_t time_taken) const
Write a timing even out to a file.
Definition: io.hpp:244