Add Fastor library
This commit is contained in:
317
noarch/include/Fastor/expressions/views/tensor_diag_views.h
Normal file
317
noarch/include/Fastor/expressions/views/tensor_diag_views.h
Normal file
@@ -0,0 +1,317 @@
|
||||
#ifndef TENSOR_DIAG_VIEWS_H
|
||||
#define TENSOR_DIAG_VIEWS_H
|
||||
|
||||
#include "Fastor/tensor/Tensor.h"
|
||||
#include "Fastor/tensor/TensorMap.h"
|
||||
#include "Fastor/tensor/Ranges.h"
|
||||
#include "Fastor/expressions/linalg_ops/linalg_traits.h"
|
||||
|
||||
namespace Fastor {
|
||||
|
||||
template<template<typename,size_t...> class TensorType, typename T, size_t M, size_t N, size_t DIM>
|
||||
struct TensorDiagViewExpr<TensorType<T,M,N>,DIM> : public AbstractTensor<TensorDiagViewExpr<TensorType<T,M,N>,DIM>,DIM> {
|
||||
private:
|
||||
TensorType<T,M,N>& _expr;
|
||||
bool _does_alias = false;
|
||||
constexpr FASTOR_INLINE Tensor<T,M,N> get_tensor() const {return _expr;};
|
||||
public:
|
||||
using scalar_type = T;
|
||||
using simd_vector_type = typename Tensor<T,M,N>::simd_vector_type;
|
||||
using simd_abi_type = typename simd_vector_type::abi_type;
|
||||
using result_type = Tensor<T,M>;
|
||||
using V = SIMDVector<T,simd_abi_type>;
|
||||
static constexpr FASTOR_INDEX Dimension = 1;
|
||||
static constexpr FASTOR_INDEX Stride = simd_vector_type::Size;
|
||||
static constexpr FASTOR_INDEX rank() {return 1;}
|
||||
constexpr FASTOR_INLINE FASTOR_INDEX size() const {return M;}
|
||||
constexpr FASTOR_INLINE FASTOR_INDEX dimension(FASTOR_INDEX ) const {return M;}
|
||||
constexpr const TensorType<T,M,N>& expr() const {return _expr;}
|
||||
|
||||
FASTOR_INLINE TensorViewExpr<TensorType<T,M,N>,2>& noalias() {
|
||||
_does_alias = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FASTOR_INLINE TensorDiagViewExpr(Tensor<T,M,N> &_ex) : _expr(_ex) {
|
||||
static_assert(M==N, "MATRIX MUST BE SQUARE FOR DIAGONAL VIEW");
|
||||
}
|
||||
|
||||
// Copy assignment
|
||||
//---------------------------------------------------------------------------------//
|
||||
FASTOR_INLINE void operator=(const TensorDiagViewExpr<TensorType<T,M,N>,DIM>& other_src) {
|
||||
// Diagonal views don't alias
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
// Get around recursive inlining issue
|
||||
const result_type tmp(other_src);
|
||||
this->operator=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(other_src.dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) = other_src.template eval_s<T>(i,i);
|
||||
}
|
||||
}
|
||||
|
||||
// AbstractTensor binders
|
||||
//---------------------------------------------------------------------------------//
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorDiagViewExpr<TensorType<T,M,N>,2>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) = other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator+=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorDiagViewExpr<TensorType<T,M,N>,2>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator+=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) += other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator-=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorDiagViewExpr<TensorType<T,M,N>,2>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator-=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) -= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator*=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorDiagViewExpr<TensorType<T,M,N>,2>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator*=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) *= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator/=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorDiagViewExpr<TensorType<T,M,N>,2>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator/=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) /= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Scalar binders
|
||||
//---------------------------------------------------------------------------------//
|
||||
template<typename U, enable_if_t_<is_arithmetic_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(U num) {
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) = num;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U, enable_if_t_<is_arithmetic_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(U num) {
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) += num;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U, enable_if_t_<is_arithmetic_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(U num) {
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) -= num;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U, enable_if_t_<is_arithmetic_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(U num) {
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) *= num;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U, enable_if_t_<is_arithmetic_v_<U> && !is_integral_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(U num) {
|
||||
T inum = T(1) / T(num);
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) *= inum;
|
||||
}
|
||||
}
|
||||
template<typename U, enable_if_t_<is_arithmetic_v_<U> && is_integral_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(U num) {
|
||||
for (FASTOR_INDEX i = 0; i < M; ++i) {
|
||||
_expr(i,i) /= num;
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluators
|
||||
//---------------------------------------------------------------------------------//
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX idx) const {
|
||||
V _vec;
|
||||
std::array<int,V::Size> inds;
|
||||
for (auto j=0; j<V::Size; ++j) {
|
||||
const size_t it = idx+j;
|
||||
inds[j] = it*N+it;
|
||||
}
|
||||
vector_setter(_vec,_expr.data(),inds);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE U eval_s(FASTOR_INDEX idx) const {
|
||||
return _expr(idx,idx);
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
V _vec;
|
||||
vector_setter(_vec,_expr.data(),i*N+j);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
return _expr(i,j);
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> teval(const std::array<int,2>& as) const {
|
||||
V _vec;
|
||||
vector_setter(_vec,_expr.data(),as[0]*N+as[1]);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
constexpr FASTOR_INLINE U teval_s(const std::array<int,2>& as) const {
|
||||
return _expr.eval_s(as);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Actual definition of diag function
|
||||
// Note that like other views the input can only be an evaluated tensor
|
||||
template<typename T, size_t M, size_t N>
|
||||
TensorDiagViewExpr<Tensor<T,M,N>,2> diag(Tensor<T,M,N> &a) {
|
||||
return TensorDiagViewExpr<Tensor<T,M,N>,2>(a);
|
||||
}
|
||||
|
||||
template<typename T, size_t M, size_t N>
|
||||
TensorDiagViewExpr<TensorMap<T,M,N>,2> diag(TensorMap<T,M,N> &a) {
|
||||
return TensorDiagViewExpr<TensorMap<T,M,N>,2>(a);
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace Fastor
|
||||
|
||||
|
||||
#endif
|
||||
281
noarch/include/Fastor/expressions/views/tensor_filter_views.h
Normal file
281
noarch/include/Fastor/expressions/views/tensor_filter_views.h
Normal file
@@ -0,0 +1,281 @@
|
||||
#ifndef TENSOR_FILTER_VIEWS_H
|
||||
#define TENSOR_FILTER_VIEWS_H
|
||||
|
||||
|
||||
#include "Fastor/tensor/Tensor.h"
|
||||
#include "Fastor/expressions/linalg_ops/linalg_traits.h"
|
||||
|
||||
|
||||
namespace Fastor {
|
||||
|
||||
template<typename T, size_t ... Rest, size_t DIMS>
|
||||
struct TensorFilterViewExpr<Tensor<T,Rest...>,Tensor<bool,Rest...>,DIMS>:
|
||||
public AbstractTensor<TensorFilterViewExpr<Tensor<T,Rest...>,Tensor<bool,Rest...>,DIMS>,DIMS> {
|
||||
private:
|
||||
Tensor<T,Rest...> &_expr;
|
||||
const Tensor<bool,Rest...> &fl_expr;
|
||||
bool _does_alias = false;
|
||||
|
||||
constexpr FASTOR_INLINE Tensor<T,Rest...> get_tensor() const {return _expr;}
|
||||
public:
|
||||
using scalar_type = T;
|
||||
using simd_vector_type = typename Tensor<T,Rest...>::simd_vector_type;
|
||||
using simd_abi_type = typename simd_vector_type::abi_type;
|
||||
using result_type = Tensor<T,Rest...>;
|
||||
static constexpr FASTOR_INDEX Dimension = DIMS;
|
||||
static constexpr FASTOR_INDEX Stride = simd_vector_type::Size;
|
||||
static constexpr FASTOR_INDEX rank() {return DIMS;}
|
||||
constexpr FASTOR_INLINE FASTOR_INDEX size() const {return pack_prod<Rest...>::value;}
|
||||
constexpr FASTOR_INLINE FASTOR_INDEX dimension(FASTOR_INDEX i) const {return fl_expr.dimension(i);}
|
||||
constexpr const Tensor<T,Rest...>& expr() const {return _expr;}
|
||||
|
||||
FASTOR_INLINE TensorFilterViewExpr<Tensor<T,Rest...>,Tensor<bool,Rest...>,DIMS>& noalias() {
|
||||
_does_alias = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr FASTOR_INLINE TensorFilterViewExpr(Tensor<T,Rest...> &_ex, const Tensor<bool,Rest...> &_it) : _expr(_ex), fl_expr(_it) {
|
||||
static_assert(sizeof...(Rest)==DIMS, "INDEXING TENSOR WITH INCORRECT NUMBER OF ARGUMENTS");
|
||||
}
|
||||
|
||||
// In place operators
|
||||
//------------------------------------------------------------------------------------//
|
||||
void operator=(const TensorFilterViewExpr<Tensor<T,Rest...>,Tensor<bool,Rest...>,DIMS> &src) {
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(src.dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] = src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
const typename Derived::result_type& tmp = evaluate(src.self());
|
||||
this->operator=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(src.self().size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(src.self().dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] = src.self().template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator+=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
const typename Derived::result_type& tmp = evaluate(src.self());
|
||||
this->operator+=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator+=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(src.self().size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(src.self().dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] += src.self().template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator-=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
const typename Derived::result_type& tmp = evaluate(src.self());
|
||||
this->operator-=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator-=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(src.self().size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(src.self().dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] -= src.self().template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator*=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
const typename Derived::result_type& tmp = evaluate(src.self());
|
||||
this->operator*=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator*=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(src.self().size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(src.self().dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] *= src.self().template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator/=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
const typename Derived::result_type& tmp = evaluate(src.self());
|
||||
this->operator/=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t OTHER_DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
void operator/=(const AbstractTensor<Derived,OTHER_DIMS> &src) {
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(src.self().size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(src.self().dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] /= src.self().template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------//
|
||||
template<typename U=T, enable_if_t_<is_arithmetic_v_<U>,bool> = false>
|
||||
void operator=(U num) {
|
||||
T tnum = (T)num;
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] = tnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_arithmetic_v_<U>,bool> = false>
|
||||
void operator+=(U num) {
|
||||
T tnum = (T)num;
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] += tnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_arithmetic_v_<U>,bool> = false>
|
||||
void operator-=(U num) {
|
||||
T tnum = (T)num;
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] -= tnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_arithmetic_v_<U>,bool> = false>
|
||||
void operator*=(U num) {
|
||||
T tnum = (T)num;
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] *= tnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_arithmetic_v_<U> && !is_integral_v_<U>,bool> = false>
|
||||
void operator/=(U num) {
|
||||
T tnum = T(1)/(T)num;
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] *= tnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename U=T, enable_if_t_<is_arithmetic_v_<U> && is_integral_v_<U>,bool> = false>
|
||||
void operator/=(U num) {
|
||||
T tnum = (T)num;
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
if (fl_expr.eval_s(i)) {
|
||||
_expr.data()[i] /= tnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------//
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i) const {
|
||||
constexpr size_t _Stride = SIMDVector<T,simd_abi_type>::Size;
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
U inds[_Stride];
|
||||
for (FASTOR_INDEX j=0; j<_Stride; ++j)
|
||||
inds[j] = fl_expr.eval_s(i+j) ? _expr.eval_s(i+j) : 0;
|
||||
_vec.load(inds,false);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE U eval_s(FASTOR_INDEX i) const {
|
||||
return fl_expr.eval_s(i) ? _expr.eval_s(i) : 0;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i, FASTOR_INDEX k) const {
|
||||
constexpr size_t _Stride = SIMDVector<T,simd_abi_type>::Size;
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
U inds[_Stride];
|
||||
for (FASTOR_INDEX j=0; j<_Stride; ++j)
|
||||
inds[j] = fl_expr.eval_s(i,k+j) ? _expr.eval_s(i,k+j) : 0;
|
||||
_vec.load(inds,false);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE U eval_s(FASTOR_INDEX i, FASTOR_INDEX k) const {
|
||||
return fl_expr.eval_s(i,k) ? _expr.eval_s(i,k) : 0;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> teval(const std::array<int,DIMS>& as) const {
|
||||
constexpr size_t _Stride = SIMDVector<T,simd_abi_type>::Size;
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
U inds[_Stride];
|
||||
for (FASTOR_INDEX j=0; j<_Stride; ++j)
|
||||
inds[j] = fl_expr.teval_s(as) ? _expr.teval_s(as) : 0;
|
||||
_vec.load(inds,false);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE U teval_s(const std::array<int,DIMS>& as) const {
|
||||
return fl_expr.teval_s(as) ? _expr.teval_s(as) : 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------------//
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace Fastor
|
||||
|
||||
|
||||
#endif // TENSOR_FILTER_VIEWS_H
|
||||
681
noarch/include/Fastor/expressions/views/tensor_fixed_views_1d.h
Normal file
681
noarch/include/Fastor/expressions/views/tensor_fixed_views_1d.h
Normal file
@@ -0,0 +1,681 @@
|
||||
#ifndef TENSOR_FIXED_VIEWS_1D_H
|
||||
#define TENSOR_FIXED_VIEWS_1D_H
|
||||
|
||||
|
||||
#include "Fastor/tensor/Tensor.h"
|
||||
#include "Fastor/tensor/Ranges.h"
|
||||
#include "Fastor/expressions/linalg_ops/linalg_traits.h"
|
||||
|
||||
|
||||
namespace Fastor {
|
||||
|
||||
|
||||
// 1D const fixed views
|
||||
//----------------------------------------------------------------------------------------------//
|
||||
template<typename T, size_t N, int F0, int L0, int S0>
|
||||
struct TensorConstFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1> :
|
||||
public AbstractTensor<TensorConstFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>,1> {
|
||||
private:
|
||||
const Tensor<T,N> &_expr;
|
||||
public:
|
||||
using scalar_type = T;
|
||||
using simd_vector_type = typename Tensor<T,N>::simd_vector_type;
|
||||
using simd_abi_type = typename simd_vector_type::abi_type;
|
||||
using result_type = Tensor<T,range_detector<F0,L0,S0>::value>;
|
||||
static constexpr FASTOR_INDEX Dimension = 1;
|
||||
static constexpr FASTOR_INDEX Stride = simd_vector_type::Size;
|
||||
static constexpr FASTOR_INLINE FASTOR_INDEX size() { return range_detector<F0,L0,S0>::value;}
|
||||
static constexpr FASTOR_INLINE FASTOR_INDEX dimension(FASTOR_INDEX ) {return range_detector<F0,L0,S0>::value;}
|
||||
constexpr const Tensor<T,N>& expr() const {return _expr;}
|
||||
|
||||
constexpr FASTOR_INLINE TensorConstFixedViewExpr1D(const Tensor<T,N> &_ex) : _expr(_ex) {}
|
||||
|
||||
template<typename U>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),S0*i+F0,S0);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i) const {
|
||||
return _expr.data()[S0*i+F0];
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),S0*(i+j)+F0,S0);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
return _expr.data()[S0*(i+j)+F0];
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> teval(const std::array<int,1>& as) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),S0*as[0]+F0,S0);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
constexpr FASTOR_INLINE U teval_s(const std::array<int,1>& as) const {
|
||||
return _expr.data()[S0*as[0]+F0];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 1D non-const fixed views
|
||||
//----------------------------------------------------------------------------------------------//
|
||||
template<typename T, size_t N, int F0, int L0, int S0>
|
||||
struct TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1> :
|
||||
public AbstractTensor<TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>,1> {
|
||||
private:
|
||||
Tensor<T,N> &_expr;
|
||||
bool _does_alias = false;
|
||||
constexpr FASTOR_INLINE Tensor<T,N> get_tensor() const {return _expr;}
|
||||
public:
|
||||
using scalar_type = T;
|
||||
using simd_vector_type = typename Tensor<T,N>::simd_vector_type;
|
||||
using simd_abi_type = typename simd_vector_type::abi_type;
|
||||
using result_type = Tensor<T,range_detector<F0,L0,S0>::value>;
|
||||
static constexpr FASTOR_INDEX Dimension = 1;
|
||||
static constexpr FASTOR_INDEX Stride = simd_vector_type::Size;
|
||||
static constexpr FASTOR_INLINE FASTOR_INDEX size() {return range_detector<F0,L0,S0>::value;}
|
||||
static constexpr FASTOR_INLINE FASTOR_INDEX dimension(FASTOR_INDEX i) {return range_detector<F0,L0,S0>::value;}
|
||||
constexpr const Tensor<T,N>& expr() const {return _expr;}
|
||||
|
||||
FASTOR_INLINE TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>& noalias() {
|
||||
_does_alias = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr FASTOR_INLINE TensorFixedViewExpr1D(Tensor<T,N> &_ex) : _expr(_ex) {}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------//
|
||||
FASTOR_HINT_INLINE void operator=(const TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1> &other_src) {
|
||||
#ifndef FASTOR_NO_ALIAS
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other_src;
|
||||
// assign temporary to this
|
||||
this->operator=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(other_src.dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
_vec_other.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] = _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------------//
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#ifndef FASTOR_NO_ALIAS
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR(is_boolean_expression_v<Derived>) {
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
_vec_other.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] = _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator+=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#ifndef FASTOR_NO_ALIAS
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator+=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) + other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] += other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] += _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] += other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] += other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator-=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#ifndef FASTOR_NO_ALIAS
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator-=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) - other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] -= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] -= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] -= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] -= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator*=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#ifndef FASTOR_NO_ALIAS
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) * other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] *= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] *= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] *= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] *= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator/=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#ifndef FASTOR_NO_ALIAS
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorFixedViewExpr1D<Tensor<T,N>,fseq<F0,L0,S0>,1>(tmp_this_tensor);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator/=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) / other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] /= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] /= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] /= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] /= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
// Scalar binders
|
||||
//----------------------------------------------------------------------------------//
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
_vec_other.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] = num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] = _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] = num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] = num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) + _vec_other;
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] += num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] += _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] += num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] += num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) - _vec_other;
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] -= num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] -= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] -= num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] -= num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) * _vec_other;
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] *= num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] *= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] *= num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] *= num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U> && !is_integral_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(U num) {
|
||||
T inum = T(1) / static_cast<T>(num);
|
||||
simd_vector_type _vec_other(inum);
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) * _vec_other;
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] *= inum;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] *= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] *= inum;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] *= inum;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U> && is_integral_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR (S0 == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) / _vec_other;
|
||||
_vec.store(&_data[i+F0],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+F0] /= num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<SIMDVector<T,simd_abi_type>::Size; ++j) {
|
||||
_data[S0*(i+j) + F0] /= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[S0*i+F0] /= num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
_data[S0*i+F0] /= num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
template<typename U>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),S0*i+F0,S0);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i) const {
|
||||
return _expr.data()[S0*i+F0];
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),S0*(i+j)+F0,S0);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
return _expr.data()[S0*(i+j)+F0];
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> teval(const std::array<int,1>& as) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),S0*as[0]+F0,S0);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
constexpr FASTOR_INLINE U teval_s(const std::array<int,1>& as) const {
|
||||
return _expr.data()[S0*as[0]+F0];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // TENSOR_FIXED_VIEWS_1D_H
|
||||
1121
noarch/include/Fastor/expressions/views/tensor_fixed_views_2d.h
Normal file
1121
noarch/include/Fastor/expressions/views/tensor_fixed_views_2d.h
Normal file
File diff suppressed because it is too large
Load Diff
1645
noarch/include/Fastor/expressions/views/tensor_fixed_views_nd.h
Normal file
1645
noarch/include/Fastor/expressions/views/tensor_fixed_views_nd.h
Normal file
File diff suppressed because it is too large
Load Diff
1152
noarch/include/Fastor/expressions/views/tensor_random_views.h
Normal file
1152
noarch/include/Fastor/expressions/views/tensor_random_views.h
Normal file
File diff suppressed because it is too large
Load Diff
10
noarch/include/Fastor/expressions/views/tensor_views.h
Normal file
10
noarch/include/Fastor/expressions/views/tensor_views.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef TENSOR_VIEWS_H
|
||||
#define TENSOR_VIEWS_H
|
||||
|
||||
#include "Fastor/expressions/views/tensor_views_1d.h"
|
||||
#include "Fastor/expressions/views/tensor_views_2d.h"
|
||||
#include "Fastor/expressions/views/tensor_views_nd.h"
|
||||
|
||||
#include "Fastor/expressions/views/tensor_views_assignment.h"
|
||||
|
||||
#endif // TENSOR_VIEWS_H
|
||||
739
noarch/include/Fastor/expressions/views/tensor_views_1d.h
Normal file
739
noarch/include/Fastor/expressions/views/tensor_views_1d.h
Normal file
@@ -0,0 +1,739 @@
|
||||
#ifndef TENSOR_VIEWS_1D_H
|
||||
#define TENSOR_VIEWS_1D_H
|
||||
|
||||
|
||||
#include "Fastor/tensor/Tensor.h"
|
||||
#include "Fastor/tensor/Ranges.h"
|
||||
#include "Fastor/expressions/linalg_ops/linalg_traits.h"
|
||||
|
||||
namespace Fastor {
|
||||
|
||||
|
||||
|
||||
// 1D const views
|
||||
//-------------------------------------------------------------------------------------//
|
||||
template<typename T, size_t N>
|
||||
struct TensorConstViewExpr<Tensor<T,N>,1>: public AbstractTensor<TensorConstViewExpr<Tensor<T,N>,1>,1> {
|
||||
private:
|
||||
const Tensor<T,N> &_expr;
|
||||
seq _seq;
|
||||
public:
|
||||
using scalar_type = T;
|
||||
using simd_vector_type = typename Tensor<T,N>::simd_vector_type;
|
||||
using simd_abi_type = typename simd_vector_type::abi_type;
|
||||
using V = simd_vector_type;
|
||||
using result_type = Tensor<T,N>;
|
||||
static constexpr FASTOR_INDEX Dimension = 1;
|
||||
static constexpr FASTOR_INDEX Stride = simd_vector_type::Size;
|
||||
static constexpr FASTOR_INDEX rank() {return 1;}
|
||||
constexpr FASTOR_INLINE FASTOR_INDEX size() const {return _seq.size();}
|
||||
constexpr FASTOR_INLINE FASTOR_INDEX dimension(FASTOR_INDEX ) const {return _seq.size();}
|
||||
constexpr const Tensor<T,N>& expr() const {return _expr;}
|
||||
|
||||
FASTOR_INLINE TensorConstViewExpr(const Tensor<T,N> &_ex, const seq &_s) : _expr(_ex), _seq(_s) {
|
||||
if (_seq._last < 0) _seq._last += N + /*including the end point*/ 1;
|
||||
if (_seq._first < 0) _seq._first += N + /*including the end point*/ 1;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),i*_seq._step+_seq._first,_seq._step);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i) const {
|
||||
return _expr.data()[i*_seq._step+_seq._first];
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),(i+j)*_seq._step+_seq._first,_seq._step);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
return _expr.data()[(i+j)*_seq._step+_seq._first];
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> teval(const std::array<int,1>& as) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),as[0]*_seq._step+_seq._first,_seq._step);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
constexpr FASTOR_INLINE U teval_s(const std::array<int,1>& as) const {
|
||||
return _expr.data()[as[0]*_seq._step+_seq._first];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 1D non-const views
|
||||
//-------------------------------------------------------------------------------------//
|
||||
template<typename T, size_t N>
|
||||
struct TensorViewExpr<Tensor<T,N>,1>: public AbstractTensor<TensorViewExpr<Tensor<T,N>,1>,1> {
|
||||
private:
|
||||
Tensor<T,N> &_expr;
|
||||
seq _seq;
|
||||
bool _does_alias = false;
|
||||
constexpr FASTOR_INLINE Tensor<T,N> get_tensor() const {return _expr;}
|
||||
public:
|
||||
using scalar_type = T;
|
||||
using simd_vector_type = typename Tensor<T,N>::simd_vector_type;
|
||||
using simd_abi_type = typename simd_vector_type::abi_type;
|
||||
using V = simd_vector_type;
|
||||
using result_type = Tensor<T,N>;
|
||||
static constexpr FASTOR_INDEX Dimension = 1;
|
||||
static constexpr FASTOR_INDEX Stride = simd_vector_type::Size;
|
||||
static constexpr FASTOR_INDEX rank() {return 1;}
|
||||
constexpr FASTOR_INLINE FASTOR_INDEX size() const {return _seq.size();}
|
||||
constexpr FASTOR_INLINE FASTOR_INDEX dimension(FASTOR_INDEX ) const {return _seq.size();}
|
||||
constexpr const Tensor<T,N>& expr() const {return _expr;}
|
||||
|
||||
FASTOR_INLINE TensorViewExpr<Tensor<T,N>,1>& noalias() {
|
||||
_does_alias = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FASTOR_INLINE TensorViewExpr(Tensor<T,N> &_ex, const seq &_s) : _expr(_ex), _seq(_s) {
|
||||
if (_seq._last < 0) _seq._last += N + /*including the end point*/ 1;
|
||||
if (_seq._first < 0) _seq._first += N + /*including the end point*/ 1;
|
||||
}
|
||||
|
||||
// View evalution operators
|
||||
// Copy assignment operators [Needed in addition to generic AbstractTensor overload]
|
||||
//----------------------------------------------------------------------------------//
|
||||
FASTOR_HINT_INLINE void operator=(const TensorViewExpr<Tensor<T,N>,1> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorViewExpr<Tensor<T,N>,1>(tmp_this_tensor,_seq);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
// Check if shape of tensors match - for this 1D case for loop unnecessary
|
||||
for (FASTOR_INDEX i=0; i<Dimension; ++i) {
|
||||
FASTOR_ASSERT(other.dimension(i)==dimension(i), "TENSOR SHAPE MISMATCH");
|
||||
}
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = other.template eval<T>(i);
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] = other.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other.template eval<T>(i);
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] = _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] = other.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] = other.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
// AbstractTensor binders
|
||||
//----------------------------------------------------------------------------------//
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorViewExpr<Tensor<T,N>,1>(tmp_this_tensor,_seq);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
FASTOR_IF_CONSTEXPR(is_boolean_expression_v<Derived>) {
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] = _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] = other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator+=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorViewExpr<Tensor<T,N>,1>(tmp_this_tensor,_seq);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator+=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) + other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] += other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] += _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] += other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] += other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator-=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorViewExpr<Tensor<T,N>,1>(tmp_this_tensor,_seq);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator-=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) - other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] -= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] -= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] -= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] -= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator*=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorViewExpr<Tensor<T,N>,1>(tmp_this_tensor,_seq);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator*=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) * other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] *= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] *= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] *= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] *= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
const typename Derived::result_type& tmp = evaluate(other.self());
|
||||
this->operator/=(tmp);
|
||||
}
|
||||
template<typename Derived, size_t DIMS, enable_if_t_<!requires_evaluation_v<Derived>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(const AbstractTensor<Derived,DIMS> &other) {
|
||||
#if !(FASTOR_NO_ALIAS)
|
||||
if (_does_alias) {
|
||||
_does_alias = false;
|
||||
// Evaluate this into a temporary
|
||||
auto tmp_this_tensor = get_tensor();
|
||||
auto tmp = TensorViewExpr<Tensor<T,N>,1>(tmp_this_tensor,_seq);
|
||||
// Assign other to temporary
|
||||
tmp = other;
|
||||
// assign temporary to this
|
||||
this->operator/=(tmp);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const Derived& other_src = other.self();
|
||||
#ifndef NDEBUG
|
||||
FASTOR_ASSERT(other_src.size()==this->size(), "TENSOR SIZE MISMATCH");
|
||||
#endif
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) / other_src.template eval<T>(i);
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] /= other_src.template eval_s<T>(i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec_other = other_src.template eval<T>(i);
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] /= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] /= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] /= other_src.template eval_s<T>(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
// scalar binders
|
||||
//----------------------------------------------------------------------------------//
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
_vec_other.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] = num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] = _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] = num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] = num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator+=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) + _vec_other;
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] += num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] += _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] += num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] += num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator-=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) - _vec_other;
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] -= num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] -= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] -= num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] -= num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator*=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) * _vec_other;
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] *= num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] *= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] *= num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] *= num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U> && !is_integral_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(U num) {
|
||||
T inum = T(1) / static_cast<T>(num);
|
||||
simd_vector_type _vec_other(inum);
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) * _vec_other;
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] *= inum;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] *= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] *= inum;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] *= inum;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
template<typename U=T, enable_if_t_<is_primitive_v_<U> && is_integral_v_<U>,bool> = false>
|
||||
FASTOR_HINT_INLINE void operator/=(U num) {
|
||||
simd_vector_type _vec_other(static_cast<T>(num));
|
||||
T *FASTOR_RESTRICT _data = _expr.data();
|
||||
if (_seq._step == 1) {
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
auto _vec = this->template eval<T>(i) / _vec_other;
|
||||
_vec.store(&_data[i+_seq._first],false);
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
_data[i+_seq._first] /= num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef FASTOR_USE_VECTORISED_EXPR_ASSIGN
|
||||
FASTOR_INDEX i;
|
||||
for (i = 0; i <ROUND_DOWN(size(),Stride); i+=Stride) {
|
||||
for (auto j=0; j<simd_vector_type::Size; ++j) {
|
||||
auto idx = (i+j)*_seq._step+_seq._first;
|
||||
_data[idx] /= _vec_other[j];
|
||||
}
|
||||
}
|
||||
for (; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] /= num;
|
||||
}
|
||||
#else
|
||||
for (FASTOR_INDEX i = 0; i <size(); i++) {
|
||||
auto idx = i*_seq._step+_seq._first;
|
||||
_data[idx] /= num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------//
|
||||
|
||||
template<typename U>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),i*_seq._step+_seq._first,_seq._step);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i) const {
|
||||
return _expr.data()[i*_seq._step+_seq._first];
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> eval(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),(i+j)*_seq._step+_seq._first,_seq._step);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr FASTOR_INLINE U eval_s(FASTOR_INDEX i, FASTOR_INDEX j) const {
|
||||
return _expr.data()[(i+j)*_seq._step+_seq._first];
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
FASTOR_INLINE SIMDVector<U,simd_abi_type> teval(const std::array<int,1>& as) const {
|
||||
SIMDVector<U,simd_abi_type> _vec;
|
||||
vector_setter(_vec,_expr.data(),as[0]*_seq._step+_seq._first,_seq._step);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
template<typename U=T>
|
||||
constexpr FASTOR_INLINE U teval_s(const std::array<int,1>& as) const {
|
||||
return _expr.data()[as[0]*_seq._step+_seq._first];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end of namespace Fastor
|
||||
|
||||
|
||||
#endif // TENSOR_VIEWS_1D_H
|
||||
1163
noarch/include/Fastor/expressions/views/tensor_views_2d.h
Normal file
1163
noarch/include/Fastor/expressions/views/tensor_views_2d.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
#ifndef TENSOR_VIEWS_ASSIGNMENT_H
|
||||
#define TENSOR_VIEWS_ASSIGNMENT_H
|
||||
|
||||
|
||||
#include "Fastor/expressions/views/tensor_views.h"
|
||||
#include "Fastor/expressions/views/tensor_fixed_views_1d.h"
|
||||
#include "Fastor/expressions/views/tensor_fixed_views_2d.h"
|
||||
#include "Fastor/expressions/views/tensor_random_views.h"
|
||||
|
||||
|
||||
namespace Fastor {
|
||||
|
||||
#define FASTOR_MAKE_ALL_TENSOR_VIEWS_ASSIGNMENT(ASSIGN_TYPE)\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename Seq>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorConstFixedViewExpr1D<TensorType,Seq,1>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename Seq>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorFixedViewExpr1D<TensorType,Seq,1>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename Seq0, typename Seq1>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorConstFixedViewExpr2D<TensorType,Seq0,Seq1,2>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename Seq0, typename Seq1>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorFixedViewExpr2D<TensorType,Seq0,Seq1,2>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename ... Fseq>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorConstFixedViewExprnD<TensorType,Fseq...>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename ... Fseq>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorFixedViewExprnD<TensorType,Fseq...>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, size_t OtherDIM>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorConstViewExpr<TensorType,OtherDIM>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, size_t OtherDIM>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorViewExpr<TensorType,OtherDIM>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename TensorIndexType>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorConstRandomViewExpr<TensorType,TensorIndexType,DIM>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename TensorIndexType>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorRandomViewExpr<TensorType,TensorIndexType,DIM>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, typename TensorIndexType>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorFilterViewExpr<TensorType,TensorIndexType,DIM>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
template<typename Derived, size_t DIM, typename TensorType, size_t OtherDIM>\
|
||||
FASTOR_INLINE void assign ##ASSIGN_TYPE (AbstractTensor<Derived,DIM> &dst, const TensorDiagViewExpr<TensorType,OtherDIM>& src) {\
|
||||
trivial_assign ##ASSIGN_TYPE (dst.self(), src.self());\
|
||||
}\
|
||||
|
||||
FASTOR_MAKE_ALL_TENSOR_VIEWS_ASSIGNMENT( )
|
||||
FASTOR_MAKE_ALL_TENSOR_VIEWS_ASSIGNMENT(_add)
|
||||
FASTOR_MAKE_ALL_TENSOR_VIEWS_ASSIGNMENT(_sub)
|
||||
FASTOR_MAKE_ALL_TENSOR_VIEWS_ASSIGNMENT(_mul)
|
||||
FASTOR_MAKE_ALL_TENSOR_VIEWS_ASSIGNMENT(_div)
|
||||
|
||||
} // end of namespace Fastor
|
||||
|
||||
|
||||
#endif // TENSOR_VIEWS_ASSIGNMENT_H
|
||||
1680
noarch/include/Fastor/expressions/views/tensor_views_nd.h
Normal file
1680
noarch/include/Fastor/expressions/views/tensor_views_nd.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user