-
Notifications
You must be signed in to change notification settings - Fork 6
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
New Literals Utils #80
Conversation
inc/zoo/swar/SWAR.h
Outdated
template <int NBits, typename T> struct SWAR; | ||
|
||
template <int NumBits, typename BaseType> struct Literals_t { | ||
constexpr static void (SWAR<NumBits, BaseType>::*value)() = nullptr; |
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 in use, remove
inc/zoo/swar/SWAR.h
Outdated
m_v = result; | ||
} | ||
|
||
constexpr static T MaxUnsignedLaneValue = ~(((~T{0}) << (NBits - 1)) << 1); |
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.
I agree this constant is worth including, but not here, and not with this calculation. See there are a bunch of constants in SWAR
, you may, for example, put it at the end of the list like this:
MaxUnsignedLaneValue = LeastSignificantLaneMask;
static_assert(SWAR<16, u64>::MaxUnsignedLaneValue == 65535); | ||
static_assert(SWAR<16, u32>::MaxUnsignedLaneValue == 65535); | ||
static_assert(SWAR<8, u32>::MaxUnsignedLaneValue == 255); | ||
static_assert(SWAR<4, u32>::MaxUnsignedLaneValue == 15); | ||
static_assert(SWAR<2, u32>::MaxUnsignedLaneValue == 3); |
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.
Decimal is not the natural base for these tests.
I know we ahve a mess of decimals and hex and binary in these tests, but let's stop the mess.
You may create an assign a PR to me to clean this up if you're upset about this request.
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.
I understand why we might want to have just one format, decimal makes the repo a little more approachable and understandable.
inc/zoo/swar/SWAR.h
Outdated
template <typename U, typename ManipulationFn> | ||
constexpr auto loadBaseTypeIntoLanes(const U (&values)[Lanes], | ||
const ManipulationFn&& manipulation) { | ||
auto result = T{0}; | ||
for (auto value : values) { | ||
auto laneValue = manipulation(value); | ||
result = (result << NBits) | laneValue; | ||
} | ||
return result; | ||
} |
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.
not 100% sure about the names for manipulation
etc right now but would be good to get your opinion on this approach.
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 might be a reasonable way to do this, but I'd use the appropriate algorithm in #include <algorithm>
and I would not take by const
-r-value reference something that ought to be a pure forwarding reference, meaning ManipulationFN &&
Make sure you never put const
-r-value, either const
-l-value when strictly necessary, or forwarding reference whenever possible.
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.
Improvements all around, but, like in the movie "Whiplash", still not quite my tempo.
Since you have given us the construction from literals, perhaps it is a good idea to do the opposite of having a conversion operator to array of values,
constexpr operator std::array<T, Lanes>();
and a named conversion to_array
inc/zoo/swar/SWAR.h
Outdated
} | ||
template <std::size_t N> | ||
constexpr BooleanSWAR(Literals_t<NBits, T>, const bool (&values)[N]) | ||
: Base(Literals<NBits, T>, values) { this->m_v << (NBits - 1); } |
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.
My typo in the comment, this has no effect, change to <<=
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.
great, works perfectly.
|
inc/zoo/swar/SWAR.h
Outdated
} | ||
return result; | ||
} | ||
|
||
template <typename Arg, std::size_t N, typename = std::enable_if_t<N == Lanes, int>> | ||
constexpr | ||
SWAR(Literals_t<NBits, T>, const Arg (&values)[N]) | ||
: m_v{loadIntoLanes(values, [](auto x) { return x; })} {} | ||
: m_v{loadIntoLanes(values)} {} |
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.
May you please indent to multiples of four spaces?
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.
You're free to merge yourself after you're satisfied
inc/zoo/swar/SWAR.h
Outdated
constexpr static auto calculateLeastSignificantLaneMask() { | ||
const auto m = | ||
sizeof(T) * 8 == NBits ? // needed to avoid shifting all bits | ||
~T(0) : | ||
~(~T(0) << NBits); | ||
return m; | ||
} | ||
constexpr static inline type |
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.
Nah...
This calculation does not deserve a name.
I think since C++17 we can use constexpr lambdas, that would be more appropriate below.
However, I showed you that this calculation is not needed, you're repating, and that's the bad part, the bulk of the work done in other constants.
Better than repeating the work is to use the work already done, primarily because then you have cross-checking that things work, if there's a mistake in the old, the new might discover it, if further nuance is discovered the new might benefit from it directly.
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.
Thanks, should have reverted. This was a debugging attempt. Was getting a red herring compiler message about this variable not being constexpr when trying to implement to_array
.
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.
The latest changes made the PR not mergeable anymore, please review
inc/zoo/swar/SWAR.h
Outdated
constexpr std::array<T, Lanes> to_array() const noexcept { | ||
std::array<T, Lanes> result; | ||
for (int i = 0; i < Lanes; ++i) { | ||
auto otherEnd = Lanes - i - 1; | ||
result[otherEnd] = at(i); | ||
} | ||
return result; | ||
} | ||
|
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 endianness conversion bothers me.
Your code is correct, but there is something about endianness that is creeping up that is bothering me.
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.
Yeah I agree there is something to figure out here. I think you would agree that the to_array should produce arrays with the same endianness as the input like this:
static_assert(SWAR{Literals<4, u8>, {1, 2}}.to_array() == std::array<u8, 2>{1, 2});
Not sure the best thing to suggest here.
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.
Your code is correct. Furthermore, your choice to adopt big endianness for arrays was superior to the alternative, but now we have this flipping of endianness that I don't know what to do about; I'm just voicing the idea, and plan to keep it in the back of my head to see where we go with this.
test/CMakeLists.txt
Outdated
@@ -81,7 +81,7 @@ if(MSVC) | |||
endif() | |||
else() | |||
# Non-MSVC specific configuration (original content) | |||
set(CMAKE_CXX_STANDARD 17) | |||
set(CMAKE_CXX_STANDARD 23) |
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.
Support for compilation under MSVC is on a "best effort" basis, we try, but we can't guarantee we will succeed at all the things. It is acceptable to bump to 23, but please explain why you found the need
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 for the non-MSVC path. This is to enable support for std::array in a constexpr context.
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.
Reverted, we should address in another PR. This one is already hard to keep track of.
@thecppzoo maybe best to merge where we were happy and add the |
4a1138c
to
a7d744d
Compare
add to_array oops make 23 for now not sure we want to commit to this? remove named function Revert "Add to Array" This reverts commit a7d744d.
a7d744d
to
1cba60e
Compare
inc/zoo/swar/SWAR.h
Outdated
MaxUnsignedLaneValue = LeastSignificantLaneMask; | ||
|
||
template <typename U> | ||
constexpr auto loadIntoLanes(const U (&values)[Lanes]) const noexcept { |
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.
Please rename to from_array
. As the symmetrical operation to to_array
.
Also, this is a factory, it ought to be static
, a class-function, not instance.
Actually, we also need a constructor from std::array
.
Apologies for all of the creep, I just think there is a lot of extra value by making SWAR
a really ergonomic type as opposed to somewhat ergonomic.
I dislike that C++ forces you to do a lot of boilerplate, I've never figured out how to make tools to eliminate the work to do the boilerplate.
My preference with this PR is to not just introduce the support for direct initialization of literals, but complete it with the following:
Separately, I think we can also add a header, such as Indicate if you'd like to split these features with me or prefer to do them all yourself. |
If you want to take on the From what I understood from playing around with this today we will require C++ >17 in order to use Even with C++23 am seeing failures to compiler on |
constexpr static auto from_array(const U (&values)[Lanes]) noexcept { | ||
auto result = T{0}; | ||
for (auto value : values) { | ||
result = (result << NBits) | 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.
blitElement?
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.
I this does not quite blit the element, if it will move in an element, it shifts up what it got and then adds to the least significant lane
moved this into a new PR for clarity. Literals can now be written like so: