ENH, SIMD: Optimize/vectorize comparison and logical operations for VSX#21258
ENH, SIMD: Optimize/vectorize comparison and logical operations for VSX#21258rafaelcfsousa wants to merge 1 commit into
Conversation
59cf6b1 to
957f601
Compare
|
Hi, I would like to request a review of my code (cc: @mattip , @seiko2plus ) The errors in the CI seem to be something related to timeout. The PRs Thanks! |
|
It seems this is a bit orthogonal to the SIMD dispatching framework. It is defining new loops with specific vsx labels, rather than trying to use the existing macro names. Is there a reason you chose this path? Since you are redefining the dispatching, we need to be very sure you are not changing the dispatching for the other architectures. Can you run benchmarks on an AVX512 machine to make sure nothing has changed? |
957f601 to
680bda0
Compare
Hi @mattip, thank you for reviewing my code! The source file The source file The changes of this PR do not affect x86 (AVX2, AVX512, etc) since they are enabled only for VSX/Power. I also executed benchmarks on an AVX512 machine to make sure that it would not generate issues in terms of performance. P.S.: I just pushed a new commit to avoid unnecessary code that was being generated for x86. Now, with/without this PR the object generated from |
| docstrings.get('numpy.core.umath.logical_and'), | ||
| 'PyUFunc_SimpleBinaryComparisonTypeResolver', | ||
| TD(nodatetime_or_obj, out='?', simd=[('avx2', ints)]), | ||
| TD(bints+inexact, out='?', simd=[('avx2', ints), ('vsx', '?fd')]), |
There was a problem hiding this comment.
bints+inexact is equivalent to nodatetime_or_obj, let's leave this as it was
| TD(bints+inexact, out='?', simd=[('avx2', ints), ('vsx', '?fd')]), | |
| TD(nodatetime_or_obj, out='?', simd=[('avx2', ints), ('vsx', '?fd')]), |
There was a problem hiding this comment.
We have a lint error with this change, should I fix it?
| "xmmintrin.h", # SSE | ||
| "emmintrin.h", # SSE2 | ||
| "immintrin.h", # AVX | ||
| "altivec.h", # VSX |
There was a problem hiding this comment.
Did this used to be available on macOS too?
There was a problem hiding this comment.
Hi @mattip, this line generates the macro #define HAVE_ALTIVEC_H 1 in the source file numpy/core/include/numpy/config.h, which means that, if I remove it the optimizations of this PR wouldn't be generated for VSX/Power.
|
A few minor nits, this looks good to me. @seiko2plus any thoughts? |
This commit optimizes the following operations for Power/VSX:
- equal, not_equal, less, less_equal, greater and greater_equal
- logical_and, logical_not and logical_or
- absolute
See below the average speedup with N=1000000:
- Comparisson functions:
- arry OP arr: bool (32.77x) float(3.36x) double(1.43x)
- arry OP scalar: bool (33.47x) float(6.34x) double(2.25x)
- Logical functions:
- logical_and: bool (118.12x)
- logical_not: bool ( 21.41x)
- logical_or: bool ( 24.40x)
- Miscellaneous:
- absolute: bool (23.12x)
680bda0 to
7e55cbe
Compare
seiko2plus
left a comment
There was a problem hiding this comment.
sorry for delay response, but the current need to modified to accomplish the following:
- using dispatch-able sources rather then compiler target attribute
- using universal intrinsics instead of raw SIMD.
| 'PyUFunc_AbsoluteTypeResolver', | ||
| TD(bints+flts+timedeltaonly, dispatch=[('loops_unary_fp', 'fd')]), | ||
| TD(ints+flts+timedeltaonly, dispatch=[('loops_unary_fp', 'fd')]), | ||
| TD('?', out='?', simd=[('vsx', '?')]), |
There was a problem hiding this comment.
| TD('?', out='?', simd=[('vsx', '?')]), | |
| TD('?', out='?', dispatch=[('loops_comparison', '?')]), |
please don't follow our legacy code, dispatch-able sources should be used instead, easy to trace, can be manged through cpu options(--cpu-dispatch, --cpu-baseline) wthin the buid.
| * 2) 8x 64-bit vectors, for DOUBLE. | ||
| */ | ||
|
|
||
| static void NPY_GCC_OPT_3 NPY_INLINE NPY_GCC_TARGET_VSX |
There was a problem hiding this comment.
please use universal intrinsics instead, it will require adding new intrinsics for packing boolean values, the rest of intrinsics already implemented.
npyv_b8 npyv_pack_b8_b16(npyv_b16 a, npyv_b16 b);
npyv_b8 npyv_pack_b8_b32(npyv_b32 a, npyv_b32 b, npyv_b32 c, npyv_b32 d);
npyv_b8 npyv_pack_b8_b64(npyv_b64 a, npyv_b64 b, npyv_b64 c, npyv_b64 d, npyv_b64 e, npyv_b64 f, npyv_b64 g, npyv_b64 h);
just create new dispatch-able source e.g. EDIT: add another example. |
|
@rafaelcfsousa the cutoff for the next version of NumPy is getting close. |
|
Hi @mattip, I already have the code implemented, and will spend 1-2 days executing testing / benchmarking. Instead of submitting the changes here, I will open a new PR as the code is completely different from the one of this PR. If you prefer I submit here, let me know. What I did: Well, as I do not have access to an ARM processor for testing, can I rely on the CI for this task? (not sure how to do that) |
|
Cool. A new PR is fine, whatever is easiest for you
Yup. If you have doubts, please point them out. I have access to aarch64 (linux) and arm64 (macOS) machines. |
|
I will close this PR as I opened another PR to implement the changes requested above (#21483). |
This PR optimizes the following operations for Power/VSX:
See below the average speedup with N=1000000:
Comparisson functions:
Logical functions:
Miscellaneous:
Note: This PR enables the optimizations above for Power8, Power9 and Power10.