diff --git a/miniapp/miniapp.cpp b/miniapp/miniapp.cpp index 20082a7893aef381d8cfec365d51e80ae71043da..bc4133cb15ceecc5c96b8b7649f286980acb232f 100644 --- a/miniapp/miniapp.cpp +++ b/miniapp/miniapp.cpp @@ -130,7 +130,7 @@ int main(int argc, char** argv) { // output profile and diagnostic feedback auto const num_steps = options.tfinal / options.dt; - util::profiler_output(0.001, m.num_cells(), int(num_steps)); + util::profiler_output(0.001, m.num_cells()*num_steps); std::cout << "there were " << m.num_spikes() << " spikes\n"; // save traces diff --git a/src/cell_group.hpp b/src/cell_group.hpp index 7bfd4bb32f1c3a9281177243ca24e1bf8d2ee9b0..77276f49e52f12dc2b8205a7d24113d7409365f4 100644 --- a/src/cell_group.hpp +++ b/src/cell_group.hpp @@ -154,19 +154,21 @@ public: EXPECTS(probe_id.gid==gid_base_); auto sampler_index = uint32_t(samplers_.size()); samplers_.push_back({probe_handles_[probe_id.index], s}); + sampler_start_times_.push_back(start_time); sample_events_.push({sampler_index, start_time}); } void remove_samplers() { sample_events_.clear(); samplers_.clear(); + sampler_start_times_.clear(); } void reset_samplers() { // clear all pending sample events and reset to start at time 0 sample_events_.clear(); for(uint32_t i=0u; i<samplers_.size(); ++i) { - sample_events_.push({i, time_type(0)}); + sample_events_.push({i, sampler_start_times_[i]}); } } @@ -192,6 +194,7 @@ private: /// pending samples to be taken event_queue<sample_event<time_type>> sample_events_; + std::vector<time_type> sampler_start_times_; /// the global id of the first target (e.g. a synapse) in this group index_type first_target_gid_; diff --git a/src/communication/mpi.hpp b/src/communication/mpi.hpp index 5b43f1a86df763426184d9d998f574cbb2a091da..9ebb0ca412d83dbb600471417beb299fd1a55a8b 100644 --- a/src/communication/mpi.hpp +++ b/src/communication/mpi.hpp @@ -125,7 +125,7 @@ namespace mpi { /// Gather all of a distributed vector /// Retains the meta data (i.e. vector partition) template <typename T> - gathered_vector<T> gather_all_meta(const std::vector<T>& values) { + gathered_vector<T> gather_all_with_partition(const std::vector<T>& values) { using gathered_type = gathered_vector<T>; using count_type = typename gathered_vector<T>::count_type; using traits = mpi_traits<T>; @@ -149,9 +149,10 @@ namespace mpi { MPI_COMM_WORLD ); - std::vector<count_type> part(displs.size()); - std::copy(displs.begin(), displs.end(), part.begin()); - return gathered_type(std::move(buffer), std::move(part)); + return gathered_type( + std::move(buffer), + std::vector<count_type>(displs.begin(), displs.end()) + ); } template <typename T> diff --git a/src/communication/mpi_global_policy.hpp b/src/communication/mpi_global_policy.hpp index f1084791ddacaa7e000b881a4b05e86b9d43a586..d12beb6372abb01526186162247b45db6ddf75b9 100644 --- a/src/communication/mpi_global_policy.hpp +++ b/src/communication/mpi_global_policy.hpp @@ -22,7 +22,7 @@ struct mpi_global_policy { template <typename Spike> static gathered_vector<Spike> gather_spikes(const std::vector<Spike>& local_spikes) { - return mpi::gather_all_meta(local_spikes); + return mpi::gather_all_with_partition(local_spikes); } static int id() { return mpi::rank(); } diff --git a/src/model.hpp b/src/model.hpp index 41fb391ca614f60c01e37b170ed0774fd03b0cbc..5d0ce4fd8bcbe010cec3629e4b5d1adde38bcd96 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -101,18 +101,6 @@ public: util::profilers_restart(); } - void print_spikes() { - std::cout << "CURRENT : "; - for(auto s : current_spikes().gather()) { - std::cout << s << " "; - } - std::cout << "\nPREVIOUS : "; - for(auto s : previous_spikes().gather()) { - std::cout << s << " "; - } - std::cout << "\n"; - } - time_type run(time_type tfinal, time_type dt) { // Calculate the size of the largest possible time integration interval // before communication of spikes is required. diff --git a/src/profiling/profiler.cpp b/src/profiling/profiler.cpp index 88c3d60d856b98a72a479258c69ff114782daaba..83c15d78fa7f4c5d6a076d4ff534ef77fc891a57 100644 --- a/src/profiling/profiler.cpp +++ b/src/profiling/profiler.cpp @@ -305,7 +305,7 @@ void profilers_restart() { } } -void profiler_output(double threshold, cell_size_type num_local_cells, int num_steps) { +void profiler_output(double threshold, std::size_t num_local_work_items) { profilers_stop(); // Find the earliest start time and latest stop time over all profilers @@ -342,8 +342,8 @@ void profiler_output(double threshold, cell_size_type num_local_cells, int num_s auto comm_rank = communication::global_policy::id(); bool print = comm_rank==0 ? true : false; - // calculate the throughput in terms of cell steps per second - auto local_throughput = num_local_cells*num_steps / wall_time; + // calculate the throughput in terms of work items per second + auto local_throughput = num_local_work_items / wall_time; auto global_throughput = communication::global_policy::sum(local_throughput); if(print) { @@ -401,7 +401,7 @@ void profiler_enter(const char*) {} void profiler_leave() {} void profiler_leave(int) {} void profilers_stop() {} -void profiler_output(double threshold, cell_size_type num_local_cells, int num_steps) {} +void profiler_output(double threshold, std::size_t num_local_work_items) {} void profilers_restart() {}; #endif diff --git a/src/profiling/profiler.hpp b/src/profiling/profiler.hpp index 0830f854a6fca9de3a75096dbec5c877a1c8f66c..a905416c49d295706bed32b7e0149948fa8f47d6 100644 --- a/src/profiling/profiler.hpp +++ b/src/profiling/profiler.hpp @@ -246,8 +246,7 @@ void profilers_stop(); void profilers_restart(); /// print the collated profiler to std::cout -//void profiler_output(double threshold); -void profiler_output(double threshold, cell_size_type num_local_cells, int num_steps); +void profiler_output(double threshold, std::size_t num_local_work_items); } // namespace util } // namespace mc diff --git a/tests/global_communication/mpi_listener.hpp b/tests/global_communication/mpi_listener.hpp index 159616dd85639710a9a79ecb8a3751e5977e5b84..a88aa68440a555949c6bd6ae3c68224cf6a40b0a 100644 --- a/tests/global_communication/mpi_listener.hpp +++ b/tests/global_communication/mpi_listener.hpp @@ -41,7 +41,9 @@ private: } void print(const char* s) { - fid_ << s; + if (fid_) { + fid_ << s; + } if (does_print()) { std::cout << s; } @@ -51,21 +53,27 @@ private: print(s.c_str()); } + /// convenience function that handles the logic of using snprintf + /// and forwarding the results to file and/or stdout. + /// + /// TODO : it might be an idea to use a resizeable buffer template <typename... Args> - void pprintf(const char* s, Args&&... args) { + void printf_helper(const char* s, Args&&... args) { snprintf(buffer_, sizeof(buffer_), s, std::forward<Args>(args)...); print(buffer_); } public: - - mpi_listener(std::string f_base) { + mpi_listener(std::string f_base="") { rank_ = nest::mc::communication::global_policy::id(); size_ = nest::mc::communication::global_policy::size(); + if (f_base.empty()) { + return; + } std::string fname = f_base + "_" + std::to_string(rank_) + ".txt"; fid_.open(fname); - if (!fid_.good()) { + if (!fid_) { throw std::runtime_error("could not open file " + fname + " for test output"); } } @@ -73,10 +81,10 @@ public: /// Messages that are printed at the start and end of the test program. /// i.e. once only. virtual void OnTestProgramStart(const UnitTest&) override { - pprintf("*** test output for rank %d of %d\n\n", rank_, size_); + printf_helper("*** test output for rank %d of %d\n\n", rank_, size_); } virtual void OnTestProgramEnd(const UnitTest&) override { - pprintf("*** end test output for rank %d of %d\n", rank_, size_); + printf_helper("*** end test output for rank %d of %d\n", rank_, size_); } /// Messages that are printed at the start and end of each test case. @@ -88,7 +96,7 @@ public: test_case_tests_ = 0; } virtual void OnTestCaseEnd(const TestCase& test_case) override { - pprintf( + printf_helper( "[PASSED %3d; FAILED %3d] of %3d tests in %s\n\n", test_case_tests_-test_case_failures_, test_case_failures_, @@ -99,7 +107,7 @@ public: // Called before a test starts. virtual void OnTestStart(const TestInfo& test_info) override { - pprintf( " TEST %s::%s\n", test_info.test_case_name(), test_info.name()); + printf_helper( " TEST %s::%s\n", test_info.test_case_name(), test_info.name()); test_failures_ = 0; } @@ -115,7 +123,7 @@ public: pos = summary.find("\n", pos+1); } - pprintf( + printf_helper( " LOCAL_%s\n %s\n %s:%d\n%s\n %s\n", test_part_result.failed() ? "FAIL" : "SUCCESS", banner, @@ -140,7 +148,7 @@ public: nest::mc::communication::global_policy::sum(test_failures_>0 ? 1 : 0); if (global_errors>0) { test_case_failures_++; - pprintf(" GLOBAL_FAIL on %d ranks\n", global_errors); + printf_helper(" GLOBAL_FAIL on %d ranks\n", global_errors); } } }; diff --git a/tests/global_communication/test.cpp b/tests/global_communication/test.cpp index 640e4006973db9e65251e55b76132bbc8b908eea..1ddb6d41baf5d84cefc5b7f4e542a7cf79d2598c 100644 --- a/tests/global_communication/test.cpp +++ b/tests/global_communication/test.cpp @@ -11,22 +11,22 @@ #include <communication/global_policy.hpp> #include <util/ioutil.hpp> -using namespace nest; +using namespace nest::mc; int main(int argc, char **argv) { // We need to set the communicator policy at the top level // this allows us to build multiple communicators in the tests - mc::communication::global_policy_guard global_guard(argc, argv); + communication::global_policy_guard global_guard(argc, argv); // initialize google test environment - ::testing::InitGoogleTest(&argc, argv); + testing::InitGoogleTest(&argc, argv); // set up a custom listener that prints messages in an MPI-friendly way auto& listeners = testing::UnitTest::GetInstance()->listeners(); // first delete the original printer delete listeners.Release(listeners.default_result_printer()); // now add our custom printer - listeners.Append(new mpi_listener("global_comms")); + listeners.Append(new mpi_listener("results_global_communication")); // record the local return value for tests run on this mpi rank // 0 : success @@ -35,5 +35,5 @@ int main(int argc, char **argv) { // perform global collective, to ensure that all ranks return // the same exit code - return mc::communication::global_policy::max(result); + return communication::global_policy::max(result); } diff --git a/tests/global_communication/test_communicator.cpp b/tests/global_communication/test_communicator.cpp index 1b50e1b037e70146272e8f3c2737ef45c50505b9..f79d4e2d6e42b382bc4b54e16d29187ea531b7c0 100644 --- a/tests/global_communication/test_communicator.cpp +++ b/tests/global_communication/test_communicator.cpp @@ -15,4 +15,21 @@ using time_type = float; using communicator_type = communication::communicator<time_type, communication::global_policy>; TEST(communicator, setup) { + /* + using policy = communication::global_policy; + + auto num_domains = policy::size(); + auto rank = policy::id(); + + auto counts = policy.gather_all(1); + EXPECT_EQ(counts.size(), unsigned(num_domains)); + for(auto i : counts) { + EXPECT_EQ(i, 1); + } + + auto part = util::parition_view(counts); + for(auto p : part) { + EXPECT_EQ(p.second-p.first, 1); + } + */ } diff --git a/tests/unit/test_algorithms.cpp b/tests/unit/test_algorithms.cpp index 9d370ddaf47c94fda470c01719a5c1989e5b766d..e00da203627a6906ce8be99f435709ad9a09a1d2 100644 --- a/tests/unit/test_algorithms.cpp +++ b/tests/unit/test_algorithms.cpp @@ -14,8 +14,8 @@ TEST(algorithms, parallel_sort) std::vector<int> v(n); std::iota(v.begin(), v.end(), 1); - std::random_device rd; - std::shuffle(v.begin(), v.end(), std::mt19937(rd())); + // intialize with the default random seed + std::shuffle(v.begin(), v.end(), std::mt19937()); // assert that the original vector has in fact been permuted EXPECT_FALSE(std::is_sorted(v.begin(), v.end()));