-
Notifications
You must be signed in to change notification settings - Fork 12
Implement lane-wise modulo. #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
295d602
dbf8115
2327807
7c10d29
0b8b214
e3a802d
7ed6e88
03edd02
0648bb1
0d0a833
33183cd
a7d744d
06af01c
ffc1120
5b837e6
c97318f
3dd0296
da9ccb9
da64b7d
11ccd9e
aab033a
ba6a5ba
f3d9f42
783f189
f9e28b1
d636521
d880691
bbad583
f6a04f1
e39d298
0ca3600
f7ffe70
53e56f5
b62355a
bf93d56
79d3847
a585ad9
711bb08
f1452cb
f45632a
79148d3
08a73e1
0228573
0829a7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,31 +86,29 @@ ARRAY_TEST(S8_64, 255, 255, 255, 255, 255, 255, 255, 255); | |
| ARRAY_TEST(S16_32, 65534, 65534); | ||
| ARRAY_TEST(S16_64, 65534, 65534, 65534, 65534); | ||
|
|
||
| #define F false | ||
| #define T true | ||
| using BS = BooleanSWAR<4, u16>; | ||
| static_assert(BS{Literals<4, u16>, {F, F, F, F}}.value() == 0b0000'0000'0000'0000); | ||
| static_assert(BS{Literals<4, u16>, {T, F, F, F}}.value() == 0b1000'0000'0000'0000); | ||
| static_assert(BS{Literals<4, u16>, {F, T, F, F}}.value() == 0b0000'1000'0000'0000); | ||
| static_assert(BS{Literals<4, u16>, {F, F, T, F}}.value() == 0b0000'0000'1000'0000); | ||
| static_assert(BS{Literals<4, u16>, {F, F, F, T}}.value() == 0b0000'0000'0000'1000); | ||
| static_assert(BS{Literals<4, u16>, {T, F, F, F}}.value() == 0b1000'0000'0000'0000); | ||
| static_assert(BS{Literals<4, u16>, {0, 0, 0, 0}}.value() == 0b0000'0000'0000'0000); | ||
| static_assert(BS{Literals<4, u16>, {1, 0, 0, 0}}.value() == 0b1000'0000'0000'0000); | ||
| static_assert(BS{Literals<4, u16>, {0, 1, 0, 0}}.value() == 0b0000'1000'0000'0000); | ||
| static_assert(BS{Literals<4, u16>, {0, 0, 1, 0}}.value() == 0b0000'0000'1000'0000); | ||
| static_assert(BS{Literals<4, u16>, {0, 0, 0, 1}}.value() == 0b0000'0000'0000'1000); | ||
| static_assert(BS{Literals<4, u16>, {1, 0, 0, 0}}.value() == 0b1000'0000'0000'0000); | ||
|
|
||
|
|
||
| namespace equality { | ||
| using S = SWAR<8, u32>; | ||
| using BS = BooleanSWAR<8, u32>; | ||
| static_assert(equals(S{S::Literal, {1, 2, 3, 4}}, | ||
| S{S::Literal, {1, 2, 3, 4}}).value() | ||
| == BS{BS::Literal, {T, T, T, T}}.value()); | ||
|
|
||
| static_assert(equals(S{S::Literal, {1, 2, 3, 4}}, | ||
| S{S::Literal, {5, 6, 7, 8}}).value() | ||
| == BS{BS::Literal, {F, F, F, F}}.value()); | ||
|
|
||
| static_assert(equals(S{S::Literal, {1, 2, 3, 4}}, | ||
| S{S::Literal, {5, 2, 7, 4}}).value() | ||
| == BS{BS::Literal, {F, T, F, T}}.value()); | ||
| template <typename S = S, typename BS = BS> | ||
| constexpr auto laneWiseEqualsTest( | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| const typename S::type (&left)[S::Lanes], | ||
| const typename S::type (&right)[S::Lanes], | ||
| const bool (&expected)[S::Lanes]) { | ||
| return equals(S{S::Literal, left}, S{S::Literal, right}).value() | ||
|
Comment on lines
+105
to
+106
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Accidental levels of indentation, scopes are not closed at the indentation level. |
||
| == BS{BS::Literal, expected}.value(); | ||
| } | ||
| static_assert(laneWiseEqualsTest({1, 2, 3, 4}, {1, 2, 3, 4}, {1, 1, 1, 1})); | ||
| static_assert(laneWiseEqualsTest({1, 2, 3, 4}, {5, 6, 7, 8}, {0, 0, 0, 0})); | ||
|
Comment on lines
+109
to
+110
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are whole- |
||
| static_assert(laneWiseEqualsTest({1, 2, 3, 4}, {5, 2, 7, 4}, {0, 1, 0, 1})); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is legitimate as written |
||
| } | ||
|
|
||
| namespace math_test { | ||
|
|
@@ -121,33 +119,31 @@ static_assert(math::moduloPowerOfTwo<4096>(4097) == 1); | |
|
|
||
| using S = SWAR<8, u32>; | ||
| using BS = BooleanSWAR<8, u32>; | ||
| static_assert(subtractOneUnsafe(S{S::Literal, {1, 3, 4, 8}}).value() | ||
| == S{S::Literal, {0, 2, 3, 7}}.value()); | ||
|
|
||
| static_assert(isPowerOfTwo(S{S::Literal, {1, 3, 4, 8}}).value() | ||
| == BS{BS::Literal, {T, F, T, T}}.value()); | ||
|
|
||
| static_assert(isPowerOfTwo(S{S::Literal, {3, 7, 11, 101}}).value() | ||
| == BS{BS::Literal, {F, F, F, F}}.value()); | ||
|
|
||
| static_assert(isPowerOfTwo(S{S::Literal, {2, 64, 128, 7}}).value() | ||
| == BS{BS::Literal, {T, T, T, 0}}.value()); | ||
|
|
||
| template <typename S, typename BS> | ||
| constexpr auto powerOfTwoTest( | ||
| const typename S::type (&input)[S::Lanes], | ||
| const bool (&expected)[S::Lanes]) { | ||
| return isPowerOfTwo(S{S::Literal, input}).value() == BS{BS::Literal, expected}.value(); | ||
| } | ||
| static_assert(powerOfTwoTest<S, BS>({1, 2, 3, 4}, {1, 1, 0, 1})); | ||
| static_assert(powerOfTwoTest<S, BS>({2, 3, 64, 77}, {1, 0, 1, 0})); | ||
| static_assert(powerOfTwoTest<S, BS>({3, 65, 128, 0}, {0, 0, 1, 1})); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This much copy&pasting is not valuable. |
||
| static_assert(powerOfTwoTest<S, BS>({256, 7, 11, 101}, {1, 0, 0, 0})); | ||
| static_assert(powerOfTwoTest<S, BS>({2, 64, 128, 7}, {1, 1, 1, 0})); | ||
|
|
||
| template <size_t N, typename S = S, typename BS = BS> | ||
| constexpr auto moduloSwarTest( | ||
| const typename S::type (&input)[S::Lanes], | ||
| const typename S::type (&expected)[S::Lanes]) { | ||
| return moduloPowerOfTwo<N>(S{S::Literal, input}).value() == S{S::Literal, expected}.value(); | ||
| } | ||
| static_assert(moduloPowerOfTwo<4>(S{0}).value() == 0); | ||
|
|
||
| static_assert(moduloPowerOfTwo<4>(S{S::Literal, {0, 2, 4, 6}}).value() | ||
| == S{S::Literal, {0, 2, 0, 2}}.value()); | ||
|
|
||
| static_assert(moduloPowerOfTwo<8>(S{S::Literal, {0, 2, 4, 9}}).value() | ||
| == S{S::Literal, {0, 2, 4, 1}}.value()); | ||
|
|
||
| static_assert(moduloPowerOfTwo<64>(S{S::Literal, {0, 1, 64, 65}}).value() | ||
| == S{S::Literal, {0, 1, 0, 1}}.value()); | ||
| static_assert(moduloSwarTest<4>({0, 2, 4, 6}, {0, 2, 0, 2})); | ||
| static_assert(moduloSwarTest<4>({1, 3, 5, 7}, {1, 3, 1, 3})); | ||
| static_assert(moduloSwarTest<8>({9, 8, 16, 7}, {1, 0, 0, 7})); | ||
| static_assert(moduloSwarTest<16>({17, 32, 64, 127}, {1, 0, 0, 15})); | ||
| } | ||
|
|
||
| #undef F | ||
| #undef T | ||
|
|
||
| namespace Multiplication { | ||
|
|
||
| static_assert(~int64_t(0) == negate(S4_64{S4_64::LeastSignificantBit}).value()); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not right, if you want "all lanes equal" you use the underlying value comparison as in all other tests.
Unit tests ought to demonstrate how to use a codebase. Using per-lane comparisons for a whole-base-type comparison is inadequate.
There is a probem with
equalswhich is that is terseness invites incorrect use.Even if you use
equals, the comparison against aBooleanSWARof alltrueis inelegant:not(boolean(~equals(, since we have the conversion to boolean