#ifndef TENSOR_H #define TENSOR_H #include "Fastor/config/config.h" #include "Fastor/util/util.h" #include "Fastor/backend/backend.h" #include "Fastor/simd_vector/SIMDVector.h" #include "Fastor/tensor/AbstractTensor.h" #include "Fastor/tensor/Ranges.h" #include "Fastor/tensor/ForwardDeclare.h" #include "Fastor/expressions/linalg_ops/linalg_ops.h" #include #include namespace Fastor { template class Tensor: public AbstractTensor,sizeof...(Rest)> { public: using scalar_type = T; using simd_vector_type = choose_best_simd_vector_t; using simd_abi_type = typename simd_vector_type::abi_type; using result_type = Tensor; using dimension_t = std::integral_constant; static constexpr FASTOR_INLINE FASTOR_INDEX rank() {return sizeof...(Rest);} static constexpr FASTOR_INLINE FASTOR_INDEX size() {return pack_prod::value;} FASTOR_INLINE FASTOR_INDEX dimension(FASTOR_INDEX dim) const { #if FASTOR_SHAPE_CHECK FASTOR_ASSERT(dim>=0 && dim < sizeof...(Rest), "TENSOR SHAPE MISMATCH"); #endif constexpr FASTOR_INDEX DimensionHolder[sizeof...(Rest)] = {Rest...}; return DimensionHolder[dim]; } FASTOR_INLINE Tensor& noalias() {return *this;} // Classic constructors //----------------------------------------------------------------------------------------------------------// // Default constructor constexpr FASTOR_INLINE Tensor() = default; // Copy constructor FASTOR_INLINE Tensor(const Tensor &other) { // This constructor cannot be default if (_data == other.data()) return; // fast memcopy std::copy(other.data(),other.data()+size(),_data); }; // Constructor from a scalar template,bool> = false> constexpr FASTOR_INLINE Tensor(U num) { #ifdef FASTOR_ZERO_INITIALISE // This is for compile time initialisation, so it is fine scalar_type cnum = (scalar_type)num; FASTOR_INDEX i = 0; for (; i::value> &arr, int layout=RowMajor) { std::copy(arr.data(),arr.data()+pack_prod::value,_data); if (layout == RowMajor) return; else *this = tocolumnmajor(*this); } FASTOR_INLINE Tensor(const std::vector &arr, int layout=RowMajor) { std::copy(arr.data(),arr.data()+pack_prod::value,_data); if (layout == RowMajor) return; else *this = tocolumnmajor(*this); } //----------------------------------------------------------------------------------------------------------// // CRTP constructors //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// // Generic AbstractTensors #ifndef FASTOR_DISABLE_SPECIALISED_CTR template && !has_tensor_fixed_view_2d_v && !has_tensor_fixed_view_nd_v) || DIMS!=sizeof...(Rest),bool> = false> #else template #endif FASTOR_INLINE Tensor(const AbstractTensor& src) { FASTOR_ASSERT(src.self().size()==size(), "TENSOR SIZE MISMATCH"); assign(*this, src.self()); } //----------------------------------------------------------------------------------------------------------// // Specialised constructors //----------------------------------------------------------------------------------------------------------// #include "Fastor/tensor/SpecialisedConstructors.h" //----------------------------------------------------------------------------------------------------------// // AbstractTensor and scalar in-place operators //----------------------------------------------------------------------------------------------------------// #include "Fastor/tensor/TensorInplaceOperators.h" //----------------------------------------------------------------------------------------------------------// // Raw pointer providers //----------------------------------------------------------------------------------------------------------// #ifdef FASTOR_ZERO_INITIALISE constexpr FASTOR_INLINE T* data() const { return const_cast(this->_data);} #else FASTOR_INLINE T* data() const { return const_cast(this->_data);} #endif FASTOR_INLINE T* data() {return this->_data;} //----------------------------------------------------------------------------------------------------------// // Scalar & block indexing //----------------------------------------------------------------------------------------------------------// #include "Fastor/tensor/IndexRetriever.h" #include "Fastor/tensor/ScalarIndexing.h" #include "Fastor/tensor/BlockIndexing.h" //----------------------------------------------------------------------------------------------------------// // Expression templates evaluators //----------------------------------------------------------------------------------------------------------// #include "Fastor/tensor/TensorEvaluator.h" //----------------------------------------------------------------------------------------------------------// // Tensor methods //----------------------------------------------------------------------------------------------------------// #include "Fastor/tensor/TensorMethods.h" //----------------------------------------------------------------------------------------------------------// // Converters //----------------------------------------------------------------------------------------------------------// #include "Fastor/tensor/PODConverters.h" //----------------------------------------------------------------------------------------------------------// // Cast method //----------------------------------------------------------------------------------------------------------// template FASTOR_INLINE Tensor cast() const { Tensor out; U *out_data = out.data(); for (FASTOR_INDEX i=0; i(_data[i]); } return out; } //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// protected: template FASTOR_INLINE void verify_dimensions(const AbstractTensor& src_) const { static_assert(DIMS==dimension_t::value, "TENSOR RANK MISMATCH"); #ifndef NDEBUG const Derived &src = src_.self(); FASTOR_ASSERT(src.size()==this->size(), "TENSOR SIZE MISMATCH"); // Check if shape of tensors match for (FASTOR_INDEX i=0; i::value] = {}; #else FASTOR_ALIGN T _data[pack_prod::value]; #endif //----------------------------------------------------------------------------------------------------------// }; } // end of namespace Fastor #include "Fastor/tensor/TensorAssignment.h" #endif // TENSOR_H