6 #ifndef TURI_SPARSE_SIM_SLICED_MATRIX_UTILITIES_H 7 #define TURI_SPARSE_SIM_SLICED_MATRIX_UTILITIES_H 10 #include <core/logging/assertions.hpp> 11 #include <core/parallel/atomic.hpp> 12 #include <core/parallel/lambda_omp.hpp> 14 namespace turi {
namespace sparse_sim {
19 size_t get_upper_triangular_slice_height(
size_t _w,
size_t _s);
26 std::vector<size_t> calculate_upper_triangular_slice_structure(
27 size_t num_items,
size_t target_item_count_per_pass,
size_t max_num_slices);
41 static constexpr
size_t _data_size(
size_t n_rows,
size_t n_cols) {
42 return ((n_cols - 1) * n_rows) - (n_rows * (n_rows - 1)) / 2;
50 resize(_num_rows, _num_cols);
68 data.reserve(n_elements);
71 size_t rows()
const {
return num_rows; }
72 size_t cols()
const {
return num_cols; }
76 void resize(
size_t _num_rows,
size_t _num_cols) {
77 DASSERT_LE(_num_rows, _num_cols);
80 size_t s = _data_size(num_rows, num_cols);
81 data.assign(s, value_type());
82 setup_row_index_map();
88 size_t index = data_index(row_idx, col_idx);
95 size_t index = data_index(i, j);
101 template <
typename ApplyFunction>
103 void apply(
size_t idx_1,
size_t idx_2, ApplyFunction&& apply_f) {
104 size_t index = data_index(idx_1, idx_2);
105 apply_f(data[index]);
110 template <
typename ProcessValueFunction>
111 void apply_all(ProcessValueFunction&& process_interaction) {
113 atomic<size_t> row_idx = 0;
115 in_parallel([&](
size_t thread_idx,
size_t num_threads) {
118 size_t idx_1 = (++row_idx) - 1;
119 if(idx_1 >= num_rows)
break;
121 size_t idx_2 = idx_1 + 1;
122 if(idx_2 >= num_cols)
continue;
124 value_type * __restrict__ d_ptr = data.data() + data_index(idx_1, idx_2);
126 for(; idx_2 != num_cols; ++idx_2, ++d_ptr) {
127 process_interaction(idx_1, idx_2, *d_ptr);
134 size_t num_cols=0, num_rows=0;
135 std::vector<value_type> data;
136 std::vector<size_t> row_index_map;
139 row_index_map.resize(num_rows + 1);
144 for(
size_t r = 0; r < num_rows; ++r) {
145 row_index_map[r] = _data_size(r, num_cols) - r;
148 row_index_map[num_rows] = data.size();
154 DASSERT_LT(row_idx, num_rows);
155 DASSERT_LT(col_idx, num_cols);
156 DASSERT_LT(row_idx, col_idx);
158 size_t index = row_index_map[row_idx] + (col_idx - 1);
159 DASSERT_LT(index, data.size());
void resize(size_t _num_rows, size_t _num_cols)
void reserve(size_t n_elements)
void apply_all(ProcessValueFunction &&process_interaction)
value_type & operator()(size_t row_idx, size_t col_idx)
GL_HOT_INLINE_FLATTEN void apply(size_t idx_1, size_t idx_2, ApplyFunction &&apply_f)
#define GL_HOT_INLINE_FLATTEN
const value_type & operator()(size_t i, size_t j) const
void in_parallel(const std::function< void(size_t thread_id, size_t num_threads)> &fn)