Mercurial > hg > CbC > CbC_gcc
diff gcc/testsuite/g++.dg/tree-ssa/pr90078.C @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/testsuite/g++.dg/tree-ssa/pr90078.C Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,199 @@ +// { dg-do compile } +// { dg-options "-std=c++14 -O2 -ftemplate-depth=1000000" } + +template <class T, int Dim0, int Dim1, int Dim2> struct Tensor3; +template <class A, class T, int Dim0, int Dim1, int Dim2, char i, char j, + char k> +struct Tensor3_Expr; + +template <class T, int Dim0, int Dim1, int Dim2, int Dim3> struct Tensor4; +template <class A, class T, int Dim0, int Dim1, int Dim2, int Dim3, char i, + char j, char k, char l> +struct Tensor4_Expr; + +template <char i, int Dim> struct Index +{}; +template <const int N> struct Number +{ + Number(){}; + operator int() const { return N; } +}; + +template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2> +struct Tensor3 +{ + T data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2]; + + T operator()(const int N1, const int N2, const int N3) const + { + return data[N1][N2][N3]; + } + + template <char i, char j, char k, int Dim0, int Dim1, int Dim2> + Tensor3_Expr<const Tensor3<T, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>, T, + Dim0, Dim1, Dim2, i, j, k> + operator()(const Index<i, Dim0>, const Index<j, Dim1>, + const Index<k, Dim2>) const + { + return Tensor3_Expr<const Tensor3<T, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>, + T, Dim0, Dim1, Dim2, i, j, k>(*this); + } +}; + +template <class A, class T, int Dim0, int Dim1, int Dim2, char i, char j, + char k> +struct Tensor3_Expr +{ + A iter; + + Tensor3_Expr(const A &a) : iter(a) {} + T operator()(const int N1, const int N2, const int N3) const + { + return iter(N1, N2, N3); + } +}; + +template <class A, class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, + int Dim0, int Dim1, int Dim2, char i, char j, char k> +struct Tensor3_Expr<Tensor3<A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2>, T, Dim0, + Dim1, Dim2, i, j, k> +{ + Tensor3<A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2> &iter; + + Tensor3_Expr(Tensor3<A, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2> &a) : iter(a) + {} + T operator()(const int N1, const int N2, const int N3) const + { + return iter(N1, N2, N3); + } +}; + +template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim23, + int Dim4, int Dim5, char i, char j, char k, char l, char m> +struct Tensor3_times_Tensor3_21 +{ + Tensor3_Expr<A, T, Dim0, Dim1, Dim23, i, j, k> iterA; + Tensor3_Expr<B, U, Dim23, Dim4, Dim5, k, l, m> iterB; + + template <int CurrentDim> + T eval(const int N1, const int N2, const int N3, const int N4, + const Number<CurrentDim> &) const + { + return iterA(N1, N2, CurrentDim - 1) * iterB(CurrentDim - 1, N3, N4) + + eval(N1, N2, N3, N4, Number<CurrentDim - 1>()); + } + T eval(const int N1, const int N2, const int N3, const int N4, + const Number<1> &) const + { + return iterA(N1, N2, 0) * iterB(0, N3, N4); + } + + Tensor3_times_Tensor3_21( + const Tensor3_Expr<A, T, Dim0, Dim1, Dim23, i, j, k> &a, + const Tensor3_Expr<B, U, Dim23, Dim4, Dim5, k, l, m> &b) + : iterA(a), iterB(b) + {} + T operator()(const int &N1, const int &N2, const int &N3, + const int &N4) const + { + return eval(N1, N2, N3, N4, Number<Dim23>()); + } +}; + +template <class A, class B, class T, class U, int Dim0, int Dim1, int Dim23, + int Dim4, int Dim5, char i, char j, char k, char l, char m> +Tensor4_Expr<Tensor3_times_Tensor3_21<A, B, T, U, Dim0, Dim1, Dim23, Dim4, + Dim5, i, j, k, l, m>, + T, Dim0, Dim1, Dim4, Dim5, i, j, l, m> +operator*(const Tensor3_Expr<A, T, Dim0, Dim1, Dim23, i, j, k> &a, + const Tensor3_Expr<B, U, Dim23, Dim4, Dim5, k, l, m> &b) +{ + using TensorExpr = Tensor3_times_Tensor3_21<A, B, T, U, Dim0, Dim1, Dim23, + Dim4, Dim5, i, j, k, l, m>; + return Tensor4_Expr<TensorExpr, T, Dim0, Dim1, Dim4, Dim5, i, j, l, m>( + TensorExpr(a, b)); +}; + +template <class T, int Tensor_Dim0, int Tensor_Dim1, int Tensor_Dim2, + int Tensor_Dim3> +struct Tensor4 +{ + T data[Tensor_Dim0][Tensor_Dim1][Tensor_Dim2][Tensor_Dim3]; + + Tensor4() {} + T &operator()(const int N1, const int N2, const int N3, const int N4) + { + return data[N1][N2][N3][N4]; + } + + template <char i, char j, char k, char l, int Dim0, int Dim1, int Dim2, + int Dim3> + Tensor4_Expr<Tensor4<T, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>, + T, Dim0, Dim1, Dim2, Dim3, i, j, k, l> + operator()(const Index<i, Dim0>, const Index<j, Dim1>, const Index<k, Dim2>, + const Index<l, Dim3>) + { + return Tensor4_Expr< + Tensor4<T, Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3>, T, Dim0, + Dim1, Dim2, Dim3, i, j, k, l>(*this); + }; +}; + +template <class A, class T, int Dim0, int Dim1, int Dim2, int Dim3, char i, + char j, char k, char l> +struct Tensor4_Expr +{ + A iter; + + Tensor4_Expr(const A &a) : iter(a) {} + T operator()(const int N1, const int N2, const int N3, const int N4) const + { + return iter(N1, N2, N3, N4); + } +}; + +template <class A, class T, int Dim0, int Dim1, int Dim2, int Dim3, char i, + char j, char k, char l> +struct Tensor4_Expr<Tensor4<A, Dim0, Dim1, Dim2, Dim3>, T, Dim0, Dim1, Dim2, + Dim3, i, j, k, l> +{ + Tensor4<A, Dim0, Dim1, Dim2, Dim3> &iter; + + Tensor4_Expr(Tensor4<A, Dim0, Dim1, Dim2, Dim3> &a) : iter(a) {} + T operator()(const int N1, const int N2, const int N3, const int N4) const + { + return iter(N1, N2, N3, N4); + } + + template <class B, class U, int Dim1_0, int Dim1_1, int Dim1_2, int Dim1_3, + char i_1, char j_1, char k_1, char l_1> + auto &operator=(const Tensor4_Expr<B, U, Dim1_0, Dim1_1, Dim1_2, Dim1_3, i_1, + j_1, k_1, l_1> &rhs) + { + for(int ii = 0; ii < Dim0; ++ii) + for(int jj = 0; jj < Dim1; ++jj) + for(int kk = 0; kk < Dim2; ++kk) + for(int ll = 0; ll < Dim3; ++ll) + { + iter(ii, jj, kk, ll) = rhs(ii, jj, kk, ll); + } + return *this; + } +}; + +int main() +{ + Tensor3<float, 100, 100, 1000> t1; + Tensor3<float, 1000, 100, 100> t2; + + Index<'l', 100> l; + Index<'m', 100> m; + Index<'k', 1000> k; + Index<'n', 100> n; + Index<'o', 100> o; + + Tensor4<float, 100, 100, 100, 100> res; + res(l, m, n, o) = t1(l, m, k) * t2(k, n, o); + return 0; +} +