diff --git a/algo_rationale.html b/algo_rationale.html index 30e0d82844..ddb12e6443 100644 --- a/algo_rationale.html +++ b/algo_rationale.html @@ -125,7 +125,7 @@
SIMD algorithms are complex to design, implement and tests as a lot of care has to be put into details like correct tail handling, alignment handling or unrolling.
EVE's algorithms and views module is designed to simplify such design while:
@@ -137,24 +137,24 @@All those features are usable through generic interfaces to allow for reuse of similar loops structure at the cost of some idiosyncrasies.
For a in-depth discussion about those issues, you can take a look at the Algorithms section of our CppCon talk.
-Many algorithms require some form of while(f != l)
loop. However, with SIMD, even this simple operation is non trivial. EVE algorithm building-blocks provide implementation for the most frequent loop structure. Those loops can then customized and reused without having to care about the actual range type used. For example, eve::mismatch is implemented as a customized call to eve::find.
Iterators are more fundamental than ranges. However, ranges can have some extra information like, for example, that instead of begin()
it has aligned_begin()
and the algorithm can use that. So the interfaces are range
based. We don't generally accept iterator
in interfaces just because it increases the maintenance. The eve::algo::as_range can be used to turn iterators pair into a EVE compatible range.
One case where it can be very awkward to use ranges instead of iterators is in multi-range algorithms , like transform_to
. In this case, unless we have some reason no to, we allow for passing anything that zips to range
, i.e. range
, iterator
or iterator
,range
. Exceptions are documented and have static_assert
s that will tell you it's not supported.
Many things that we want to accept in the interfaces as range
and/or iterator
are not ideal for writing code against. We also need to strip things like vector::iterator
to pointers. What also we want is to associate a cardinal
with iterator
.
This is why we have two layers: relaxed_range
/relaxed_iterator
and iterator
. There are a few things that relaxed_*
should be able to do but the main one is preprocess_range(traits, f, l)
which returns enhanced traits
and iterator
pair.
EVE allows to customize algorithms with traits. Traits are passed via []
and can be combined.
The more common ones are:
diff --git a/changelog.html b/changelog.html index a5638d0343..0162478e05 100644 --- a/changelog.html +++ b/changelog.html @@ -125,24 +125,24 @@Codename: Perdita Quiescent
-eve::complex
.Full Changelog: https://github.com/jfalcou/eve/compare/v2022.09.1...2023.02.15
-Codename: Rosalind Serendipitous
This is a patch release that fix some issue with the versioning of EVE installation and some documentation issue.
Full Changelog: https://github.com/jfalcou/eve/compare/v2022.09.0...2022.09.1
-Codename: Rosalind Serendipitous
-A lot. The main non-code changes is our move from MIT License to the BOOST SOFTWARE License. Next to that, support for more algorithms and complex numbers has been added.
Starting this fall, we will also try to provide more regular release.
@@ -242,17 +242,17 @@Thanks to all our new contributor for this release!
Codename: Miranda Numinous
-This release is an API/ABI breaking changes release.
A lot of improvements in QoL, QoI, and API have been made. Some more breaking ABI changes are planned, including a passive move toward an include file layout more amenable to future modularization.
@@ -345,7 +345,7 @@Thanks to all our new contributor for this release!
**the-moisrex**
made their first contribution in https://github.com/jfalcou/eve/pull/1025**toughengineer**
made their first contribution in https://github.com/jfalcou/eve/pull/1182Codename: Titania Unleashed
-Initial beta release
When you call a function on one or more SIMD values, you expect the computation to be performed on every elements of its parameters. Sometimes, you may want to make the application of a given function dependent on some condition.
Let's explore the functionalities EVE provides for achieving those results.
-Let's say the function we want to write computes the product of two values a
and b
if a
is equal to b
and their difference otherwise.
The scalar code is looking like:
@@ -164,7 +164,7 @@false
, here the difference of a
and b
if ... else
statement, eve::if_else will evaluates all its arguments before performing its selection even if potential short-cut can be applied later on.Let's define a sqrt_positive
function that computes the square root of its argument if it's positive or returns it unchanged otherwise. One can write:
If passing a simple logical expression is the most common use-case of the conditional syntax, one may requires more flexibility. To do so, EVE provides various objects to express more elaborated conditions.
-One may want to use the conditional syntax to call a function but instead of returning the first argument if the condition is false, one may want to return an arbitrary value. This use case is handled by the eve::if_ helper by wrapping logical expression so that an alternative value can be specified.
Let's modify sqrt_positive
so that, if the argument is not positive, 0 is returned instead.
Some algorithms require conditional function calls but use logical expression relative to the element index inside a eve::simd_value rather than its value. One may want for example to not compute an expression on the first and last element of such eve::simd_value.
A frequent example is trying to load data from memory while ignoring trailing garbage or out of bounds values:
@@ -320,7 +320,7 @@The output is obviously the same.
-Conditional operations on SIMD values is a good way to keep a high level code over some complex computations. EVE provides different levels of abstraction for such operations as well as various helpers to specify how the conditions can be computed based either on values or indexes.
diff --git a/dev_cmake.html b/dev_cmake.html index a4ec637c61..00f49a61cb 100644 --- a/dev_cmake.html +++ b/dev_cmake.html @@ -126,7 +126,7 @@From now on, we make the assumption your Docker instance is running and that you're logged into its interactive shell as per the protocol previously defined. In this tutorial, we will go over the process to configure the tests and run them properly.
-First, you'd need to create a build directory and cd into it
mkdir build_arch && cd build_arch @@ -167,7 +167,7 @@
Arm (sve-512) cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/gcc.sve512.cmake Once run, your build folder should contain all the necessary artifact to compile and run EVE test suite.
-+
Compiling EVE Unit Tests
EVE provides a large number of test targets that are grouped by theme. Each of these themes and tests with a theme can be compiled with a proper target.
In term of options, we encourage you to use the
@@ -223,7 +223,7 @@-DEVE_NO_FORCEINLINE
macro that prevents costly optimization to be used during the compilation of tests.
Once compiled, the test executable are located in the unit
folder and can be run via:
./unit/unit.core.abs.exe
The unit.exe
target is very large and requires a comfortable amount of CPUs to be compiled in parallel.
Random tests run a given function over a samples of random values to test its relative precision. The following table list the main high-level random target.
constexpr auto | eve::tanpi = functor<tanpi_t> |
elementwise_callable object computing the tangent from an input in \(\pi\) multiples. | |
constexpr full_circle_type const | eve::full_circle = {} |
Higher-order Callable Object imbuing a limited range semantic onto other Callable Objects. | |
constexpr quarter_circle_type const | eve::quarter_circle = {} |
Higher-order Callable Object imbuing a limited range semantic onto other Callable Objects. | |
constexpr half_circle_type const | eve::half_circle = {} |
Higher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects. | |
Parameters
* `x`: [floating value](@ref floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -190,7 +189,7 @@Example
- +}diff --git a/group__math__trig_ga18a94fd518b423cd10fbc07e5ac67d26.html b/group__math__trig_ga18a94fd518b423cd10fbc07e5ac67d26.html index d8f10d0155..5876c1d636 100644 --- a/group__math__trig_ga18a94fd518b423cd10fbc07e5ac67d26.html +++ b/group__math__trig_ga18a94fd518b423cd10fbc07e5ac67d26.html @@ -153,13 +153,12 @@Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr auto tanpielementwise_callable object computing the tangent from an input in multiples.Definition: tanpi.hpp:78constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159Parameters
* `x`: [floating value](@ref floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. diff --git a/group__math__trig_ga19188d4707f5219c4a8a3f964518a616.html b/group__math__trig_ga19188d4707f5219c4a8a3f964518a616.html index edb1028c34..9ad0718494 100644 --- a/group__math__trig_ga19188d4707f5219c4a8a3f964518a616.html +++ b/group__math__trig_ga19188d4707f5219c4a8a3f964518a616.html @@ -153,13 +153,12 @@Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr auto tandelementwise_callable object computing the tangent from an input in degrees.Definition: tand.hpp:78constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159
x
: floating value.Parameters
Parameters
* `x`:[floating real value](@ref eve::floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -190,7 +189,7 @@Example
- +}diff --git a/group__math__trig_ga216a80d7f91be23dc0d74e26eb057000.html b/group__math__trig_ga216a80d7f91be23dc0d74e26eb057000.html index 26256d4a8f..76ab9e62a1 100644 --- a/group__math__trig_ga216a80d7f91be23dc0d74e26eb057000.html +++ b/group__math__trig_ga216a80d7f91be23dc0d74e26eb057000.html @@ -153,13 +153,12 @@Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr auto cosdelementwise_callable object object computing cosine from an input in degrees.Definition: cosd.hpp:80constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159Parameters
* `x`: [floating real value](@ref eve::floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -190,7 +189,7 @@Example
- +}diff --git a/group__math__trig_ga39e50b4c59911e463be1a11fc958fb86.html b/group__math__trig_ga39e50b4c59911e463be1a11fc958fb86.html index 0e2b47ac3e..9c2fd4283d 100644 --- a/group__math__trig_ga39e50b4c59911e463be1a11fc958fb86.html +++ b/group__math__trig_ga39e50b4c59911e463be1a11fc958fb86.html @@ -153,17 +153,14 @@Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304Header file
// Semantic options- - - + + +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159-constexpr full_circle_type const full_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:158constexpr half_circle_type const half_circleHigher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects.Definition: trigo_tags.hpp:160Parameters
* `x`: [floating value](@ref eve::floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -205,9 +202,9 @@Example
- - - + + +}diff --git a/group__math__trig_ga507c21955358dcd61c84f41e65d977c4.html b/group__math__trig_ga507c21955358dcd61c84f41e65d977c4.html index 0ea571c33d..4bb66b289a 100644 --- a/group__math__trig_ga507c21955358dcd61c84f41e65d977c4.html +++ b/group__math__trig_ga507c21955358dcd61c84f41e65d977c4.html @@ -153,13 +153,12 @@Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr auto sinpielementwise_callable object computing the sine from an input in multiples.Definition: sinpi.hpp:78constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159Parameters
* `x`: [floating value](@ref floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -190,7 +189,7 @@Example
- +}diff --git a/group__math__trig_ga5125fa88aef3909aad8d39e760305c82.html b/group__math__trig_ga5125fa88aef3909aad8d39e760305c82.html deleted file mode 100644 index 77387502ce..0000000000 --- a/group__math__trig_ga5125fa88aef3909aad8d39e760305c82.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - -Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304E.V.E: eve::quarter_circle - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- -- - - - - - - - - - diff --git a/group__math__trig_ga582ee61bd6909c6b95af359339d32c2b.html b/group__math__trig_ga582ee61bd6909c6b95af359339d32c2b.html deleted file mode 100644 index 4bc13633c6..0000000000 --- a/group__math__trig_ga582ee61bd6909c6b95af359339d32c2b.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - - --- - --- ------ --Loading...-Searching...-No Matches-- --◆ quarter_circle
- -----
-- -- --
-- -eve::quarter_circle = {} --inlineconstexpr ----Members Functions
-- --
- Parameters
- -
--
-- f An instance of eve::callable - -
- Returns
- A Callable Object performing the same kind of operation but gives the correct result in \([-\pi/4, +\pi/4]\) only and Nan outside. (respectively \([-45, +45]\) if the input in in degrees, \([-0.25, +0.25]\) if the input in in \(\pi\) multiples)
E.V.E: eve::full_circle - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- -- - - - - - - - - - diff --git a/group__math__trig_ga664582204f1e5e323b88bf429706c77f.html b/group__math__trig_ga664582204f1e5e323b88bf429706c77f.html index 49796254cb..7a7113418d 100644 --- a/group__math__trig_ga664582204f1e5e323b88bf429706c77f.html +++ b/group__math__trig_ga664582204f1e5e323b88bf429706c77f.html @@ -153,17 +153,14 @@-- - --- ------ --Loading...-Searching...-No Matches-- --◆ full_circle
- -----
-- -- --
-- -eve::full_circle = {} --inlineconstexpr ----Members Functions
-- --
- Parameters
- -
--
-- f An instance of eve::callable -
- Returns
- A Callable Object performing the same kind of operation but gives the correct result in \([-\pi, +\pi]\) only and Nan outside. (respectively \([-180, +180]\) if the input in in degrees, \([-1.0, +1.0]\) if the input in in \(\pi\) multiples)
full_circle is currently supported only by direct trigonometric object functions This decorator leads to the fastest algorithm at full precision.
- -Header file
// Semantic options- - - + + +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr full_circle_type const full_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:158-constexpr auto cscelementwise_callable object computing the cosecant of the input.Definition: csc.hpp:85constexpr half_circle_type const half_circleHigher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects.Definition: trigo_tags.hpp:160Parameters
Parameters
* `x`: [floating value](@ref eve::floating_value). @@ -194,7 +193,7 @@Example
- +}diff --git a/group__math__trig_ga84bdaf88941577d9b23999ae965b631b.html b/group__math__trig_ga84bdaf88941577d9b23999ae965b631b.html index 84efae64ef..e3efa0580e 100644 --- a/group__math__trig_ga84bdaf88941577d9b23999ae965b631b.html +++ b/group__math__trig_ga84bdaf88941577d9b23999ae965b631b.html @@ -153,12 +153,11 @@Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr auto sindcosdelementwise_callable object computing the simultaneous computation of sine an cosine from an argument...Definition: sindcosd.hpp:81Parameters
* `x`: [floating value](@ref floating_value). @@ -182,7 +181,7 @@Example
std::cout << "<- wf = " << wf << "\n";- +}diff --git a/group__math__trig_ga84c8a10368a87019fd81eb234c3f09da.html b/group__math__trig_ga84c8a10368a87019fd81eb234c3f09da.html index 9521f82238..79c32ca468 100644 --- a/group__math__trig_ga84c8a10368a87019fd81eb234c3f09da.html +++ b/group__math__trig_ga84c8a10368a87019fd81eb234c3f09da.html @@ -153,12 +153,11 @@Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr auto secpielementwise_callable object computing secant from an input in multiples.Definition: secpi.hpp:81Parameters
* `x`: [floating value](@ref floating_value). @@ -193,7 +192,7 @@Example
- +}diff --git a/group__math__trig_ga9016964468b90f782aa01ba4be5e44ed.html b/group__math__trig_ga9016964468b90f782aa01ba4be5e44ed.html index 3d4a17fc9d..c75bd0e10a 100644 --- a/group__math__trig_ga9016964468b90f782aa01ba4be5e44ed.html +++ b/group__math__trig_ga9016964468b90f782aa01ba4be5e44ed.html @@ -153,17 +153,14 @@Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304Header file
// Semantic options- - - + + +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr full_circle_type const full_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:158-constexpr auto secelementwise_callable object computing the secant of the input.Definition: sec.hpp:85constexpr half_circle_type const half_circleHigher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects.Definition: trigo_tags.hpp:160Parameters
* `x`: [floating value](@ref floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -203,9 +200,9 @@Example
- - - + + +}diff --git a/group__math__trig_ga91c450585092c45e088080706f4fe3df.html b/group__math__trig_ga91c450585092c45e088080706f4fe3df.html index 16c40390fd..7ed480dfbd 100644 --- a/group__math__trig_ga91c450585092c45e088080706f4fe3df.html +++ b/group__math__trig_ga91c450585092c45e088080706f4fe3df.html @@ -153,12 +153,11 @@Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr auto sinpicospielementwise_callable object computing the simultaneous computation of sin an cos from an argument in ...Definition: sinpicospi.hpp:79Parameters
* `x`: [floating value](@ref floating_value). @@ -182,7 +181,7 @@Example
std::cout << "<- wf = " << wf << "\n";-std::cout << "-> sinpicospi[quarter_circle](wf)= " << eve::sinpicospi[eve::quarter_circle](wf) << "\n";+std::cout << "-> sinpicospi[quarter_circle](wf)= " << eve::sinpicospi[eve::quarter_circle](wf) << "\n";}diff --git a/group__math__trig_ga9d321e65637ca035df92af12c1dcc5eb.html b/group__math__trig_ga9d321e65637ca035df92af12c1dcc5eb.html index de6fa661d8..00d7a68660 100644 --- a/group__math__trig_ga9d321e65637ca035df92af12c1dcc5eb.html +++ b/group__math__trig_ga9d321e65637ca035df92af12c1dcc5eb.html @@ -153,12 +153,11 @@Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr auto secdelementwise_callable object computing the secant from an input in degree.Definition: secd.hpp:80Parameters
* `x`: [floating value](@ref eve::floating_value). @@ -194,7 +193,7 @@Example
- +}diff --git a/group__math__trig_ga9f7c4b010d79f473531a7d83902b4d02.html b/group__math__trig_ga9f7c4b010d79f473531a7d83902b4d02.html index 1023e607e9..d5ab46bf6e 100644 --- a/group__math__trig_ga9f7c4b010d79f473531a7d83902b4d02.html +++ b/group__math__trig_ga9f7c4b010d79f473531a7d83902b4d02.html @@ -153,17 +153,14 @@Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304Header file
// Semantic options- - - + + +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr full_circle_type const full_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:158-constexpr auto sincoselementwise_callable object computing the simultaneous computation of sine an cosine.Definition: sincos.hpp:86constexpr half_circle_type const half_circleHigher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects.Definition: trigo_tags.hpp:160Parameters
* `x`: [floating value](@ref floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -191,9 +188,9 @@Example
std::cout << "<- wf = " << wf << "\n";- - - + + +}diff --git a/group__math__trig_gab8d411aa6820539627b8475e86395d45.html b/group__math__trig_gab8d411aa6820539627b8475e86395d45.html index 80195e41a4..6f487e37a4 100644 --- a/group__math__trig_gab8d411aa6820539627b8475e86395d45.html +++ b/group__math__trig_gab8d411aa6820539627b8475e86395d45.html @@ -150,17 +150,14 @@Header file
// Semantic options- - - + + +}-The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr full_circle_type const full_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:158-constexpr auto rempio2elementwise_callable object computing the remainder of the division by .Definition: rempio2.hpp:86constexpr half_circle_type const half_circleHigher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects.Definition: trigo_tags.hpp:160Parameters
* `x`: [floating value](@ref floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -191,9 +188,9 @@Example
std::cout << "<- wf = " << wf << "\n";- - - + + +}diff --git a/group__math__trig_gad0a09342c6bb010028e1686a0b1f599c.html b/group__math__trig_gad0a09342c6bb010028e1686a0b1f599c.html index 070524611c..b5c1c5ac24 100644 --- a/group__math__trig_gad0a09342c6bb010028e1686a0b1f599c.html +++ b/group__math__trig_gad0a09342c6bb010028e1686a0b1f599c.html @@ -153,17 +153,14 @@Header file
// Semantic options- - - + + +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr full_circle_type const full_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:158-constexpr auto cotelementwise_callable object computing the cotangent of the input.Definition: cot.hpp:88constexpr half_circle_type const half_circleHigher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects.Definition: trigo_tags.hpp:160Parameters
* `x`: [floating value](@ref eve::floating_value). * `c`: [Conditional expression](@ref conditional_expr) masking the operation. @@ -203,9 +200,9 @@Example
- - - + + +}diff --git a/group__math__trig_gad7f9ab92c007e0ae6219cd7c5991ffa9.html b/group__math__trig_gad7f9ab92c007e0ae6219cd7c5991ffa9.html deleted file mode 100644 index 4b2f9a0e79..0000000000 --- a/group__math__trig_gad7f9ab92c007e0ae6219cd7c5991ffa9.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - -E.V.E: eve::half_circle - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- -- - - - - - - - - - diff --git a/group__math__trig_gade4a273af7fb50439ae8974d4e5e8222.html b/group__math__trig_gade4a273af7fb50439ae8974d4e5e8222.html index 301f456624..056854605a 100644 --- a/group__math__trig_gade4a273af7fb50439ae8974d4e5e8222.html +++ b/group__math__trig_gade4a273af7fb50439ae8974d4e5e8222.html @@ -153,12 +153,11 @@-- - --- ------ --Loading...-Searching...-No Matches-- --◆ half_circle
- -----
-- -- --
-- -eve::half_circle = {} --inlineconstexpr ----Members Functions
-- --
- Parameters
- -
--
-- f An instance of eve::callable - -
- Returns
- A Callable Object performing the same kind of operation, but gives the correct result for \([-\pi/2, +\pi/2]\) only and Nan outside. (respectively \([-90, +90]\) if the input in in degrees, \([-0.5, +0.5]\) if the input in in \(\pi\) multiples)
Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr auto cotpielementwise_callable object computing the cotangent from an input in multiples.Definition: cotpi.hpp:80Parameters
* `x`: [floating value](@ref floating_value). @@ -191,7 +190,7 @@Example
- +}diff --git a/group__math__trig_gae413e8b133a104f344513b9500b7708b.html b/group__math__trig_gae413e8b133a104f344513b9500b7708b.html index 39a5d174e1..77376495da 100644 --- a/group__math__trig_gae413e8b133a104f344513b9500b7708b.html +++ b/group__math__trig_gae413e8b133a104f344513b9500b7708b.html @@ -153,12 +153,11 @@Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304Header file
// Semantic options- +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159constexpr auto cscpielementwise_callable object computing the cosecant in multiples.Definition: cscpi.hpp:74Parameters
@@ -191,7 +190,7 @@Example
- +}diff --git a/group__math__trig_gaf171d35de1087cbe903e3c5748cf19f3.html b/group__math__trig_gaf171d35de1087cbe903e3c5748cf19f3.html index 1a026ae8d0..dfebf772fa 100644 --- a/group__math__trig_gaf171d35de1087cbe903e3c5748cf19f3.html +++ b/group__math__trig_gaf171d35de1087cbe903e3c5748cf19f3.html @@ -153,16 +153,13 @@Conditional expression ignoring the k last lanes from a eve::simd_value.Definition: conditional.hpp:304Header file
// Semantic options- - - + + +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159-constexpr full_circle_type const full_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:158constexpr half_circle_type const half_circleHigher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects.Definition: trigo_tags.hpp:160Parameters
* `x`: [floating value](@ref floating_value). @@ -206,9 +203,9 @@Example
- - - + + +}diff --git a/group__math__trig_gaf92ef4ab7d8bd5a527db4d94bcebbdf7.html b/group__math__trig_gaf92ef4ab7d8bd5a527db4d94bcebbdf7.html index a8aab30b0a..8054ad899f 100644 --- a/group__math__trig_gaf92ef4ab7d8bd5a527db4d94bcebbdf7.html +++ b/group__math__trig_gaf92ef4ab7d8bd5a527db4d94bcebbdf7.html @@ -153,16 +153,13 @@Header file
// Semantic options- - - + + +}Specifies that a type is a Conditional Expression.Definition: conditional.hpp:27The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...Definition: value.hpp:95-The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...Definition: value.hpp:107-constexpr quarter_circle_type const quarter_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:159-constexpr full_circle_type const full_circleHigher-order Callable Object imbuing a limited range semantic onto other Callable Objects.Definition: trigo_tags.hpp:158constexpr half_circle_type const half_circleHigher-order Callable Object imbuing a limited range standard semantic onto other Callable Objects.Definition: trigo_tags.hpp:160Parameters
* `x`: [floating value](@ref floating_value). @@ -205,9 +202,9 @@Example
- - - + + +}diff --git a/index.html b/index.html index 7b44aa9206..f1efba4398 100644 --- a/index.html +++ b/index.html @@ -127,7 +127,7 @@EVE is a new implementation of the previous EVE SIMD library by Falcou et al. which for a while was named Boost.SIMD. It's a C++20 and onward implementation of a type based wrapper around SIMD extensions sets for most current architectures. It aims at showing how C++20 can be used to design and implement efficient, low level, high abstraction library suited for high performances.
It's a research project first and an open source library second. We reserve the right to change API and baseline compiler required until the first official 0.1 release. However, we'll try to minimize disruption. Semantic versioning will ensure API retro-compatibility if anything huge needs to change.
-+
Video materials
SIMD in C++20: EVE of a new Era - CppCon 2021
@@ -135,7 +135,7 @@
-
+
Bibliographic References
If you want to refers to EVE, you can currently use those papers (by order of preference in citation). A new, more up-to-date EVE specific journal paper is in the work atm.
diff --git a/index.js b/index.js index 3e3aaf764d..d9f69a58cb 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ var index = [ - [ "Video materials", "index.html#autotoc_md68", null ], - [ "Bibliographic References", "index.html#autotoc_md69", null ] + [ "Video materials", "index.html#autotoc_md63", null ], + [ "Bibliographic References", "index.html#autotoc_md64", null ] ]; \ No newline at end of file diff --git a/inter-with-native.html b/inter-with-native.html index b98504260d..dff4dfeae7 100644 --- a/inter-with-native.html +++ b/inter-with-native.html @@ -164,7 +164,7 @@
constexpr auto remove_ifSIMD version of std::remove_if.Definition: remove.hpp:87-static constexpr size_type size() noexceptSize of the wide in number of lanes.Definition: wide.hpp:376+
What about non-native sizes?
If the number is less than the one that can be natively represented, it's internally still represented as a full register. For example wide<int, eve::fixed<2>> on x86 is still __m128i. The relevant data just occupy the first 2 elements, the others can be garbage.
If the cardinal is larger than the one that can be natively represented, you can use slice to get to the half the wide size.
diff --git a/intro-01.html b/intro-01.html index 328949994a..d388e21ace 100644 --- a/intro-01.html +++ b/intro-01.html @@ -124,7 +124,7 @@Basic Operations-+
Initial problem
Let's say we want to convert 2D cartesian coordinates to 2D polar coordinates. This is a rather common exercise and will only require basic arithmetic and trigonometric functions.
Cartesian coordinates are usually represented by a pair of floating point values \((x,y)\). In a similar way, polar coordinate can be represented as a pair \((\rho,\theta)\) where \(\rho\) represents the length of the ray and \(\theta\) represents the angle with the X axis.
@@ -142,7 +142,7 @@return std::atan2(y, x);}As expected, the code only requires arithmetic operations and some trigonometry. Fellow mathematicians in the audience may have some remarks on this code. For now, we will deal with the fact that it requires \(\theta\) to be in radians and that the accuracy of computing \(\rho\) this way is maybe sub-optimal. We will address those concerns later.
-+
From scalar to SIMD using eve::wide
The next step is to work a SIMD version of those functions. When dealing with SIMD data types, one has to remember that a single operation has to be performed on multiple values. There, we will be working on multiple
x
andy
to computes multiple \(\rho\) and \(\theta\).SIMD instructions sets provides architecture-specific types for SIMD register along with ISA specific functions. Of course, handling such types and functions is highly non-portable. To overcome this issue, EVE provides a generic, architecture agnostic type for SIMD computation: eve::wide.
@@ -169,7 +169,7 @@
constexpr auto atan2elementwise_callable object computing the arc tangent using the signs of the arguments to determine t...Definition: atan2.hpp:109eve::wide behaves like a regular type and can just be dropped as a replacement for any C++ arithmetic types.
-+
Handling eve::wide
The remaining question is how to put data inside an instance of eve::wide so we can write tests for our SIMD cartesian to polar conversion function.
#include <iostream>@@ -205,7 +205,7 @@
(4, 4, 4, 4, 4, 4, 4, 4) (1.5, 3, 4.5, 6, 7.5, 9, 10.5, 12) => (4.272, 5, 6.0208, 7.2111, 8.5, 9.84886, 11.2361, 12.6491)(4, 4, 4, 4, 4, 4, 4, 4) (1.5, 3, 4.5, 6, 7.5, 9, 10.5, 12) => (0.358771, 0.643501, 0.844154, 0.982794, 1.08084, 1.15257, 1.20682, 1.24905)As expected, EVE code scales naturally with the selected architecture at compile time.
-+
Mathematical Epilogue
As stated earlier, we are currently using a slightly brutal computation for \(\rho\). Indeed, if the magnitudes of
x
andy
vary greatly, we may end up with overflow or cancellation, both classic IEEE 754 floating-point issues.Computing the square root of the sum of the squares of x and y, without undue overflow or underflow at intermediate stages of the computation is the job of a very specific function:
@@ -218,7 +218,7 @@std::hypot
. Quite handily, EVE also proposes a SIMD implementation via eve::hypot.
return eve::hypot(x, y);}-constexpr auto hypottuple_callable computing the norm of its inputs.Definition: hypot.hpp:88+
Conclusion
In this first tutorial, we managed to:
In the previous tutorial, we managed to convert a sequential function into a function using SIMD types and functions. In general, such function is meant to be applied to a large set of data instead of a single register.
As for usual sequential computation, we want to lift ourselves from raw loops and think using algorithms. EVE provides such ready-to-use SIMD aware algorithms and this tutorial will take a look at how to handle them.
-Let's try to apply our sequential conversion function over data stored in std::vector
using standard algorithms.
Very similar code, except for the fact the input data are passed directly without using iterators.
-We can turn this range-based code into a SIMD-aware call to one of the algorithms defined in eve::algo. All algorithms in EVE are range-based thus simplifying the transition from code using standard algorithms.
get
or structured bindings).In SIMD algorithms we by default assume that the provided operation is simple (a few instructions), since this is the common case. This means we use aligned reads and do unrolling, which is an important optimisation. However, for a complex case, like here, it is beneficial to opt out.
EVE provides various traits to customize algorithms behavior. The traits we're interested in are:
Best strategy is always to benchmark your code and tune algorithms accordingly.
Note that this kind of tuning is not reserved to algorithms. The callable eve::hypot
can also be tuned (here as eve::hypot[eve::pedantic]
) to enforce some behaviors regarding accuracy or standard compliance).
In this tutorial, we managed to:
In the previous tutorials, we built a SIMD function to compute those cartesian-polar conversions and we used them in the context of a SIMD algorithm to apply them over an arbitrary set of data. While doing so, we introduced the eve::views::zip component that helped us gather multiple ranges into a single one. This worked by feeding eve::algo::transform_to's lambda a tuple of eve::wide.
This interaction between SIMD registers and tuple-like types is very interesting and EVE provides different ways to take advantage of these interactions. In this tutorial, we'll go over how EVE can help you design SIMD-aware tuple to write higher level SIMD code.
-If we go back to the initial scalar conversion functions, we can actually merge both rho
and theta
functions in a single to_polar
function that will return a tuple of float containing both results of the conversion.
This version of the code just works out of the box. eve::wide is just a C++ type and thus interacts normally with other standard components.
-If the previous code is fine, it has the disadvantage of not being compatible to the general SIMD principle of EVE. Indeed, std::tuple
is not a eve::simd_value even when it contains eve::wide.
A better model should allow us to use eve::wide of tuples. To do so, we use kumi::tuple instead of std::tuple
. This change is due to the higher flexibility of kumi::tuple and its system of extension. kumi, as a library is integrated within EVE through the eve/product_type.hpp
header file and does not need any special setup.
eve::algo::allow_frequency_scaling
to simplify the example. We talk more about it in frequency scaling tutorial.In this tutorial, we managed to:
In the previous tutorial, we laid out how EVE can use SIMD-aware tuples to handle more complex cases. In this tutorial, we'll go over how we can design semantically equivalent user-defined types.
-Using tuples as a random bag of values returned from functions is somewhat lackluster. Indeed, one would prefer names over field numbers, thus rising the level of abstraction.
Following this trend, we can rewrite our scalar to_polar
function to return a proper structure.
Note how the semantic improved by being able to explicitly states we return a SIMD register made of instance of polar_coords
.
All this boilerplate can be overwhelming so instead of adapting existing code, you may want to build a new user-defined type directly usable as a SIMD type. EVE provides an intrusive protocol to do just that via the use of the eve::struct_support helper.
eve::like<polar_coords>
used as a parameters concept means that the function accepts any type that behaves like a polar_coords
, i.e polar_coords
and eve::wide<polar_coords>
. Such function can also be defined as regular function, but this form is easier and safer.This is the bare minimum we can do with eve::struct_support. Additional operators can be added along with stream insertion. Check eve::struct_support documentation for more informations.
-The last step in this situation is now to process multiples udt::polar_coords
using algorithms. The most efficient way to do so is to use eve::soa_vector as a container for SIMD-aware types, either adapted or created using eve::struct_support.
eve::soa_vector provides a std::vector
-like interface but perform automatic Structure of Array storage optimisation, ensures the best alignment possible for each sub-members and is directly usable as EVE algorithm input or output.
In this tutorial, we managed to:
The EVE library uses compile-time code generation process to ensure a high-level of performance. However, there can be many reasons why your application or library might run on unknown systems. Thus, you may want to be able to write your SIMD kernel once and yet be able to adapt to your end-user's hardware.
A first solution could be to just recompile a given kernel with different architecture settings and link everything. Then, at runtime, use eve::is_supported to choose the correct implementation between the available ones. However, in attempting to solve the problem in this way, you'll face issues as the core of EVE is based on templated callable object, you may end up violating the One Definition Rule and end up with a binary containing the incorrect symbols and implementations.
-A more successful approach is to isolate the various versions of a given kernel into separate dynamic libraries. In this case, no multiple definition can happen. This means to use dynamic libraries to store your code and dynamic loading.
Dynamic loading in itself is a large topic mostly due to its OS specific components so a good read on the subject is maybe in order. Once you are acquainted with dynamic loading, let's start building our own SIMD dynamic system.
-Let's write a small function that will consume a pointer to a data block containing float
values and the size of the data block to process. Inside this kernel, we'll use some algorithms to vectorise this process.
compute_kernel
, we display some information about the SIMD API we are using and proceed to the computation. As a quick way to handle the data, we pass a std::span
to our algorithm.Nothing special is required except for the extern "C"
attribute. If we want to get around this limitation and have a function taking arbitrary C++ types as parameters, there are different strategies. One such strategy is to use the mangled name to export a function returning an array or structure containing all the pre-computed functions pointers from the .so
library.
We now need to write an actual compute
function that our users will call. This is the place where most of the OS-dependent code will be written. The example we give is made to work on Linux. For a more OS-independent way to handle dynamic loading, you can have a look at libltdl or use your preferred OS API.
The code looks like this:
@@ -205,7 +205,7 @@Obviously, in realistic settings you would actually care about runtime issues, check that every pointer are non-null, and use functions like dlerror
to find out what would have caused an issue. This is left as an exercice for the reader.
The next part is much more down-to-earth. We need to compile the kernel function inside multiple dynamic libraries with different set of options. Then, we need to compile the main binary. To simplify this process, EVE provides a CMake function named eve_build_variants
that you can access directly when using find_package
or that can be included manually in your CMake after installing the library via include(eve-multiarch)
.
Its synopsis is:
The complete project is available as in the examples/multi-arch
folder. As an exercise, try to modify the code to handle AVX512 and check everything still works.
Handling multiple architecture within a single application is not trivial. It requires some scaffolding, much of those being provided by EVE itself at both the CMake and C++ level.
elementwise_callable
object computing the arc cosine. EVE requires a C++20 compliant compiler. Here is the current minimal compiler version supported:
Required header: #include <eve/traits/product_type.hpp>
By default, instances of eve::wide<T>
where T
is an User-Defined Product Type supports ordering. However, one can specialize eve::supports_ordering
for a given type to evaluates to false
in order to disable ordering for this type.
Alternatively, any type T
providing an internal eve_disable_ordering
type will be treated as if eve::supports_ordering<T>::
value
evaluates to false
, thus disabling ordering operators for eve::wide<T>
.