Recently, reduction where-clauses have been implemented. The where clause is a condition that determines at runtime (or at compile time) whether a given reduction may be applied. There are two main use cases for where clauses:
- To avoid invalid results: In some circumstances, applying certain reductions may lead to invalid results (for example a real-valued sqrt function applied to a complex-valued input, derivative of tan(x) in pi/2…)
- For optimization purposes.
reduction (x : scalar) -> abs(x) = x where x >= 0 reduction (x : scalar) -> abs(x) = -x where x < 0
In case the compiler has no information on the sign of x, the following mapping is applied:
abs(x) -> x >= 0 ? x : (x < 0 ? -x : abs(x))
And the evaluation of the where clauses of the reduction is performed at runtime. However, when the compiler has information on x (e.g.
assert(x <= -1)), the mapping will be much simpler:
abs(x) -> -x
Note that the
abs(.) function is a trivial example, in practice this could be more complicated:
reduction (x : scalar) -> some_op(x, a) = superfast_op(x, a) where 0 <= a && a < 1 reduction (x : scalar) -> some_op(x, a) = accurate_op(x, a) where 1 <= a