-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Multi threaded cluster finder. (#115)
Added a prototype for the multi threaded cluster finder including python bindings
- Loading branch information
Showing
19 changed files
with
861 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#pragma once | ||
|
||
#include <chrono> | ||
#include <fmt/color.h> | ||
#include <fmt/format.h> | ||
#include <memory> | ||
#include <thread> | ||
|
||
#include "aare/ProducerConsumerQueue.hpp" | ||
|
||
namespace aare { | ||
|
||
template <class ItemType> class CircularFifo { | ||
uint32_t fifo_size; | ||
aare::ProducerConsumerQueue<ItemType> free_slots; | ||
aare::ProducerConsumerQueue<ItemType> filled_slots; | ||
|
||
public: | ||
CircularFifo() : CircularFifo(100){}; | ||
CircularFifo(uint32_t size) : fifo_size(size), free_slots(size + 1), filled_slots(size + 1) { | ||
|
||
// TODO! how do we deal with alignment for writing? alignas??? | ||
// Do we give the user a chance to provide memory locations? | ||
// Templated allocator? | ||
for (size_t i = 0; i < fifo_size; ++i) { | ||
free_slots.write(ItemType{}); | ||
} | ||
} | ||
|
||
bool next() { | ||
// TODO! avoid default constructing ItemType | ||
ItemType it; | ||
if (!filled_slots.read(it)) | ||
return false; | ||
if (!free_slots.write(std::move(it))) | ||
return false; | ||
return true; | ||
} | ||
|
||
~CircularFifo() {} | ||
|
||
using value_type = ItemType; | ||
|
||
auto numFilledSlots() const noexcept { return filled_slots.sizeGuess(); } | ||
auto numFreeSlots() const noexcept { return free_slots.sizeGuess(); } | ||
auto isFull() const noexcept { return filled_slots.isFull(); } | ||
|
||
ItemType pop_free() { | ||
ItemType v; | ||
while (!free_slots.read(v)) | ||
; | ||
return std::move(v); | ||
// return v; | ||
} | ||
|
||
bool try_pop_free(ItemType &v) { return free_slots.read(v); } | ||
|
||
ItemType pop_value(std::chrono::nanoseconds wait, std::atomic<bool> &stopped) { | ||
ItemType v; | ||
while (!filled_slots.read(v) && !stopped) { | ||
std::this_thread::sleep_for(wait); | ||
} | ||
return std::move(v); | ||
} | ||
|
||
ItemType pop_value() { | ||
ItemType v; | ||
while (!filled_slots.read(v)) | ||
; | ||
return std::move(v); | ||
} | ||
|
||
ItemType *frontPtr() { return filled_slots.frontPtr(); } | ||
|
||
// TODO! Add function to move item from filled to free to be used | ||
// with the frontPtr function | ||
|
||
template <class... Args> void push_value(Args &&...recordArgs) { | ||
while (!filled_slots.write(std::forward<Args>(recordArgs)...)) | ||
; | ||
} | ||
|
||
template <class... Args> bool try_push_value(Args &&...recordArgs) { | ||
return filled_slots.write(std::forward<Args>(recordArgs)...); | ||
} | ||
|
||
template <class... Args> void push_free(Args &&...recordArgs) { | ||
while (!free_slots.write(std::forward<Args>(recordArgs)...)) | ||
; | ||
} | ||
|
||
template <class... Args> bool try_push_free(Args &&...recordArgs) { | ||
return free_slots.write(std::forward<Args>(recordArgs)...); | ||
} | ||
}; | ||
|
||
} // namespace aare |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#pragma once | ||
#include <atomic> | ||
#include <thread> | ||
|
||
#include "aare/ProducerConsumerQueue.hpp" | ||
#include "aare/ClusterVector.hpp" | ||
#include "aare/ClusterFinderMT.hpp" | ||
|
||
namespace aare { | ||
|
||
class ClusterCollector{ | ||
ProducerConsumerQueue<ClusterVector<int>>* m_source; | ||
std::atomic<bool> m_stop_requested{false}; | ||
std::atomic<bool> m_stopped{true}; | ||
std::chrono::milliseconds m_default_wait{1}; | ||
std::thread m_thread; | ||
std::vector<ClusterVector<int>> m_clusters; | ||
|
||
void process(){ | ||
m_stopped = false; | ||
fmt::print("ClusterCollector started\n"); | ||
while (!m_stop_requested || !m_source->isEmpty()) { | ||
if (ClusterVector<int> *clusters = m_source->frontPtr(); | ||
clusters != nullptr) { | ||
m_clusters.push_back(std::move(*clusters)); | ||
m_source->popFront(); | ||
}else{ | ||
std::this_thread::sleep_for(m_default_wait); | ||
} | ||
} | ||
fmt::print("ClusterCollector stopped\n"); | ||
m_stopped = true; | ||
} | ||
|
||
public: | ||
ClusterCollector(ClusterFinderMT<uint16_t, double, int32_t>* source){ | ||
m_source = source->sink(); | ||
m_thread = std::thread(&ClusterCollector::process, this); | ||
} | ||
void stop(){ | ||
m_stop_requested = true; | ||
m_thread.join(); | ||
} | ||
std::vector<ClusterVector<int>> steal_clusters(){ | ||
if(!m_stopped){ | ||
throw std::runtime_error("ClusterCollector is still running"); | ||
} | ||
return std::move(m_clusters); | ||
} | ||
}; | ||
|
||
} // namespace aare |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#pragma once | ||
#include <atomic> | ||
#include <filesystem> | ||
#include <thread> | ||
|
||
#include "aare/ProducerConsumerQueue.hpp" | ||
#include "aare/ClusterVector.hpp" | ||
#include "aare/ClusterFinderMT.hpp" | ||
|
||
namespace aare{ | ||
|
||
class ClusterFileSink{ | ||
ProducerConsumerQueue<ClusterVector<int>>* m_source; | ||
std::atomic<bool> m_stop_requested{false}; | ||
std::atomic<bool> m_stopped{true}; | ||
std::chrono::milliseconds m_default_wait{1}; | ||
std::thread m_thread; | ||
std::ofstream m_file; | ||
|
||
|
||
void process(){ | ||
m_stopped = false; | ||
fmt::print("ClusterFileSink started\n"); | ||
while (!m_stop_requested || !m_source->isEmpty()) { | ||
if (ClusterVector<int> *clusters = m_source->frontPtr(); | ||
clusters != nullptr) { | ||
// Write clusters to file | ||
int32_t frame_number = clusters->frame_number(); //TODO! Should we store frame number already as int? | ||
uint32_t num_clusters = clusters->size(); | ||
m_file.write(reinterpret_cast<const char*>(&frame_number), sizeof(frame_number)); | ||
m_file.write(reinterpret_cast<const char*>(&num_clusters), sizeof(num_clusters)); | ||
m_file.write(reinterpret_cast<const char*>(clusters->data()), clusters->size() * clusters->item_size()); | ||
m_source->popFront(); | ||
}else{ | ||
std::this_thread::sleep_for(m_default_wait); | ||
} | ||
} | ||
fmt::print("ClusterFileSink stopped\n"); | ||
m_stopped = true; | ||
} | ||
|
||
public: | ||
ClusterFileSink(ClusterFinderMT<uint16_t, double, int32_t>* source, const std::filesystem::path& fname){ | ||
m_source = source->sink(); | ||
m_thread = std::thread(&ClusterFileSink::process, this); | ||
m_file.open(fname, std::ios::binary); | ||
} | ||
void stop(){ | ||
m_stop_requested = true; | ||
m_thread.join(); | ||
m_file.close(); | ||
} | ||
}; | ||
|
||
|
||
} // namespace aare |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.