diff --git a/src/communication/communicator.hpp b/src/communication/communicator.hpp index e59e15f5b2bf5ab7482ad9ce0c11fb0ea1359638..0289fc3192e268bd5e647d659747635509914ef8 100644 --- a/src/communication/communicator.hpp +++ b/src/communication/communicator.hpp @@ -92,20 +92,19 @@ public: /// events in each queue are all events that must be delivered to targets in that cell /// group as a result of the global spike exchange. std::vector<event_queue> exchange(const std::vector<spike_type>& local_spikes, - std::function<void (const std::vector<spike_type>&)> export_function) //const std::vector<spike_type>& + std::function<void (const std::vector<spike_type>&)> do_export_rank, + std::function<void(const std::vector<spike_type>&)> do_export_single) { // global all-to-all to gather a local copy of the global spike list on each node. - bool file_per_rank = true; - if (file_per_rank) { - export_function(local_spikes); //local_spikes - } - + do_export_rank(local_spikes); auto global_spikes = communication_policy_.gather_spikes( local_spikes ); num_spikes_ += global_spikes.size(); + do_export_single(global_spikes); + // check each global spike in turn to see it generates local events. // if so, make the events and insert them into the appropriate event list. auto queues = std::vector<event_queue>(num_groups_local()); diff --git a/src/communication/export_manager.hpp b/src/communication/export_manager.hpp index ccef9c1c86538a75ca38f855509c409ff647474d..ed4997282ac6d2f71894b8aa987d8ac80250d8db 100644 --- a/src/communication/export_manager.hpp +++ b/src/communication/export_manager.hpp @@ -1,27 +1,82 @@ -//#pragma once -// -//#include <algorithm> -//#include <iostream> -//#include <fstream> -//#include <vector> -//#include <random> -// -//#include <spike.hpp> -// -//#include "exporter_interface.hpp" -// -//namespace nest { -//namespace mc { -//namespace communication { -// -//class export_manager { -// -// -// -//}; -// -// -// -//} //communication -//} // namespace mc -//} // namespace nest \ No newline at end of file +#pragma once + +#include <algorithm> +#include <iostream> + +#include <vector> +#include <memory> +#include <utility> + +#include <spike.hpp> +#include <util.hpp> +#include <common_types.hpp> +#include "exporter_interface.hpp" +#include "exporter_spike_file.hpp" +#include "exporter_spike_single_file.hpp" + +namespace nest { +namespace mc { +namespace communication { + +template <typename Time, typename CommunicationPolicy> +class export_manager { +public: + using time_type = Time; + using spike_type = spike<cell_member_type, time_type>; + export_manager() + { + + if (true) { // single file per rank + + rank_exporters_.push_back( + nest::mc::util::make_unique< + nest::mc::communication::exporter_spike_file<Time, CommunicationPolicy> >( + "rank", "./", "gdf")); + + + } + + + if (true) { // single file per simulation + single_exporters_.push_back( + nest::mc::util::make_unique< + nest::mc::communication::exporter_spike_single_file<Time, CommunicationPolicy> >( + "single", "./", "gdf")); + } + } + + void do_export_rank(const std::vector<spike_type>& spikes) + { + for (auto &exporter : rank_exporters_) + { + exporter->add_and_export(spikes); + } + } + + void do_export_single(const std::vector<spike_type>& spikes) + { + if (!communication_policy_.id() == 0) { + return; + } + + for (auto &exporter : single_exporters_) + { + exporter->add_and_export(spikes); + } + } + +private: + // + std::vector<std::unique_ptr<exporter_interface<Time, CommunicationPolicy> > > rank_exporters_; + + std::vector<std::unique_ptr<exporter_interface<Time, CommunicationPolicy> > > single_exporters_; + + + CommunicationPolicy communication_policy_; +}; + + + +} //communication +} // namespace mc +} // namespace nest \ No newline at end of file diff --git a/src/communication/exporter_spike_single_file.hpp b/src/communication/exporter_spike_single_file.hpp index b22d77c011ef21d31195b290c4d5566d93817f11..249e7583b28b6043e20b719ba8d1d9facfb8c339 100644 --- a/src/communication/exporter_spike_single_file.hpp +++ b/src/communication/exporter_spike_single_file.hpp @@ -72,10 +72,6 @@ public: // Does not throw void do_export() override { - if (!communication_policy_.id() == 0) { - return; - } - for (auto spike : spikes_) { *file_handle_ << spike.source.gid << " " << spike.time << std::endl; } @@ -90,9 +86,6 @@ public: // Does not do the actual export void add_data(std::vector<spike_type>spikes) override { - if (!communication_policy_.id() == 0) { - return; - } spikes_.insert(std::end(spikes_), std::begin(spikes), std::end(spikes)); @@ -101,10 +94,6 @@ public: // Add and export data to file in a single function void add_and_export(const std::vector<spike_type>& spikes) override { - if (!communication_policy_.id() == 0) { - return; - } - add_data(spikes); do_export(); } @@ -114,9 +103,6 @@ public: // We need a way to assertain the status of the stream bool ok() const override { - if (!communication_policy_.id() == 0) { - return true; - } return ok_ && file_handle_->good(); } diff --git a/src/model.hpp b/src/model.hpp index f7e22d28c939c6fb1f81bd41e7a127d6f5a6d3cd..d84396c7ca2bed6a3223f1cf24bff1de6724d30e 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -12,9 +12,7 @@ #include <thread_private_spike_store.hpp> #include <communication/communicator.hpp> #include <communication/global_policy.hpp> -#include <communication/exporter_interface.hpp> -#include <communication/exporter_spike_single_file.hpp> -#include <communication/exporter_spike_file.hpp> +#include <communication/export_manager.hpp> #include <profiling/profiler.hpp> #include "trace_sampler.hpp" @@ -74,8 +72,7 @@ public: bool single_file = true; if (single_file == true) { - exporter_ = nest::mc::util::make_unique<exporter_spike_single_file_type>( - "file_name", "./","gdf"); + exporter_ = nest::mc::util::make_unique<exporter_manager_type>(); } // Allocate an empty queue buffer for each cell group @@ -139,7 +136,8 @@ public: PE("stepping", "exchange"); auto local_spikes = previous_spikes().gather(); future_events() = communicator_.exchange(local_spikes, - [&] (const std::vector<spike_type>& spikes){ exporter_->add_and_export(spikes); }); + [&](const std::vector<spike_type>& spikes) { exporter_->do_export_rank(spikes); }, + [&] (const std::vector<spike_type>& spikes){ exporter_->do_export_single(spikes); }); PL(2); }; @@ -194,10 +192,9 @@ private: using local_spike_store_type = thread_private_spike_store<time_type>; util::double_buffer< local_spike_store_type > local_spikes_; - using exporter_interface_type = nest::mc::communication::exporter_interface<time_type, communication::global_policy>; - using exporter_spike_single_file_type = nest::mc::communication::exporter_spike_file<time_type, communication::global_policy>; + using exporter_manager_type = nest::mc::communication::export_manager<time_type, communication::global_policy>; - std::unique_ptr<exporter_interface_type> exporter_; + std::unique_ptr<exporter_manager_type> exporter_; // Convenience functions that map the spike buffers and event queues onto // the appropriate integration interval. //