#ifndef TENSOR_ASSIGNMENT_H #define TENSOR_ASSIGNMENT_H namespace Fastor { //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// template FASTOR_INLINE void trivial_assign(AbstractTensor &dst, const AbstractTensor &src_) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; const OtherDerived &src = src_.self(); FASTOR_ASSERT(src.size()==dst.self().size(), "TENSOR SIZE MISMATCH"); T* _data = dst.self().data(); FASTOR_IF_CONSTEXPR(!is_boolean_expression_v) { FASTOR_INDEX i = 0; for (; i (i).store(&_data[i], FASTOR_ALIGNED); } for (; i < src.size(); ++i) { _data[i] = src.template eval_s(i); } } else { for (FASTOR_INDEX i = 0; i < src.size(); ++i) { _data[i] = src.template eval_s(i); } } } template FASTOR_INLINE void trivial_assign_add(AbstractTensor &dst, const AbstractTensor &src_) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; const OtherDerived &src = src_.self(); FASTOR_ASSERT(src.size()==dst.self().size(), "TENSOR SIZE MISMATCH"); T* _data = dst.self().data(); FASTOR_IF_CONSTEXPR(!is_boolean_expression_v) { FASTOR_INDEX i = 0; for (; i (i); _vec.store(&_data[i], FASTOR_ALIGNED); } for (; i < src.size(); ++i) { _data[i] += src.template eval_s(i); } } else { for (FASTOR_INDEX i = 0; i < src.size(); ++i) { _data[i] += src.template eval_s(i); } } } template FASTOR_INLINE void trivial_assign_sub(AbstractTensor &dst, const AbstractTensor &src_) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; const OtherDerived &src = src_.self(); FASTOR_ASSERT(src.size()==dst.self().size(), "TENSOR SIZE MISMATCH"); T* _data = dst.self().data(); FASTOR_IF_CONSTEXPR(!is_boolean_expression_v) { FASTOR_INDEX i = 0; for (; i (i); _vec.store(&_data[i], FASTOR_ALIGNED); } for (; i < src.size(); ++i) { _data[i] -= src.template eval_s(i); } } else { for (FASTOR_INDEX i = 0; i < src.size(); ++i) { _data[i] -= src.template eval_s(i); } } } template FASTOR_INLINE void trivial_assign_mul(AbstractTensor &dst, const AbstractTensor &src_) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; const OtherDerived &src = src_.self(); FASTOR_ASSERT(src.size()==dst.self().size(), "TENSOR SIZE MISMATCH"); T* _data = dst.self().data(); FASTOR_IF_CONSTEXPR(!is_boolean_expression_v) { FASTOR_INDEX i = 0; for (; i (i); _vec.store(&_data[i], FASTOR_ALIGNED); } for (; i < src.size(); ++i) { _data[i] *= src.template eval_s(i); } } else { for (FASTOR_INDEX i = 0; i < src.size(); ++i) { _data[i] *= src.template eval_s(i); } } } template FASTOR_INLINE void trivial_assign_div(AbstractTensor &dst, const AbstractTensor &src_) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; const OtherDerived &src = src_.self(); FASTOR_ASSERT(src.size()==dst.self().size(), "TENSOR SIZE MISMATCH"); T* _data = dst.self().data(); FASTOR_IF_CONSTEXPR(!is_boolean_expression_v) { FASTOR_INDEX i = 0; for (; i (i); _vec.store(&_data[i], FASTOR_ALIGNED); } for (; i < src.size(); ++i) { _data[i] /= src.template eval_s(i); } } else { for (FASTOR_INDEX i = 0; i < src.size(); ++i) { _data[i] /= src.template eval_s(i); } } } //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// template, bool> = false> FASTOR_INLINE void trivial_assign(AbstractTensor &dst, U num) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; T* _data = dst.self().data(); T cnum = (T)num; V _vec(cnum); FASTOR_INDEX i = 0; for (; i< ROUND_DOWN(dst.self().size(),V::Size); i+=V::Size) { _vec.store(&_data[i], FASTOR_ALIGNED); } for (; i, bool> = false> FASTOR_INLINE void trivial_assign_add(AbstractTensor &dst, U num) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; T* _data = dst.self().data(); T cnum = (T)num; V _vec(cnum); FASTOR_INDEX i = 0; for (; i< ROUND_DOWN(dst.self().size(),V::Size); i+=V::Size) { V _vec_out(&_data[i], FASTOR_ALIGNED); _vec_out += _vec; _vec_out.store(&_data[i], FASTOR_ALIGNED); } for (; i, bool> = false> FASTOR_INLINE void trivial_assign_sub(AbstractTensor &dst, U num) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; T* _data = dst.self().data(); T cnum = (T)num; V _vec(cnum); FASTOR_INDEX i = 0; for (; i< ROUND_DOWN(dst.self().size(),V::Size); i+=V::Size) { V _vec_out(&_data[i], FASTOR_ALIGNED); _vec_out -= _vec; _vec_out.store(&_data[i], FASTOR_ALIGNED); } for (; i, bool> = false> FASTOR_INLINE void trivial_assign_mul(AbstractTensor &dst, U num) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; T* _data = dst.self().data(); T cnum = (T)num; V _vec(cnum); FASTOR_INDEX i = 0; for (; i< ROUND_DOWN(dst.self().size(),V::Size); i+=V::Size) { V _vec_out(&_data[i], FASTOR_ALIGNED); _vec_out *= _vec; _vec_out.store(&_data[i], FASTOR_ALIGNED); } for (; i && !is_integral_v_, bool> = false> FASTOR_INLINE void trivial_assign_div(AbstractTensor &dst, U num) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; T* _data = dst.self().data(); T cnum = T(1) / (T)num; V _vec(cnum); FASTOR_INDEX i = 0; for (; i< ROUND_DOWN(dst.self().size(),V::Size); i+=V::Size) { V _vec_out(&_data[i], FASTOR_ALIGNED); _vec_out *= _vec; _vec_out.store(&_data[i], FASTOR_ALIGNED); } for (; i && is_integral_v_, bool> = false> FASTOR_INLINE void trivial_assign_div(AbstractTensor &dst, U num) { using T = typename Derived::scalar_type; using V = typename Derived::simd_vector_type; T* _data = dst.self().data(); T cnum = (T)num; V _vec(cnum); FASTOR_INDEX i = 0; for (; i< ROUND_DOWN(dst.self().size(),V::Size); i+=V::Size) { V _vec_out(&_data[i], FASTOR_ALIGNED); _vec_out /= _vec; _vec_out.store(&_data[i], FASTOR_ALIGNED); } for (; i constexpr FASTOR_INLINE void assign(AbstractTensor &dst, const Tensor &src) { if (dst.self().data()==src.data()) return; trivial_assign(dst.self(),src); } template constexpr FASTOR_INLINE void assign_add(AbstractTensor &dst, const Tensor &src) { trivial_assign_add(dst.self(),src); } template constexpr FASTOR_INLINE void assign_sub(AbstractTensor &dst, const Tensor &src) { trivial_assign_sub(dst.self(),src); } template constexpr FASTOR_INLINE void assign_mul(AbstractTensor &dst, const Tensor &src) { trivial_assign_mul(dst.self(),src); } template constexpr FASTOR_INLINE void assign_div(AbstractTensor &dst, const Tensor &src) { trivial_assign_div(dst.self(),src); } template,bool> = false> constexpr FASTOR_INLINE void assign(AbstractTensor &dst, U num) { trivial_assign(dst.self(),num); } template,bool> = false> constexpr FASTOR_INLINE void assign_add(AbstractTensor &dst, U num) { trivial_assign_add(dst.self(),num); } template,bool> = false> constexpr FASTOR_INLINE void assign_sub(AbstractTensor &dst, U num) { trivial_assign_sub(dst.self(),num); } template,bool> = false> constexpr FASTOR_INLINE void assign_mul(AbstractTensor &dst, U num) { trivial_assign_mul(dst.self(),num); } template,bool> = false> constexpr FASTOR_INLINE void assign_div(AbstractTensor &dst, U num) { trivial_assign_div(dst.self(),num); } //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// } // end of namespace Fastor #endif // TENSOR_ASSIGNMENT_H