Grid 0.7.0
Tensor_index.h
Go to the documentation of this file.
1/*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/tensors/Tensor_index.h
6
7 Copyright (C) 2015
8
9Author: Peter Boyle <paboyle@ph.ed.ac.uk>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License along
22 with this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25 See the full license in the file "LICENSE" in the top level distribution directory
26*************************************************************************************/
27/* END LEGAL */
28#ifndef GRID_TENSOR_INDEX_H
29#define GRID_TENSOR_INDEX_H
30
32// Recursion for trace, transpose, peek, poke a specific index
34// Allow trace to recurse if vector, but never terminate on a vector
35// trace of a different index can distribute across the vector index in a replicated way
36// but we do not trace a vector index.
37
39
40/* Needed?
41 template<int Level> accelerator_inline ComplexF traceIndex(const ComplexF arg) { return arg;}
42 template<int Level> accelerator_inline ComplexD traceIndex(const ComplexD arg) { return arg;}
43 template<int Level> accelerator_inline RealF traceIndex(const RealF arg) { return arg;}
44 template<int Level> accelerator_inline RealD traceIndex(const RealD arg) { return arg;}
45*/
46template<int Level>
48
49public:
50
52 // Type Queries
54 template<class vtype> static accelerator_inline int indexRank(const iScalar<vtype> tmp) { return TensorIndexRecursion<Level-1>::indexRank(tmp._internal); }
55 template<class vtype,int N> static accelerator_inline int indexRank(const iVector<vtype,N> tmp){ return TensorIndexRecursion<Level-1>::indexRank(tmp._internal[0]); }
56 template<class vtype,int N> static accelerator_inline int indexRank(const iMatrix<vtype,N> tmp){ return TensorIndexRecursion<Level-1>::indexRank(tmp._internal[0][0]); }
57
58 template<class vtype> static accelerator_inline int isScalar(const iScalar<vtype> tmp) { return TensorIndexRecursion<Level-1>::isScalar(tmp._internal); }
59 template<class vtype,int N> static accelerator_inline int isScalar(const iVector<vtype,N> tmp){ return TensorIndexRecursion<Level-1>::isScalar(tmp._internal[0]); }
60 template<class vtype,int N> static accelerator_inline int isScalar(const iMatrix<vtype,N> tmp){ return TensorIndexRecursion<Level-1>::isScalar(tmp._internal[0][0]); }
61
62 template<class vtype> static accelerator_inline int isVector(const iScalar<vtype> tmp) { return TensorIndexRecursion<Level-1>::isVector(tmp._internal); }
63 template<class vtype,int N> static accelerator_inline int isVector(const iVector<vtype,N> tmp){ return TensorIndexRecursion<Level-1>::isVector(tmp._internal[0]); }
64 template<class vtype,int N> static accelerator_inline int isVector(const iMatrix<vtype,N> tmp){ return TensorIndexRecursion<Level-1>::isVector(tmp._internal[0][0]); }
65
66 template<class vtype> static accelerator_inline int isMatrix(const iScalar<vtype> tmp) { return TensorIndexRecursion<Level-1>::isMatrix(tmp._internal); }
67 template<class vtype,int N> static accelerator_inline int isMatrix(const iVector<vtype,N> tmp){ return TensorIndexRecursion<Level-1>::isMatrix(tmp._internal[0]); }
68 template<class vtype,int N> static accelerator_inline int isMatrix(const iMatrix<vtype,N> tmp){ return TensorIndexRecursion<Level-1>::isMatrix(tmp._internal[0][0]); }
70 // Trace
72 template<class vtype>
74 {
75 iScalar<decltype(TensorIndexRecursion<Level-1>::traceIndex(arg._internal))> ret;
77 return ret;
78 }
79 template<class vtype,int N>
81 {
82 iVector<decltype(TensorIndexRecursion<Level-1>::traceIndex(arg._internal[0])),N> ret;
83 for(int i=0;i<N;i++){
84 ret._internal[i] = TensorIndexRecursion<Level-1>::traceIndex(arg._internal[i]);
85 }
86 return ret;
87 }
88 template<class vtype,int N>
89 static accelerator_inline auto traceIndex(const iMatrix<vtype,N> arg) -> iMatrix<decltype(TensorIndexRecursion<Level-1>::traceIndex(arg._internal[0][0])),N>
90 {
91 iMatrix<decltype(TensorIndexRecursion<Level-1>::traceIndex(arg._internal[0][0])),N> ret;
92 for(int i=0;i<N;i++){
93 for(int j=0;j<N;j++){
94 ret._internal[i][j] = TensorIndexRecursion<Level-1>::traceIndex(arg._internal[i][j]);
95 }}
96 return ret;
97 }
98
99 // Recursion for peeking a specific index
101 template<class vtype>
102 static accelerator_inline auto peekIndex(const iScalar<vtype> arg,int i) -> iScalar<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal,0))>
103 {
104 iScalar<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal,0))> ret;
106 return ret;
107 }
108 template<class vtype>
109 static accelerator_inline auto peekIndex(const iScalar<vtype> arg,int i,int j) -> iScalar<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal,0,0))>
110 {
111 iScalar<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal,0,0))> ret;
113 return ret;
114 }
115
116 template<class vtype,int N>
117 static accelerator_inline auto peekIndex(const iVector<vtype,N> arg,int ii) -> iVector<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal[0],0)),N>
118 {
119 iVector<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal[0],0)),N> ret;
120 for(int i=0;i<N;i++){
121 ret._internal[i] = TensorIndexRecursion<Level-1>::peekIndex(arg._internal[i],ii);
122 }
123 return ret;
124 }
125 template<class vtype,int N>
126 static accelerator_inline auto peekIndex(const iVector<vtype,N> arg,int ii,int jj)
127 -> iVector<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal[0],0,0)),N>
128 {
129 iVector<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal[0],0,0)),N> ret;
130 for(int i=0;i<N;i++){
131 ret._internal[i] = TensorIndexRecursion<Level-1>::peekIndex(arg._internal[i],ii,jj);
132 }
133 return ret;
134 }
135
136 template<class vtype,int N>
137 static accelerator_inline auto peekIndex(const iMatrix<vtype,N> arg,int ii) -> iMatrix<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal[0][0],0)),N>
138 {
139 iMatrix<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal[0][0],0)),N> ret;
140 for(int i=0;i<N;i++){
141 for(int j=0;j<N;j++){
142 ret._internal[i][j] = TensorIndexRecursion<Level-1>::peekIndex(arg._internal[i][j],ii);
143 }}
144 return ret;
145 }
146 template<class vtype,int N>
147 static accelerator_inline auto peekIndex(const iMatrix<vtype,N> arg,int ii,int jj)
148 -> iMatrix<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal[0][0],0,0)),N>
149 {
150 iMatrix<decltype(TensorIndexRecursion<Level-1>::peekIndex(arg._internal[0][0],0,0)),N> ret;
151 for(int i=0;i<N;i++){
152 for(int j=0;j<N;j++){
153 ret._internal[i][j] = TensorIndexRecursion<Level-1>::peekIndex(arg._internal[i][j],ii,jj);
154 }}
155 return ret;
156 }
157
158 // Recursion for poking a specific index
160
161 template<class vtype> accelerator_inline static
163 {
165 }
166 template<class vtype> accelerator_inline static
167 void pokeIndex(iScalar<vtype> &ret, const iScalar<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal,0,0))> &arg, int i,int j)
168 {
170 }
171
172 template<class vtype,int N> accelerator_inline static
173 void pokeIndex(iVector<vtype,N> &ret, const iVector<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal[0],0)),N> &arg, int i)
174 {
175 for(int ii=0;ii<N;ii++){
176 TensorIndexRecursion<Level-1>::pokeIndex(ret._internal[ii],arg._internal[ii],i);
177 }
178 }
179 template<class vtype,int N> accelerator_inline static
180 void pokeIndex(iVector<vtype,N> &ret, const iVector<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal[0],0,0)),N> &arg, int i,int j)
181 {
182 for(int ii=0;ii<N;ii++){
183 TensorIndexRecursion<Level-1>::pokeIndex(ret._internal[ii],arg._internal[ii],i,j);
184 }
185 }
186
187 template<class vtype,int N> accelerator_inline static
188 void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal[0][0],0)),N> &arg, int i)
189 {
190 for(int ii=0;ii<N;ii++){
191 for(int jj=0;jj<N;jj++){
192 TensorIndexRecursion<Level-1>::pokeIndex(ret._internal[ii][jj],arg._internal[ii][jj],i);
193 }}
194 }
195 template<class vtype,int N> accelerator_inline static
196 void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(TensorIndexRecursion<Level-1>::peekIndex(ret._internal[0][0],0,0)),N> &arg, int i,int j)
197 {
198 for(int ii=0;ii<N;ii++){
199 for(int jj=0;jj<N;jj++){
200 TensorIndexRecursion<Level-1>::pokeIndex(ret._internal[ii][jj],arg._internal[ii][jj],i,j);
201 }}
202 }
203
205 // Recursion for transposing a specific index
207 template<class vtype> accelerator_inline
209 {
210 iScalar<vtype> ret;
212 return ret;
213 }
214 template<class vtype,int N> accelerator_inline
216 {
218 for(int i=0;i<N;i++){
220 }
221 return ret;
222 }
223 template<class vtype,int N> accelerator_inline
225 {
227 for(int i=0;i<N;i++){
228 for(int j=0;j<N;j++){
229 ret._internal[i][j] = TensorIndexRecursion<Level-1>::transposeIndex(arg._internal[i][j]);
230 }}
231 return ret;
232 }
233};
234
236// strip const & ref quali's
238#define RemoveCRV(a) typename std::remove_const<typename std::remove_reference<decltype(a)>::type>::type
239template<>
241public:
243 // Type Queries
245 template<class vtype> static accelerator_inline int indexRank(const iScalar<vtype> tmp) { return 1; }
246 template<class vtype,int N> static accelerator_inline int indexRank(const iVector<vtype,N> tmp){ return N; }
247 template<class vtype,int N> static accelerator_inline int indexRank(const iMatrix<vtype,N> tmp){ return N; }
248
249 template<class vtype> static accelerator_inline int isScalar(const iScalar<vtype> tmp) { return true;}
250 template<class vtype,int N> static accelerator_inline int isScalar(const iVector<vtype,N> tmp){ return false;}
251 template<class vtype,int N> static accelerator_inline int isScalar(const iMatrix<vtype,N> tmp){ return false;}
252
253 template<class vtype> static accelerator_inline int isVector(const iScalar<vtype> tmp) { return false;}
254 template<class vtype,int N> static accelerator_inline int isVector(const iVector<vtype,N> tmp){ return true;}
255 template<class vtype,int N> static accelerator_inline int isVector(const iMatrix<vtype,N> tmp){ return false;}
256
257 template<class vtype> static accelerator_inline int isMatrix(const iScalar<vtype> tmp) { return false;}
258 template<class vtype,int N> static accelerator_inline int isMatrix(const iVector<vtype,N> tmp){ return false;}
259 template<class vtype,int N> static accelerator_inline int isMatrix(const iMatrix<vtype,N> tmp){ return true;}
260
262 // Ends recursion for trace (scalar/vector/matrix)
264 template<class vtype> accelerator_inline
265 static auto traceIndex(const iScalar<vtype> arg) -> iScalar<RemoveCRV(arg._internal)>
266 {
267 iScalar<RemoveCRV(arg._internal)> ret;
268 ret._internal = arg._internal;
269 return ret;
270 }
271 template<class vtype,int N> accelerator_inline
272 static auto traceIndex(const iVector<vtype,N> arg) -> iScalar<RemoveCRV(arg._internal[0])>
273 {
274 iScalar<RemoveCRV(arg._internal[0])> ret;
275 zeroit(ret);
276 for(int i=0;i<N;i++){
277 ret._internal = ret._internal+ arg._internal[i];
278 }
279 return ret;
280 }
281 template<class vtype,int N> accelerator_inline
282 static auto traceIndex(const iMatrix<vtype,N> arg) -> iScalar<RemoveCRV(arg._internal[0][0])>
283 {
284 iScalar<RemoveCRV(arg._internal[0][0])> ret;
285 zeroit(ret);
286 for(int i=0;i<N;i++){
287 ret._internal = ret._internal+arg._internal[i][i];
288 }
289 return ret;
290 }
291
292 // Ends recursion for transpose scalar/matrix ; no way to terminate on vector
294 template<class vtype> accelerator_inline
296 {
297 iScalar<vtype> ret;
298 ret._internal = arg._internal;
299 return ret;
300 }
301 template<class vtype,int N> accelerator_inline
303 {
305 ret=Zero();
306 for(int i=0;i<N;i++){
307 for(int j=0;j<N;j++){
308 ret._internal[i][j] = ret._internal[i][j]+arg._internal[i][j];
309 }}
310 return ret;
311 }
312
313 // End recursion for peeking a specific index; single index on vector, double index on matrix
315 template<class vtype,int N> accelerator_inline
316 static auto peekIndex(const iVector<vtype,N> arg,int ii) -> iScalar<vtype>
317 {
318 iScalar<vtype> ret;
319 ret._internal = arg._internal[ii];
320 return ret;
321 }
322 template<class vtype,int N> accelerator_inline
323 static auto peekIndex(const iMatrix<vtype,N> arg,int ii,int jj) -> iScalar<vtype>
324 {
325 iScalar<vtype> ret;
326 ret._internal = arg._internal[ii][jj];
327 return ret;
328 }
329 // Vector poke, one index
330 template<class vtype,int N> accelerator_inline static
331 void pokeIndex(iVector<vtype,N> &ret, const iScalar<vtype> &arg,int i)
332 {
333 ret._internal[i] = arg._internal;
334 }
335 // Matrix poke two indices
336 template<class vtype,int N> accelerator_inline static
337 void pokeIndex(iMatrix<vtype,N> &ret, const iScalar<vtype> &arg,int i,int j)
338 {
339 ret._internal[i][j] = arg._internal;
340 }
341
342};
343
345// External wrappers
347template<int Level,class vtype> accelerator_inline int indexRank(void)
348{
349 vtype tmp;
351}
352template<int Level,class vtype> accelerator_inline int isScalar(void)
353{
354 vtype tmp;
356}
357template<int Level,class vtype> accelerator_inline int isVector(void)
358{
359 vtype tmp;
361}
362template<int Level,class vtype> accelerator_inline int isMatrix(void)
363{
364 vtype tmp;
366}
367
368template<int Level,class vtype> accelerator_inline auto traceIndex (const vtype &arg) -> RemoveCRV(TensorIndexRecursion<Level>::traceIndex(arg))
369{
372 return ret;
373}
374template<int Level,class vtype> accelerator_inline auto transposeIndex (const vtype &arg) -> RemoveCRV(TensorIndexRecursion<Level>::transposeIndex(arg))
375{
378 return ret;
379}
380
381template<int Level,class vtype> accelerator_inline auto peekIndex (const vtype &arg,int i) -> RemoveCRV(TensorIndexRecursion<Level>::peekIndex(arg,0))
382{
385 return ret;
386}
387template<int Level,class vtype> accelerator_inline auto peekIndex (const vtype &arg,int i,int j) -> RemoveCRV(TensorIndexRecursion<Level>::peekIndex(arg,0,0))
388{
391 return ret;
392}
393
394template<int Level,class vtype> accelerator_inline
395void pokeIndex (vtype &ret,const decltype(TensorIndexRecursion<Level>::peekIndex(ret,0)) &arg,int i)
396{
398}
399
400template<int Level,class vtype> accelerator_inline
401void pokeIndex (vtype &ret,const decltype(TensorIndexRecursion<Level>::peekIndex(ret,0,0)) &arg,int i,int j)
402{
404}
405
406
407#undef RemoveCRV
408
410
411#endif
#define accelerator_inline
accelerator_inline void zeroit(Grid_simd2< S, V > &z)
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
accelerator_inline void pokeIndex(vtype &ret, const decltype(TensorIndexRecursion< Level >::peekIndex(ret, 0)) &arg, int i)
accelerator_inline int isVector(void)
accelerator_inline int isScalar(void)
accelerator_inline auto peekIndex(const vtype &arg, int i) -> RemoveCRV(TensorIndexRecursion< Level >::peekIndex(arg, 0))
accelerator_inline auto transposeIndex(const vtype &arg) -> RemoveCRV(TensorIndexRecursion< Level >::transposeIndex(arg))
accelerator_inline auto traceIndex(const vtype &arg) -> RemoveCRV(TensorIndexRecursion< Level >::traceIndex(arg))
accelerator_inline int isMatrix(void)
#define RemoveCRV(a)
accelerator_inline int indexRank(void)
static accelerator_inline int isScalar(const iVector< vtype, N > tmp)
static accelerator_inline int indexRank(const iMatrix< vtype, N > tmp)
static accelerator_inline int isVector(const iVector< vtype, N > tmp)
static accelerator_inline int isMatrix(const iVector< vtype, N > tmp)
static accelerator_inline void pokeIndex(iVector< vtype, N > &ret, const iScalar< vtype > &arg, int i)
static accelerator_inline auto peekIndex(const iVector< vtype, N > arg, int ii) -> iScalar< vtype >
static accelerator_inline auto traceIndex(const iMatrix< vtype, N > arg) -> iScalar< RemoveCRV(arg._internal[0][0])>
static accelerator_inline void pokeIndex(iMatrix< vtype, N > &ret, const iScalar< vtype > &arg, int i, int j)
static accelerator_inline int isVector(const iMatrix< vtype, N > tmp)
static accelerator_inline auto transposeIndex(const iMatrix< vtype, N > arg) -> iMatrix< vtype, N >
static accelerator_inline int isScalar(const iScalar< vtype > tmp)
static accelerator_inline int isMatrix(const iMatrix< vtype, N > tmp)
static accelerator_inline int isScalar(const iMatrix< vtype, N > tmp)
static accelerator_inline int isMatrix(const iScalar< vtype > tmp)
static accelerator_inline auto peekIndex(const iMatrix< vtype, N > arg, int ii, int jj) -> iScalar< vtype >
static accelerator_inline int isVector(const iScalar< vtype > tmp)
static accelerator_inline int indexRank(const iVector< vtype, N > tmp)
static accelerator_inline auto traceIndex(const iVector< vtype, N > arg) -> iScalar< RemoveCRV(arg._internal[0])>
static accelerator_inline auto traceIndex(const iScalar< vtype > arg) -> iScalar< RemoveCRV(arg._internal)>
static accelerator_inline auto transposeIndex(const iScalar< vtype > arg) -> iScalar< vtype >
static accelerator_inline int indexRank(const iScalar< vtype > tmp)
static accelerator_inline int isMatrix(const iScalar< vtype > tmp)
static accelerator_inline int isScalar(const iScalar< vtype > tmp)
static accelerator_inline auto transposeIndex(const iMatrix< vtype, N > arg) -> iMatrix< vtype, N >
static accelerator_inline int isScalar(const iMatrix< vtype, N > tmp)
static accelerator_inline int isMatrix(const iMatrix< vtype, N > tmp)
static accelerator_inline auto transposeIndex(const iVector< vtype, N > arg) -> iVector< vtype, N >
static accelerator_inline void pokeIndex(iScalar< vtype > &ret, const iScalar< decltype(TensorIndexRecursion< Level-1 >::peekIndex(ret._internal, 0))> &arg, int i)
static accelerator_inline void pokeIndex(iMatrix< vtype, N > &ret, const iMatrix< decltype(TensorIndexRecursion< Level-1 >::peekIndex(ret._internal[0][0], 0, 0)), N > &arg, int i, int j)
static accelerator_inline void pokeIndex(iVector< vtype, N > &ret, const iVector< decltype(TensorIndexRecursion< Level-1 >::peekIndex(ret._internal[0], 0, 0)), N > &arg, int i, int j)
static accelerator_inline int indexRank(const iScalar< vtype > tmp)
static accelerator_inline int isVector(const iMatrix< vtype, N > tmp)
static accelerator_inline void pokeIndex(iScalar< vtype > &ret, const iScalar< decltype(TensorIndexRecursion< Level-1 >::peekIndex(ret._internal, 0, 0))> &arg, int i, int j)
static accelerator_inline auto traceIndex(const iScalar< vtype > arg) -> iScalar< decltype(TensorIndexRecursion< Level-1 >::traceIndex(arg._internal))>
static accelerator_inline auto traceIndex(const iMatrix< vtype, N > arg) -> iMatrix< decltype(TensorIndexRecursion< Level-1 >::traceIndex(arg._internal[0][0])), N >
static accelerator_inline int indexRank(const iMatrix< vtype, N > tmp)
static accelerator_inline auto peekIndex(const iScalar< vtype > arg, int i, int j) -> iScalar< decltype(TensorIndexRecursion< Level-1 >::peekIndex(arg._internal, 0, 0))>
static accelerator_inline auto peekIndex(const iMatrix< vtype, N > arg, int ii, int jj) -> iMatrix< decltype(TensorIndexRecursion< Level-1 >::peekIndex(arg._internal[0][0], 0, 0)), N >
static accelerator_inline int isScalar(const iVector< vtype, N > tmp)
static accelerator_inline auto peekIndex(const iMatrix< vtype, N > arg, int ii) -> iMatrix< decltype(TensorIndexRecursion< Level-1 >::peekIndex(arg._internal[0][0], 0)), N >
static accelerator_inline int isVector(const iVector< vtype, N > tmp)
static accelerator_inline int isVector(const iScalar< vtype > tmp)
static accelerator_inline auto peekIndex(const iScalar< vtype > arg, int i) -> iScalar< decltype(TensorIndexRecursion< Level-1 >::peekIndex(arg._internal, 0))>
static accelerator_inline auto peekIndex(const iVector< vtype, N > arg, int ii, int jj) -> iVector< decltype(TensorIndexRecursion< Level-1 >::peekIndex(arg._internal[0], 0, 0)), N >
static accelerator_inline int indexRank(const iVector< vtype, N > tmp)
static accelerator_inline void pokeIndex(iVector< vtype, N > &ret, const iVector< decltype(TensorIndexRecursion< Level-1 >::peekIndex(ret._internal[0], 0)), N > &arg, int i)
static accelerator_inline auto traceIndex(const iVector< vtype, N > arg) -> iVector< decltype(TensorIndexRecursion< Level-1 >::traceIndex(arg._internal[0])), N >
static accelerator_inline auto transposeIndex(const iScalar< vtype > arg) -> iScalar< vtype >
static accelerator_inline void pokeIndex(iMatrix< vtype, N > &ret, const iMatrix< decltype(TensorIndexRecursion< Level-1 >::peekIndex(ret._internal[0][0], 0)), N > &arg, int i)
static accelerator_inline auto peekIndex(const iVector< vtype, N > arg, int ii) -> iVector< decltype(TensorIndexRecursion< Level-1 >::peekIndex(arg._internal[0], 0)), N >
static accelerator_inline int isMatrix(const iVector< vtype, N > tmp)
Definition Simd.h:194
vtype _internal[N][N]
vtype _internal
vtype _internal[N]