Commit c967f13d authored by Paul Schütze's avatar Paul Schütze
Browse files

Merge branch 'threadpool_singlethreaded' into 'master'

Threadpool: Always call initialize/finalizeThread

See merge request allpix-squared/allpix-squared!584
parents 5602a16e 75448b47
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -243,10 +243,10 @@ In addition to the constructor, each module can override the following methods:
\begin{itemize}
\item \parameter{initialize()}: Called once per module from the main thread after loading and constructing all modules and before starting the event loop.
This method can for example be used to initialize histograms.
\item \parameter{initializeThread()}: Called after global initialization but before event processing and gives the possibility to initialize worker thread-specific members for modules if multithreading is used.
\item \parameter{initializeThread()}: Called after global initialization but before event processing and gives the possibility to initialize worker thread-specific members for modules. If multithreading is used, this method is called by each worker thread separately; if the simulation is run single-threaded, it is called once by the main thread.
\item \parameter{run(Event* event)}: Called for every event in the simulation, with a pointer to the current event object as parameter.
An exception should be thrown for serious errors, otherwise a warning should be logged.
\item \parameter{finalizeThread()}: Called for each worker thread after processing all events in the run by each worker thread separately if multithreading is used.
\item \parameter{finalizeThread()}: Called for each worker thread after processing all events in the run. If multithreading is used, this method is called by each worker thread separately; if the simulation is run single-threaded, it is called once by the main thread.
\item \parameter{finalize()}: Called once per module from the main thread after processing all events in the run and before destructing the module.
Typically used to save the output data (like histograms).
Any exceptions should be thrown from here instead of the destructor.
+13 −0
Original line number Diff line number Diff line
@@ -47,6 +47,14 @@ ThreadPool::ThreadPool(unsigned int num_threads,
                                  worker_init_function,
                                  worker_finalize_function);
        }

        // When running single-threadedly, execute initialize function directly and store finalize function for later
        if(threads_.empty()) {
            if(worker_init_function) {
                worker_init_function();
            }
            finalize_function_ = worker_finalize_function;
        }
    } catch(...) {
        destroy();
        throw;
@@ -149,6 +157,11 @@ void ThreadPool::destroy() {
            thread.join();
        }
    }

    // Execute the cleanup function at the end of run if running single-threaded
    if(threads_.empty() && finalize_function_) {
        finalize_function_();
    }
}

bool ThreadPool::valid() {
+1 −0
Original line number Diff line number Diff line
@@ -270,6 +270,7 @@ namespace allpix {
        using Task = std::unique_ptr<std::packaged_task<void()>>;
        SafeQueue<Task> queue_;
        bool with_buffered_{true};
        std::function<void()> finalize_function_{};

        std::atomic_bool done_{false};

+5 −13
Original line number Diff line number Diff line
@@ -152,24 +152,16 @@ void DepositionCosmicsModule::initialize_g4_action() {
}

void DepositionCosmicsModule::finalizeThread() {
    {
    // Call base class thread finalization:
    DepositionGeant4Module::finalizeThread();

    LOG(DEBUG) << "CRY instance reports simulation time of "
               << Units::display(cry_instance_time_simulated_, {"us", "ms", "s"});
    std::lock_guard<std::mutex> lock{stats_mutex_};
    total_time_simulated_ += cry_instance_time_simulated_;
}

    // Call base class thread finalization:
    DepositionGeant4Module::finalizeThread();
}

void DepositionCosmicsModule::finalize() {

    // Without multithreading we need to fetch the total simulation time from the main thread:
    if(!multithreadingEnabled()) {
        total_time_simulated_ = cry_instance_time_simulated_;
    }

    LOG(STATUS) << "Total simulated time in CRY: " << Units::display(total_time_simulated_, {"us", "ms", "s"});

    // Call base class finalization:
+4 −7
Original line number Diff line number Diff line
@@ -341,11 +341,6 @@ void DepositionGeant4Module::finalize() {
        }
    }

    // Record the number of sensors and the total charges
    if(!multithreadingEnabled()) {
        record_module_statistics();
    }

    // Print summary or warns if module did not output any charges
    if(number_of_sensors_ > 0 && total_charges_ > 0 && last_event_num_ > 0) {
        size_t average_charge = total_charges_ / number_of_sensors_ / last_event_num_;
@@ -360,9 +355,11 @@ void DepositionGeant4Module::finalizeThread() {
    // Record the number of sensors and the total charges
    record_module_statistics();

    if(multithreadingEnabled()) {
        auto* run_manager_mt = static_cast<MTRunManager*>(run_manager_g4_);
        run_manager_mt->TerminateForThread();
    }
}

void DepositionGeant4Module::construct_sensitive_detectors_and_fields(double fano_factor,
                                                                      double charge_creation_energy,