diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index cc323f9..37f3857 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -11,9 +11,13 @@ jobs: # find all examples in build/examples and run them run: | pwd - find -name "*.cpp" -not -path "./build/*" | xargs -I {} -n 1 -P 10 clang-format {} -Werror --dry-run -style='file:.clang-format' + mkdir build + cd build + cmake .. + cmake --build . --target=check-format + diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c1c349..d330d16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,3 +164,22 @@ add_subdirectory(examples) if(AARE_PYTHON_BINDINGS) add_subdirectory(python) endif() + + +# custom target to run check formatting with clang-format +add_custom_target( + check-format + COMMAND find \( -name "*.cpp" -o -name "*.hpp" \) -not -path "./build/*" | xargs -I {} -n 1 -P 10 bash -c "clang-format -Werror -style=\"file:.clang-format\" {} | diff {} -" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Checking code formatting with clang-format" + VERBATIM + +) + +add_custom_target( + format-files + COMMAND find \( -name "*.cpp" -o -name "*.hpp" \) -not -path "./build/*" | xargs -I {} -n 1 -P 10 bash -c "clang-format -i -style=\"file:.clang-format\" {}" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Formatting with clang-format" + VERBATIM +) \ No newline at end of file diff --git a/core/include/aare/CircularFifo.hpp b/core/include/aare/CircularFifo.hpp index 9c01b9a..0684737 100644 --- a/core/include/aare/CircularFifo.hpp +++ b/core/include/aare/CircularFifo.hpp @@ -14,29 +14,27 @@ template class CircularFifo { uint32_t fifo_size; folly::ProducerConsumerQueue free_slots; folly::ProducerConsumerQueue filled_slots; - + public: CircularFifo() : CircularFifo(100){}; - CircularFifo(uint32_t size) - : fifo_size(size), free_slots(size+1), filled_slots(size+1) { + 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? + // 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; - + 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() {} @@ -47,66 +45,53 @@ template class CircularFifo { 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 &stopped) { - ItemType v; - while (!filled_slots.read(v) && !stopped) { - std::this_thread::sleep_for(wait); + ItemType pop_free() { + ItemType v; + while (!free_slots.read(v)) + ; + return std::move(v); + // return v; } - return std::move(v); -} -ItemType pop_value() { - ItemType v; - while (!filled_slots.read(v)) - ; - return std::move(v); -} + bool try_pop_free(ItemType &v) { return free_slots.read(v); } -ItemType* frontPtr(){ - return filled_slots.frontPtr(); -} + ItemType pop_value(std::chrono::nanoseconds wait, std::atomic &stopped) { + ItemType v; + while (!filled_slots.read(v) && !stopped) { + std::this_thread::sleep_for(wait); + } + return std::move(v); + } -// TODO! Add function to move item from filled to free to be used -// with the frontPtr function + ItemType pop_value() { + ItemType v; + while (!filled_slots.read(v)) + ; + return std::move(v); + } + ItemType *frontPtr() { return filled_slots.frontPtr(); } -template -void push_value(Args&&... recordArgs) { - while (!filled_slots.write(std::forward(recordArgs)...)) - ; -} + // TODO! Add function to move item from filled to free to be used + // with the frontPtr function -template -bool try_push_value(Args&&... recordArgs) { - return filled_slots.write(std::forward(recordArgs)...); + template void push_value(Args &&...recordArgs) { + while (!filled_slots.write(std::forward(recordArgs)...)) + ; + } -} + template bool try_push_value(Args &&...recordArgs) { + return filled_slots.write(std::forward(recordArgs)...); + } -template -void push_free(Args&&... recordArgs) { - while (!free_slots.write(std::forward(recordArgs)...)) - ; -} - -template -bool try_push_free(Args&&... recordArgs) { - return free_slots.write(std::forward(recordArgs)...); - -} + template void push_free(Args &&...recordArgs) { + while (!free_slots.write(std::forward(recordArgs)...)) + ; + } + template bool try_push_free(Args &&...recordArgs) { + return free_slots.write(std::forward(recordArgs)...); + } }; } // namespace aare \ No newline at end of file diff --git a/core/include/aare/DType.hpp b/core/include/aare/DType.hpp index cca5a0d..9a696fb 100644 --- a/core/include/aare/DType.hpp +++ b/core/include/aare/DType.hpp @@ -19,7 +19,7 @@ enum class endian { }; class DType { - //TODO! support for non native endianess? + // TODO! support for non native endianess? static_assert(sizeof(long) == sizeof(int64_t), "long should be 64bits"); public: diff --git a/core/include/aare/Frame.hpp b/core/include/aare/Frame.hpp index 211e4dc..e785fc2 100644 --- a/core/include/aare/Frame.hpp +++ b/core/include/aare/Frame.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -27,15 +26,13 @@ class Frame { Frame(std::byte *fp, ssize_t rows, ssize_t cols, ssize_t m_bitdepth); std::byte *get(int row, int col); - - //TODO! can we, or even want to remove the template? - template - void set(int row, int col, T data) { - assert(sizeof(T) == m_bitdepth/8); + // TODO! can we, or even want to remove the template? + template void set(int row, int col, T data) { + assert(sizeof(T) == m_bitdepth / 8); if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) { throw std::out_of_range("Invalid row or column index"); } - std::memcpy(m_data+(row*m_cols + col)*(m_bitdepth/8), &data, m_bitdepth/8); + std::memcpy(m_data + (row * m_cols + col) * (m_bitdepth / 8), &data, m_bitdepth / 8); } ssize_t rows() const { return m_rows; } @@ -43,7 +40,7 @@ class Frame { ssize_t bitdepth() const { return m_bitdepth; } ssize_t size() const { return m_rows * m_cols * m_bitdepth / 8; } std::byte *data() const { return m_data; } - + Frame &operator=(Frame &other) { m_rows = other.rows(); m_cols = other.cols(); @@ -62,20 +59,15 @@ class Frame { other.m_rows = other.m_cols = other.m_bitdepth = 0; } - template - NDView view() { + template NDView view() { std::vector shape = {m_rows, m_cols}; - T* data = reinterpret_cast(m_data); + T *data = reinterpret_cast(m_data); return NDView(data, shape); } - template - NDArray image() { - return NDArray(this->view()); - } + template NDArray image() { return NDArray(this->view()); } ~Frame() { delete[] m_data; } }; - } // namespace aare \ No newline at end of file diff --git a/core/include/aare/NDArray.hpp b/core/include/aare/NDArray.hpp index 284c4bf..b394763 100644 --- a/core/include/aare/NDArray.hpp +++ b/core/include/aare/NDArray.hpp @@ -22,31 +22,24 @@ namespace aare { template class NDArray { public: - NDArray() - : shape_(), strides_(c_strides(shape_)), size_(0), - data_(nullptr){}; + NDArray() : shape_(), strides_(c_strides(shape_)), size_(0), data_(nullptr){}; explicit NDArray(std::array shape) : shape_(shape), strides_(c_strides(shape_)), - size_(std::accumulate(shape_.begin(), shape_.end(), 1, - std::multiplies())), - data_(new T[size_]){}; + size_(std::accumulate(shape_.begin(), shape_.end(), 1, std::multiplies())), data_(new T[size_]){}; - NDArray(std::array shape, T value) : NDArray(shape) { - this->operator=(value); - } + NDArray(std::array shape, T value) : NDArray(shape) { this->operator=(value); } /* When constructing from a NDView we need to copy the data since NDArray expect to own its data, and span is just a view*/ - NDArray(NDView span):NDArray(span.shape()){ + NDArray(NDView span) : NDArray(span.shape()) { std::copy(span.begin(), span.end(), begin()); // fmt::print("NDArray(NDView span)\n"); } // Move constructor NDArray(NDArray &&other) - : shape_(other.shape_), strides_(c_strides(shape_)), - size_(other.size_), data_(nullptr) { + : shape_(other.shape_), strides_(c_strides(shape_)), size_(other.size_), data_(nullptr) { data_ = other.data_; other.reset(); // fmt::print("NDArray(NDArray &&other)\n"); @@ -54,20 +47,17 @@ template class NDArray { // Copy constructor NDArray(const NDArray &other) - : shape_(other.shape_), strides_(c_strides(shape_)), - size_(other.size_), data_(new T[size_]) { + : shape_(other.shape_), strides_(c_strides(shape_)), size_(other.size_), data_(new T[size_]) { std::copy(other.data_, other.data_ + size_, data_); // fmt::print("NDArray(const NDArray &other)\n"); } - ~NDArray() { - delete[] data_; - } + ~NDArray() { delete[] data_; } auto begin() { return data_; } auto end() { return data_ + size_; } - using value_type = T; + using value_type = T; NDArray &operator=(NDArray &&other); // Move assign NDArray &operator=(const NDArray &other); // Copy assign @@ -80,8 +70,7 @@ template class NDArray { NDArray &operator*=(const NDArray &other); NDArray operator/(const NDArray &other); // NDArray& operator/=(const NDArray& other); - template - NDArray &operator/=(const NDArray &other) { + template NDArray &operator/=(const NDArray &other) { // check shape if (shape_ == other.shape()) { for (int i = 0; i < size_; ++i) { @@ -118,21 +107,15 @@ template class NDArray { NDArray &operator++(); // pre inc - template - typename std::enable_if::type - operator()(Ix... index) { + template typename std::enable_if::type operator()(Ix... index) { return data_[element_offset(strides_, index...)]; } - template - typename std::enable_if::type - operator()(Ix... index) const{ + template typename std::enable_if::type operator()(Ix... index) const { return data_[element_offset(strides_, index...)]; } - - template - typename std::enable_if::type value(Ix... index) { + template typename std::enable_if::type value(Ix... index) { return data_[element_offset(strides_, index...)]; } @@ -142,7 +125,7 @@ template class NDArray { T *data() { return data_; } std::byte *buffer() { return reinterpret_cast(data_); } ssize_t size() const { return size_; } - size_t total_bytes() const {return size_*sizeof(T);} + size_t total_bytes() const { return size_ * sizeof(T); } std::array shape() const noexcept { return shape_; } ssize_t shape(ssize_t i) const noexcept { return shape_[i]; } std::array strides() const noexcept { return strides_; } @@ -175,8 +158,7 @@ template class NDArray { }; // Move assign -template -NDArray &NDArray::operator=(NDArray &&other) { +template NDArray &NDArray::operator=(NDArray &&other) { if (this != &other) { delete[] data_; data_ = other.data_; @@ -188,15 +170,12 @@ NDArray &NDArray::operator=(NDArray &&other) { return *this; } -template -NDArray NDArray::operator+(const NDArray &other) { +template NDArray NDArray::operator+(const NDArray &other) { NDArray result(*this); result += other; return result; } -template -NDArray & -NDArray::operator+=(const NDArray &other) { +template NDArray &NDArray::operator+=(const NDArray &other) { // check shape if (shape_ == other.shape_) { for (int i = 0; i < size_; ++i) { @@ -208,16 +187,13 @@ NDArray::operator+=(const NDArray &other) { } } -template -NDArray NDArray::operator-(const NDArray &other) { +template NDArray NDArray::operator-(const NDArray &other) { NDArray result{*this}; result -= other; return result; } -template -NDArray & -NDArray::operator-=(const NDArray &other) { +template NDArray &NDArray::operator-=(const NDArray &other) { // check shape if (shape_ == other.shape_) { for (int i = 0; i < size_; ++i) { @@ -228,16 +204,13 @@ NDArray::operator-=(const NDArray &other) { throw(std::runtime_error("Shape of ImageDatas must match")); } } -template -NDArray NDArray::operator*(const NDArray &other) { +template NDArray NDArray::operator*(const NDArray &other) { NDArray result = *this; result *= other; return result; } -template -NDArray & -NDArray::operator*=(const NDArray &other) { +template NDArray &NDArray::operator*=(const NDArray &other) { // check shape if (shape_ == other.shape_) { for (int i = 0; i < size_; ++i) { @@ -249,15 +222,13 @@ NDArray::operator*=(const NDArray &other) { } } -template -NDArray NDArray::operator/(const NDArray &other) { +template NDArray NDArray::operator/(const NDArray &other) { NDArray result = *this; result /= other; return result; } -template -NDArray &NDArray::operator&=(const T &mask) { +template NDArray &NDArray::operator&=(const T &mask) { for (auto it = begin(); it != end(); ++it) *it &= mask; return *this; @@ -278,8 +249,7 @@ NDArray &NDArray::operator&=(const T &mask) { // } // } -template -NDArray NDArray::operator>(const NDArray &other) { +template NDArray NDArray::operator>(const NDArray &other) { if (shape_ == other.shape_) { NDArray result{shape_}; for (int i = 0; i < size_; ++i) { @@ -291,9 +261,7 @@ NDArray NDArray::operator>(const NDArray &other) { } } -template -NDArray & -NDArray::operator=(const NDArray &other) { +template NDArray &NDArray::operator=(const NDArray &other) { if (this != &other) { delete[] data_; shape_ = other.shape_; @@ -305,8 +273,7 @@ NDArray::operator=(const NDArray &other) { return *this; } -template -bool NDArray::operator==(const NDArray &other) const { +template bool NDArray::operator==(const NDArray &other) const { if (shape_ != other.shape_) return false; @@ -317,68 +284,57 @@ bool NDArray::operator==(const NDArray &other) const { return true; } -template -bool NDArray::operator!=(const NDArray &other) const { +template bool NDArray::operator!=(const NDArray &other) const { return !((*this) == other); } -template -NDArray &NDArray::operator++() { +template NDArray &NDArray::operator++() { for (int i = 0; i < size_; ++i) data_[i] += 1; return *this; } -template -NDArray &NDArray::operator=(const T &value) { +template NDArray &NDArray::operator=(const T &value) { std::fill_n(data_, size_, value); return *this; } -template -NDArray &NDArray::operator+=(const T &value) { +template NDArray &NDArray::operator+=(const T &value) { for (int i = 0; i < size_; ++i) data_[i] += value; return *this; } -template -NDArray NDArray::operator+(const T &value) { +template NDArray NDArray::operator+(const T &value) { NDArray result = *this; result += value; return result; } -template -NDArray &NDArray::operator-=(const T &value) { +template NDArray &NDArray::operator-=(const T &value) { for (int i = 0; i < size_; ++i) data_[i] -= value; return *this; } -template -NDArray NDArray::operator-(const T &value) { +template NDArray NDArray::operator-(const T &value) { NDArray result = *this; result -= value; return result; } -template -NDArray &NDArray::operator/=(const T &value) { +template NDArray &NDArray::operator/=(const T &value) { for (int i = 0; i < size_; ++i) data_[i] /= value; return *this; } -template -NDArray NDArray::operator/(const T &value) { +template NDArray NDArray::operator/(const T &value) { NDArray result = *this; result /= value; return result; } -template -NDArray &NDArray::operator*=(const T &value) { +template NDArray &NDArray::operator*=(const T &value) { for (int i = 0; i < size_; ++i) data_[i] *= value; return *this; } -template -NDArray NDArray::operator*(const T &value) { +template NDArray NDArray::operator*(const T &value) { NDArray result = *this; result *= value; return result; @@ -408,8 +364,7 @@ template void NDArray::Print_some() { } } -template -void save(NDArray &img, std::string pathname) { +template void save(NDArray &img, std::string pathname) { std::ofstream f; f.open(pathname, std::ios::binary); f.write(img.buffer(), img.size() * sizeof(T)); @@ -417,8 +372,7 @@ void save(NDArray &img, std::string pathname) { } template -NDArray load(const std::string &pathname, - std::array shape) { +NDArray load(const std::string &pathname, std::array shape) { NDArray img{shape}; std::ifstream f; f.open(pathname, std::ios::binary); @@ -427,5 +381,4 @@ NDArray load(const std::string &pathname, return img; } - } // namespace aare \ No newline at end of file diff --git a/core/include/aare/NDView.hpp b/core/include/aare/NDView.hpp index 3a493fb..5a1525b 100644 --- a/core/include/aare/NDView.hpp +++ b/core/include/aare/NDView.hpp @@ -4,17 +4,16 @@ #include #include #include -#include #include +#include namespace aare { template using Shape = std::array; -//TODO! fix mismatch between signed and unsigned -template -Shape make_shape(const std::vector& shape){ - if(shape.size() != Ndim) +// TODO! fix mismatch between signed and unsigned +template Shape make_shape(const std::vector &shape) { + if (shape.size() != Ndim) throw std::runtime_error("Shape size mismatch"); Shape arr; std::copy_n(shape.begin(), Ndim, arr.begin()); @@ -44,11 +43,11 @@ template std::array make_array(const std::vector class NDView { +template class NDView { public: NDView(){}; - NDView(T* buffer, std::array shape) { + NDView(T *buffer, std::array shape) { buffer_ = buffer; strides_ = c_strides(shape); shape_ = shape; @@ -60,7 +59,6 @@ template class NDView { strides_ = c_strides(make_array(shape)); shape_ = make_array(shape); size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies()); - } template typename std::enable_if::type operator()(Ix... index) { diff --git a/core/include/aare/ProducerConsumerQueue.hpp b/core/include/aare/ProducerConsumerQueue.hpp index b10c327..0ac71df 100644 --- a/core/include/aare/ProducerConsumerQueue.hpp +++ b/core/include/aare/ProducerConsumerQueue.hpp @@ -31,158 +31,151 @@ #include #include -constexpr std::size_t hardware_destructive_interference_size = 128; +constexpr std::size_t hardware_destructive_interference_size = 128; namespace folly { /* * ProducerConsumerQueue is a one producer and one consumer queue * without locks. */ -template -struct ProducerConsumerQueue { - typedef T value_type; +template struct ProducerConsumerQueue { + typedef T value_type; - ProducerConsumerQueue(const ProducerConsumerQueue&) = delete; - ProducerConsumerQueue& operator=(const ProducerConsumerQueue&) = delete; + ProducerConsumerQueue(const ProducerConsumerQueue &) = delete; + ProducerConsumerQueue &operator=(const ProducerConsumerQueue &) = delete; - // size must be >= 2. - // - // Also, note that the number of usable slots in the queue at any - // given time is actually (size-1), so if you start with an empty queue, - // isFull() will return true after size-1 insertions. - explicit ProducerConsumerQueue(uint32_t size) - : size_(size), - records_(static_cast(std::malloc(sizeof(T) * size))), - readIndex_(0), - writeIndex_(0) { - assert(size >= 2); - if (!records_) { - throw std::bad_alloc(); - } - } - - ~ProducerConsumerQueue() { - // We need to destruct anything that may still exist in our queue. - // (No real synchronization needed at destructor time: only one - // thread can be doing this.) - if (!std::is_trivially_destructible::value) { - size_t readIndex = readIndex_; - size_t endIndex = writeIndex_; - while (readIndex != endIndex) { - records_[readIndex].~T(); - if (++readIndex == size_) { - readIndex = 0; + // size must be >= 2. + // + // Also, note that the number of usable slots in the queue at any + // given time is actually (size-1), so if you start with an empty queue, + // isFull() will return true after size-1 insertions. + explicit ProducerConsumerQueue(uint32_t size) + : size_(size), records_(static_cast(std::malloc(sizeof(T) * size))), readIndex_(0), writeIndex_(0) { + assert(size >= 2); + if (!records_) { + throw std::bad_alloc(); } - } } - std::free(records_); - } + ~ProducerConsumerQueue() { + // We need to destruct anything that may still exist in our queue. + // (No real synchronization needed at destructor time: only one + // thread can be doing this.) + if (!std::is_trivially_destructible::value) { + size_t readIndex = readIndex_; + size_t endIndex = writeIndex_; + while (readIndex != endIndex) { + records_[readIndex].~T(); + if (++readIndex == size_) { + readIndex = 0; + } + } + } - template - bool write(Args&&... recordArgs) { - auto const currentWrite = writeIndex_.load(std::memory_order_relaxed); - auto nextRecord = currentWrite + 1; - if (nextRecord == size_) { - nextRecord = 0; - } - if (nextRecord != readIndex_.load(std::memory_order_acquire)) { - new (&records_[currentWrite]) T(std::forward(recordArgs)...); - writeIndex_.store(nextRecord, std::memory_order_release); - return true; + std::free(records_); } - // queue is full - return false; - } + template bool write(Args &&...recordArgs) { + auto const currentWrite = writeIndex_.load(std::memory_order_relaxed); + auto nextRecord = currentWrite + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + if (nextRecord != readIndex_.load(std::memory_order_acquire)) { + new (&records_[currentWrite]) T(std::forward(recordArgs)...); + writeIndex_.store(nextRecord, std::memory_order_release); + return true; + } - // move (or copy) the value at the front of the queue to given variable - bool read(T& record) { - auto const currentRead = readIndex_.load(std::memory_order_relaxed); - if (currentRead == writeIndex_.load(std::memory_order_acquire)) { - // queue is empty - return false; + // queue is full + return false; } - auto nextRecord = currentRead + 1; - if (nextRecord == size_) { - nextRecord = 0; + // move (or copy) the value at the front of the queue to given variable + bool read(T &record) { + auto const currentRead = readIndex_.load(std::memory_order_relaxed); + if (currentRead == writeIndex_.load(std::memory_order_acquire)) { + // queue is empty + return false; + } + + auto nextRecord = currentRead + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + record = std::move(records_[currentRead]); + records_[currentRead].~T(); + readIndex_.store(nextRecord, std::memory_order_release); + return true; } - record = std::move(records_[currentRead]); - records_[currentRead].~T(); - readIndex_.store(nextRecord, std::memory_order_release); - return true; - } - // pointer to the value at the front of the queue (for use in-place) or - // nullptr if empty. - T* frontPtr() { - auto const currentRead = readIndex_.load(std::memory_order_relaxed); - if (currentRead == writeIndex_.load(std::memory_order_acquire)) { - // queue is empty - return nullptr; + // pointer to the value at the front of the queue (for use in-place) or + // nullptr if empty. + T *frontPtr() { + auto const currentRead = readIndex_.load(std::memory_order_relaxed); + if (currentRead == writeIndex_.load(std::memory_order_acquire)) { + // queue is empty + return nullptr; + } + return &records_[currentRead]; } - return &records_[currentRead]; - } - // queue must not be empty - void popFront() { - auto const currentRead = readIndex_.load(std::memory_order_relaxed); - assert(currentRead != writeIndex_.load(std::memory_order_acquire)); + // queue must not be empty + void popFront() { + auto const currentRead = readIndex_.load(std::memory_order_relaxed); + assert(currentRead != writeIndex_.load(std::memory_order_acquire)); - auto nextRecord = currentRead + 1; - if (nextRecord == size_) { - nextRecord = 0; + auto nextRecord = currentRead + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + records_[currentRead].~T(); + readIndex_.store(nextRecord, std::memory_order_release); } - records_[currentRead].~T(); - readIndex_.store(nextRecord, std::memory_order_release); - } - bool isEmpty() const { - return readIndex_.load(std::memory_order_acquire) == - writeIndex_.load(std::memory_order_acquire); - } - - bool isFull() const { - auto nextRecord = writeIndex_.load(std::memory_order_acquire) + 1; - if (nextRecord == size_) { - nextRecord = 0; + bool isEmpty() const { + return readIndex_.load(std::memory_order_acquire) == writeIndex_.load(std::memory_order_acquire); } - if (nextRecord != readIndex_.load(std::memory_order_acquire)) { - return false; + + bool isFull() const { + auto nextRecord = writeIndex_.load(std::memory_order_acquire) + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + if (nextRecord != readIndex_.load(std::memory_order_acquire)) { + return false; + } + // queue is full + return true; } - // queue is full - return true; - } - // * If called by consumer, then true size may be more (because producer may - // be adding items concurrently). - // * If called by producer, then true size may be less (because consumer may - // be removing items concurrently). - // * It is undefined to call this from any other thread. - size_t sizeGuess() const { - int ret = writeIndex_.load(std::memory_order_acquire) - - readIndex_.load(std::memory_order_acquire); - if (ret < 0) { - ret += size_; + // * If called by consumer, then true size may be more (because producer may + // be adding items concurrently). + // * If called by producer, then true size may be less (because consumer may + // be removing items concurrently). + // * It is undefined to call this from any other thread. + size_t sizeGuess() const { + int ret = writeIndex_.load(std::memory_order_acquire) - readIndex_.load(std::memory_order_acquire); + if (ret < 0) { + ret += size_; + } + return ret; } - return ret; - } - // maximum number of items in the queue. - size_t capacity() const { return size_ - 1; } + // maximum number of items in the queue. + size_t capacity() const { return size_ - 1; } - private: - using AtomicIndex = std::atomic; + private: + using AtomicIndex = std::atomic; - char pad0_[hardware_destructive_interference_size]; - const uint32_t size_; - T* const records_; + char pad0_[hardware_destructive_interference_size]; + const uint32_t size_; + T *const records_; - alignas(hardware_destructive_interference_size) AtomicIndex readIndex_; - alignas(hardware_destructive_interference_size) AtomicIndex writeIndex_; + alignas(hardware_destructive_interference_size) AtomicIndex readIndex_; + alignas(hardware_destructive_interference_size) AtomicIndex writeIndex_; - char pad1_[hardware_destructive_interference_size - sizeof(AtomicIndex)]; + char pad1_[hardware_destructive_interference_size - sizeof(AtomicIndex)]; }; } // namespace folly \ No newline at end of file diff --git a/core/include/aare/VariableSizeClusterFinder.hpp b/core/include/aare/VariableSizeClusterFinder.hpp index d1da285..01b7c0c 100644 --- a/core/include/aare/VariableSizeClusterFinder.hpp +++ b/core/include/aare/VariableSizeClusterFinder.hpp @@ -5,7 +5,6 @@ #include #include - #include "aare/NDArray.hpp" const int MAX_CLUSTER_SIZE = 200; @@ -23,9 +22,9 @@ template class ClusterFinder { // std::vector rows{}; // std::vector cols{}; - int16_t rows[MAX_CLUSTER_SIZE]={0}; - int16_t cols[MAX_CLUSTER_SIZE]={0}; - double enes[MAX_CLUSTER_SIZE]={0}; + int16_t rows[MAX_CLUSTER_SIZE] = {0}; + int16_t cols[MAX_CLUSTER_SIZE] = {0}; + double enes[MAX_CLUSTER_SIZE] = {0}; }; private: @@ -39,11 +38,11 @@ template class ClusterFinder { bool use_noise_map = false; int peripheralThresholdFactor_ = 5; int current_label; - const std::array di{{0, -1, -1, -1}}; // row ### 8-neighbour by scaning from left to right - const std::array dj{{-1, -1, 0, 1}}; // col ### 8-neighbour by scaning from top to bottom + const std::array di{{0, -1, -1, -1}}; // row ### 8-neighbour by scaning from left to right + const std::array dj{{-1, -1, 0, 1}}; // col ### 8-neighbour by scaning from top to bottom const std::array di_{{0, 0, -1, 1, -1, 1, -1, 1}}; // row - const std::array dj_{{-1, 1, 0, 0, 1, -1, -1, 1}}; // col - std::map child; // heirachy: key: child; val: parent + const std::array dj_{{-1, 1, 0, 0, 1, -1, -1, 1}}; // col + std::map child; // heirachy: key: child; val: parent std::unordered_map h_size; std::vector hits; // std::vector> row @@ -51,14 +50,16 @@ template class ClusterFinder { public: ClusterFinder(image_shape shape, T threshold) - : shape_(shape), labeled_(shape, 0), peripheral_labeled_(shape, 0), binary_(shape), - threshold_(threshold) { + : shape_(shape), labeled_(shape, 0), peripheral_labeled_(shape, 0), binary_(shape), threshold_(threshold) { hits.reserve(2000); } NDArray labeled() { return labeled_; } - void set_noiseMap(NDView noise_map) { noiseMap = noise_map; use_noise_map = true; } + void set_noiseMap(NDView noise_map) { + noiseMap = noise_map; + use_noise_map = true; + } void set_peripheralThresholdFactor(int factor) { peripheralThresholdFactor_ = factor; } void find_clusters(NDView img); void find_clusters_X(NDView img); @@ -81,8 +82,8 @@ template class ClusterFinder { fmt::print("{} -> {}\n", it->first, it->second); } } - size_t total_clusters() const{ - //TODO! fix for stealing + size_t total_clusters() const { + // TODO! fix for stealing return hits.size(); } @@ -103,8 +104,8 @@ template class ClusterFinder { auto old = it->second; it->second = to; add_link(old, to); - }else{ - //found value is smaller than what we want to link + } else { + // found value is smaller than what we want to link add_link(to, it->second); } } @@ -117,7 +118,7 @@ template int ClusterFinder::check_neighbours(int i, int j) { for (int k = 0; k < 4; ++k) { const auto row = i + di[k]; const auto col = j + dj[k]; - if (row >= 0 && col >= 0 && row= 0 && col >= 0 && row < shape_[0] && col < shape_[1]) { auto tmp = labeled_.value(i + di[k], j + dj[k]); if (tmp != 0) neighbour_labels.push_back(tmp); @@ -139,8 +140,7 @@ template int ClusterFinder::check_neighbours(int i, int j) { auto next = current + 1; add_link(*current, *next); } - return neighbour_labels.back(); //already sorted - + return neighbour_labels.back(); // already sorted } } @@ -162,7 +162,7 @@ template void ClusterFinder::find_clusters_X(NDView img) { for (int i = 0; i < shape_[0]; ++i) { for (int j = 0; j < shape_[1]; ++j) { if (use_noise_map) - threshold_ = 5*noiseMap(i, j); + threshold_ = 5 * noiseMap(i, j); if (original_(i, j) > threshold_) { // printf("========== Cluster index: %d\n", clusterIndex); rec_FillHit(clusterIndex, i, j); @@ -178,7 +178,7 @@ template void ClusterFinder::find_clusters_X(NDView img) { template void ClusterFinder::rec_FillHit(int clusterIndex, int i, int j) { // printf("original_(%d, %d)=%f\n", i, j, original_(i,j)); // printf("h_size[%d].size=%d\n", clusterIndex, h_size[clusterIndex].size); - if (h_size[clusterIndex].size < MAX_CLUSTER_SIZE){ + if (h_size[clusterIndex].size < MAX_CLUSTER_SIZE) { h_size[clusterIndex].rows[h_size[clusterIndex].size] = i; h_size[clusterIndex].cols[h_size[clusterIndex].size] = j; h_size[clusterIndex].enes[h_size[clusterIndex].size] = original_(i, j); @@ -197,11 +197,10 @@ template void ClusterFinder::rec_FillHit(int clusterIndex, int i const auto col = j + dj_[k]; if (row >= 0 && col >= 0 && row < shape_[0] && col < shape_[1]) { if (use_noise_map) - threshold_ = peripheralThresholdFactor_*noiseMap(row, col); - if (original_(row, col) > threshold_){ + threshold_ = peripheralThresholdFactor_ * noiseMap(row, col); + if (original_(row, col) > threshold_) { rec_FillHit(clusterIndex, row, col); - } - else{ + } else { // if (h_size[clusterIndex].size < MAX_CLUSTER_SIZE){ // h_size[clusterIndex].size += 1; // h_size[clusterIndex].rows[h_size[clusterIndex].size] = row; @@ -229,7 +228,7 @@ template void ClusterFinder::first_pass() { for (int i = 0; i < original_.size(); ++i) { if (use_noise_map) - threshold_ = 5*noiseMap(i); + threshold_ = 5 * noiseMap(i); binary_(i) = (original_(i) > threshold_); } @@ -258,8 +257,8 @@ template void ClusterFinder::second_pass() { while (it != child.end()) { current_label = it->second; it = child.find(current_label); - //do this once before doing the second pass? - //all values point to the final one... + // do this once before doing the second pass? + // all values point to the final one... } labeled_(i) = current_label; } @@ -280,14 +279,13 @@ template void ClusterFinder::store_clusters() { // (j-1 >= 0 and labeled_(i, j-1) != 0) or // (i+1 < shape_[0] and labeled_(i+1, j) != 0) or // (j+1 < shape_[1] and labeled_(i, j+1) != 0) - ){ + ) { Hit &record = h_size[labeled_(i, j)]; - if (record.size < MAX_CLUSTER_SIZE){ + if (record.size < MAX_CLUSTER_SIZE) { record.rows[record.size] = i; record.cols[record.size] = j; record.enes[record.size] = original_(i, j); - } - else{ + } else { continue; } record.size += 1; @@ -301,10 +299,9 @@ template void ClusterFinder::store_clusters() { } } } - + for (const auto &h : h_size) hits.push_back(h.second); - } } // namespace aare diff --git a/core/include/aare/ZmqSocket.hpp b/core/include/aare/ZmqSocket.hpp index 96973c9..67859df 100644 --- a/core/include/aare/ZmqSocket.hpp +++ b/core/include/aare/ZmqSocket.hpp @@ -1,10 +1,9 @@ #pragma once #include +#include #include #include -#include - // Socket to receive data from a ZMQ publisher // needs to be in sync with the main library (or maybe better use the versioning in the header) @@ -12,7 +11,7 @@ // forward declare zmq_msg_t to avoid including zmq.h in the header class zmq_msg_t; -namespace aare{ +namespace aare { /** zmq header structure (from slsDetectorPackage)*/ struct zmqHeader { @@ -65,24 +64,23 @@ struct zmqHeader { std::array rx_roi{}; }; - -class ZmqSocket{ +class ZmqSocket { void *m_context{nullptr}; void *m_socket{nullptr}; std::string m_endpoint; int m_zmq_hwm{1000}; int m_timeout_ms{1000}; constexpr static size_t m_max_header_size = 1024; - char* m_header_buffer = new char[m_max_header_size]; + char *m_header_buffer = new char[m_max_header_size]; bool decode_header(zmqHeader &h); -public: - ZmqSocket(const std::string& endpoint); + public: + ZmqSocket(const std::string &endpoint); ~ZmqSocket(); - ZmqSocket(const ZmqSocket&) = delete; - ZmqSocket operator=(const ZmqSocket&) = delete; - ZmqSocket(ZmqSocket&&) = delete; + ZmqSocket(const ZmqSocket &) = delete; + ZmqSocket operator=(const ZmqSocket &) = delete; + ZmqSocket(ZmqSocket &&) = delete; void connect(); void disconnect(); @@ -90,8 +88,6 @@ public: void set_timeout_ms(int n); int receive(zmqHeader &header, std::byte *data); - - }; } // namespace aare \ No newline at end of file diff --git a/core/include/aare/defs.hpp b/core/include/aare/defs.hpp index 5eba329..8ce8037 100644 --- a/core/include/aare/defs.hpp +++ b/core/include/aare/defs.hpp @@ -1,15 +1,15 @@ #pragma once #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include +#include -namespace aare{ +namespace aare { typedef struct { uint64_t frameNumber; @@ -26,7 +26,7 @@ typedef struct { uint8_t detType; uint8_t version; uint8_t packetMask[64]; -}__attribute__((packed)) sls_detector_header; +} __attribute__((packed)) sls_detector_header; struct xy { int row; @@ -36,29 +36,21 @@ struct xy { // using image_shape = std::array; using dynamic_shape = std::vector; -enum class DetectorType { Jungfrau, Eiger, Mythen3, Moench,ChipTestBoard }; +enum class DetectorType { Jungfrau, Eiger, Mythen3, Moench, ChipTestBoard }; -enum class TimingMode {Auto, Trigger}; +enum class TimingMode { Auto, Trigger }; -template -T StringTo(std::string sv){ - return T(sv); -} +template T StringTo(std::string sv) { return T(sv); } -template -std::string toString(T sv){ - return T(sv); -} +template std::string toString(T sv) { return T(sv); } template <> DetectorType StringTo(std::string); template <> std::string toString(DetectorType type); - template <> TimingMode StringTo(std::string); using DataTypeVariants = std::variant; - struct RawFileConfig { int module_gap_row{}; int module_gap_col{}; @@ -72,6 +64,4 @@ struct RawFileConfig { } }; - - } // namespace aare \ No newline at end of file diff --git a/file_io/include/aare/File.hpp b/file_io/include/aare/File.hpp index cd93487..7399543 100644 --- a/file_io/include/aare/File.hpp +++ b/file_io/include/aare/File.hpp @@ -1,7 +1,7 @@ #pragma once #include "aare/FileInterface.hpp" -namespace aare{ +namespace aare { class File { private: FileInterface *file_impl; @@ -12,8 +12,8 @@ class File { // - w writing (overwrites existing file) // - a appending (appends to existing file) // TODO! do we need to support w+, r+ and a+? - File(std::filesystem::path fname, std::string mode,FileConfig cfg = {}); - void write(Frame& frame); + File(std::filesystem::path fname, std::string mode, FileConfig cfg = {}); + void write(Frame &frame); Frame read(); Frame iread(size_t frame_number); std::vector read(size_t n_frames); @@ -27,10 +27,9 @@ class File { size_t total_frames() const; ssize_t rows() const; ssize_t cols() const; - ssize_t bitdepth() const; + ssize_t bitdepth() const; File(File &&other); - ~File(); }; diff --git a/file_io/include/aare/FileFactory.hpp b/file_io/include/aare/FileFactory.hpp index d61e422..4572e9c 100644 --- a/file_io/include/aare/FileFactory.hpp +++ b/file_io/include/aare/FileFactory.hpp @@ -4,7 +4,7 @@ #include "aare/utils/logger.hpp" #include -namespace aare{ +namespace aare { class FileFactory { // Class that will be used to create FileInterface objects @@ -17,7 +17,7 @@ class FileFactory { // virtual int deleteFile() = 0; static FileInterface *load_file(std::filesystem::path p, std::string mode, FileConfig cfg = {}) { if ((mode == "r" or mode == "a") and not std::filesystem::exists(p)) { - throw std::runtime_error(LOCATION+"File does not exist"); + throw std::runtime_error(LOCATION + "File does not exist"); } auto factory = get_factory(p); diff --git a/file_io/include/aare/FileInterface.hpp b/file_io/include/aare/FileInterface.hpp index c8774af..f403f62 100644 --- a/file_io/include/aare/FileInterface.hpp +++ b/file_io/include/aare/FileInterface.hpp @@ -1,7 +1,7 @@ #pragma once +#include "aare/DType.hpp" #include "aare/Frame.hpp" #include "aare/defs.hpp" -#include "aare/DType.hpp" #include "aare/utils/logger.hpp" #include #include @@ -96,4 +96,4 @@ class FileInterface { ssize_t m_bitdepth{}; }; -} \ No newline at end of file +} // namespace aare \ No newline at end of file diff --git a/file_io/include/aare/NumpyFile.hpp b/file_io/include/aare/NumpyFile.hpp index e10c9df..4a8276a 100644 --- a/file_io/include/aare/NumpyFile.hpp +++ b/file_io/include/aare/NumpyFile.hpp @@ -1,19 +1,19 @@ #pragma once +#include "aare/DType.hpp" #include "aare/FileInterface.hpp" #include "aare/NumpyHelpers.hpp" -#include "aare/DType.hpp" #include "aare/defs.hpp" +#include #include #include -#include -namespace aare{ +namespace aare { class NumpyFile : public FileInterface { FILE *fp = nullptr; size_t initial_header_len = 0; size_t current_frame{}; - std::filesystem::path m_fname; + std::filesystem::path m_fname; uint32_t header_len{}; uint8_t header_len_size{}; ssize_t header_size{}; @@ -26,9 +26,7 @@ class NumpyFile : public FileInterface { Frame get_frame(size_t frame_number); public: - - - NumpyFile(const std::filesystem::path& fname); + NumpyFile(const std::filesystem::path &fname); NumpyFile(FileConfig, NumpyHeader); void write(Frame &frame) override; Frame read() override { return get_frame(this->current_frame++); } @@ -48,11 +46,10 @@ class NumpyFile : public FileInterface { DType dtype() const { return m_header.dtype; } std::vector shape() const { return m_header.shape; } - - //load the full numpy file into a NDArray - template - NDArray load(){ - NDArray arr(make_shape(m_header.shape)); + + // load the full numpy file into a NDArray + template NDArray load() { + NDArray arr(make_shape(m_header.shape)); fseek(fp, header_size, SEEK_SET); fread(arr.data(), sizeof(T), arr.size(), fp); return arr; diff --git a/file_io/include/aare/NumpyFileFactory.hpp b/file_io/include/aare/NumpyFileFactory.hpp index f78565e..3e27ed0 100644 --- a/file_io/include/aare/NumpyFileFactory.hpp +++ b/file_io/include/aare/NumpyFileFactory.hpp @@ -14,10 +14,9 @@ class NumpyFileFactory : public FileFactory { public: NumpyFileFactory(std::filesystem::path fpath); void parse_metadata(FileInterface *_file) override{/*TODO! remove after refactor*/}; - NumpyFile* load_file_read() override; - NumpyFile* load_file_write(FileConfig) override; - void parse_fname(FileInterface*)override{}; - + NumpyFile *load_file_read() override; + NumpyFile *load_file_write(FileConfig) override; + void parse_fname(FileInterface *) override{}; }; } // namespace aare \ No newline at end of file diff --git a/file_io/include/aare/NumpyHelpers.hpp b/file_io/include/aare/NumpyHelpers.hpp index 05b10bc..b45fbbb 100644 --- a/file_io/include/aare/NumpyHelpers.hpp +++ b/file_io/include/aare/NumpyHelpers.hpp @@ -21,7 +21,7 @@ using shape_t = std::vector; struct NumpyHeader { DType dtype{aare::DType::ERROR}; bool fortran_order{false}; - shape_t shape{}; + shape_t shape{}; std::string to_string() const; }; @@ -51,9 +51,8 @@ template bool in_array(T val, const std::array &arr bool is_digits(const std::string &str); aare::DType parse_descr(std::string typestring); -size_t write_header(std::filesystem::path fname, const NumpyHeader &header) ; -size_t write_header(std::ostream &out, const NumpyHeader &header) ; - +size_t write_header(std::filesystem::path fname, const NumpyHeader &header); +size_t write_header(std::ostream &out, const NumpyHeader &header); } // namespace NumpyHelpers } // namespace aare \ No newline at end of file diff --git a/file_io/include/aare/RawFile.hpp b/file_io/include/aare/RawFile.hpp index 5630e40..7b8e450 100644 --- a/file_io/include/aare/RawFile.hpp +++ b/file_io/include/aare/RawFile.hpp @@ -9,10 +9,9 @@ namespace aare { class RawFile : public FileInterface { using config = RawFileConfig; - public: - std::filesystem::path m_fname; //TO be made private! + std::filesystem::path m_fname; // TO be made private! void write(Frame &frame) override{}; Frame read() override { return get_frame(this->current_frame++); }; std::vector read(size_t n_frames) override; @@ -27,10 +26,10 @@ class RawFile : public FileInterface { size_t pixels() override { return m_rows * m_cols; } // goto frame number - void seek(size_t frame_number) override{ this->current_frame = frame_number; }; + void seek(size_t frame_number) override { this->current_frame = frame_number; }; // return the position of the file pointer (in number of frames) - size_t tell() override{ return this->current_frame; }; + size_t tell() override { return this->current_frame; }; size_t n_subfiles; size_t n_subfile_parts; @@ -66,8 +65,8 @@ class RawFile : public FileInterface { size_t total_frames() const override { return m_total_frames; } ssize_t rows() const override { return m_rows; } - ssize_t cols() const override{ return m_cols; } - ssize_t bitdepth() const override{ return m_bitdepth; } + ssize_t cols() const override { return m_cols; } + ssize_t bitdepth() const override { return m_bitdepth; } private: size_t current_frame{}; @@ -75,4 +74,4 @@ class RawFile : public FileInterface { Frame get_frame(size_t frame_number); }; -} \ No newline at end of file +} // namespace aare \ No newline at end of file diff --git a/file_io/include/aare/RawFileFactory.hpp b/file_io/include/aare/RawFileFactory.hpp index 7d0389c..901b5ff 100644 --- a/file_io/include/aare/RawFileFactory.hpp +++ b/file_io/include/aare/RawFileFactory.hpp @@ -10,10 +10,9 @@ class RawFileFactory : public FileFactory { void parse_raw_metadata(RawFile *file); public: - RawFileFactory(std::filesystem::path fpath); RawFile *load_file_read() override; - RawFile *load_file_write(FileConfig) override{return new RawFile();}; + RawFile *load_file_write(FileConfig) override { return new RawFile(); }; void parse_metadata(FileInterface *) override; void parse_fname(FileInterface *) override; void open_subfiles(FileInterface *); @@ -21,4 +20,4 @@ class RawFileFactory : public FileFactory { void find_geometry(FileInterface *); }; -} \ No newline at end of file +} // namespace aare \ No newline at end of file diff --git a/include/aare/aare.hpp b/include/aare/aare.hpp index 6734b06..78a74d0 100644 --- a/include/aare/aare.hpp +++ b/include/aare/aare.hpp @@ -1 +1 @@ -//This is the top level header to include and what most users will use \ No newline at end of file +// This is the top level header to include and what most users will use \ No newline at end of file diff --git a/utils/include/aare/utils/logger.hpp b/utils/include/aare/utils/logger.hpp index 4587f2c..ec7d05d 100644 --- a/utils/include/aare/utils/logger.hpp +++ b/utils/include/aare/utils/logger.hpp @@ -115,7 +115,7 @@ template void error(const Strings... s) { internal::logger extern void set_streams(std::streambuf *out, std::streambuf *err); extern void set_streams(std::streambuf *out); extern void set_verbosity(LOGGING_LEVEL level); -extern void set_output_file(std::string filename); +extern void set_output_file(std::string filename); extern Logger &get_logger_instance(); } // namespace logger