eschnett / SIMD.jl

Explicit SIMD vector operations for Julia
Other
169 stars 35 forks source link

Vectorized math functions #106

Open dubosipsl opened 1 year ago

dubosipsl commented 1 year ago

Thanks for developing SIMD.jl which I use in a number-crunching project of mine for explicit vectorization.

When experimenting with SIMD I realized that many math functions (e.g. exp, log), when given a SIMD.Vec, would simply call Base for each element of the Vec rather than offering a vectorized implementation. This makes Julia look bad compared to, say, Fortran. Please correct me if I am wrong.

After some search I found that SLEEFPirates.jl offers such vectorized implementations, sometimes with slightly degraded accuracy as with @fastmath.

So I developed some code to use SLEEFPirates when calling exp_fast etc. on SIMD.Vec arguments. The code is here : https://gitlab.in2p3.fr/ipsl/lmd/intro/geofluids/gfpackages/-/blob/master/Computing/GFLoops/julia/src/CPU/vector_math.jl This works well for my purposes but I feel this would rather be part of SIMD.jl, possibly with a weak dependency on SLEEFPirates ?

I have also some code providing a few non-mathematical "missing" features (mostly array indexing) here : https://gitlab.in2p3.fr/ipsl/lmd/intro/geofluids/gfpackages/-/blob/master/Computing/GFLoops/julia/src/CPU/simd.jl

Any thoughts, including critics on my code, are welcome.

eschnett commented 1 year ago

Thanks! I'd be very interested in have such code in SIMD.jl. Unfortunately I might not have time to look at that in detail in then near future. Maybe you or someone else has time to turn this into a pull request?

A dependency on SLEEFPirates.jl or a similar package sounds fine to me.

KristofferC commented 1 year ago

A dependency on SLEEFPirates.jl or a similar package sounds fine to me.

To me that really sounds like the reverse of what should be done. The design of this package is very "clean" and limited in scope and if anything, other packages should depend on it. It provides:

Depending on SLEEFPirates would pull in VectorizationBase.jl which is a direct "competitor" to SIMD.jl. Just look at all the code in https://github.com/JuliaSIMD/VectorizationBase.jl/tree/master/src. It's an endless amount of bloat. If you add a dependency on VectorizationBase the whole point of this package falls apart and you might as well just use VectorizationBase in the first place.

dubosipsl commented 1 year ago

I see you concern. With what I did vectorized functions go to SLEEFPirates then VectorizationBase, and bypass SIMD.jl .

Proceeding the other way round would be to make SLEEFPirates work with SIMD.Vec . I have taken a brief look at the SLEEFPirates code and this looks beyond my capacities. There are a lot of optimized variants depending on architecture and I get lost very quickly.

I have also looked at SLEEF.jl . The code is a lot simpler. After some modifications I have managed to let exp(x) work with SIMD.Vec. It may be possible to do that for the other functions too with some effort. It would require a few extra functions in SIMD.jl too(for instance, unsafe_trunc for SIMD.Vec).

There is no urgency on my side. We can discuss further this topic if you are interested.

dubosipsl commented 1 year ago

Following up. I have turned the aforementioned vector_math.jl into a standalone package depending on SIMD, VectorizationBase and SLEEFPirates as advocated by @KristofferC .
https://gitlab.in2p3.fr/ipsl/lmd/intro/geofluids/gfpackages/-/tree/master/Computing/SIMDFunctions

Now import SIMDFunctions provides vectorized versions of cos(x::SIMD.Vec) and the like.

Ideally it would be registered with the general registry, but I have zero experience with that. Would you be willing to help ? If so I could improve the doc. Probably tests are needed too.

dubosipsl commented 1 year ago

Yet another possibility is to let SLEEFPirates be a weak dependency ( Julia 1.9). See #117. Benefits: