Grid 0.7.0
Tensor_class.h
Go to the documentation of this file.
1/*************************************************************************************
2Grid physics library, www.github.com/paboyle/Grid
3Source file: ./lib/tensors/Tensor_class.h
4Copyright (C) 2015
5
6Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
7Author: Peter Boyle <paboyle@ph.ed.ac.uk>
8Author: Michael Marshall <michael.marshall@ed.ac.au>
9Author: Christoph Lehner <christoph@lhnr.de>
10
11This program is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2 of the License, or
14(at your option) any later version.
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19You should have received a copy of the GNU General Public License along
20with this program; if not, write to the Free Software Foundation, Inc.,
2151 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22See the full license in the file "LICENSE" in the top level distribution
23directory
24*************************************************************************************/
25 /* END LEGAL */
26#pragma once
27
29
31// Scalar, Vector, Matrix objects.
32// These can be composed to form tensor products of internal indices.
34
35// It is useful to NOT have any constructors
36// so that these classes assert "is_pod<class> == true"
37// because then the standard C++ valarray container eliminates fill overhead on
38// new allocation and
39// non-move copying.
40//
41// However note that doing this eliminates some syntactical sugar such as
42// calling the constructor explicitly or implicitly
43//
45
46// Too late to remove these traits from Grid Tensors, so inherit from GridTypeMapper
47#define GridVector_CopyTraits \
48 using element = vtype; \
49 using scalar_type = typename Traits::scalar_type; \
50 using vector_type = typename Traits::vector_type; \
51 using scalar_typeD = typename Traits::scalar_typeD; \
52 using vector_typeD = typename Traits::vector_typeD; \
53 using tensor_reduced = typename Traits::tensor_reduced; \
54 using scalar_object = typename Traits::scalar_object; \
55 using scalar_objectD = typename Traits::scalar_objectD; \
56 using Complexified = typename Traits::Complexified; \
57 using Realified = typename Traits::Realified; \
58 using DoublePrecision = typename Traits::DoublePrecision; \
59 using DoublePrecision2= typename Traits::DoublePrecision2; \
60 static constexpr int TensorLevel = Traits::TensorLevel
61
63// Allows to turn scalar<scalar<scalar<double>>>> back to double.
65template <class T>
66accelerator_inline typename std::enable_if<!isGridTensor<T>::value, T>::type
68 return arg;
69}
70template <class vtype>
72 -> decltype(TensorRemove(arg._internal)) {
73 return TensorRemove(arg._internal);
74}
75
76template <class vtype>
77class iScalar {
78public:
79 vtype _internal;
80
83
84 static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); }
85
86 // Scalar no action
87 accelerator iScalar() = default;
88
90 zeroit(that._internal);
91 }
92
93 accelerator_inline iScalar(scalar_type s) : _internal(s){}; // recurse down and hit the constructor for vector_type
94
95 accelerator_inline iScalar(const Zero &z) { zeroit(*this); };
96
98 zeroit(*this); return *this;
99 }
101 vstream(out._internal, in._internal);
102 }
103 friend accelerator_inline void vbroadcast(iScalar<vtype> &out,const iScalar<vtype> &in,int lane){
104 vbroadcast(out._internal,in._internal,lane);
105 }
107 prefetch(that._internal);
108 }
109 friend accelerator_inline void permute(iScalar<vtype> &out, const iScalar<vtype> &in, int permutetype) {
110 permute(out._internal, in._internal, permutetype);
111 }
114 }
116 const iScalar<vtype> &in1,const iScalar<vtype> &in2,int type)
117 {
119 }
120
121 // Unary negation
123 iScalar<vtype> ret;
124 ret._internal = -r._internal;
125 return ret;
126 }
127 // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour
129 *this = (*this) * r;
130 return *this;
131 }
133 *this = (*this) - r;
134 return *this;
135 }
137 *this = (*this) + r;
138 return *this;
139 }
140 accelerator_inline vtype &operator()(void) { return _internal; }
141 accelerator_inline const vtype &operator()(void) const { return _internal; }
142
143 // Type casts meta programmed, must be pure scalar to match TensorRemove
144 template <class U = vtype, class V = scalar_type, IfComplex<V> = 0, IfNotSimd<U> = 0> accelerator_inline
145 operator ComplexF() const {
146 return (TensorRemove(_internal));
147 }
148 template <class U = vtype, class V = scalar_type, IfComplex<V> = 0, IfNotSimd<U> = 0> accelerator_inline
149 operator ComplexD() const {
150 return (TensorRemove(_internal));
151 }
152 // instantiation of "Grid::iScalar<vtype>::operator Grid::RealD() const [with vtype=Grid::Real, U=Grid::Real, V=Grid::RealD, <unnamed>=0, <unnamed>=0U]"
153 template <class U = vtype, class V = scalar_type, IfReal<V> = 0,IfNotSimd<U> = 0> accelerator_inline
154 operator RealD() const {
155 return (RealD) TensorRemove(_internal);
156 }
157 template <class U = vtype, class V = scalar_type, IfInteger<V> = 0, IfNotSimd<U> = 0> accelerator_inline
158 operator Integer() const {
160 }
161
162 // convert from a something to a scalar via constructor of something arg
163 template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type * = nullptr>
165 _internal = arg;
166 return *this;
167 }
168
169 // Convert elements
170 template <class ttype>
172 _internal = arg._internal;
173 return *this;
174 }
175
176 // Host only
177 friend std::ostream &operator<<(std::ostream &stream,const iScalar<vtype> &o) {
178 stream << "S {" << o._internal << "}";
179 return stream;
180 };
181 // FIXME These will break with change of data layout
182 strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(&_internal); }
183 strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(&_internal); }
184 strong_inline const scalar_type * end() const { return begin() + Traits::count; }
185 strong_inline scalar_type * end() { return begin() + Traits::count; }
186};
187
188template <class vtype, int N>
189class iVector {
190public:
191 vtype _internal[N];
192
194
196
197 static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); }
198
199 template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type * = nullptr>
201 zeroit(*this);
202 for (int i = 0; i < N; i++) _internal[i] = arg;
203 return *this;
204 }
205
206 accelerator iVector() = default;
207 accelerator_inline iVector(const Zero &z) { zeroit(*this); };
208
209 template<class other>
211 {
212 for (int i = 0; i < N; i++) {
213 _internal[i] = him._internal[i];
214 }
215 return *this;
216 }
218 zeroit(*this);
219 return *this;
220 }
222 for (int i = 0; i < N; i++) {
223 zeroit(that._internal[i]);
224 }
225 }
227 for (int i = 0; i < N; i++) prefetch(that._internal[i]);
228 }
230 for (int i = 0; i < N; i++) {
231 vstream(out._internal[i], in._internal[i]);
232 }
233 }
235 for(int i=0;i<N;i++){
236 vbroadcast(out._internal[i],in._internal[i],lane);
237 }
238 }
239 friend accelerator_inline void permute(iVector<vtype,N> &out,const iVector<vtype,N> &in,int permutetype){
240 for(int i=0;i<N;i++){
241 permute(out._internal[i],in._internal[i],permutetype);
242 }
243 }
245 for(int i=0;i<N;i++){
246 rotate(out._internal[i],in._internal[i],rot);
247 }
248 }
250 const iVector<vtype,N> &in1,const iVector<vtype,N> &in2,int type){
251 for(int i=0;i<N;i++){
252 exchange(out1._internal[i],out2._internal[i],in1._internal[i], in2._internal[i],type);
253 }
254 }
255
256 // Unary negation
259 for (int i = 0; i < N; i++) ret._internal[i] = -r._internal[i];
260 return ret;
261 }
262 // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour
264 *this = (*this) * r;
265 return *this;
266 }
268 *this = (*this) - r;
269 return *this;
270 }
272 *this = (*this) + r;
273 return *this;
274 }
275 accelerator_inline vtype &operator()(int i) { return _internal[i]; }
276 accelerator_inline const vtype &operator()(int i) const { return _internal[i]; }
277
278 // Host
279 friend std::ostream &operator<<(std::ostream &stream, const iVector<vtype, N> &o) {
280 stream << "V<" << N << ">{";
281 for (int i = 0; i < N; i++) {
282 stream << o._internal[i];
283 if (i < N - 1) stream << ",";
284 }
285 stream << "}";
286 return stream;
287 };
288 // strong_inline vtype && operator ()(int i) {
289 // return _internal[i];
290 // }
291
292 // FIXME These will break with change of data layout
293 strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(_internal); }
294 strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(_internal); }
295 strong_inline const scalar_type * end() const { return begin() + Traits::count; }
296 strong_inline scalar_type * end() { return begin() + Traits::count; }
297
298};
299
300template <class vtype, int N>
301class iMatrix {
302public:
303 vtype _internal[N][N];
304
306
308
309 static accelerator_inline constexpr int Nsimd(void) { return sizeof(vector_type)/sizeof(scalar_type); }
310
311 accelerator_inline iMatrix(const Zero &z) { zeroit(*this); };
312 accelerator iMatrix() = default;
313
314 // Allow for type conversion.
315 template<class other>
317 for (int i = 0; i < N; i++)
318 for (int j = 0; j < N; j++)
319 _internal[i][j] = rhs._internal[i][j];
320 return *this;
321 };
322
324 (*this) = s;
325 }; // recurse down and hit the constructor for vector_type
326
328 zeroit(*this);
329 return *this;
330 }
331 template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type * = nullptr>
333 zeroit(*this);
334 for (int i = 0; i < N; i++) _internal[i][i] = arg;
335 return *this;
336 }
337
339 for(int i=0;i<N;i++){
340 for(int j=0;j<N;j++){
341 zeroit(that._internal[i][j]);
342 }}
343 }
345 for(int i=0;i<N;i++) {
346 for(int j=0;j<N;j++) {
347 prefetch(that._internal[i][j]);
348 }}
349 }
351 for(int i=0;i<N;i++){
352 for(int j=0;j<N;j++){
353 vstream(out._internal[i][j],in._internal[i][j]);
354 }}
355 }
357 for(int i=0;i<N;i++){
358 for(int j=0;j<N;j++){
359 vbroadcast(out._internal[i][j],in._internal[i][j],lane);
360 }}
361 }
362
363 friend accelerator_inline void permute(iMatrix<vtype,N> &out,const iMatrix<vtype,N> &in,int permutetype){
364 for(int i=0;i<N;i++){
365 for(int j=0;j<N;j++){
366 permute(out._internal[i][j],in._internal[i][j],permutetype);
367 }}
368 }
370 for(int i=0;i<N;i++){
371 for(int j=0;j<N;j++){
372 rotate(out._internal[i][j],in._internal[i][j],rot);
373 }}
374 }
376 const iMatrix<vtype,N> &in1,const iMatrix<vtype,N> &in2,int type){
377 for(int i=0;i<N;i++){
378 for(int j=0;j<N;j++){
379 exchange(out1._internal[i][j],out2._internal[i][j],in1._internal[i][j], in2._internal[i][j],type);
380 }}
381 }
382
383 // Unary negation
386 for (int i = 0; i < N; i++) {
387 for (int j = 0; j < N; j++) {
388 ret._internal[i][j] = -r._internal[i][j];
389 }}
390 return ret;
391 }
392 // *=,+=,-= operators inherit from corresponding "*,-,+" behaviour
393 template <class T>
395 *this = (*this) * r;
396 return *this;
397 }
398 template <class T>
400 *this = (*this) - r;
401 return *this;
402 }
403 template <class T>
405 *this = (*this) + r;
406 return *this;
407 }
408
409 // returns an lvalue reference
410 accelerator_inline vtype &operator()(int i, int j) { return _internal[i][j]; }
411 accelerator_inline const vtype &operator()(int i, int j) const {
412 return _internal[i][j];
413 }
414
415 // Host function only
416 friend std::ostream &operator<<(std::ostream &stream, const iMatrix<vtype, N> &o) {
417 stream << "M<" << N << ">{";
418 for (int i = 0; i < N; i++) {
419 stream << "{";
420 for (int j = 0; j < N; j++) {
421 stream << o._internal[i][j];
422 if (j < N - 1) stream << ",";
423 }
424 stream << "}";
425 if (i != N - 1) stream << "\n\t\t";
426 }
427 stream << "}";
428 return stream;
429 };
430
431 // strong_inline vtype && operator ()(int i,int j) {
432 // return _internal[i][j];
433 // }
434
435 // FIXME These will break with change of data layout
436 strong_inline const scalar_type * begin() const { return reinterpret_cast<const scalar_type *>(_internal[0]); }
437 strong_inline scalar_type * begin() { return reinterpret_cast< scalar_type *>(_internal[0]); }
438 strong_inline const scalar_type * end() const { return begin() + Traits::count; }
439 strong_inline scalar_type * end() { return begin() + Traits::count; }
440};
441
442template <class v> accelerator_inline
443void vprefetch(const iScalar<v> &vv) {
445}
446template <class v, int N> accelerator_inline
447void vprefetch(const iVector<v, N> &vv) {
448 for (int i = 0; i < N; i++) {
449 vprefetch(vv._internal[i]);
450 }
451}
452template <class v, int N> accelerator_inline
453void vprefetch(const iMatrix<v, N> &vv) {
454 for (int i = 0; i < N; i++) {
455 for (int j = 0; j < N; j++) {
456 vprefetch(vv._internal[i][j]);
457 }
458 }
459}
460
462
463
464#ifdef GRID_SYCL
465template<class vec> struct sycl::is_device_copyable<Grid::iScalar<vec> > : public std::true_type {};
466template<class vec,int N> struct sycl::is_device_copyable<Grid::iVector<vec,N> > : public std::true_type {};
467template<class vec,int N> struct sycl::is_device_copyable<Grid::iMatrix<vec,N> > : public std::true_type {};
468#endif
#define accelerator_inline
#define accelerator
#define rot(a, b, n, w)
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
uint32_t Integer
Definition Simd.h:58
std::complex< RealF > ComplexF
Definition Simd.h:78
std::complex< RealD > ComplexD
Definition Simd.h:79
double RealD
Definition Simd.h:61
accelerator_inline std::enable_if<!isGridTensor< T >::value, T >::type TensorRemove(T arg)
accelerator_inline void vprefetch(const iScalar< v > &vv)
#define strong_inline
Definition Threads.h:36
Definition Simd.h:194
accelerator_inline const vtype & operator()(int i, int j) const
friend accelerator_inline void prefetch(iMatrix< vtype, N > &that)
accelerator_inline iMatrix(scalar_type s)
friend accelerator_inline iMatrix< vtype, N > operator-(const iMatrix< vtype, N > &r)
friend std::ostream & operator<<(std::ostream &stream, const iMatrix< vtype, N > &o)
accelerator_inline auto operator=(T arg) -> iMatrix< vtype, N >
friend accelerator_inline void permute(iMatrix< vtype, N > &out, const iMatrix< vtype, N > &in, int permutetype)
friend accelerator_inline void vbroadcast(iMatrix< vtype, N > &out, const iMatrix< vtype, N > &in, int lane)
strong_inline scalar_type * begin()
GridTypeMapper< iMatrix< CComplex, N > > Traits
friend accelerator_inline void zeroit(iMatrix< vtype, N > &that)
accelerator_inline vtype & operator()(int i, int j)
friend accelerator_inline void vstream(iMatrix< vtype, N > &out, const iMatrix< vtype, N > &in)
strong_inline const scalar_type * end() const
static accelerator_inline constexpr int Nsimd(void)
friend accelerator_inline void rotate(iMatrix< vtype, N > &out, const iMatrix< vtype, N > &in, int rot)
accelerator_inline iMatrix< vtype, N > & operator-=(const T &r)
accelerator_inline iMatrix(const Zero &z)
accelerator_inline iMatrix & operator=(const iMatrix< other, N > &rhs)
strong_inline scalar_type * end()
friend accelerator_inline void exchange(iMatrix< vtype, N > &out1, iMatrix< vtype, N > &out2, const iMatrix< vtype, N > &in1, const iMatrix< vtype, N > &in2, int type)
accelerator_inline iMatrix< vtype, N > & operator=(const Zero &hero)
accelerator_inline iMatrix< vtype, N > & operator+=(const T &r)
accelerator_inline iMatrix< vtype, N > & operator*=(const T &r)
accelerator iMatrix()=default
strong_inline const scalar_type * begin() const
friend accelerator_inline void vbroadcast(iScalar< vtype > &out, const iScalar< vtype > &in, int lane)
accelerator_inline iScalar< vtype > & operator+=(const iScalar< vtype > &r)
friend accelerator_inline void vstream(iScalar< vtype > &out, const iScalar< vtype > &in)
accelerator_inline iScalar< vtype > & operator-=(const iScalar< vtype > &r)
static accelerator_inline constexpr int Nsimd(void)
accelerator_inline iScalar(scalar_type s)
friend accelerator_inline void rotate(iScalar< vtype > &out, const iScalar< vtype > &in, int rot)
GridTypeMapper< iScalar< vInteger > > Traits
accelerator_inline iScalar< vtype > operator=(T arg)
friend accelerator_inline iScalar< vtype > operator-(const iScalar< vtype > &r)
accelerator_inline iScalar< vtype > operator=(const iScalar< ttype > &arg)
friend accelerator_inline void zeroit(iScalar< vtype > &that)
accelerator_inline const vtype & operator()(void) const
friend accelerator_inline void permute(iScalar< vtype > &out, const iScalar< vtype > &in, int permutetype)
strong_inline const scalar_type * end() const
friend accelerator_inline void exchange(iScalar< vtype > &out1, iScalar< vtype > &out2, const iScalar< vtype > &in1, const iScalar< vtype > &in2, int type)
accelerator iScalar()=default
friend accelerator_inline void prefetch(iScalar< vtype > &that)
strong_inline scalar_type * begin()
accelerator_inline iScalar< vtype > & operator*=(const iScalar< vtype > &r)
accelerator_inline vtype & operator()(void)
strong_inline scalar_type * end()
accelerator_inline iScalar< vtype > & operator=(const Zero &hero)
strong_inline const scalar_type * begin() const
accelerator_inline iScalar(const Zero &z)
friend std::ostream & operator<<(std::ostream &stream, const iScalar< vtype > &o)
friend accelerator_inline void exchange(iVector< vtype, N > &out1, iVector< vtype, N > &out2, const iVector< vtype, N > &in1, const iVector< vtype, N > &in2, int type)
friend accelerator_inline void vstream(iVector< vtype, N > &out, const iVector< vtype, N > &in)
friend accelerator_inline void prefetch(iVector< vtype, N > &that)
friend accelerator_inline void permute(iVector< vtype, N > &out, const iVector< vtype, N > &in, int permutetype)
accelerator_inline iVector< vtype, N > & operator*=(const iScalar< vtype > &r)
strong_inline scalar_type * begin()
accelerator_inline iVector(const Zero &z)
strong_inline scalar_type * end()
GridTypeMapper< iVector< CComplex, N > > Traits
strong_inline const scalar_type * begin() const
friend accelerator_inline void rotate(iVector< vtype, N > &out, const iVector< vtype, N > &in, int rot)
accelerator_inline iVector< vtype, N > & operator=(const Zero &hero)
friend accelerator_inline iVector< vtype, N > operator-(const iVector< vtype, N > &r)
friend accelerator_inline void zeroit(iVector< vtype, N > &that)
friend accelerator_inline void vbroadcast(iVector< vtype, N > &out, const iVector< vtype, N > &in, int lane)
accelerator_inline auto operator=(T arg) -> iVector< vtype, N >
accelerator_inline iVector< vtype, N > & operator=(const iVector< other, N > &him)
static accelerator_inline constexpr int Nsimd(void)
accelerator_inline vtype & operator()(int i)
strong_inline const scalar_type * end() const
accelerator_inline const vtype & operator()(int i) const
friend std::ostream & operator<<(std::ostream &stream, const iVector< vtype, N > &o)
accelerator_inline iVector< vtype, N > & operator-=(const iVector< vtype, N > &r)
accelerator_inline iVector< vtype, N > & operator+=(const iVector< vtype, N > &r)
accelerator iVector()=default