From d1274da76615f5cc5fcc489eee2421a2d64d3a9b Mon Sep 17 00:00:00 2001 From: David Feltell Date: Sat, 30 May 2020 19:50:28 +0100 Subject: [PATCH] Support assignment from `TensorMap` wrapping a `const` type to a `Tensor` storing non-`const` * Add test that copy-assigns to a `Tensor` from a `TensorMap` wrapping an array of `const`-qualified data. * Missing inline declaration for a `maskstore` overload causing "multiple definition of `Fastor::maskstore`" errors. * Use destination type (i.e. non-const) to construct `SIMDVector` in `eval` functions, otherwise we get "assignment of read-only location" errors. * Don't `const`-qualify destination tensor in `assign`, otherwise overload resolution of called `trivial_assign` fails. --- Fastor/simd_vector/simd_vector_common.h | 2 ++ Fastor/tensor/TensorEvaluator.h | 12 ++++++------ Fastor/tensor/TensorMap.h | 2 +- tests/test_tensormap/test_tensormap.cpp | 10 ++++++++++ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Fastor/simd_vector/simd_vector_common.h b/Fastor/simd_vector/simd_vector_common.h index c3c4e7a..1522f1f 100644 --- a/Fastor/simd_vector/simd_vector_common.h +++ b/Fastor/simd_vector/simd_vector_common.h @@ -599,6 +599,8 @@ void maskstore(std::complex * FASTOR_RESTRICT a, const int (&maska)[4], _mm256_maskstore_pd(reinterpret_cast(a ), (__m256i) mask0, lo); _mm256_maskstore_pd(reinterpret_cast(a+2), (__m256i) mask1, hi); } +template<> +FASTOR_INLINE void maskstore(std::complex * FASTOR_RESTRICT a, const int (&maska)[8], SIMDVector,simd_abi::avx> &v) { // Split the mask in to a higher and lower part - we need two masks for this __m256i mask0 = _mm256_set_epi32(maska[4],maska[4],maska[5],maska[5],maska[6],maska[6],maska[7],maska[7]); diff --git a/Fastor/tensor/TensorEvaluator.h b/Fastor/tensor/TensorEvaluator.h index 54ecabe..27bc8d1 100644 --- a/Fastor/tensor/TensorEvaluator.h +++ b/Fastor/tensor/TensorEvaluator.h @@ -4,8 +4,8 @@ // Expression templates evaluators //----------------------------------------------------------------------------------------------------------// template -FASTOR_INLINE SIMDVector eval(FASTOR_INDEX i) const { - SIMDVector _vec; +FASTOR_INLINE SIMDVector eval(FASTOR_INDEX i) const { + SIMDVector _vec; _vec.load(&_data[get_mem_index(i)],false); return _vec; } @@ -14,8 +14,8 @@ FASTOR_INLINE T eval_s(FASTOR_INDEX i) const { return _data[get_mem_index(i)]; } template -FASTOR_INLINE SIMDVector eval(FASTOR_INDEX i, FASTOR_INDEX j) const { - SIMDVector _vec; +FASTOR_INLINE SIMDVector eval(FASTOR_INDEX i, FASTOR_INDEX j) const { + SIMDVector _vec; _vec.load(&_data[get_flat_index(i,j)],false); return _vec; } @@ -25,8 +25,8 @@ FASTOR_INLINE T eval_s(FASTOR_INDEX i, FASTOR_INDEX j) const { } template -FASTOR_INLINE SIMDVector teval(const std::array &as) const { - SIMDVector _vec; +FASTOR_INLINE SIMDVector teval(const std::array &as) const { + SIMDVector _vec; _vec.load(&_data[get_flat_index(as)],false); return _vec; } diff --git a/Fastor/tensor/TensorMap.h b/Fastor/tensor/TensorMap.h index 509358e..9215a48 100644 --- a/Fastor/tensor/TensorMap.h +++ b/Fastor/tensor/TensorMap.h @@ -143,7 +143,7 @@ FASTOR_MAKE_OS_STREAM_TENSORn(TensorMap) template -FASTOR_INLINE void assign(const AbstractTensor &dst, const TensorMap &src) { +FASTOR_INLINE void assign(AbstractTensor &dst, const TensorMap &src) { if (dst.self().data()==src.data()) return; trivial_assign(dst.self(),src); } diff --git a/tests/test_tensormap/test_tensormap.cpp b/tests/test_tensormap/test_tensormap.cpp index 64e05a0..1fe5542 100644 --- a/tests/test_tensormap/test_tensormap.cpp +++ b/tests/test_tensormap/test_tensormap.cpp @@ -55,6 +55,16 @@ void run() { FASTOR_EXIT_ASSERT(abs(a.sum() - ma.sum()) < Tol); } + // Map a const array and copy-assign it to a non-const tensor. + { + const T data[] = {1, 2, 3}; + TensorMap mdata{data}; + Tensor tdata = mdata; + Tensor check{1, 2, 3}; + + FASTOR_EXIT_ASSERT(all_of(tdata == check)); + } + print(FGRN(BOLD("All tests passed successfully"))); }