From: Matthias Maier Date: Thu, 5 Sep 2019 20:35:37 +0000 (-0500) Subject: add documentation X-Git-Tag: v9.2.0-rc1~1132^2~2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad2bec1f8b38a1c7b058a6ee484df7b05bdb43c9;p=dealii.git add documentation --- diff --git a/include/deal.II/base/vectorization.h b/include/deal.II/base/vectorization.h index 281b47b474..8bcc454c07 100644 --- a/include/deal.II/base/vectorization.h +++ b/include/deal.II/base/vectorization.h @@ -3966,21 +3966,94 @@ operator<<(std::ostream &out, const VectorizedArray &p) /** - * TODO + * enum class encoding binary operations for a component-wise comparison of + * VectorizedArray data types. + * + * @note In case of SIMD vecorization (sse, avx, av512) we select the + * corresponding ordered, non-signalling (OQ) variants. */ enum class SIMDComparison : int { +#if DEAL_II_COMPILER_VECTORIZATION_LEVEL >= 2 && defined(__AVX__) equal = _CMP_EQ_OQ, not_equal = _CMP_NEQ_OQ, less_than = _CMP_LT_OQ, less_than_or_equal = _CMP_LE_OQ, greater_than = _CMP_GT_OQ, greater_than_or_equal = _CMP_GE_OQ +#else + equal, + not_equal, + less_than, + less_than_or_equal, + greater_than, + greater_than_or_equal +#endif }; /** - * TODO + * Computes the vectorized equivalent of the following ternary operation: + * @code + * (left OP right) ? true_value : false_value + * @endcode + * where OP is a binary operator (such as =, + * !=, <, <=, >, and + * >=). + * + * Such a computational idiom is useful as an alternative to branching + * whenever the control flow itself would depend on (computed) data. For + * example, in case of a scalar data type the statement + * (left < right) ? true_value : false_value + * could have been also implementd using an if-statement: + * @code + * if (left < right) + * result = true_value; + * else + * result = false_value; + * @endcode + * This, however, is fundamentally impossible in case of vectorization + * because different decisions will be necessary on different vector entries + * (lanes) and + * the first variant (based on a ternary operator) has to be used instead: + * @code + * result = compare_and_apply_mask + * (left, right, true_value, false_value); + * @endcode + * Some more illustrative examples (that are less efficient than the + * dedicated std::max and std::abs overloads): + * @code + * VectorizedArray left; + * VectorizedArray right; + * + * // std::max + * const auto maximum = compare_and_apply_mask + * (left, right, left, right); + * + * // std::abs + * const auto absolute = compare_and_apply_mask + * (left, VectorizedArray(0.), -left, left); + * @endcode + * + * More precisely, this function first computes a (boolean) mask that is + * the result of a binary operator OP applied to all elements + * of the VectorizedArray arguments @p left and @p right. The mask is then + * used to either select the corresponding component of @p true_value (if + * the binary operation equates to true), or @p false_value. The binary + * operator is encoded via the SIMDComparison template argument + * @p predicate. + * + * In order to ease with generic programming approaches, the function + * provides overloads for all VectorizedArray variants as well as + * generic POD types such as double and float. + * + * @note For this function to work the binary operation has to be encoded + * via a SIMDComparison template argument @p predicate. Depending on it + * appropriate low-level machine instructions are generated replacing the + * call to compare_and_apply_mask. This also explains why @p predicate is a + * compile-time constant template parameter and not a constant function + * argument. In order to be able to emit the correct low-level instruction, + * the compiler has to know the comparison at compile time. */ template DEAL_II_ALWAYS_INLINE inline Number @@ -4017,7 +4090,8 @@ compare_and_apply_mask(const Number &left, /** - * TODO + * Specialization of above function for the non-vectorized + * VectorizedArray variant. */ template DEAL_II_ALWAYS_INLINE inline VectorizedArray