Line data Source code
1 : ///////////////////////////////////////////////////////////////////////////
2 : // Inastemp - Berenger Bramas MPCDF - 2016
3 : // Under MIT Licence, please you must read the LICENCE file.
4 : ///////////////////////////////////////////////////////////////////////////
5 : #ifndef INAVECSCALARFLOAT_HPP
6 : #define INAVECSCALARFLOAT_HPP
7 :
8 : #include "InastempGlobal.h"
9 : #include "Common/InaUtils.hpp"
10 : #include "Common/InaIfElse.hpp"
11 :
12 : #include <cmath>
13 : #include <initializer_list>
14 :
15 : template <class RealType>
16 : class InaVecMaskSCALAR;
17 :
18 : template <class RealType>
19 : class InaVecSCALAR;
20 :
21 : // Mask type
22 : template <>
23 : class InaVecMaskSCALAR<float> {
24 : bool mask;
25 : public:
26 : // Classic constructors
27 : inline InaVecMaskSCALAR(){}
28 :
29 : inline InaVecMaskSCALAR(const InaVecMaskSCALAR&) = default;
30 : inline InaVecMaskSCALAR& operator=(const InaVecMaskSCALAR&) = default;
31 :
32 : // Native data type compatibility
33 : inline /*not explicit*/ InaVecMaskSCALAR(const bool inMask)
34 20 : : mask(inMask){}
35 :
36 : inline InaVecMaskSCALAR& operator=(const bool inMask){
37 : mask = inMask;
38 : return (*this);
39 : }
40 :
41 : inline explicit operator bool() const{
42 : return mask;
43 : }
44 :
45 : inline bool getMask() const{
46 : return mask;
47 : }
48 :
49 : // Binary methods
50 : inline InaVecMaskSCALAR Not() const{
51 : return InaVecMaskSCALAR(!mask);
52 : }
53 :
54 : inline bool isAllTrue() const{
55 : // true if all FF
56 : return mask;
57 : }
58 :
59 : inline bool isAllFalse() const{
60 : // true if all zero
61 : return !mask;
62 : }
63 :
64 : // Double args methods
65 : inline static InaVecMaskSCALAR And(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
66 : return InaVecMaskSCALAR(inMask1.mask & inMask2.mask);
67 : }
68 :
69 : inline static InaVecMaskSCALAR NotAnd(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
70 : return InaVecMaskSCALAR((!inMask1.mask) & inMask2.mask);
71 : }
72 :
73 : inline static InaVecMaskSCALAR Or(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
74 : return InaVecMaskSCALAR(inMask1.mask | inMask2.mask);
75 : }
76 :
77 : inline static InaVecMaskSCALAR Xor(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
78 : return InaVecMaskSCALAR(inMask1.mask ^ inMask2.mask);
79 : }
80 :
81 : inline static bool IsEqual(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
82 : return inMask1.mask == inMask2.mask;
83 : }
84 :
85 : inline static bool IsNotEqual(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
86 1 : return inMask1.mask != inMask2.mask;
87 : }
88 : };
89 :
90 : // Mask must have operators
91 : inline InaVecMaskSCALAR<float> operator&(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
92 : return InaVecMaskSCALAR<float>::And(inMask1, inMask2);
93 : }
94 :
95 : inline InaVecMaskSCALAR<float> operator|(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
96 : return InaVecMaskSCALAR<float>::Or(inMask1, inMask2);
97 : }
98 :
99 : inline InaVecMaskSCALAR<float> operator^(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
100 : return InaVecMaskSCALAR<float>::Xor(inMask1, inMask2);
101 : }
102 :
103 : inline bool operator==(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
104 4 : return InaVecMaskSCALAR<float>::IsEqual(inMask1, inMask2);
105 : }
106 :
107 : inline bool operator!=(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
108 2 : return InaVecMaskSCALAR<float>::IsNotEqual(inMask1, inMask2);
109 : }
110 :
111 : // Vec type
112 : template <>
113 : class InaVecSCALAR<float> {
114 : protected:
115 : float vec;
116 :
117 : public:
118 : using VecRawType = float;
119 : using MaskType = InaVecMaskSCALAR<float>;
120 : using RealType = float;
121 : [[deprecated("Please use the method instead")]]
122 : static const int VecLength = 1;
123 : static const int Alignement= 1;
124 : static const bool IsOfFixedSize = true;
125 :
126 : static constexpr int GetVecLength(){
127 : return 1;
128 : }
129 :
130 : static constexpr bool IsRealFma(){
131 : return false;
132 : }
133 :
134 32 : inline InaVecSCALAR(){}
135 : inline InaVecSCALAR(const InaVecSCALAR&) = default;
136 : inline InaVecSCALAR& operator = (const InaVecSCALAR&) = default;
137 :
138 : // Constructor from raw type
139 : inline /*not explicit*/ InaVecSCALAR(const float inVec)
140 258 : : vec(inVec){
141 : }
142 :
143 : inline InaVecSCALAR& operator=(const float inVec){
144 : vec = inVec;
145 : return *this;
146 : }
147 :
148 : inline InaVecSCALAR& setFromRawType(const float inVec){
149 : vec = inVec;
150 : return *this;
151 : }
152 :
153 : inline explicit operator float() const{
154 : return vec;
155 : }
156 :
157 : inline float getVec() const{
158 : return vec;
159 : }
160 :
161 : // Constructor from scalar
162 :
163 : // Constructor from vec
164 : inline InaVecSCALAR(const std::initializer_list<float> lst)
165 10 : : InaVecSCALAR(lst.begin()){
166 : }
167 :
168 : inline explicit InaVecSCALAR(const float ptr[])
169 903 : : vec(*ptr){
170 : }
171 :
172 : inline InaVecSCALAR& setFromArray(const float ptr[]){
173 30 : vec = *ptr;
174 : return *this;
175 : }
176 :
177 : inline InaVecSCALAR& setFromAlignedArray(const float ptr[]){
178 5 : vec = *ptr;
179 : return *this;
180 : }
181 :
182 : inline InaVecSCALAR& setFromIndirectArray(const float values[], const int inIndirection[]) {
183 12 : vec = values[inIndirection[0]];
184 : return *this;
185 : }
186 :
187 : inline InaVecSCALAR& setFromIndirect2DArray(const float inArray[], const int inIndirection1[],
188 : const int inLeadingDimension, const int inIndirection2[]){
189 15 : vec = inArray[inIndirection1[0] * inLeadingDimension + inIndirection2[0]];
190 : return *this;
191 : }
192 :
193 : // Move back to array
194 : inline void storeInArray(float ptr[]) const {
195 218 : ptr[0] = vec;
196 : }
197 :
198 : inline void storeInAlignedArray(float ptr[]) const {
199 : ptr[0] = vec;
200 : }
201 :
202 : // Acce to individual values
203 : inline float at(const int /*index*/) const {
204 : return vec;
205 : }
206 :
207 : // Horizontal operation
208 : inline float horizontalSum() const {
209 : return vec;
210 : }
211 :
212 : inline float horizontalMul() const {
213 : return vec;
214 : }
215 :
216 : inline float minInVec() const {
217 : return vec;
218 : }
219 :
220 : inline float maxInVec() const {
221 : return vec;
222 : }
223 :
224 : inline InaVecSCALAR sqrt() const {
225 20 : return std::sqrt(vec);
226 : }
227 :
228 : inline InaVecSCALAR exp() const {
229 27 : return std::exp(vec);
230 : }
231 :
232 : inline InaVecSCALAR expLowAcc() const {
233 20 : return std::exp(vec);
234 : }
235 :
236 : inline InaVecSCALAR rsqrt() const {
237 20 : return 1/std::sqrt(vec);
238 : }
239 :
240 : inline InaVecSCALAR abs() const {
241 15 : return vec<0?-vec:vec;
242 : }
243 :
244 : inline InaVecSCALAR floor() const {
245 25 : return std::floor(vec);
246 : }
247 :
248 : inline InaVecSCALAR signOf() const {
249 25 : return vec < 0.f ? -1 : vec > 0.f ? 1.f : 0.f;
250 : }
251 :
252 : inline InaVecSCALAR isPositive() const {
253 25 : return vec >= 0.f ? 1.f : 0.f;
254 : }
255 :
256 : inline InaVecSCALAR isNegative() const {
257 25 : return vec <= 0.f ? 1.f : 0.f;
258 : }
259 :
260 : inline InaVecSCALAR isPositiveStrict() const {
261 25 : return vec > 0.f ? 1.f : 0.f;
262 : }
263 :
264 : inline InaVecSCALAR isNegativeStrict() const {
265 25 : return vec < 0.f ? 1.f : 0.f;
266 : }
267 :
268 : inline InaVecSCALAR isZero() const {
269 15 : return vec == 0.f ? 1.f : 0.f;
270 : }
271 :
272 : inline InaVecSCALAR isNotZero() const {
273 15 : return vec == 0.f ? 0.f : 1.f;
274 : }
275 :
276 : inline InaVecMaskSCALAR<float> isPositiveMask() const {
277 25 : return vec >= 0.f ? true : false;
278 : }
279 :
280 : inline InaVecMaskSCALAR<float> isNegativeMask() const {
281 25 : return vec <= 0.f ? true : false;
282 : }
283 :
284 : inline InaVecMaskSCALAR<float> isPositiveStrictMask() const {
285 25 : return vec > 0.f ? true : false;
286 : }
287 :
288 : inline InaVecMaskSCALAR<float> isNegativeStrictMask() const {
289 25 : return vec < 0.f ? true : false;
290 : }
291 :
292 : inline InaVecMaskSCALAR<float> isZeroMask() const {
293 20 : return vec == 0.f ? true : false;
294 : }
295 :
296 : inline InaVecMaskSCALAR<float> isNotZeroMask() const {
297 18 : return vec == 0.f ? false : true;
298 : }
299 :
300 : // Static basic methods
301 : inline static InaVecSCALAR GetZero() {
302 20 : return 0.f;
303 : }
304 :
305 : inline static InaVecSCALAR GetOne() {
306 5 : return 1.f;
307 : }
308 :
309 : inline static InaVecSCALAR Min(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
310 : return (inVec1.vec <= inVec2.vec ? inVec1 : inVec2);
311 : }
312 :
313 : inline static InaVecSCALAR Max(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
314 : return (inVec1.vec >= inVec2.vec ? inVec1 : inVec2);
315 : }
316 :
317 : inline static InaVecSCALAR IsLowerOrEqual(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
318 20 : return inVec1.vec <= inVec2.vec ? 1.f : 0.f;
319 : }
320 :
321 : inline static InaVecSCALAR IsLower(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
322 20 : return inVec1.vec < inVec2.vec ? 1.f : 0.f;
323 : }
324 :
325 : inline static InaVecSCALAR IsGreaterOrEqual(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
326 20 : return inVec1.vec >= inVec2.vec ? 1.f : 0.f;
327 : }
328 :
329 : inline static InaVecSCALAR IsGreater(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
330 20 : return inVec1.vec > inVec2.vec ? 1.f : 0.f;
331 : }
332 :
333 : inline static InaVecSCALAR IsEqual(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
334 20 : return inVec1.vec == inVec2.vec ? 1.f : 0.f;
335 : }
336 :
337 : inline static InaVecSCALAR IsNotEqual(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
338 20 : return inVec1.vec != inVec2.vec ? 1.f : 0.f;
339 : }
340 :
341 : inline static InaVecMaskSCALAR<float> IsLowerOrEqualMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
342 25 : return inVec1.vec <= inVec2.vec ? true : false;
343 : }
344 :
345 : inline static InaVecMaskSCALAR<float> IsLowerMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
346 21 : return inVec1.vec < inVec2.vec ? true : false;
347 : }
348 :
349 : inline static InaVecMaskSCALAR<float> IsGreaterOrEqualMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
350 24 : return inVec1.vec >= inVec2.vec ? true : false;
351 : }
352 :
353 : inline static InaVecMaskSCALAR<float> IsGreaterMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
354 20 : return inVec1.vec > inVec2.vec ? true : false;
355 : }
356 :
357 : inline static InaVecMaskSCALAR<float> IsEqualMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
358 46 : return inVec1.vec == inVec2.vec ? true : false;
359 : }
360 :
361 : inline static InaVecMaskSCALAR<float> IsNotEqualMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
362 31 : return inVec1.vec != inVec2.vec ? true : false;
363 : }
364 :
365 : inline static InaVecSCALAR BitsAnd(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
366 60 : return InaUtils::ConvertBits< int, float >(InaUtils::ConvertBits< float, int >(inVec1.vec) & InaUtils::ConvertBits< float, int >(inVec2.vec));
367 : }
368 :
369 : inline static InaVecSCALAR BitsNotAnd(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
370 80 : return InaUtils::ConvertBits< int, float >((~InaUtils::ConvertBits< float, int >(inVec1.vec)) & InaUtils::ConvertBits< float, int >(inVec2.vec));
371 : }
372 :
373 : inline static InaVecSCALAR BitsOr(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
374 204 : return InaUtils::ConvertBits< int, float >(InaUtils::ConvertBits< float, int >(inVec1.vec) | InaUtils::ConvertBits< float, int >(inVec2.vec));
375 : }
376 :
377 : inline static InaVecSCALAR BitsXor(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
378 60 : return InaUtils::ConvertBits< int, float >(InaUtils::ConvertBits< float, int >(inVec1.vec) ^ InaUtils::ConvertBits< float, int >(inVec2.vec));
379 : }
380 :
381 : inline static const char* GetName() {
382 : return "InaVecSCALAR<float>";
383 : }
384 :
385 : inline static InaIfElse< InaVecSCALAR<float> >::ThenClass If(const InaVecMaskSCALAR<float>& inTest) {
386 30 : return InaIfElse< InaVecSCALAR<float> >::IfClass().If(inTest);
387 : }
388 :
389 : inline static InaVecSCALAR IfElse(const InaVecMaskSCALAR<float>& inMask, const InaVecSCALAR& inIfTrue, const InaVecSCALAR& inIfFalse) {
390 4 : return inMask?inIfTrue:inIfFalse;
391 : }
392 :
393 : inline static InaVecSCALAR IfTrue(const InaVecMaskSCALAR<float>& inMask, const InaVecSCALAR& inIfTrue) {
394 528 : return inMask?inIfTrue:0.f;
395 : }
396 :
397 : inline static InaVecSCALAR IfFalse(const InaVecMaskSCALAR<float>& inMask, const InaVecSCALAR& inIfFalse) {
398 36 : return inMask?0:inIfFalse;
399 : }
400 :
401 : // Inner operators
402 : inline InaVecSCALAR<float>& operator+=(const InaVecSCALAR<float>& inVec){
403 6 : vec += inVec.vec;
404 : return *this;
405 : }
406 :
407 : inline InaVecSCALAR<float>& operator-=(const InaVecSCALAR<float>& inVec){
408 1 : vec -= inVec.vec;
409 : return *this;
410 : }
411 :
412 : inline InaVecSCALAR<float>& operator/=(const InaVecSCALAR<float>& inVec){
413 1 : vec /= inVec.vec;
414 : return *this;
415 : }
416 :
417 : inline InaVecSCALAR<float>& operator*=(const InaVecSCALAR<float>& inVec){
418 36 : vec *= inVec.vec;
419 : return *this;
420 : }
421 :
422 : inline InaVecSCALAR<float> operator-() const {
423 20 : return -vec;
424 : }
425 :
426 : inline InaVecSCALAR<float> pow(size_t power) const{
427 50 : return InaUtils::FastPow<InaVecSCALAR<float>>(vec, power);
428 : }
429 :
430 : // Multiple sum
431 : template <class ... Args>
432 20 : inline static void MultiHorizontalSum(float sumRes[], const InaVecSCALAR<float>& inVec, Args ...args){
433 915 : sumRes[0] += inVec.vec;
434 920 : MultiHorizontalSum(&sumRes[1], args...);
435 20 : }
436 :
437 : inline static void MultiHorizontalSum(float /*sumRes*/[]){
438 : }
439 :
440 : inline static InaVecSCALAR<float> Fma(const InaVecSCALAR<float>& inValAdd, const InaVecSCALAR<float>& inValMul1, const InaVecSCALAR<float>& inValMul2){
441 27 : return inValAdd.vec + (inValMul1.vec * inValMul2.vec);
442 : }
443 : };
444 :
445 : // Bits operators
446 : inline InaVecSCALAR<float> operator&(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
447 : return InaVecSCALAR<float>::BitsAnd(inVec1, inVec2);
448 : }
449 :
450 : inline InaVecSCALAR<float> operator|(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
451 : return InaVecSCALAR<float>::BitsOr(inVec1, inVec2);
452 : }
453 :
454 : inline InaVecSCALAR<float> operator^(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
455 : return InaVecSCALAR<float>::BitsXor(inVec1, inVec2);
456 : }
457 :
458 : // Dual operators
459 : inline InaVecSCALAR<float> operator+(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
460 23 : return inVec1.getVec() + inVec2.getVec();
461 : }
462 :
463 : inline InaVecSCALAR<float> operator-(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
464 23 : return inVec1.getVec() - inVec2.getVec();
465 : }
466 :
467 : inline InaVecSCALAR<float> operator/(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
468 13 : return inVec1.getVec() / inVec2.getVec();
469 : }
470 :
471 : inline InaVecSCALAR<float> operator*(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
472 38 : return inVec1.getVec() * inVec2.getVec();
473 : }
474 :
475 : // Tests and comparions
476 : inline InaVecMaskSCALAR<float> operator<(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
477 1 : return InaVecSCALAR<float>::IsLowerMask(inVec1,inVec2);
478 : }
479 :
480 : inline InaVecMaskSCALAR<float> operator<=(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
481 4 : return InaVecSCALAR<float>::IsLowerOrEqualMask(inVec1,inVec2);
482 : }
483 :
484 : inline InaVecMaskSCALAR<float> operator>(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
485 : return InaVecSCALAR<float>::IsGreaterMask(inVec1,inVec2);
486 : }
487 :
488 : inline InaVecMaskSCALAR<float> operator>=(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
489 2 : return InaVecSCALAR<float>::IsGreaterOrEqualMask(inVec1,inVec2);
490 : }
491 :
492 : inline InaVecMaskSCALAR<float> operator==(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
493 25 : return InaVecSCALAR<float>::IsEqualMask(inVec1,inVec2);
494 : }
495 :
496 : inline InaVecMaskSCALAR<float> operator!=(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
497 11 : return InaVecSCALAR<float>::IsNotEqualMask(inVec1,inVec2);
498 : }
499 :
500 :
501 :
502 :
503 : #endif // INAVECFLOAT_HPP
|