From d7da87ca1d98e6dc867e4af7c38dc9f56b031349 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 12 Oct 2018 07:03:20 -0500 Subject: [PATCH] Write C++ version of Timer class and use in synchronize_bank --- CMakeLists.txt | 1 + include/openmc/timer.h | 47 +++++++++++++++++++++++++++++++++ src/api.F90 | 4 +-- src/eigenvalue.cpp | 12 ++++++--- src/output.F90 | 6 ++--- src/simulation.F90 | 2 -- src/state_point.F90 | 6 ++--- src/timer.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++ src/timer_header.F90 | 22 +++++++++++++--- 9 files changed, 142 insertions(+), 18 deletions(-) create mode 100644 include/openmc/timer.h create mode 100644 src/timer.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 99d4e4a5ef..84f21427ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -443,6 +443,7 @@ add_library(libopenmc SHARED src/string_functions.cpp src/summary.cpp src/surface.cpp + src/timer.cpp src/thermal.cpp src/xml_interface.cpp src/xsdata.cpp diff --git a/include/openmc/timer.h b/include/openmc/timer.h new file mode 100644 index 0000000000..11dfd1adfe --- /dev/null +++ b/include/openmc/timer.h @@ -0,0 +1,47 @@ +#ifndef OPENMC_TIMER_H +#define OPENMC_TIMER_H + +#include + +namespace openmc { + +//============================================================================== +//! Class for measuring time elapsed +//============================================================================== + +class Timer { +public: + using clock = std::chrono::high_resolution_clock; + + Timer() {}; + + //! Start running the timer + void start (); + + //! Get total elapsed time in seconds + //! \return Elapsed time in [s] + double elapsed(); + + //! Stop running the timer + void stop(); + + //! Stop the timer and reset its elapsed time + void reset(); + +private: + bool running_ {false}; //!< is timer running? + std::chrono::time_point start_; //!< starting point for clock + double elapsed_; //!< elasped time in [s] +}; + +//============================================================================== +// Global variables +//============================================================================== + +extern Timer time_bank; +extern Timer time_bank_sample; +extern Timer time_bank_sendrecv; + +} // namespace openmc + +#endif // OPENMC_TIMER_H diff --git a/src/api.F90 b/src/api.F90 index d79aa24508..18162e6009 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -276,14 +276,12 @@ contains call time_initialize % reset() call time_read_xs % reset() call time_unionize % reset() - call time_bank % reset() - call time_bank_sample % reset() - call time_bank_sendrecv % reset() call time_tallies % reset() call time_inactive % reset() call time_active % reset() call time_transport % reset() call time_finalize % reset() + call reset_timers() err = 0 end function openmc_reset diff --git a/src/eigenvalue.cpp b/src/eigenvalue.cpp index 459204ea36..ba3ebfae54 100644 --- a/src/eigenvalue.cpp +++ b/src/eigenvalue.cpp @@ -13,6 +13,7 @@ #include "openmc/search.h" #include "openmc/settings.h" #include "openmc/simulation.h" +#include "openmc/timer.h" #include // for min #include @@ -32,6 +33,8 @@ xt::xtensor source_frac; void synchronize_bank() { + time_bank.start(); + // Get pointers to source/fission bank Bank* source_bank; Bank* fission_bank; @@ -94,7 +97,7 @@ void synchronize_bank() } double p_sample = static_cast(sites_needed) / total; - //time_bank_sample % start() + time_bank_sample.start(); // ========================================================================== // SAMPLE N_PARTICLES FROM FISSION BANK AND PLACE IN TEMP_SITES @@ -167,8 +170,8 @@ void synchronize_bank() finish = simulation::work_index[mpi::rank + 1]; } - //time_bank_sample % stop() - //time_bank_sendrecv % start() + time_bank_sample.stop(); + time_bank_sendrecv.start(); #ifdef OPENMC_MPI // ========================================================================== @@ -266,7 +269,8 @@ void synchronize_bank() std::copy(temp_sites, temp_sites + settings::n_particles, source_bank); #endif - //time_bank_sendrecv % stop() + time_bank_sendrecv.stop(); + time_bank.stop(); } void shannon_entropy() diff --git a/src/output.F90 b/src/output.F90 index 4363731f09..0511675116 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -511,9 +511,9 @@ contains end if write(ou,100) " Time in active batches", time_active % elapsed if (run_mode == MODE_EIGENVALUE) then - write(ou,100) " Time synchronizing fission bank", time_bank % elapsed - write(ou,100) " Sampling source sites", time_bank_sample % elapsed - write(ou,100) " SEND/RECV source sites", time_bank_sendrecv % elapsed + write(ou,100) " Time synchronizing fission bank", time_bank_elapsed() + write(ou,100) " Sampling source sites", time_bank_sample_elapsed() + write(ou,100) " SEND/RECV source sites", time_bank_sendrecv_elapsed() end if write(ou,100) " Time accumulating tallies", time_tallies % elapsed if (cmfd_run) write(ou,100) " Time in CMFD", time_cmfd % elapsed diff --git a/src/simulation.F90 b/src/simulation.F90 index 2359306d20..4bbf94ed11 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -294,9 +294,7 @@ contains #endif ! Distribute fission bank across processors evenly - call time_bank % start() call synchronize_bank() - call time_bank % stop() ! Calculate shannon entropy if (entropy_on) call shannon_entropy() diff --git a/src/state_point.F90 b/src/state_point.F90 index 11e4ad6214..548db766c7 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -419,11 +419,11 @@ contains time_active % get_value()) if (run_mode == MODE_EIGENVALUE) then call write_dataset(runtime_group, "synchronizing fission bank", & - time_bank % get_value()) + time_bank_elapsed()) call write_dataset(runtime_group, "sampling source sites", & - time_bank_sample % get_value()) + time_bank_sample_elapsed()) call write_dataset(runtime_group, "SEND-RECV source sites", & - time_bank_sendrecv % get_value()) + time_bank_sendrecv_elapsed()) end if call write_dataset(runtime_group, "accumulating tallies", & time_tallies % get_value()) diff --git a/src/timer.cpp b/src/timer.cpp new file mode 100644 index 0000000000..85b1eb7717 --- /dev/null +++ b/src/timer.cpp @@ -0,0 +1,60 @@ +#include "openmc/timer.h" + +namespace openmc { + +//============================================================================== +// Timer implementation +//============================================================================== + +void Timer::start () +{ + running_ = true; + start_ = clock::now(); +} + +void Timer::stop() +{ + elapsed_ = elapsed(); + running_ = false; +} + +void Timer::reset() +{ + running_ = false; + elapsed_ = 0.0; +} + +double Timer::elapsed() +{ + if (running_) { + std::chrono::duration diff = clock::now() - start_; + return elapsed_ += diff.count(); + } else { + return elapsed_; + } +} + +//============================================================================== +// Global variables +//============================================================================== + +Timer time_bank; +Timer time_bank_sample; +Timer time_bank_sendrecv; + +//============================================================================== +// Fortran compatibility +//============================================================================== + +extern "C" double time_bank_elapsed() { return time_bank.elapsed(); } +extern "C" double time_bank_sample_elapsed() { return time_bank_sample.elapsed(); } +extern "C" double time_bank_sendrecv_elapsed() { return time_bank_sendrecv.elapsed(); } + +extern "C" void reset_timers() +{ + time_bank.reset(); + time_bank_sample.reset(); + time_bank_sendrecv.reset(); +} + +} // namespace openmc diff --git a/src/timer_header.F90 b/src/timer_header.F90 index a147a551df..1691546964 100644 --- a/src/timer_header.F90 +++ b/src/timer_header.F90 @@ -1,9 +1,28 @@ module timer_header + use, intrinsic :: ISO_C_BINDING + use constants, only: ZERO implicit none + interface + function time_bank_elapsed() result(t) bind(C) + import C_DOUBLE + real(C_DOUBLE) :: t + end function + function time_bank_sample_elapsed() result(t) bind(C) + import C_DOUBLE + real(C_DOUBLE) :: t + end function + function time_bank_sendrecv_elapsed() result(t) bind(C) + import C_DOUBLE + real(C_DOUBLE) :: t + end function + subroutine reset_timers() bind(C) + end subroutine + end interface + !=============================================================================== ! TIMER represents a timer that can be started and stopped to measure how long ! different routines run. The intrinsic routine system_clock is used to measure @@ -29,9 +48,6 @@ module timer_header type(Timer) :: time_initialize ! timer for initialization type(Timer) :: time_read_xs ! timer for reading cross sections type(Timer) :: time_unionize ! timer for material xs-energy grid union - type(Timer) :: time_bank ! timer for fission bank synchronization - type(Timer) :: time_bank_sample ! timer for fission bank sampling - type(Timer) :: time_bank_sendrecv ! timer for fission bank SEND/RECV type(Timer) :: time_tallies ! timer for accumulate tallies type(Timer) :: time_inactive ! timer for inactive batches type(Timer) :: time_active ! timer for active batches