Argon 0.1.0
Loading...
Searching...
No Matches
load_store.hpp
1
2
3#pragma once
4#include <cstddef>
5#include <cstdint>
6#include <iterator>
7#include <ranges>
8#include <span>
9#include "argon/argon_full.hpp"
10#include "argon/helpers/argon_for.hpp"
11#include "argon/helpers/size.hpp"
12#include "arm_simd/helpers/vec128.hpp"
13
14#ifdef __ARM_FEATURE_MVE
15#define simd mve
16#else
17#define simd neon
18#endif
19
20namespace argon::vectorize {
21
24
25template <typename ScalarType>
26struct load_store : public std::ranges::view_interface<load_store<ScalarType>> {
28 using intrinsic_type = simd::Vec128_t<ScalarType>;
29
31 static constexpr size_t lanes = sizeof(intrinsic_type) / sizeof(ScalarType);
32
33 public:
35 struct Iterator {
36 using iterator_category = std::forward_iterator_tag;
38 using difference_type = std::ptrdiff_t;
39
40 Iterator() = default;
41
44 Iterator(ScalarType* ptr) : ptr{ptr}, vec{value_type::Load(ptr)} {}
45
46 const value_type& operator*() const { return vec; }
47
51 dirty_ = true;
52 return vec;
53 }
54
55 const value_type* operator->() const { return &vec; }
56
60 dirty_ = true;
61 return &vec;
62 }
63
66 Iterator& operator++() {
67 if (dirty_) {
68 vec.StoreTo(ptr); // store before increment
69 }
70 ptr += lanes;
71 vec = value_type::Load(ptr);
72 return *this;
73 }
74
76 Iterator operator++(int) {
77 Iterator tmp = *this;
78 ++(*this);
79 return tmp;
80 }
81
84 friend bool operator==(const Iterator& a, const Iterator& b) { return a.ptr == b.ptr; }
85
87 friend bool operator==(const Iterator& a, const ScalarType* ptr) { return a.ptr == ptr; }
88
91 friend bool operator!=(const Iterator& a, const Iterator& b) { return a.ptr != b.ptr; }
92
94 friend bool operator!=(const Iterator& a, const ScalarType* ptr) { return a.ptr != ptr; }
95
97 void reload() { vec = value_type::Load(ptr); }
98
99 private:
100 bool dirty_;
101 ScalarType* ptr = nullptr;
102 value_type vec;
103 };
104 static_assert(std::input_or_output_iterator<Iterator>);
105
107 struct ConstIterator {
108 using iterator_category = std::forward_iterator_tag;
110 using difference_type = std::ptrdiff_t;
111
112 ConstIterator() = default;
113
116 ConstIterator(const ScalarType* ptr) : ptr{ptr}, vec{value_type::Load(ptr)} {}
117
120 const value_type operator*() const { return vec; }
121
124 ConstIterator& operator++() {
125 ptr += lanes;
126 vec = value_type::Load(ptr);
127 return *this;
128 }
129
132 ConstIterator operator++(int) {
133 ConstIterator tmp = *this;
134 ++(*this);
135 return tmp;
136 }
137
140 friend bool operator==(const ConstIterator& a, const ConstIterator& b) { return a.ptr == b.ptr; }
141
144 friend bool operator!=(const ConstIterator& a, const ConstIterator& b) { return a.ptr != b.ptr; }
145
146 private:
147 const ScalarType* ptr = nullptr;
148 value_type vec;
149 };
150 static_assert(std::input_iterator<ConstIterator>);
151
154
158 load_store(ScalarType* start, ScalarType* end)
159 : start_{start}, size_{helpers::vectorizeable_size<ScalarType>(end - start) / lanes} {};
160
164 load_store(ScalarType* start, const size_t size)
165 : start_{start}, size_{helpers::vectorizeable_size<ScalarType>(size) / lanes} {};
166
169 load_store(std::span<ScalarType> span)
170 : start_{span.data()}, size_{helpers::vectorizeable_size<ScalarType>(span.size()) / lanes} {};
171
175 template <std::ranges::contiguous_range R>
177 : start_{&*std::ranges::begin(r)}, size_{helpers::vectorizeable_size<ScalarType>(std::ranges::size(r)) / lanes} {}
178
181 iterator begin() const { return Iterator(start_); }
182
185 ScalarType* end() const { return start_ + (size_ * lanes); }
186
189 const_iterator cbegin() const { return ConstIterator(start_); }
190
193 const ScalarType* cend() const { return start_ + (size_ * lanes); }
194
198 size_t size() const { return size_; }
199
200 private:
201 ScalarType* start_;
202 size_t size_;
203};
204
207template <std::ranges::contiguous_range R>
208load_store(R&& r) -> load_store<std::ranges::range_value_t<R>>;
209
210static_assert(std::ranges::range<load_store<int32_t>>);
211static_assert(std::ranges::view<load_store<int32_t>>);
212static_assert(std::movable<load_store<int32_t>>);
213static_assert(std::ranges::viewable_range<load_store<int32_t>>);
214
215} // namespace argon::vectorize
216#undef simd
Contains helper templates and concepts for type manipulation and compile-time utilities.
Definition helpers.hpp:12
typename ArgonFor< std::remove_cv_t< T > >::type ArgonFor_t
Helper alias to get the Argon type for a given vector type.
Definition argon_for.hpp:45
Lane deconstruction feature.
Definition argon_full.hpp:302
A const iterator for the vectorized view.
Definition load_store.hpp:107
const value_type operator*() const
Dereference the const iterator to get the current value.
Definition load_store.hpp:120
ConstIterator(const ScalarType *ptr)
Constructs a const iterator from a pointer to the start of the range.
Definition load_store.hpp:116
ConstIterator operator++(int)
Postfix increment operator for the const iterator.
Definition load_store.hpp:132
helpers::ArgonFor_t< intrinsic_type > value_type
The value type of the iterator.
Definition load_store.hpp:109
friend bool operator==(const ConstIterator &a, const ConstIterator &b)
Equivalence operator.
Definition load_store.hpp:140
friend bool operator!=(const ConstIterator &a, const ConstIterator &b)
Non-equivalence operator.
Definition load_store.hpp:144
std::ptrdiff_t difference_type
The difference type of the iterator.
Definition load_store.hpp:110
std::forward_iterator_tag iterator_category
The iterator category.
Definition load_store.hpp:108
ConstIterator & operator++()
Increment operator for the const iterator.
Definition load_store.hpp:124
An iterator for the vectorized view.
Definition load_store.hpp:35
friend bool operator==(const Iterator &a, const ScalarType *ptr)
Comparison operators for the iterator.
Definition load_store.hpp:87
helpers::ArgonFor_t< intrinsic_type > value_type
The value type of the iterator.
Definition load_store.hpp:37
friend bool operator!=(const Iterator &a, const Iterator &b)
Comparison operators for the iterator.
Definition load_store.hpp:91
Iterator(ScalarType *ptr)
Constructs an iterator from a pointer to the start of the range.
Definition load_store.hpp:44
Iterator & operator++()
Increment the iterator to the next value.
Definition load_store.hpp:66
void reload()
Reload the iterator with the current value.
Definition load_store.hpp:97
Iterator operator++(int)
Postfix increment operator for the iterator.
Definition load_store.hpp:76
std::forward_iterator_tag iterator_category
The iterator category.
Definition load_store.hpp:36
value_type & operator*()
Dereference the iterator to get the current value.
Definition load_store.hpp:50
value_type * operator->()
Dereference the iterator to get the current value.
Definition load_store.hpp:59
friend bool operator==(const Iterator &a, const Iterator &b)
Comparison operators for the iterator.
Definition load_store.hpp:84
std::ptrdiff_t difference_type
The difference type of the iterator.
Definition load_store.hpp:38
friend bool operator!=(const Iterator &a, const ScalarType *ptr)
Comparison operators for the iterator.
Definition load_store.hpp:94
load_store(ScalarType *start, ScalarType *end)
Constructs a vectorized view from a pointer to the start of the range and the end of the range.
Definition load_store.hpp:158
load_store(std::span< ScalarType > span)
Constructs a vectorized view from a span.
Definition load_store.hpp:169
iterator begin() const
Returns an iterator to the beginning.
Definition load_store.hpp:181
ConstIterator const_iterator
The const iterator type for the vectorized view.
Definition load_store.hpp:153
size_t size() const
Get the size of the view.
Definition load_store.hpp:198
Iterator iterator
The iterator type for the vectorized view.
Definition load_store.hpp:152
simd::Vec128_t< ScalarType > intrinsic_type
The SIMD vector type used for vectorization.
Definition load_store.hpp:28
static constexpr size_t lanes
The number of lanes in the SIMD vector.
Definition load_store.hpp:31
load_store(R &&r)
Constructs a vectorized view from a range.
Definition load_store.hpp:176
const ScalarType * cend() const
Returns a const iterator to the end of the range.
Definition load_store.hpp:193
load_store(ScalarType *start, const size_t size)
Constructs a vectorized view from a pointer to the start of the range and the size of the range.
Definition load_store.hpp:164
const_iterator cbegin() const
Returns a const iterator to the beginning of the range.
Definition load_store.hpp:189
ScalarType * end() const
Returns an iterator to the end.
Definition load_store.hpp:185
Definition ptr.hpp:74