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