Skip to content

Commit 43e1f13

Browse files
author
Fikret Ardal
committed
add simd OP scalar binary operations and tests
1 parent 7a7ca7d commit 43e1f13

File tree

8 files changed

+1394
-22
lines changed

8 files changed

+1394
-22
lines changed

c++/nda/algorithms.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ namespace nda {
212212
template <ArrayOfRank<2> A>
213213
double frobenius_norm(A const &a) {
214214
if constexpr (vectorizable_array<A> and not is_complex_v<get_value_t<A>>) {
215-
std::cout << "VECTORIZED" << std::endl;
216215
using value_t = get_value_t<A>;
217216
using simd_t = native_simd<value_t>;
218217
simd_t r_simd(value_t(0));

c++/nda/simd/arch/AVX/type.hpp

Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,58 @@ namespace nda {
164164
return *this;
165165
}
166166

167+
template <typename U>
168+
requires std::is_arithmetic_v<U>
169+
simd_type operator+(const U &other) {
170+
return *this + simd_type(static_cast<value_t>(other));
171+
}
172+
173+
template <typename U>
174+
requires std::is_arithmetic_v<U>
175+
simd_type operator-(const U &other) {
176+
return *this - simd_type(static_cast<value_t>(other));
177+
}
178+
179+
template <typename U>
180+
requires std::is_arithmetic_v<U>
181+
simd_type operator*(const U &other) {
182+
return *this * simd_type(static_cast<value_t>(other));
183+
}
184+
185+
template <typename U>
186+
requires std::is_arithmetic_v<U>
187+
simd_type operator/(const U &other) {
188+
return *this / simd_type(static_cast<value_t>(other));
189+
}
190+
191+
template <typename U>
192+
requires std::is_arithmetic_v<U>
193+
simd_type &operator+=(const U &other) {
194+
*this = *this + simd_type(static_cast<value_t>(other));
195+
return *this;
196+
}
197+
198+
template <typename U>
199+
requires std::is_arithmetic_v<U>
200+
simd_type &operator-=(const U &other) {
201+
*this = *this - simd_type(static_cast<value_t>(other));
202+
return *this;
203+
}
204+
205+
template <typename U>
206+
requires std::is_arithmetic_v<U>
207+
simd_type &operator*=(const U &other) {
208+
*this = *this * simd_type(static_cast<value_t>(other));
209+
return *this;
210+
}
211+
212+
template <typename U>
213+
requires std::is_arithmetic_v<U>
214+
simd_type &operator/=(const U &other) {
215+
*this = *this / simd_type(static_cast<value_t>(other));
216+
return *this;
217+
}
218+
167219
operator intrinsic_t() const { return value; }
168220

169221
simd_type operator-() const { return simd_type{} - *this; }
@@ -336,6 +388,58 @@ namespace nda {
336388
return *this;
337389
}
338390

391+
template <typename U>
392+
requires std::is_arithmetic_v<U>
393+
simd_type operator+(const U &other) {
394+
return *this + simd_type(static_cast<value_t>(other));
395+
}
396+
397+
template <typename U>
398+
requires std::is_arithmetic_v<U>
399+
simd_type operator-(const U &other) {
400+
return *this - simd_type(static_cast<value_t>(other));
401+
}
402+
403+
template <typename U>
404+
requires std::is_arithmetic_v<U>
405+
simd_type operator*(const U &other) {
406+
return *this * simd_type(static_cast<value_t>(other));
407+
}
408+
409+
template <typename U>
410+
requires std::is_arithmetic_v<U>
411+
simd_type operator/(const U &other) {
412+
return *this / simd_type(static_cast<value_t>(other));
413+
}
414+
415+
template <typename U>
416+
requires std::is_arithmetic_v<U>
417+
simd_type &operator+=(const U &other) {
418+
*this = *this + simd_type(static_cast<value_t>(other));
419+
return *this;
420+
}
421+
422+
template <typename U>
423+
requires std::is_arithmetic_v<U>
424+
simd_type &operator-=(const U &other) {
425+
*this = *this - simd_type(static_cast<value_t>(other));
426+
return *this;
427+
}
428+
429+
template <typename U>
430+
requires std::is_arithmetic_v<U>
431+
simd_type &operator*=(const U &other) {
432+
*this = *this * simd_type(static_cast<value_t>(other));
433+
return *this;
434+
}
435+
436+
template <typename U>
437+
requires std::is_arithmetic_v<U>
438+
simd_type &operator/=(const U &other) {
439+
*this = *this / simd_type(static_cast<value_t>(other));
440+
return *this;
441+
}
442+
339443
operator intrinsic_t() const { return value; }
340444

341445
simd_type operator-() const { return simd_type{} - *this; }
@@ -437,6 +541,58 @@ namespace nda {
437541
return *this;
438542
}
439543

544+
template <typename U>
545+
requires std::is_arithmetic_v<U>
546+
simd_type operator+(const U &other) {
547+
return *this + simd_type(static_cast<value_t>(other));
548+
}
549+
550+
template <typename U>
551+
requires std::is_arithmetic_v<U>
552+
simd_type operator-(const U &other) {
553+
return *this - simd_type(static_cast<value_t>(other));
554+
}
555+
556+
template <typename U>
557+
requires std::is_arithmetic_v<U>
558+
simd_type operator*(const U &other) {
559+
return *this * simd_type(static_cast<value_t>(other));
560+
}
561+
562+
template <typename U>
563+
requires std::is_arithmetic_v<U>
564+
simd_type operator/(const U &other) {
565+
return *this / simd_type(static_cast<value_t>(other));
566+
}
567+
568+
template <typename U>
569+
requires std::is_arithmetic_v<U>
570+
simd_type &operator+=(const U &other) {
571+
*this = *this + simd_type(static_cast<value_t>(other));
572+
return *this;
573+
}
574+
575+
template <typename U>
576+
requires std::is_arithmetic_v<U>
577+
simd_type &operator-=(const U &other) {
578+
*this = *this - simd_type(static_cast<value_t>(other));
579+
return *this;
580+
}
581+
582+
template <typename U>
583+
requires std::is_arithmetic_v<U>
584+
simd_type &operator*=(const U &other) {
585+
*this = *this * simd_type(static_cast<value_t>(other));
586+
return *this;
587+
}
588+
589+
template <typename U>
590+
requires std::is_arithmetic_v<U>
591+
simd_type &operator/=(const U &other) {
592+
*this = *this / simd_type(static_cast<value_t>(other));
593+
return *this;
594+
}
595+
440596
operator intrinsic_t() const { return value; }
441597

442598
simd_type operator-() const {
@@ -541,6 +697,58 @@ namespace nda {
541697
return *this;
542698
}
543699

700+
template <typename U>
701+
requires std::is_arithmetic_v<U>
702+
simd_type operator+(const U &other) {
703+
return *this + simd_type(static_cast<value_t>(other));
704+
}
705+
706+
template <typename U>
707+
requires std::is_arithmetic_v<U>
708+
simd_type operator-(const U &other) {
709+
return *this - simd_type(static_cast<value_t>(other));
710+
}
711+
712+
template <typename U>
713+
requires std::is_arithmetic_v<U>
714+
simd_type operator*(const U &other) {
715+
return *this * simd_type(static_cast<value_t>(other));
716+
}
717+
718+
template <typename U>
719+
requires std::is_arithmetic_v<U>
720+
simd_type operator/(const U &other) {
721+
return *this / simd_type(static_cast<value_t>(other));
722+
}
723+
724+
template <typename U>
725+
requires std::is_arithmetic_v<U>
726+
simd_type &operator+=(const U &other) {
727+
*this = *this + simd_type(static_cast<value_t>(other));
728+
return *this;
729+
}
730+
731+
template <typename U>
732+
requires std::is_arithmetic_v<U>
733+
simd_type &operator-=(const U &other) {
734+
*this = *this - simd_type(static_cast<value_t>(other));
735+
return *this;
736+
}
737+
738+
template <typename U>
739+
requires std::is_arithmetic_v<U>
740+
simd_type &operator*=(const U &other) {
741+
*this = *this * simd_type(static_cast<value_t>(other));
742+
return *this;
743+
}
744+
745+
template <typename U>
746+
requires std::is_arithmetic_v<U>
747+
simd_type &operator/=(const U &other) {
748+
*this = *this / simd_type(static_cast<value_t>(other));
749+
return *this;
750+
}
751+
544752
operator intrinsic_t() const { return value; }
545753

546754
simd_type operator-() const {
@@ -693,6 +901,74 @@ namespace nda {
693901
return *this;
694902
}
695903

904+
template <typename U>
905+
requires std::is_arithmetic_v<U> or is_complex_v<U>
906+
simd_type operator+(const U &other) {
907+
if constexpr (std::is_arithmetic_v<U>) {
908+
return *this + simd_type(value_t(other, U{}));
909+
} else {
910+
return *this + simd_type(static_cast<value_t>(other));
911+
}
912+
}
913+
914+
template <typename U>
915+
requires std::is_arithmetic_v<U> or is_complex_v<U>
916+
simd_type operator-(const U &other) {
917+
if constexpr (std::is_arithmetic_v<U>) {
918+
return *this - simd_type(value_t(other, U{}));
919+
} else {
920+
return *this - simd_type(static_cast<value_t>(other));
921+
}
922+
}
923+
924+
template <typename U>
925+
requires std::is_arithmetic_v<U> or is_complex_v<U>
926+
simd_type operator*(const U &other) {
927+
if constexpr (std::is_arithmetic_v<U>) {
928+
return simd_type(_mm256_mul_ps(value, _mm256_set1_ps(static_cast<scalar_t>(other))));
929+
} else {
930+
return *this * simd_type(static_cast<value_t>(other));
931+
}
932+
}
933+
934+
template <typename U>
935+
requires std::is_arithmetic_v<U> or is_complex_v<U>
936+
simd_type operator/(const U &other) {
937+
if constexpr (std::is_arithmetic_v<U>) {
938+
return simd_type(_mm256_div_ps(value, _mm256_set1_ps(static_cast<scalar_t>(other))));
939+
} else {
940+
return *this / simd_type(static_cast<value_t>(other));
941+
}
942+
}
943+
944+
template <typename U>
945+
requires std::is_arithmetic_v<U> or is_complex_v<U>
946+
simd_type &operator+=(const U &other) {
947+
*this = *this + other;
948+
return *this;
949+
}
950+
951+
template <typename U>
952+
requires std::is_arithmetic_v<U> or is_complex_v<U>
953+
simd_type &operator-=(const U &other) {
954+
*this = *this - other;
955+
return *this;
956+
}
957+
958+
template <typename U>
959+
requires std::is_arithmetic_v<U> or is_complex_v<U>
960+
simd_type &operator*=(const U &other) {
961+
*this = *this * other;
962+
return *this;
963+
}
964+
965+
template <typename U>
966+
requires std::is_arithmetic_v<U> or is_complex_v<U>
967+
simd_type &operator/=(const U &other) {
968+
*this = *this / other;
969+
return *this;
970+
}
971+
696972
operator intrinsic_t() const { return value; }
697973

698974
simd_type operator-() const {
@@ -835,6 +1111,76 @@ namespace nda {
8351111
return *this;
8361112
}
8371113

1114+
template <typename U>
1115+
requires std::is_arithmetic_v<U> or is_complex_v<U>
1116+
simd_type operator+(const U &other) {
1117+
if constexpr (std::is_arithmetic_v<U>) {
1118+
return *this + simd_type(value_t(other, U{}));
1119+
} else {
1120+
return *this + simd_type(static_cast<value_t>(other));
1121+
}
1122+
}
1123+
1124+
template <typename U>
1125+
requires std::is_arithmetic_v<U> or is_complex_v<U>
1126+
simd_type operator-(const U &other) {
1127+
if constexpr (std::is_arithmetic_v<U>) {
1128+
return *this - simd_type(value_t(other, U{}));
1129+
} else {
1130+
return *this - simd_type(static_cast<value_t>(other));
1131+
}
1132+
}
1133+
1134+
template <typename U>
1135+
requires std::is_arithmetic_v<U> or is_complex_v<U>
1136+
simd_type operator*(const U &other) {
1137+
if constexpr (std::is_arithmetic_v<U>) {
1138+
return simd_type(_mm256_mul_pd(value, _mm256_set1_pd(static_cast<scalar_t>(other))));
1139+
} else {
1140+
return *this * simd_type(static_cast<value_t>(other));
1141+
}
1142+
}
1143+
1144+
template <typename U>
1145+
requires std::is_arithmetic_v<U> or is_complex_v<U>
1146+
simd_type operator/(const U &other) {
1147+
if constexpr (std::is_arithmetic_v<U>) {
1148+
return simd_type(_mm256_div_pd(value, _mm256_set1_pd(static_cast<scalar_t>(other))));
1149+
} else {
1150+
return *this / simd_type(static_cast<value_t>(other));
1151+
}
1152+
}
1153+
1154+
template <typename U>
1155+
requires std::is_arithmetic_v<U> or is_complex_v<U>
1156+
simd_type &operator+=(const U &other) {
1157+
*this = *this + other;
1158+
return *this;
1159+
}
1160+
1161+
template <typename U>
1162+
requires std::is_arithmetic_v<U> or is_complex_v<U>
1163+
simd_type &operator-=(const U &other) {
1164+
*this = *this - other;
1165+
return *this;
1166+
}
1167+
1168+
template <typename U>
1169+
requires std::is_arithmetic_v<U> or is_complex_v<U>
1170+
simd_type &operator*=(const U &other) {
1171+
*this = *this * other;
1172+
return *this;
1173+
}
1174+
1175+
template <typename U>
1176+
requires std::is_arithmetic_v<U> or is_complex_v<U>
1177+
simd_type &operator/=(const U &other) {
1178+
*this = *this / other;
1179+
return *this;
1180+
}
1181+
1182+
1183+
8381184
operator intrinsic_t() const { return value; }
8391185

8401186
simd_type operator-() const {

0 commit comments

Comments
 (0)