-
Notifications
You must be signed in to change notification settings - Fork 277
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
Implement vec_perm #451
Implement vec_perm #451
Conversation
ci/run.sh
Outdated
@@ -26,6 +26,7 @@ case ${TARGET} in | |||
export STDSIMD_DISABLE_ASSERT_INSTR=1 | |||
;; | |||
powerpc64-*) | |||
export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+altivec" |
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 should not be required
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.
That is some stray from testing, let me remove it now.
47b90c2
to
20ec176
Compare
Now using the arch-specific newtypes. |
Now we also have xxpermdi so we can check how vsx instructions fare. |
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.
So it's looking really good. I've left some comments, mostly nitpicks.
I am worried that #[inline]
won't be enough to propagate the constant through the trait method, but I don't recall if we can use #[inline(always)]
here or not.
coresimd/powerpc/altivec.rs
Outdated
} | ||
} | ||
|
||
vector_perm!{ i8x16 } |
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.
These should be implemented for the powerpc vector types, not the portable vector types. Right now they are type aliases, but the PowerPC vector types should be newtypes like on arm and mips.
coresimd/powerpc/altivec.rs
Outdated
/// Vector permute. | ||
#[inline] | ||
#[target_feature(enable = "altivec")] | ||
pub unsafe fn vec_perm<T>(a: T, b: T, c: vector_unsigned_char) -> T |
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.
assert_instr
is missing, and won't work on the generic function. You are going to have to add some functions somewhere for it to work (at that point the solution will probably look very similar to that of vec_add
).
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.
vec_vperm is the function used for the test.
#[inline] | ||
#[target_feature(enable = "altivec")] | ||
#[cfg_attr(test, assert_instr(vperm))] | ||
unsafe fn vec_vperm(a: vector_signed_int, b: vector_signed_int, c: vector_unsigned_char) -> vector_signed_int { |
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 think we should add assert_instr
tests for all vector types.
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.
That function is the only one that is called for every vector type.
All the vector types are transmuted to i32x4.
coresimd/powerpc/altivec.rs
Outdated
T: sealed::VectorPerm, | ||
{ | ||
|
||
if cfg!(target_endian = "little") { |
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.
prefer conditional compilation here: #[cfg(target_endian = "little")]
and #[cfg(not(target_endian = "little"))]
(or #[cfg(target_endian = "big")]
).
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.
Something along the lines of
#[cfg(target_endian = "little")]
mod endian {
}
#[cfg(target_endian = "big")]
mod endian {
}
use self::endian::*;
coresimd/powerpc/altivec.rs
Outdated
@@ -666,6 +734,18 @@ mod tests { | |||
use simd::*; | |||
use stdsimd_test::simd_test; | |||
|
|||
#[simd_test(enable = "altivec")] | |||
unsafe fn vec_perm_u16x8() { |
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.
there should be one run-time test for every vector type as well
I think that for consistency with how it is done in the other architectures we should name the run-time tests: test_{intrinsic_name}_{short_vector_types}
, so this becomes test_vec_perm_u16x8
.
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 can macro those tests, but it would basically test that transmute works for those types.
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.
That would be great, testing these is tedious, but sometimes optimizations happen that break this, and we also scan for assert_instr in stdsimd-verify
. It would be great if the names of these functions follows a convention so that the code that scans them automatically becomes easier to write. (I followed one convention for vec_add, but maybe there is a better one).
coresimd/powerpc64/vsx.rs
Outdated
#[inline] | ||
#[target_feature(enable = "vsx")] | ||
#[cfg_attr(test, assert_instr(xxpermdi, dm = 0x0))] | ||
unsafe fn xxpermdi(a: i64x2, b: i64x2, dm: u8) -> i64x2 { |
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 think this is missing a #[rustc_args_required_const(2)]
to require that the user passes a compile-time constant to dm
.
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.
That won't work with the trait approach :/
crap
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.
Maybe make this function and the trait method impls #[inline(always)]
?
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 function exists mainly for the instruction test.
The const-argument is enforced on the only part that the user sees. Probably #[inline(always)]
is a good idea in case the compiler decides to not const-propagate w/out the specific hint.
coresimd/powerpc64/vsx.rs
Outdated
use stdsimd_test::simd_test; | ||
|
||
#[simd_test(enable = "vsx")] | ||
unsafe fn vec_xxpermdi_u62x2() { |
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.
Also missing tests for the other vector types.
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.
As per vec_perm, it it would test how good mem::transmute
is.
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.
Here the tests for other vector types are still missing, otherwise the rest of the PR LGTM and can be merged.
I refactored the endian-biased intrinsic support so it is a bit more structured. |
So this looks good. I'll retry the tests once CI is working again. |
6eba577
to
99bc589
Compare
Now the set is rebased over #455 |
That's a... curious test failure!
|
Yes... how do we implement equality for that type on BE? |
It's here: https://github.com/rust-lang-nursery/stdsimd/blob/master/coresimd/ppsv/api/partial_eq.rs#L9 We do a vertical equality comparison and then test if all bits are set. |
I managed to find other unrelated problems while trying to reproduce the issue locally: rust-lang/rust#50960 Shall we demote powerpc and powerpc64 for the time being? |
That was the original plan any ways. We are currently only running the Since |
Now it is all green (by cheating) :) |
So I would prefer to just disable the run-time tests in CI e.g. by passing an environment variable that just ignores the |
Sure, could you please point me how to do that and suggest a name for the variable? |
We already have The place is the |
Bit and Little endian supported.
Otherwise some objdump output would not parse correctly.
It is what objdump produces usually.
Use STDSIMD_TEST_NORUN=1 to disable them.
Do you see something wrong in my travis update? |
The big endian variant will be supported properly later.
The run script doesn't forward the environment set on travis. I put the env variable directly in the script. |
Thanks a lot for this! This is really good work! |
It is pretty much the opposite of
vec_add
: there is a single instructionvperm
that works with all the possible vector types as long the operands and return type match.The instruction has an endianness bias and it is implemented only for little endian for now.