reduced duplicate code

This commit is contained in:
froejdh_e
2025-07-24 10:57:02 +02:00
parent 348fd0f937
commit 46876bfa73
4 changed files with 43 additions and 24 deletions

View File

@@ -178,6 +178,22 @@ class NDView : public ArrayExpr<NDView<T, Ndim>, Ndim> {
const T *data() const { return buffer_; } const T *data() const { return buffer_; }
void print_all() const; void print_all() const;
/**
* @brief Create a subview of a range of the first dimension.
* This is useful for splitting a batches of frames in parallel processing.
* @param first The first index of the subview (inclusive).
* @param last The last index of the subview (exclusive).
* @return A new NDView that is a subview of the current view.
* @throws std::runtime_error if the range is invalid.
*/
NDView sub_view(ssize_t first, ssize_t last) const {
if (first < 0 || last > shape_[0] || first >= last)
throw std::runtime_error(LOCATION + "Invalid sub_view range");
auto new_shape = shape_;
new_shape[0] = last - first;
return NDView(buffer_ + first * strides_[0], new_shape);
}
private: private:
T *buffer_{nullptr}; T *buffer_{nullptr};
std::array<ssize_t, Ndim> strides_{}; std::array<ssize_t, Ndim> strides_{};

View File

@@ -3,6 +3,7 @@
#include "aare/NDArray.hpp" #include "aare/NDArray.hpp"
#include "aare/NDView.hpp" #include "aare/NDView.hpp"
#include "aare/defs.hpp" #include "aare/defs.hpp"
#include "aare/utils/par.hpp"
#include "aare/utils/task.hpp" #include "aare/utils/task.hpp"
#include <cstdint> #include <cstdint>
#include <future> #include <future>
@@ -111,35 +112,30 @@ void apply_calibration(NDView<T, 3> res, NDView<uint16_t, 3> raw_data,
for (const auto &lim : limits) for (const auto &lim : limits)
futures.push_back(std::async( futures.push_back(std::async(
static_cast<void (*)(NDView<T, 3>, NDView<uint16_t, 3>, static_cast<void (*)(NDView<T, 3>, NDView<uint16_t, 3>,
NDView<T, Ndim>, NDView<T, Ndim>, int, int)>( NDView<T, Ndim>, NDView<T, Ndim>, int,
int)>(
apply_calibration_impl), apply_calibration_impl),
res, raw_data, ped, cal, lim.first, lim.second)); res, raw_data, ped, cal, lim.first, lim.second));
for (auto &f : futures) for (auto &f : futures)
f.get(); f.get();
} }
std::pair<NDArray<size_t, 3>, NDArray<size_t, 3>> std::pair<NDArray<size_t, 3>, NDArray<size_t, 3>>
sum_and_count_per_gain(NDView<uint16_t, 3> raw_data); sum_and_count_per_gain(NDView<uint16_t, 3> raw_data);
std::pair<NDArray<size_t, 2>, NDArray<size_t, 2>> std::pair<NDArray<size_t, 2>, NDArray<size_t, 2>>
sum_and_count_g0(NDView<uint16_t, 3> raw_data); sum_and_count_g0(NDView<uint16_t, 3> raw_data);
template <typename T> template <typename T>
NDArray<T, 2> calculate_pedestal_g0(NDView<uint16_t, 3> raw_data, NDArray<T, 2> calculate_pedestal_g0(NDView<uint16_t, 3> raw_data,
ssize_t n_threads) { ssize_t n_threads) {
std::vector<std::future<std::pair<NDArray<size_t, 2>, NDArray<size_t, 2>>>> std::vector<std::future<std::pair<NDArray<size_t, 2>, NDArray<size_t, 2>>>>
futures; futures;
futures.reserve(n_threads); futures.reserve(n_threads);
auto limits = split_task(0, raw_data.shape(0), n_threads);
// make subviews for each thread auto subviews = make_subviews(raw_data, n_threads);
std::vector<NDView<uint16_t, 3>> subviews;
for (const auto &lim : limits) {
subviews.emplace_back(
raw_data.data() + lim.first * raw_data.strides()[0],
std::array<ssize_t, 3>{lim.second - lim.first, raw_data.shape(1),
raw_data.shape(2)});
}
for (auto view : subviews) { for (auto view : subviews) {
futures.push_back(std::async( futures.push_back(std::async(
static_cast<std::pair<NDArray<size_t, 2>, NDArray<size_t, 2>> (*)( static_cast<std::pair<NDArray<size_t, 2>, NDArray<size_t, 2>> (*)(
@@ -157,26 +153,17 @@ NDArray<T, 2> calculate_pedestal_g0(NDView<uint16_t, 3> raw_data,
} }
return safe_divide<T>(accumulator, count); return safe_divide<T>(accumulator, count);
} }
template <typename T> template <typename T>
NDArray<T, 3> calculate_pedestal(NDView<uint16_t, 3> raw_data, NDArray<T, 3> calculate_pedestal(NDView<uint16_t, 3> raw_data,
ssize_t n_threads) { ssize_t n_threads) {
std::vector<std::future<std::pair<NDArray<size_t, 3>, NDArray<size_t, 3>>>> std::vector<std::future<std::pair<NDArray<size_t, 3>, NDArray<size_t, 3>>>>
futures; futures;
futures.reserve(n_threads); futures.reserve(n_threads);
auto limits = split_task(0, raw_data.shape(0), n_threads);
// make subviews for each thread auto subviews = make_subviews(raw_data, n_threads);
std::vector<NDView<uint16_t, 3>> subviews;
for (const auto &lim : limits) {
subviews.emplace_back(
raw_data.data() + lim.first * raw_data.strides()[0],
std::array<ssize_t, 3>{lim.second - lim.first, raw_data.shape(1),
raw_data.shape(2)});
}
for (auto view : subviews) { for (auto view : subviews) {
futures.push_back(std::async( futures.push_back(std::async(
static_cast<std::pair<NDArray<size_t, 3>, NDArray<size_t, 3>> (*)( static_cast<std::pair<NDArray<size_t, 3>, NDArray<size_t, 3>> (*)(

View File

@@ -1,7 +1,10 @@
#pragma once
#include <thread> #include <thread>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "aare/utils/task.hpp"
namespace aare { namespace aare {
template <typename F> template <typename F>
@@ -15,4 +18,17 @@ void RunInParallel(F func, const std::vector<std::pair<int, int>> &tasks) {
thread.join(); thread.join();
} }
} }
template <typename T>
std::vector<NDView<T,3>> make_subviews(NDView<T, 3> &data, ssize_t n_threads) {
std::vector<NDView<T, 3>> subviews;
subviews.reserve(n_threads);
auto limits = split_task(0, data.shape(0), n_threads);
for (const auto &lim : limits) {
subviews.push_back(data.sub_view(lim.first, lim.second));
}
return subviews;
}
} // namespace aare } // namespace aare

View File

@@ -1,4 +1,4 @@
#pragma once
#include <utility> #include <utility>
#include <vector> #include <vector>