From d6a65a9b929b1862a78de843ceaa7848e5a588e3 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 21 Mar 2024 11:45:37 -0600 Subject: [PATCH] Align Tensor to make vectorization possible. --- include/deal.II/base/tensor.h | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/include/deal.II/base/tensor.h b/include/deal.II/base/tensor.h index 5548dc4807..40f45b307b 100644 --- a/include/deal.II/base/tensor.h +++ b/include/deal.II/base/tensor.h @@ -442,6 +442,55 @@ private: +namespace internal +{ + namespace TensorImplementation + { + /** + * Whether or not the 'values' array of Tensor can be treated as (i.e., + * bitcasted to) a vectorized array (of possibly more than 'dim' elements, + * where the padding elements would then have to + * be ignored by all functions). + * + * We can store the values as an array that can be casted to VectorizedArray + * if we are considering a rank-1 tensor, and if it stores `double` or + * `float` values, and if there are at most 4 values -- we do not try to + * vectorize the uncommon case of `dim>4`. We also don't consider the case + * `dim==1` because in that case vectorization does not provide any benefit. + * + * Note that this leads to a platform dependent alignment given that + * we want to treat the elements as VectorizedArray and that whether + * or not a VectorizedArray of sufficiently large size exists depends + * on the platform we're on. + */ + template + constexpr bool can_treat_values_as_vectorized_array = + ((rank == 1) && + /* Only if dim==2,3,4 */ + (dim > 1) && (dim <= 4) && + /* Only for float and double tensors */ + (std::is_same_v || std::is_same_v)&& + /* Only if a VectorizedArray is avaiable where N>=dim + (but we only have to consider N=2 or 4 because dim==2,3,4). */ + (internal::VectorizedArrayWidthSpecifier::max_width >= + (dim <= 2 ? 2 : 4))); + + /** + * Compute the alignment to be used for Tensor objects. We align it + * by 2 or 4 times the size of the scalar object for rank-1 tensors if + * rank-1 tensors can be treated as vectorized arrays (which makes sure that + * the higher-rank tensors are then also so aligned). Otherwise, set the + * alignment to the alignment of `Number`. + */ + template + constexpr size_t tensor_alignment = + (can_treat_values_as_vectorized_array<1, dim, Number> ? + (dim <= 2 ? 2 : 4) * sizeof(Number) : + alignof(Number)); + } // namespace TensorImplementation +} // namespace internal + + /** * A general tensor class with an arbitrary rank, i.e. with an arbitrary * number of indices. The Tensor class provides an indexing operator and a bit @@ -516,7 +565,8 @@ private: * @ingroup geomprimitives */ template -class Tensor +class alignas( + internal::TensorImplementation::tensor_alignment) Tensor { public: static_assert(rank_ >= 1, -- 2.39.5