Argon 0.1.0
Loading...
Searching...
No Matches
load.hpp
1// Copyright 2025 Katherine Whitlock
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
18
19#pragma once
20#include <ranges>
21#include "argon/argon_full.hpp"
22#include "argon/helpers/size.hpp"
23#include "arm_simd/helpers/vec128.hpp"
24
25#ifdef __ARM_FEATURE_MVE
26#define simd mve
27#else
28#define simd neon
29#endif
30
31namespace argon::vectorize {
32
35template <typename ScalarType>
36struct load : std::ranges::view_interface<load<ScalarType>> {
37 using intrinsic_type = simd::Vec128_t<ScalarType>;
38 static constexpr size_t lanes =
39 sizeof(intrinsic_type) / sizeof(ScalarType);
40
41 public:
44 struct LoadIterator {
45 using iterator_category = std::bidirectional_iterator_tag;
46 using difference_type = std::ptrdiff_t;
48 using reference_type = value_type&;
49
50 LoadIterator() = default;
51
54 LoadIterator(const ScalarType* ptr) : ptr_{ptr} {}
55
59 Argon<ScalarType> operator*() const { return value_type::Load(ptr_); }
60
64 LoadIterator& operator+=(int n) {
65 ptr_ += n * lanes;
66 return *this;
67 }
68
72 LoadIterator& operator-=(int n) {
73 ptr_ -= n * lanes;
74 return *this;
75 }
76
79 LoadIterator operator++(int) {
80 LoadIterator tmp = *this;
81 ++(*this);
82 return tmp;
83 }
84
87 LoadIterator& operator++() {
88 ptr_ += lanes;
89 return *this;
90 }
91
94 LoadIterator operator--(int) {
95 LoadIterator tmp = *this;
96 --(*this);
97 return tmp;
98 }
99
102 LoadIterator& operator--() {
103 ptr_ -= lanes;
104 return *this;
105 }
106
110 LoadIterator operator+(int n) const {
111 LoadIterator it = *this;
112 it += n;
113 return it;
114 }
115
119 LoadIterator operator-(int n) const {
120 LoadIterator it = *this;
121 it -= n;
122 return it;
123 }
124
128 LoadIterator& operator[](int n) const { return *(*this + n); }
129
133 difference_type operator-(const LoadIterator& other) const { return ptr_ - other.ptr_; }
134
139 friend LoadIterator operator+(const int n, const LoadIterator& it) { return it + n; }
140
142 friend bool operator==(const LoadIterator& a, const LoadIterator& b) { return a.ptr_ == b.ptr_; }
143
145 friend bool operator==(const LoadIterator& a, const ScalarType* ptr) { return a.ptr_ == ptr; }
146
148 friend bool operator!=(const LoadIterator& a, const LoadIterator& b) { return a.ptr_ != b.ptr_; }
149
151 friend bool operator!=(const LoadIterator& a, const ScalarType* ptr) { return a.ptr_ != ptr; }
152
154 friend auto operator<=>(const LoadIterator& a, const LoadIterator& b) { return a.ptr_ <=> b.ptr_; }
155
156 private:
157 const ScalarType* ptr_;
158 };
159 static_assert(std::sized_sentinel_for<LoadIterator, LoadIterator>);
160 static_assert(std::bidirectional_iterator<LoadIterator>);
161 static_assert(std::input_iterator<LoadIterator>);
162
164 using sentinel = const ScalarType*;
165
168 iterator begin() { return start_; }
169
172 const ScalarType* end() { return start_ + (size_ * lanes); }
173
176 size_t size() const { return size_; }
177
181 template <std::ranges::contiguous_range R>
182 load(R&& r)
183 : start_{&*std::ranges::begin(r)}, size_{helpers::vectorizeable_size<ScalarType>(std::ranges::size(r)) / lanes} {}
184
187 load(const std::span<ScalarType> span)
188 : start_{span.data()}, size_{helpers::vectorizeable_size<ScalarType>(span.size()) / lanes} {}
189
190 private:
191 const ScalarType* start_;
192 size_t size_;
193};
194
195static_assert(std::ranges::range<load<int32_t>>);
196static_assert(std::ranges::view<load<int32_t>>);
197static_assert(std::movable<load<int32_t>>);
198static_assert(std::ranges::viewable_range<load<int32_t>>);
199
200template <std::ranges::contiguous_range R>
201load(R&& r) -> load<std::remove_cv_t<std::ranges::range_value_t<R>>>;
202
203template <typename ScalarType>
204load(const std::span<ScalarType>) -> load<std::remove_cv_t<ScalarType>>;
205
206} // namespace argon::vectorize
207#undef simd
Definition argon_full.hpp:24
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
The Iterator type for the range.
Definition load.hpp:44
LoadIterator & operator+=(int n)
Increments the iterator by a number of steps.
Definition load.hpp:64
friend bool operator!=(const LoadIterator &a, const LoadIterator &b)
Compares LoadIterators for inequality.
Definition load.hpp:148
LoadIterator operator+(int n) const
Adds an integer to the iterator and returns a new iterator.
Definition load.hpp:110
Argon< ScalarType > operator*() const
Dereferences the iterator to get the SIMD vector.
Definition load.hpp:59
LoadIterator operator++(int)
Postfix increment operator.
Definition load.hpp:79
friend bool operator==(const LoadIterator &a, const ScalarType *ptr)
Compares LoadIterators for equality.
Definition load.hpp:145
std::bidirectional_iterator_tag iterator_category
The iterator category.
Definition load.hpp:45
LoadIterator & operator-=(int n)
Decrements the iterator by a number of steps.
Definition load.hpp:72
LoadIterator & operator++()
Prefix increment operator.
Definition load.hpp:87
std::ptrdiff_t difference_type
The difference type.
Definition load.hpp:46
friend LoadIterator operator+(const int n, const LoadIterator &it)
Adds an integer to the iterator and returns a new iterator.
Definition load.hpp:139
friend bool operator==(const LoadIterator &a, const LoadIterator &b)
Compares LoadIterators for equality.
Definition load.hpp:142
LoadIterator & operator--()
Prefix decrement operator.
Definition load.hpp:102
friend bool operator!=(const LoadIterator &a, const ScalarType *ptr)
Compares LoadIterators for inequality.
Definition load.hpp:151
LoadIterator operator--(int)
Postfix decrement operator.
Definition load.hpp:94
LoadIterator operator-(int n) const
Subtracts an integer from the iterator and returns a new iterator.
Definition load.hpp:119
difference_type operator-(const LoadIterator &other) const
Calculates the difference between two iterators.
Definition load.hpp:133
helpers::ArgonFor_t< intrinsic_type > value_type
The value type of the iterator.
Definition load.hpp:47
LoadIterator(const ScalarType *ptr)
Constructs a LoadIterator from a pointer to the data.
Definition load.hpp:54
friend auto operator<=>(const LoadIterator &a, const LoadIterator &b)
Compares LoadIterators.
Definition load.hpp:154
LoadIterator & operator[](int n) const
Accesses the element at the given index.
Definition load.hpp:128
const ScalarType * end()
Returns an iterator to the end of the range.
Definition load.hpp:172
size_t size() const
Returns the size of the range.
Definition load.hpp:176
load(R &&r)
Construct a load from a range.
Definition load.hpp:182
static constexpr size_t lanes
The number of lanes in the SIMD vector.
Definition load.hpp:38
const ScalarType * sentinel
The sentinel type for the range.
Definition load.hpp:164
iterator begin()
Returns an iterator to the beginning of the range.
Definition load.hpp:168
load(const std::span< ScalarType > span)
Construct a load from a span.
Definition load.hpp:187
LoadIterator iterator
The iterator type for the range.
Definition load.hpp:163
simd::Vec128_t< ScalarType > intrinsic_type
The SIMD vector type.
Definition load.hpp:37
Definition ptr.hpp:74