#include "constants.h" #include "client.h" #include "boundary.h" #include "modal.h" #include "pursuit.h" namespace EPP { void MATLAB_Pursuer::start( MATLAB_Sample sample, Parameters parameters) noexcept { _result = std::shared_ptr(new Result); _result->begin = std::chrono::steady_clock::now(); _result->qualified.clear(); _result->projections = 0; _result->passes = 0; _result->clusters = 0; _result->graphs = 0; _result->candidates.reserve(parameters.finalists); for (int measurement = 0; measurement < sample.measurements; ++measurement) if (parameters.censor.empty() || !parameters.censor.at(measurement)) Worker::enqueue(new QualifyMeasurement(sample, parameters, measurement)); // Worker::work_list.push( // new QualifyMeasurement(sample, parameters, measurement)); // Worker::work_available.notify_all(); if (threads == 0) { std::unique_lock lock(mutex); while (!Worker::work_list.empty()) { Work *work = Worker::work_list.front(); Worker::work_list.pop(); lock.unlock(); work->parallel(); lock.lock(); work->serial(); delete work; } } } void MATLAB_Pursuer::start( const unsigned short int measurements, const unsigned long int events, const float *const data, std::vector &subset) noexcept { MATLAB_Sample sample(measurements, events, data, subset); start(sample, Default); } void MATLAB_Pursuer::start( const unsigned short int measurements, const unsigned long int events, const float *const data) noexcept { MATLAB_Sample sample(measurements, events, data); start(sample, Default); } bool MATLAB_Pursuer::finished() noexcept { std::unique_lock lock(EPP::mutex); return !EPP::work_outstanding; } void MATLAB_Pursuer::wait() noexcept { std::unique_lock lock(EPP::mutex); while (EPP::work_outstanding) EPP::work_completed.wait(lock); } std::shared_ptr MATLAB_Pursuer::result() noexcept { wait(); _result->end = std::chrono::steady_clock::now(); _result->milliseconds = std::chrono::duration_cast(_result->end - _result->begin); return _result; } std::shared_ptr MATLAB_Pursuer::pursue( const unsigned short int measurements, const unsigned long int events, const float *const data, std::vector &subset) noexcept { start(measurements, events, data, subset); return result(); } std::shared_ptr MATLAB_Pursuer::pursue( const unsigned short int measurements, const unsigned long int events, const float *const data) noexcept { start(measurements, events, data); return result(); }; MATLAB_Pursuer::MATLAB_Pursuer(int threads) noexcept : threads(threads < 0 ? std::thread::hardware_concurrency() : threads) { // start some worker threads Worker::kiss_of_death = false; workers = new std::thread[threads]; for (int i = 0; i < threads; i++) workers[i] = std::thread( []() { EPP::Worker worker; }); } MATLAB_Pursuer::MATLAB_Pursuer() noexcept : MATLAB_Pursuer(std::thread::hardware_concurrency()){}; MATLAB_Pursuer::~MATLAB_Pursuer() { // tell the workers to exit and wait for them to shut down EPP::Worker::kiss_of_death = true; { std::unique_lock lock(EPP::mutex); EPP::Worker::work_available.notify_all(); } for (int i = 0; i < threads; i++) workers[i].join(); delete[] workers; _result.reset(); } }