Skip to content
Open
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
295d602
new literals
jamierpond Apr 16, 2024
dbf8115
PR feedback
jamierpond Apr 19, 2024
2327807
tidy tests
jamierpond Apr 19, 2024
7c10d29
tidy reused code for booleanswaer
jamierpond Apr 19, 2024
0b8b214
update name
jamierpond Apr 19, 2024
e3a802d
style
jamierpond Apr 19, 2024
7ed6e88
test style
jamierpond Apr 19, 2024
03edd02
fix
jamierpond Apr 19, 2024
0648bb1
undef util
jamierpond Apr 19, 2024
0d0a833
simplify again
jamierpond Apr 19, 2024
33183cd
fmt
jamierpond Apr 19, 2024
a7d744d
Add to Array
jamierpond Apr 19, 2024
06af01c
rename
jamierpond Apr 20, 2024
ffc1120
nailed it
jamierpond Apr 20, 2024
5b837e6
cleanup
jamierpond Apr 20, 2024
c97318f
array tests?
jamierpond Apr 20, 2024
3dd0296
indentaion
jamierpond Apr 20, 2024
da9ccb9
update indent
jamierpond Apr 20, 2024
da64b7d
from array
jamierpond Apr 20, 2024
11ccd9e
more updates
jamierpond May 13, 2024
aab033a
wip
jamierpond May 15, 2024
ba6a5ba
rm unused
jamierpond May 15, 2024
f3d9f42
respect 80 chars
jamierpond May 15, 2024
783f189
undo clang formatting
jamierpond May 15, 2024
f9e28b1
format boolean swar
jamierpond May 15, 2024
d636521
improvementws
jamierpond May 26, 2024
d880691
indentation
jamierpond May 26, 2024
bbad583
make sure we understand equality
jamierpond May 26, 2024
f6a04f1
works
jamierpond May 26, 2024
e39d298
implement modulo
jamierpond May 26, 2024
0ca3600
modulo works!
jamierpond May 26, 2024
f7ffe70
snifae
jamierpond May 26, 2024
53e56f5
better example
jamierpond May 26, 2024
b62355a
Update SWAR.h
thecppzoo May 26, 2024
bf93d56
Update SWAR.h
thecppzoo May 26, 2024
79d3847
Attempt to sidestep MSVC bug
thecppzoo May 26, 2024
a585ad9
camelCawe
jamierpond May 27, 2024
711bb08
Merge branch 'jp/swar-to-array' into jp/ml-basics
jamierpond May 27, 2024
f1452cb
indentatino
jamierpond May 27, 2024
f45632a
auto
jamierpond May 27, 2024
79148d3
add utils
jamierpond May 27, 2024
08a73e1
tidy up
jamierpond May 27, 2024
0228573
weren't using that anyway
jamierpond May 27, 2024
0829a7e
tidy up tests
jamierpond May 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 39 additions & 43 deletions test/swar/BasicOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Copy link
Owner

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 equals which is that is terseness invites incorrect use.
Even if you use equals, the comparison against a BooleanSWAR of all true is inelegant:
not(boolean(~equals(, since we have the conversion to boolean

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

laneWiseEquals is problematic:
What does it mean? there are results that are expected to be equal or different according to a collection of expected boolean values, that is not even suggested by the name.
Then, laneWiseEquals suggests LANE WISE EQUALS. I guess that you call your "expected" comparison "WISE EQUAL".
Notwithstanding other problems, perhaps lanewiseEqualityComparisonExpected?

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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidental levels of indentation, scopes are not closed at the indentation level.
Do you think moving the end of the argument list to the right helps the code in any way?
Why is the declaration of the three arguments more nested than the implementation?

== 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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are whole-BooleanSWAR comparisons that can be achieved via the boolean conversion

static_assert(laneWiseEqualsTest({1, 2, 3, 4}, {5, 2, 7, 4}, {0, 1, 0, 1}));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is legitimate as written

}

namespace math_test {
Expand All @@ -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}));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This much copy&pasting is not valuable.
Did you consider packing all of the redundancy into an X macro?

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());
Expand Down