YAKL
YAKL_componentwise.h
Go to the documentation of this file.
1 
2 #pragma once
3 // Included by YAKL.h
4 
6 namespace yakl {
7  // These are some convenient intrinsics functions (think Fortran intrinsics library)
8 
9  // Componentwise operations on arrays
10 
11  // You're going to see some strange things in here when using parallel_for. It's all because of CUDA. Thanks CUDA.
12 
14  namespace componentwise {
15 
17  // Binary operators with Array LHS and scalar RHS
19 
20  // Addition
21  template <class T1, class T2, int N, int STYLE,
22  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
23  inline Array<decltype(T1()+T2()),N,memHost,STYLE>
24  operator+( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
25  auto ret = left.template createHostObject<decltype(T1()+T2())>();
26  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] + right; }
27  return ret;
28  }
29  template <class T1, class T2, int N, int STYLE>
30  inline Array<decltype(T1()+T2()),N,memDevice,STYLE>
31  add_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
32  auto ret = left.template createDeviceObject<decltype(T1()+T2())>();
33  if constexpr (streams_enabled) fence();
34  c::parallel_for( "YAKL_internal_array_operator+" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] + right; });
35  if constexpr (streams_enabled) fence();
36  return ret;
37  }
38  template <class T1, class T2, int N, int STYLE,
39  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
40  inline Array<decltype(T1()+T2()),N,memDevice,STYLE>
41  operator+( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
42  return add_array_scalar( left , right );
43  }
44  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
45  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
46  YAKL_INLINE SArray<decltype(T1()+T2()),N,D0,D1,D2,D3>
47  operator+( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
48  SArray<decltype(T1()+T2()),N,D0,D1,D2,D3> ret;
49  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] + right; }
50  return ret;
51  }
52  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
53  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
54  YAKL_INLINE FSArray<decltype(T1()+T2()),N,B0,B1,B2,B3>
55  operator+( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
56  FSArray<decltype(T1()+T2()),N,B0,B1,B2,B3> ret;
57  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] + right; }
58  return ret;
59  }
60 
61  // Subtraction
62  template <class T1, class T2, int N, int STYLE,
63  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
64  inline Array<decltype(T1()-T2()),N,memHost,STYLE>
65  operator-( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
66  auto ret = left.template createHostObject<decltype(T1()-T2())>();
67  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] - right; }
68  return ret;
69  }
70  template <class T1, class T2, int N, int STYLE>
71  inline Array<decltype(T1()-T2()),N,memDevice,STYLE>
72  sub_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
73  auto ret = left.template createDeviceObject<decltype(T1()-T2())>();
74  if constexpr (streams_enabled) fence();
75  c::parallel_for( "YAKL_internal_array_operator-" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] - right; });
76  if constexpr (streams_enabled) fence();
77  return ret;
78  }
79  template <class T1, class T2, int N, int STYLE,
80  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
81  inline Array<decltype(T1()-T2()),N,memDevice,STYLE>
82  operator-( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
83  return sub_array_scalar( left , right );
84  }
85  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
86  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
87  YAKL_INLINE SArray<decltype(T1()-T2()),N,D0,D1,D2,D3>
88  operator-( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
89  SArray<decltype(T1()-T2()),N,D0,D1,D2,D3> ret;
90  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] - right; }
91  return ret;
92  }
93  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
94  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
95  YAKL_INLINE FSArray<decltype(T1()-T2()),N,B0,B1,B2,B3>
96  operator-( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
97  FSArray<decltype(T1()-T2()),N,B0,B1,B2,B3> ret;
98  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] - right; }
99  return ret;
100  }
101 
102  // Multiplication
103  template <class T1, class T2, int N, int STYLE,
104  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
105  inline Array<decltype(T1()*T2()),N,memHost,STYLE>
106  operator*( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
107  auto ret = left.template createHostObject<decltype(T1()*T2())>();
108  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] * right; }
109  return ret;
110  }
111  template <class T1, class T2, int N, int STYLE>
112  inline Array<decltype(T1()*T2()),N,memDevice,STYLE>
113  mult_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
114  auto ret = left.template createDeviceObject<decltype(T1()*T2())>();
115  if constexpr (streams_enabled) fence();
116  c::parallel_for( "YAKL_internal_array_operator*" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] * right; });
117  if constexpr (streams_enabled) fence();
118  return ret;
119  }
120  template <class T1, class T2, int N, int STYLE,
121  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
122  inline Array<decltype(T1()*T2()),N,memDevice,STYLE>
123  operator*( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
124  return mult_array_scalar( left , right );
125  }
126  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
127  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
128  YAKL_INLINE SArray<decltype(T1()*T2()),N,D0,D1,D2,D3>
129  operator*( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
130  SArray<decltype(T1()*T2()),N,D0,D1,D2,D3> ret;
131  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] * right; }
132  return ret;
133  }
134  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
135  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
136  YAKL_INLINE FSArray<decltype(T1()*T2()),N,B0,B1,B2,B3>
137  operator*( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
138  FSArray<decltype(T1()*T2()),N,B0,B1,B2,B3> ret;
139  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] * right; }
140  return ret;
141  }
142 
143  // Division
144  template <class T1, class T2, int N, int STYLE,
145  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
146  inline Array<decltype(T1()/T2()),N,memHost,STYLE>
147  operator/( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
148  auto ret = left.template createHostObject<decltype(T1()/T2())>();
149  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] / right; }
150  return ret;
151  }
152  template <class T1, class T2, int N, int STYLE>
153  inline Array<decltype(T1()/T2()),N,memDevice,STYLE>
154  div_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
155  auto ret = left.template createDeviceObject<decltype(T1()/T2())>();
156  if constexpr (streams_enabled) fence();
157  c::parallel_for( "YAKL_internal_array_operator/" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] / right; });
158  if constexpr (streams_enabled) fence();
159  return ret;
160  }
161  template <class T1, class T2, int N, int STYLE,
162  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
163  inline Array<decltype(T1()/T2()),N,memDevice,STYLE>
164  operator/( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
165  return div_array_scalar( left , right );
166  }
167  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
168  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
169  YAKL_INLINE SArray<decltype(T1()/T2()),N,D0,D1,D2,D3>
170  operator/( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
171  SArray<decltype(T1()/T2()),N,D0,D1,D2,D3> ret;
172  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] / right; }
173  return ret;
174  }
175  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
176  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
177  YAKL_INLINE FSArray<decltype(T1()/T2()),N,B0,B1,B2,B3>
178  operator/( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
179  FSArray<decltype(T1()/T2()),N,B0,B1,B2,B3> ret;
180  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] / right; }
181  return ret;
182  }
183 
184  // Greater than >
185  template <class T1, class T2, int N, int STYLE,
186  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
187  inline Array<decltype(T1()>T2()),N,memHost,STYLE>
188  operator>( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
189  auto ret = left.template createHostObject<decltype(T1()>T2())>();
190  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] > right; }
191  return ret;
192  }
193  template <class T1, class T2, int N, int STYLE>
194  inline Array<decltype(T1()>T2()),N,memDevice,STYLE>
195  gt_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
196  auto ret = left.template createDeviceObject<decltype(T1()>T2())>();
197  if constexpr (streams_enabled) fence();
198  c::parallel_for( "YAKL_internal_array_operator>" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] > right; });
199  if constexpr (streams_enabled) fence();
200  return ret;
201  }
202  template <class T1, class T2, int N, int STYLE,
203  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
204  inline Array<decltype(T1()>T2()),N,memDevice,STYLE>
205  operator>( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
206  return gt_array_scalar( left , right );
207  }
208  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
209  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
210  YAKL_INLINE SArray<decltype(T1()>T2()),N,D0,D1,D2,D3>
211  operator>( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
212  SArray<decltype(T1()>T2()),N,D0,D1,D2,D3> ret;
213  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] > right; }
214  return ret;
215  }
216  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
217  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
218  YAKL_INLINE FSArray<decltype(T1()>T2()),N,B0,B1,B2,B3>
219  operator>( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
220  FSArray<decltype(T1()>T2()),N,B0,B1,B2,B3> ret;
221  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] > right; }
222  return ret;
223  }
224 
225  // Less than <
226  template <class T1, class T2, int N, int STYLE,
227  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
228  inline Array<decltype(T1()<T2()),N,memHost,STYLE>
229  operator<( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
230  auto ret = left.template createHostObject<decltype(T1()<T2())>();
231  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] < right; }
232  return ret;
233  }
234  template <class T1, class T2, int N, int STYLE>
235  inline Array<decltype(T1()<T2()),N,memDevice,STYLE>
236  lt_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
237  auto ret = left.template createDeviceObject<decltype(T1()<T2())>();
238  if constexpr (streams_enabled) fence();
239  c::parallel_for( "YAKL_internal_array_operator<" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] < right; });
240  if constexpr (streams_enabled) fence();
241  return ret;
242  }
243  template <class T1, class T2, int N, int STYLE,
244  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
245  inline Array<decltype(T1()<T2()),N,memDevice,STYLE>
246  operator<( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
247  return lt_array_scalar( left , right );
248  }
249  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
250  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
251  YAKL_INLINE SArray<decltype(T1()<T2()),N,D0,D1,D2,D3>
252  operator<( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
253  SArray<decltype(T1()<T2()),N,D0,D1,D2,D3> ret;
254  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] < right; }
255  return ret;
256  }
257  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
258  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
259  YAKL_INLINE FSArray<decltype(T1()<T2()),N,B0,B1,B2,B3>
260  operator<( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
261  FSArray<decltype(T1()<T2()),N,B0,B1,B2,B3> ret;
262  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] < right; }
263  return ret;
264  }
265 
266  // Greater than or equal to >=
267  template <class T1, class T2, int N, int STYLE,
268  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
269  inline Array<decltype(T1()>=T2()),N,memHost,STYLE>
270  operator>=( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
271  auto ret = left.template createHostObject<decltype(T1()>=T2())>();
272  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] >= right; }
273  return ret;
274  }
275  template <class T1, class T2, int N, int STYLE>
276  inline Array<decltype(T1()>=T2()),N,memDevice,STYLE>
277  ge_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
278  auto ret = left.template createDeviceObject<decltype(T1()>=T2())>();
279  if constexpr (streams_enabled) fence();
280  c::parallel_for( "YAKL_internal_array_operator>=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] >= right; });
281  if constexpr (streams_enabled) fence();
282  return ret;
283  }
284  template <class T1, class T2, int N, int STYLE,
285  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
286  inline Array<decltype(T1()>=T2()),N,memDevice,STYLE>
287  operator>=( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
288  return ge_array_scalar( left , right );
289  }
290  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
291  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
292  YAKL_INLINE SArray<decltype(T1()>=T2()),N,D0,D1,D2,D3>
293  operator>=( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
294  SArray<decltype(T1()>=T2()),N,D0,D1,D2,D3> ret;
295  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] >= right; }
296  return ret;
297  }
298  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
299  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
300  YAKL_INLINE FSArray<decltype(T1()>=T2()),N,B0,B1,B2,B3>
301  operator>=( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
302  FSArray<decltype(T1()>=T2()),N,B0,B1,B2,B3> ret;
303  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] >= right; }
304  return ret;
305  }
306 
307  // Less than or equal to <=
308  template <class T1, class T2, int N, int STYLE,
309  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
310  inline Array<decltype(T1()<=T2()),N,memHost,STYLE>
311  operator<=( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
312  auto ret = left.template createHostObject<decltype(T1()<=T2())>();
313  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] <= right; }
314  return ret;
315  }
316  template <class T1, class T2, int N, int STYLE>
317  inline Array<decltype(T1()<=T2()),N,memDevice,STYLE>
318  le_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
319  auto ret = left.template createDeviceObject<decltype(T1()<=T2())>();
320  if constexpr (streams_enabled) fence();
321  c::parallel_for( "YAKL_internal_array_operator<=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] <= right; });
322  if constexpr (streams_enabled) fence();
323  return ret;
324  }
325  template <class T1, class T2, int N, int STYLE,
326  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
327  inline Array<decltype(T1()<=T2()),N,memDevice,STYLE>
328  operator<=( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
329  return le_array_scalar( left , right );
330  }
331  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
332  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
333  YAKL_INLINE SArray<decltype(T1()<=T2()),N,D0,D1,D2,D3>
334  operator<=( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
335  SArray<decltype(T1()<=T2()),N,D0,D1,D2,D3> ret;
336  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] <= right; }
337  return ret;
338  }
339  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
340  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
341  YAKL_INLINE FSArray<decltype(T1()<=T2()),N,B0,B1,B2,B3>
342  operator<=( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
343  FSArray<decltype(T1()<=T2()),N,B0,B1,B2,B3> ret;
344  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] <= right; }
345  return ret;
346  }
347 
348  // Equal to ==
349  template <class T1, class T2, int N, int STYLE,
350  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
351  inline Array<decltype(T1()==T2()),N,memHost,STYLE>
352  operator==( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
353  auto ret = left.template createHostObject<decltype(T1()==T2())>();
354  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] == right; }
355  return ret;
356  }
357  template <class T1, class T2, int N, int STYLE>
358  inline Array<decltype(T1()==T2()),N,memDevice,STYLE>
359  eq_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
360  auto ret = left.template createDeviceObject<decltype(T1()==T2())>();
361  if constexpr (streams_enabled) fence();
362  c::parallel_for( "YAKL_internal_array_operator==" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] == right; });
363  if constexpr (streams_enabled) fence();
364  return ret;
365  }
366  template <class T1, class T2, int N, int STYLE,
367  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
368  inline Array<decltype(T1()==T2()),N,memDevice,STYLE>
369  operator==( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
370  return eq_array_scalar( left , right );
371  }
372  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
373  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
374  YAKL_INLINE SArray<decltype(T1()==T2()),N,D0,D1,D2,D3>
375  operator==( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
376  SArray<decltype(T1()==T2()),N,D0,D1,D2,D3> ret;
377  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] == right; }
378  return ret;
379  }
380  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
381  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
382  YAKL_INLINE FSArray<decltype(T1()==T2()),N,B0,B1,B2,B3>
383  operator==( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
384  FSArray<decltype(T1()==T2()),N,B0,B1,B2,B3> ret;
385  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] == right; }
386  return ret;
387  }
388 
389  // Not equal to !=
390  template <class T1, class T2, int N, int STYLE,
391  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
392  inline Array<decltype(T1()!=T2()),N,memHost,STYLE>
393  operator!=( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
394  auto ret = left.template createHostObject<decltype(T1()!=T2())>();
395  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] != right; }
396  return ret;
397  }
398  template <class T1, class T2, int N, int STYLE>
399  inline Array<decltype(T1()!=T2()),N,memDevice,STYLE>
400  ne_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
401  auto ret = left.template createDeviceObject<decltype(T1()!=T2())>();
402  if constexpr (streams_enabled) fence();
403  c::parallel_for( "YAKL_internal_array_operator!=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] != right; });
404  if constexpr (streams_enabled) fence();
405  return ret;
406  }
407  template <class T1, class T2, int N, int STYLE,
408  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
409  inline Array<decltype(T1()!=T2()),N,memDevice,STYLE>
410  operator!=( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
411  return ne_array_scalar( left , right );
412  }
413  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
414  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
415  YAKL_INLINE SArray<decltype(T1()!=T2()),N,D0,D1,D2,D3>
416  operator!=( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
417  SArray<decltype(T1()!=T2()),N,D0,D1,D2,D3> ret;
418  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] != right; }
419  return ret;
420  }
421  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
422  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
423  YAKL_INLINE FSArray<decltype(T1()!=T2()),N,B0,B1,B2,B3>
424  operator!=( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
425  FSArray<decltype(T1()!=T2()),N,B0,B1,B2,B3> ret;
426  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] != right; }
427  return ret;
428  }
429 
430  // logical and &&
431  template <class T1, class T2, int N, int STYLE,
432  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
433  inline Array<decltype(T1()&&T2()),N,memHost,STYLE>
434  operator&&( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
435  auto ret = left.template createHostObject<decltype(T1()&&T2())>();
436  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] && right; }
437  return ret;
438  }
439  template <class T1, class T2, int N, int STYLE>
440  inline Array<decltype(T1()&&T2()),N,memDevice,STYLE>
441  and_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
442  auto ret = left.template createDeviceObject<decltype(T1()&&T2())>();
443  if constexpr (streams_enabled) fence();
444  c::parallel_for( "YAKL_internal_array_operator&&" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] && right; });
445  if constexpr (streams_enabled) fence();
446  return ret;
447  }
448  template <class T1, class T2, int N, int STYLE,
449  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
450  inline Array<decltype(T1()&&T2()),N,memDevice,STYLE>
451  operator&&( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
452  return and_array_scalar( left , right );
453  }
454  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
455  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
456  YAKL_INLINE SArray<decltype(T1()&&T2()),N,D0,D1,D2,D3>
457  operator&&( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
458  SArray<decltype(T1()&&T2()),N,D0,D1,D2,D3> ret;
459  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] && right; }
460  return ret;
461  }
462  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
463  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
464  YAKL_INLINE FSArray<decltype(T1()&&T2()),N,B0,B1,B2,B3>
465  operator&&( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
466  FSArray<decltype(T1()&&T2()),N,B0,B1,B2,B3> ret;
467  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] && right; }
468  return ret;
469  }
470 
471  // logical or ||
472  template <class T1, class T2, int N, int STYLE,
473  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
474  inline Array<decltype(T1()||T2()),N,memHost,STYLE>
475  operator||( Array<T1,N,memHost,STYLE> const &left , T2 const &right ) {
476  auto ret = left.template createHostObject<decltype(T1()||T2())>();
477  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] || right; }
478  return ret;
479  }
480  template <class T1, class T2, int N, int STYLE>
481  inline Array<decltype(T1()||T2()),N,memDevice,STYLE>
482  or_array_scalar( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
483  auto ret = left.template createDeviceObject<decltype(T1()||T2())>();
484  if constexpr (streams_enabled) fence();
485  c::parallel_for( "YAKL_internal_array_operator||" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] || right; });
486  if constexpr (streams_enabled) fence();
487  return ret;
488  }
489  template <class T1, class T2, int N, int STYLE,
490  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
491  inline Array<decltype(T1()||T2()),N,memDevice,STYLE>
492  operator||( Array<T1,N,memDevice,STYLE> const &left , T2 const &right ) {
493  return or_array_scalar( left , right );
494  }
495  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
496  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
497  YAKL_INLINE SArray<decltype(T1()||T2()),N,D0,D1,D2,D3>
498  operator||( SArray<T1,N,D0,D1,D2,D3> const &left , T2 const &right ) {
499  SArray<decltype(T1()||T2()),N,D0,D1,D2,D3> ret;
500  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] || right; }
501  return ret;
502  }
503  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
504  typename std::enable_if<std::is_arithmetic<T2>::value,bool>::type = false>
505  YAKL_INLINE FSArray<decltype(T1()||T2()),N,B0,B1,B2,B3>
506  operator||( FSArray<T1,N,B0,B1,B2,B3> const &left , T2 const &right ) {
507  FSArray<decltype(T1()||T2()),N,B0,B1,B2,B3> ret;
508  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] || right; }
509  return ret;
510  }
511 
512 
514  // Binary operators with scalar LHS and Array RHS
516 
517  // Addition
518  template <class T1, class T2, int N, int STYLE,
519  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
520  inline Array<decltype(T1()+T2()),N,memHost,STYLE>
521  operator+( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
522  auto ret = right.template createHostObject<decltype(T1()+T2())>();
523  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left + right.data()[i]; }
524  return ret;
525  }
526  template <class T1, class T2, int N, int STYLE>
527  inline Array<decltype(T1()+T2()),N,memDevice,STYLE>
528  add_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
529  auto ret = right.template createDeviceObject<decltype(T1()+T2())>();
530  if constexpr (streams_enabled) fence();
531  c::parallel_for( "YAKL_internal_array_operator+" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left + right.data()[i]; });
532  if constexpr (streams_enabled) fence();
533  return ret;
534  }
535  template <class T1, class T2, int N, int STYLE,
536  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
537  inline Array<decltype(T1()+T2()),N,memDevice,STYLE>
538  operator+( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
539  return add_scalar_array( left , right );
540  }
541  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
542  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
543  YAKL_INLINE SArray<decltype(T1()+T2()),N,D0,D1,D2,D3>
544  operator+( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
545  SArray<decltype(T1()+T2()),N,D0,D1,D2,D3> ret;
546  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left + right.data()[i]; }
547  return ret;
548  }
549  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
550  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
551  YAKL_INLINE FSArray<decltype(T1()+T2()),N,B0,B1,B2,B3>
552  operator+( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
553  FSArray<decltype(T1()+T2()),N,B0,B1,B2,B3> ret;
554  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left + right.data()[i]; }
555  return ret;
556  }
557 
558  // Subtraction
559  template <class T1, class T2, int N, int STYLE,
560  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
561  inline Array<decltype(T1()-T2()),N,memHost,STYLE>
562  operator-( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
563  auto ret = right.template createHostObject<decltype(T1()-T2())>();
564  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left - right.data()[i]; }
565  return ret;
566  }
567  template <class T1, class T2, int N, int STYLE>
568  inline Array<decltype(T1()-T2()),N,memDevice,STYLE>
569  sub_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
570  auto ret = right.template createDeviceObject<decltype(T1()-T2())>();
571  if constexpr (streams_enabled) fence();
572  c::parallel_for( "YAKL_internal_array_operator-" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left - right.data()[i]; });
573  if constexpr (streams_enabled) fence();
574  return ret;
575  }
576  template <class T1, class T2, int N, int STYLE,
577  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
578  inline Array<decltype(T1()-T2()),N,memDevice,STYLE>
579  operator-( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
580  return sub_scalar_array( left , right );
581  }
582  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
583  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
584  YAKL_INLINE SArray<decltype(T1()-T2()),N,D0,D1,D2,D3>
585  operator-( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
586  SArray<decltype(T1()-T2()),N,D0,D1,D2,D3> ret;
587  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left - right.data()[i]; }
588  return ret;
589  }
590  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
591  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
592  YAKL_INLINE FSArray<decltype(T1()-T2()),N,B0,B1,B2,B3>
593  operator-( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
594  FSArray<decltype(T1()-T2()),N,B0,B1,B2,B3> ret;
595  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left - right.data()[i]; }
596  return ret;
597  }
598 
599  // Multiplication
600  template <class T1, class T2, int N, int STYLE,
601  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
602  inline Array<decltype(T1()*T2()),N,memHost,STYLE>
603  operator*( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
604  auto ret = right.template createHostObject<decltype(T1()*T2())>();
605  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left * right.data()[i]; }
606  return ret;
607  }
608  template <class T1, class T2, int N, int STYLE>
609  inline Array<decltype(T1()*T2()),N,memDevice,STYLE>
610  mult_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
611  auto ret = right.template createDeviceObject<decltype(T1()*T2())>();
612  if constexpr (streams_enabled) fence();
613  c::parallel_for( "YAKL_internal_array_operator*" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left * right.data()[i]; });
614  if constexpr (streams_enabled) fence();
615  return ret;
616  }
617  template <class T1, class T2, int N, int STYLE,
618  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
619  inline Array<decltype(T1()*T2()),N,memDevice,STYLE>
620  operator*( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
621  return mult_scalar_array( left , right );
622  }
623  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
624  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
625  YAKL_INLINE SArray<decltype(T1()*T2()),N,D0,D1,D2,D3>
626  operator*( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
627  SArray<decltype(T1()*T2()),N,D0,D1,D2,D3> ret;
628  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left * right.data()[i]; }
629  return ret;
630  }
631  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
632  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
633  YAKL_INLINE FSArray<decltype(T1()*T2()),N,B0,B1,B2,B3>
634  operator*( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
635  FSArray<decltype(T1()*T2()),N,B0,B1,B2,B3> ret;
636  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left * right.data()[i]; }
637  return ret;
638  }
639 
640  // Division
641  template <class T1, class T2, int N, int STYLE,
642  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
643  inline Array<decltype(T1()/T2()),N,memHost,STYLE>
644  operator/( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
645  auto ret = right.template createHostObject<decltype(T1()/T2())>();
646  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left / right.data()[i]; }
647  return ret;
648  }
649  template <class T1, class T2, int N, int STYLE>
650  inline Array<decltype(T1()/T2()),N,memDevice,STYLE>
651  div_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
652  auto ret = right.template createDeviceObject<decltype(T1()/T2())>();
653  if constexpr (streams_enabled) fence();
654  c::parallel_for( "YAKL_internal_array_operator/" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left / right.data()[i]; });
655  if constexpr (streams_enabled) fence();
656  return ret;
657  }
658  template <class T1, class T2, int N, int STYLE,
659  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
660  inline Array<decltype(T1()/T2()),N,memDevice,STYLE>
661  operator/( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
662  return div_scalar_array( left , right );
663  }
664  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
665  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
666  YAKL_INLINE SArray<decltype(T1()/T2()),N,D0,D1,D2,D3>
667  operator/( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
668  SArray<decltype(T1()/T2()),N,D0,D1,D2,D3> ret;
669  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left / right.data()[i]; }
670  return ret;
671  }
672  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
673  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
674  YAKL_INLINE FSArray<decltype(T1()/T2()),N,B0,B1,B2,B3>
675  operator/( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
676  FSArray<decltype(T1()/T2()),N,B0,B1,B2,B3> ret;
677  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left / right.data()[i]; }
678  return ret;
679  }
680 
681  // Greater than >
682  template <class T1, class T2, int N, int STYLE,
683  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
684  inline Array<decltype(T1()>T2()),N,memHost,STYLE>
685  operator>( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
686  auto ret = right.template createHostObject<decltype(T1()>T2())>();
687  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left > right.data()[i]; }
688  return ret;
689  }
690  template <class T1, class T2, int N, int STYLE>
691  inline Array<decltype(T1()>T2()),N,memDevice,STYLE>
692  gt_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
693  auto ret = right.template createDeviceObject<decltype(T1()>T2())>();
694  if constexpr (streams_enabled) fence();
695  c::parallel_for( "YAKL_internal_array_operator>" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left > right.data()[i]; });
696  if constexpr (streams_enabled) fence();
697  return ret;
698  }
699  template <class T1, class T2, int N, int STYLE,
700  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
701  inline Array<decltype(T1()>T2()),N,memDevice,STYLE>
702  operator>( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
703  return gt_scalar_array( left , right );
704  }
705  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
706  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
707  YAKL_INLINE SArray<decltype(T1()>T2()),N,D0,D1,D2,D3>
708  operator>( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
709  SArray<decltype(T1()>T2()),N,D0,D1,D2,D3> ret;
710  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left > right.data()[i]; }
711  return ret;
712  }
713  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
714  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
715  YAKL_INLINE FSArray<decltype(T1()>T2()),N,B0,B1,B2,B3>
716  operator>( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
717  FSArray<decltype(T1()>T2()),N,B0,B1,B2,B3> ret;
718  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left > right.data()[i]; }
719  return ret;
720  }
721 
722  // Less than <
723  template <class T1, class T2, int N, int STYLE,
724  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
725  inline Array<decltype(T1()<T2()),N,memHost,STYLE>
726  operator<( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
727  auto ret = right.template createHostObject<decltype(T1()<T2())>();
728  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left < right.data()[i]; }
729  return ret;
730  }
731  template <class T1, class T2, int N, int STYLE>
732  inline Array<decltype(T1()<T2()),N,memDevice,STYLE>
733  lt_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
734  auto ret = right.template createDeviceObject<decltype(T1()<T2())>();
735  if constexpr (streams_enabled) fence();
736  c::parallel_for( "YAKL_internal_array_operator<" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left < right.data()[i]; });
737  if constexpr (streams_enabled) fence();
738  return ret;
739  }
740  template <class T1, class T2, int N, int STYLE,
741  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
742  inline Array<decltype(T1()<T2()),N,memDevice,STYLE>
743  operator<( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
744  return lt_scalar_array( left , right );
745  }
746  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
747  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
748  YAKL_INLINE SArray<decltype(T1()<T2()),N,D0,D1,D2,D3>
749  operator<( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
750  SArray<decltype(T1()<T2()),N,D0,D1,D2,D3> ret;
751  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left < right.data()[i]; }
752  return ret;
753  }
754  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
755  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
756  YAKL_INLINE FSArray<decltype(T1()<T2()),N,B0,B1,B2,B3>
757  operator<( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
758  FSArray<decltype(T1()<T2()),N,B0,B1,B2,B3> ret;
759  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left < right.data()[i]; }
760  return ret;
761  }
762 
763  // Greater than or equal to >=
764  template <class T1, class T2, int N, int STYLE,
765  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
766  inline Array<decltype(T1()>=T2()),N,memHost,STYLE>
767  operator>=( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
768  auto ret = right.template createHostObject<decltype(T1()>=T2())>();
769  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left >= right.data()[i]; }
770  return ret;
771  }
772  template <class T1, class T2, int N, int STYLE>
773  inline Array<decltype(T1()>=T2()),N,memDevice,STYLE>
774  ge_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
775  auto ret = right.template createDeviceObject<decltype(T1()>=T2())>();
776  if constexpr (streams_enabled) fence();
777  c::parallel_for( "YAKL_internal_array_operator>=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left >= right.data()[i]; });
778  if constexpr (streams_enabled) fence();
779  return ret;
780  }
781  template <class T1, class T2, int N, int STYLE,
782  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
783  inline Array<decltype(T1()>=T2()),N,memDevice,STYLE>
784  operator>=( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
785  return ge_scalar_array( left , right );
786  }
787  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
788  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
789  YAKL_INLINE SArray<decltype(T1()>=T2()),N,D0,D1,D2,D3>
790  operator>=( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
791  SArray<decltype(T1()>=T2()),N,D0,D1,D2,D3> ret;
792  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left >= right.data()[i]; }
793  return ret;
794  }
795  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
796  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
797  YAKL_INLINE FSArray<decltype(T1()>=T2()),N,B0,B1,B2,B3>
798  operator>=( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
799  FSArray<decltype(T1()>=T2()),N,B0,B1,B2,B3> ret;
800  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left >= right.data()[i]; }
801  return ret;
802  }
803 
804  // Less than or equal to <=
805  template <class T1, class T2, int N, int STYLE,
806  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
807  inline Array<decltype(T1()<=T2()),N,memHost,STYLE>
808  operator<=( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
809  auto ret = right.template createHostObject<decltype(T1()<=T2())>();
810  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left <= right.data()[i]; }
811  return ret;
812  }
813  template <class T1, class T2, int N, int STYLE>
814  inline Array<decltype(T1()<=T2()),N,memDevice,STYLE>
815  le_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
816  auto ret = right.template createDeviceObject<decltype(T1()<=T2())>();
817  if constexpr (streams_enabled) fence();
818  c::parallel_for( "YAKL_internal_array_operator<=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left <= right.data()[i]; });
819  if constexpr (streams_enabled) fence();
820  return ret;
821  }
822  template <class T1, class T2, int N, int STYLE,
823  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
824  inline Array<decltype(T1()<=T2()),N,memDevice,STYLE>
825  operator<=( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
826  return le_scalar_array( left , right );
827  }
828  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
829  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
830  YAKL_INLINE SArray<decltype(T1()<=T2()),N,D0,D1,D2,D3>
831  operator<=( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
832  SArray<decltype(T1()<=T2()),N,D0,D1,D2,D3> ret;
833  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left <= right.data()[i]; }
834  return ret;
835  }
836  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
837  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
838  YAKL_INLINE FSArray<decltype(T1()<=T2()),N,B0,B1,B2,B3>
839  operator<=( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
840  FSArray<decltype(T1()<=T2()),N,B0,B1,B2,B3> ret;
841  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left <= right.data()[i]; }
842  return ret;
843  }
844 
845  // Equal to ==
846  template <class T1, class T2, int N, int STYLE,
847  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
848  inline Array<decltype(T1()==T2()),N,memHost,STYLE>
849  operator==( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
850  auto ret = right.template createHostObject<decltype(T1()==T2())>();
851  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left == right.data()[i]; }
852  return ret;
853  }
854  template <class T1, class T2, int N, int STYLE>
855  inline Array<decltype(T1()==T2()),N,memDevice,STYLE>
856  eq_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
857  auto ret = right.template createDeviceObject<decltype(T1()==T2())>();
858  if constexpr (streams_enabled) fence();
859  c::parallel_for( "YAKL_internal_array_operator==" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left == right.data()[i]; });
860  if constexpr (streams_enabled) fence();
861  return ret;
862  }
863  template <class T1, class T2, int N, int STYLE,
864  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
865  inline Array<decltype(T1()==T2()),N,memDevice,STYLE>
866  operator==( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
867  return eq_scalar_array( left , right );
868  }
869  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
870  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
871  YAKL_INLINE SArray<decltype(T1()==T2()),N,D0,D1,D2,D3>
872  operator==( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
873  SArray<decltype(T1()==T2()),N,D0,D1,D2,D3> ret;
874  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left == right.data()[i]; }
875  return ret;
876  }
877  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
878  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
879  YAKL_INLINE FSArray<decltype(T1()==T2()),N,B0,B1,B2,B3>
880  operator==( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
881  FSArray<decltype(T1()==T2()),N,B0,B1,B2,B3> ret;
882  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left == right.data()[i]; }
883  return ret;
884  }
885 
886  // Not equal to !=
887  template <class T1, class T2, int N, int STYLE,
888  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
889  inline Array<decltype(T1()!=T2()),N,memHost,STYLE>
890  operator!=( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
891  auto ret = right.template createHostObject<decltype(T1()!=T2())>();
892  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left != right.data()[i]; }
893  return ret;
894  }
895  template <class T1, class T2, int N, int STYLE>
896  inline Array<decltype(T1()!=T2()),N,memDevice,STYLE>
897  ne_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
898  auto ret = right.template createDeviceObject<decltype(T1()!=T2())>();
899  if constexpr (streams_enabled) fence();
900  c::parallel_for( "YAKL_internal_array_operator!=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left != right.data()[i]; });
901  if constexpr (streams_enabled) fence();
902  return ret;
903  }
904  template <class T1, class T2, int N, int STYLE,
905  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
906  inline Array<decltype(T1()!=T2()),N,memDevice,STYLE>
907  operator!=( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
908  return ne_scalar_array( left , right );
909  }
910  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
911  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
912  YAKL_INLINE SArray<decltype(T1()!=T2()),N,D0,D1,D2,D3>
913  operator!=( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
914  SArray<decltype(T1()!=T2()),N,D0,D1,D2,D3> ret;
915  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left != right.data()[i]; }
916  return ret;
917  }
918  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
919  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
920  YAKL_INLINE FSArray<decltype(T1()!=T2()),N,B0,B1,B2,B3>
921  operator!=( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
922  FSArray<decltype(T1()!=T2()),N,B0,B1,B2,B3> ret;
923  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left != right.data()[i]; }
924  return ret;
925  }
926 
927  // logical and &&
928  template <class T1, class T2, int N, int STYLE,
929  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
930  inline Array<decltype(T1()&&T2()),N,memHost,STYLE>
931  operator&&( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
932  auto ret = right.template createHostObject<decltype(T1()&&T2())>();
933  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left && right.data()[i]; }
934  return ret;
935  }
936  template <class T1, class T2, int N, int STYLE>
937  inline Array<decltype(T1()&&T2()),N,memDevice,STYLE>
938  and_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
939  auto ret = right.template createDeviceObject<decltype(T1()&&T2())>();
940  if constexpr (streams_enabled) fence();
941  c::parallel_for( "YAKL_internal_array_operator&&" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left && right.data()[i]; });
942  if constexpr (streams_enabled) fence();
943  return ret;
944  }
945  template <class T1, class T2, int N, int STYLE,
946  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
947  inline Array<decltype(T1()&&T2()),N,memDevice,STYLE>
948  operator&&( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
949  return and_scalar_array( left , right );
950  }
951  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
952  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
953  YAKL_INLINE SArray<decltype(T1()&&T2()),N,D0,D1,D2,D3>
954  operator&&( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
955  SArray<decltype(T1()&&T2()),N,D0,D1,D2,D3> ret;
956  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left && right.data()[i]; }
957  return ret;
958  }
959  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
960  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
961  YAKL_INLINE FSArray<decltype(T1()&&T2()),N,B0,B1,B2,B3>
962  operator&&( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
963  FSArray<decltype(T1()&&T2()),N,B0,B1,B2,B3> ret;
964  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left && right.data()[i]; }
965  return ret;
966  }
967 
968  // logical or ||
969  template <class T1, class T2, int N, int STYLE,
970  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
971  inline Array<decltype(T1()||T2()),N,memHost,STYLE>
972  operator||( T1 const &left , Array<T2,N,memHost,STYLE> const &right ) {
973  auto ret = right.template createHostObject<decltype(T1()||T2())>();
974  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left || right.data()[i]; }
975  return ret;
976  }
977  template <class T1, class T2, int N, int STYLE>
978  inline Array<decltype(T1()||T2()),N,memDevice,STYLE>
979  or_scalar_array( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
980  auto ret = right.template createDeviceObject<decltype(T1()||T2())>();
981  if constexpr (streams_enabled) fence();
982  c::parallel_for( "YAKL_internal_array_operator||" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left || right.data()[i]; });
983  if constexpr (streams_enabled) fence();
984  return ret;
985  }
986  template <class T1, class T2, int N, int STYLE,
987  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
988  inline Array<decltype(T1()||T2()),N,memDevice,STYLE>
989  operator||( T1 const &left , Array<T2,N,memDevice,STYLE> const &right ) {
990  return or_scalar_array( left , right );
991  }
992  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3,
993  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
994  YAKL_INLINE SArray<decltype(T1()||T2()),N,D0,D1,D2,D3>
995  operator||( T1 const &left , SArray<T2,N,D0,D1,D2,D3> const &right ) {
996  SArray<decltype(T1()||T2()),N,D0,D1,D2,D3> ret;
997  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left || right.data()[i]; }
998  return ret;
999  }
1000  template <class T1, class T2, int N, class B0, class B1, class B2, class B3,
1001  typename std::enable_if<std::is_arithmetic<T1>::value,bool>::type = false>
1002  YAKL_INLINE FSArray<decltype(T1()||T2()),N,B0,B1,B2,B3>
1003  operator||( T1 const &left , FSArray<T2,N,B0,B1,B2,B3> const &right ) {
1004  FSArray<decltype(T1()||T2()),N,B0,B1,B2,B3> ret;
1005  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left || right.data()[i]; }
1006  return ret;
1007  }
1008 
1009 
1011  // Binary operators with Array LHS and Array RHS
1013 
1014  // Addition
1015  template <class T1, class T2, int N, int STYLE>
1016  inline Array<decltype(T1()+T2()),N,memHost,STYLE>
1018  auto ret = left.template createHostObject<decltype(T1()+T2())>();
1019  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] + right.data()[i]; }
1020  return ret;
1021  }
1022  template <class T1, class T2, int N, int STYLE>
1023  inline Array<decltype(T1()+T2()),N,memDevice,STYLE>
1025  auto ret = left.template createDeviceObject<decltype(T1()+T2())>();
1026  if constexpr (streams_enabled) fence();
1027  c::parallel_for( "YAKL_internal_array_operator+" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] + right.data()[i]; });
1028  if constexpr (streams_enabled) fence();
1029  return ret;
1030  }
1031  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1032  YAKL_INLINE SArray<decltype(T1()+T2()),N,D0,D1,D2,D3>
1034  SArray<decltype(T1()+T2()),N,D0,D1,D2,D3> ret;
1035  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] + right.data()[i]; }
1036  return ret;
1037  }
1038  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1039  YAKL_INLINE FSArray<decltype(T1()+T2()),N,B0,B1,B2,B3>
1041  FSArray<decltype(T1()+T2()),N,B0,B1,B2,B3> ret;
1042  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] + right.data()[i]; }
1043  return ret;
1044  }
1045 
1046  // Subtraction
1047  template <class T1, class T2, int N, int STYLE>
1048  inline Array<decltype(T1()-T2()),N,memHost,STYLE>
1050  auto ret = left.template createHostObject<decltype(T1()-T2())>();
1051  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] - right.data()[i]; }
1052  return ret;
1053  }
1054  template <class T1, class T2, int N, int STYLE>
1055  inline Array<decltype(T1()-T2()),N,memDevice,STYLE>
1057  auto ret = left.template createDeviceObject<decltype(T1()-T2())>();
1058  if constexpr (streams_enabled) fence();
1059  c::parallel_for( "YAKL_internal_array_operator-" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] - right.data()[i]; });
1060  if constexpr (streams_enabled) fence();
1061  return ret;
1062  }
1063  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1064  YAKL_INLINE SArray<decltype(T1()-T2()),N,D0,D1,D2,D3>
1066  SArray<decltype(T1()-T2()),N,D0,D1,D2,D3> ret;
1067  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] - right.data()[i]; }
1068  return ret;
1069  }
1070  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1071  YAKL_INLINE FSArray<decltype(T1()-T2()),N,B0,B1,B2,B3>
1073  FSArray<decltype(T1()-T2()),N,B0,B1,B2,B3> ret;
1074  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] - right.data()[i]; }
1075  return ret;
1076  }
1077 
1078  // Multiplication
1079  template <class T1, class T2, int N, int STYLE>
1080  inline Array<decltype(T1()*T2()),N,memHost,STYLE>
1082  auto ret = left.template createHostObject<decltype(T1()*T2())>();
1083  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] * right.data()[i]; }
1084  return ret;
1085  }
1086  template <class T1, class T2, int N, int STYLE>
1087  inline Array<decltype(T1()*T2()),N,memDevice,STYLE>
1089  auto ret = left.template createDeviceObject<decltype(T1()*T2())>();
1090  if constexpr (streams_enabled) fence();
1091  c::parallel_for( "YAKL_internal_array_operator*" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] * right.data()[i]; });
1092  if constexpr (streams_enabled) fence();
1093  return ret;
1094  }
1095  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1096  YAKL_INLINE SArray<decltype(T1()*T2()),N,D0,D1,D2,D3>
1098  SArray<decltype(T1()*T2()),N,D0,D1,D2,D3> ret;
1099  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] * right.data()[i]; }
1100  return ret;
1101  }
1102  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1103  YAKL_INLINE FSArray<decltype(T1()*T2()),N,B0,B1,B2,B3>
1105  FSArray<decltype(T1()*T2()),N,B0,B1,B2,B3> ret;
1106  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] * right.data()[i]; }
1107  return ret;
1108  }
1109 
1110  // Division
1111  template <class T1, class T2, int N, int STYLE>
1112  inline Array<decltype(T1()/T2()),N,memHost,STYLE>
1114  auto ret = left.template createHostObject<decltype(T1()/T2())>();
1115  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] / right.data()[i]; }
1116  return ret;
1117  }
1118  template <class T1, class T2, int N, int STYLE>
1119  inline Array<decltype(T1()/T2()),N,memDevice,STYLE>
1121  auto ret = left.template createDeviceObject<decltype(T1()/T2())>();
1122  if constexpr (streams_enabled) fence();
1123  c::parallel_for( "YAKL_internal_array_operator/" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] / right.data()[i]; });
1124  if constexpr (streams_enabled) fence();
1125  return ret;
1126  }
1127  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1128  YAKL_INLINE SArray<decltype(T1()/T2()),N,D0,D1,D2,D3>
1130  SArray<decltype(T1()/T2()),N,D0,D1,D2,D3> ret;
1131  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] / right.data()[i]; }
1132  return ret;
1133  }
1134  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1135  YAKL_INLINE FSArray<decltype(T1()/T2()),N,B0,B1,B2,B3>
1137  FSArray<decltype(T1()/T2()),N,B0,B1,B2,B3> ret;
1138  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] / right.data()[i]; }
1139  return ret;
1140  }
1141 
1142  // Greater than >
1143  template <class T1, class T2, int N, int STYLE>
1144  inline Array<decltype(T1()>T2()),N,memHost,STYLE>
1146  auto ret = left.template createHostObject<decltype(T1()>T2())>();
1147  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] > right.data()[i]; }
1148  return ret;
1149  }
1150  template <class T1, class T2, int N, int STYLE>
1151  inline Array<decltype(T1()>T2()),N,memDevice,STYLE>
1153  auto ret = left.template createDeviceObject<decltype(T1()>T2())>();
1154  if constexpr (streams_enabled) fence();
1155  c::parallel_for( "YAKL_internal_array_operator>" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] > right.data()[i]; });
1156  if constexpr (streams_enabled) fence();
1157  return ret;
1158  }
1159  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1160  YAKL_INLINE SArray<decltype(T1()>T2()),N,D0,D1,D2,D3>
1162  SArray<decltype(T1()>T2()),N,D0,D1,D2,D3> ret;
1163  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] > right.data()[i]; }
1164  return ret;
1165  }
1166  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1167  YAKL_INLINE FSArray<decltype(T1()>T2()),N,B0,B1,B2,B3>
1169  FSArray<decltype(T1()>T2()),N,B0,B1,B2,B3> ret;
1170  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] > right.data()[i]; }
1171  return ret;
1172  }
1173 
1174  // Less than <
1175  template <class T1, class T2, int N, int STYLE>
1176  inline Array<decltype(T1()<T2()),N,memHost,STYLE>
1178  auto ret = left.template createHostObject<decltype(T1()<T2())>();
1179  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] < right.data()[i]; }
1180  return ret;
1181  }
1182  template <class T1, class T2, int N, int STYLE>
1185  auto ret = left.template createDeviceObject<bool>();
1186  if constexpr (streams_enabled) fence();
1187  c::parallel_for( "YAKL_internal_array_operator<" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] < right.data()[i]; });
1188  if constexpr (streams_enabled) fence();
1189  return ret;
1190  }
1191  template <class T1, class T2, int N, int STYLE>
1194  return lt_array_array( left , right );
1195  }
1196  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1197  YAKL_INLINE SArray<decltype(T1()<T2()),N,D0,D1,D2,D3>
1199  SArray<decltype(T1()<T2()),N,D0,D1,D2,D3> ret;
1200  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] < right.data()[i]; }
1201  return ret;
1202  }
1203  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1204  YAKL_INLINE FSArray<decltype(T1()<T2()),N,B0,B1,B2,B3>
1206  FSArray<decltype(T1()<T2()),N,B0,B1,B2,B3> ret;
1207  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] < right.data()[i]; }
1208  return ret;
1209  }
1210 
1211  // Greater than or equal to >=
1212  template <class T1, class T2, int N, int STYLE>
1213  inline Array<decltype(T1()>=T2()),N,memHost,STYLE>
1215  auto ret = left.template createHostObject<decltype(T1()>=T2())>();
1216  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] >= right.data()[i]; }
1217  return ret;
1218  }
1219  template <class T1, class T2, int N, int STYLE>
1220  inline Array<decltype(T1()>=T2()),N,memDevice,STYLE>
1222  auto ret = left.template createDeviceObject<decltype(T1()>=T2())>();
1223  if constexpr (streams_enabled) fence();
1224  c::parallel_for( "YAKL_internal_array_operator>=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] >= right.data()[i]; });
1225  if constexpr (streams_enabled) fence();
1226  return ret;
1227  }
1228  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1229  YAKL_INLINE SArray<decltype(T1()>=T2()),N,D0,D1,D2,D3>
1231  SArray<decltype(T1()>=T2()),N,D0,D1,D2,D3> ret;
1232  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] >= right.data()[i]; }
1233  return ret;
1234  }
1235  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1236  YAKL_INLINE FSArray<decltype(T1()>=T2()),N,B0,B1,B2,B3>
1238  FSArray<decltype(T1()>=T2()),N,B0,B1,B2,B3> ret;
1239  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] >= right.data()[i]; }
1240  return ret;
1241  }
1242 
1243  // Less than or equal to <=
1244  template <class T1, class T2, int N, int STYLE>
1245  inline Array<decltype(T1()<=T2()),N,memHost,STYLE>
1247  auto ret = left.template createHostObject<decltype(T1()<=T2())>();
1248  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] <= right.data()[i]; }
1249  return ret;
1250  }
1251  template <class T1, class T2, int N, int STYLE>
1252  inline Array<decltype(T1()<=T2()),N,memDevice,STYLE>
1254  auto ret = left.template createDeviceObject<decltype(T1()<=T2())>();
1255  if constexpr (streams_enabled) fence();
1256  c::parallel_for( "YAKL_internal_array_operator<=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] <= right.data()[i]; });
1257  if constexpr (streams_enabled) fence();
1258  return ret;
1259  }
1260  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1261  YAKL_INLINE SArray<decltype(T1()<=T2()),N,D0,D1,D2,D3>
1263  SArray<decltype(T1()<=T2()),N,D0,D1,D2,D3> ret;
1264  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] <= right.data()[i]; }
1265  return ret;
1266  }
1267  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1268  YAKL_INLINE FSArray<decltype(T1()<=T2()),N,B0,B1,B2,B3>
1270  FSArray<decltype(T1()<=T2()),N,B0,B1,B2,B3> ret;
1271  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] <= right.data()[i]; }
1272  return ret;
1273  }
1274 
1275  // Equal to ==
1276  template <class T1, class T2, int N, int STYLE>
1277  inline Array<decltype(T1()==T2()),N,memHost,STYLE>
1279  auto ret = left.template createHostObject<decltype(T1()==T2())>();
1280  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] == right.data()[i]; }
1281  return ret;
1282  }
1283  template <class T1, class T2, int N, int STYLE>
1284  inline Array<decltype(T1()==T2()),N,memDevice,STYLE>
1286  auto ret = left.template createDeviceObject<decltype(T1()==T2())>();
1287  if constexpr (streams_enabled) fence();
1288  c::parallel_for( "YAKL_internal_array_operator==" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] == right.data()[i]; });
1289  if constexpr (streams_enabled) fence();
1290  return ret;
1291  }
1292  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1293  YAKL_INLINE SArray<decltype(T1()==T2()),N,D0,D1,D2,D3>
1295  SArray<decltype(T1()==T2()),N,D0,D1,D2,D3> ret;
1296  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] == right.data()[i]; }
1297  return ret;
1298  }
1299  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1300  YAKL_INLINE FSArray<decltype(T1()==T2()),N,B0,B1,B2,B3>
1302  FSArray<decltype(T1()==T2()),N,B0,B1,B2,B3> ret;
1303  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] == right.data()[i]; }
1304  return ret;
1305  }
1306 
1307  // Not equal to !=
1308  template <class T1, class T2, int N, int STYLE>
1309  inline Array<decltype(T1()!=T2()),N,memHost,STYLE>
1311  auto ret = left.template createHostObject<decltype(T1()!=T2())>();
1312  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] != right.data()[i]; }
1313  return ret;
1314  }
1315  template <class T1, class T2, int N, int STYLE>
1316  inline Array<decltype(T1()!=T2()),N,memDevice,STYLE>
1318  auto ret = left.template createDeviceObject<decltype(T1()!=T2())>();
1319  if constexpr (streams_enabled) fence();
1320  c::parallel_for( "YAKL_internal_array_operator!=" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] != right.data()[i]; });
1321  if constexpr (streams_enabled) fence();
1322  return ret;
1323  }
1324  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1325  YAKL_INLINE SArray<decltype(T1()!=T2()),N,D0,D1,D2,D3>
1327  SArray<decltype(T1()!=T2()),N,D0,D1,D2,D3> ret;
1328  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] != right.data()[i]; }
1329  return ret;
1330  }
1331  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1332  YAKL_INLINE FSArray<decltype(T1()!=T2()),N,B0,B1,B2,B3>
1334  FSArray<decltype(T1()!=T2()),N,B0,B1,B2,B3> ret;
1335  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] != right.data()[i]; }
1336  return ret;
1337  }
1338 
1339  // logical and &&
1340  template <class T1, class T2, int N, int STYLE>
1341  inline Array<decltype(T1()&&T2()),N,memHost,STYLE>
1343  auto ret = left.template createHostObject<decltype(T1()&&T2())>();
1344  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] && right.data()[i]; }
1345  return ret;
1346  }
1347  template <class T1, class T2, int N, int STYLE>
1348  inline Array<decltype(T1()&&T2()),N,memDevice,STYLE>
1350  auto ret = left.template createDeviceObject<decltype(T1()&&T2())>();
1351  if constexpr (streams_enabled) fence();
1352  c::parallel_for( "YAKL_internal_array_operator&&" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] && right.data()[i]; });
1353  if constexpr (streams_enabled) fence();
1354  return ret;
1355  }
1356  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1357  YAKL_INLINE SArray<decltype(T1()&&T2()),N,D0,D1,D2,D3>
1359  SArray<decltype(T1()&&T2()),N,D0,D1,D2,D3> ret;
1360  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] && right.data()[i]; }
1361  return ret;
1362  }
1363  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1364  YAKL_INLINE FSArray<decltype(T1()&&T2()),N,B0,B1,B2,B3>
1366  FSArray<decltype(T1()&&T2()),N,B0,B1,B2,B3> ret;
1367  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] && right.data()[i]; }
1368  return ret;
1369  }
1370 
1371  // logical or ||
1372  template <class T1, class T2, int N, int STYLE>
1373  inline Array<decltype(T1()||T2()),N,memHost,STYLE>
1375  auto ret = left.template createHostObject<decltype(T1()||T2())>();
1376  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] || right.data()[i]; }
1377  return ret;
1378  }
1379  template <class T1, class T2, int N, int STYLE>
1380  inline Array<decltype(T1()||T2()),N,memDevice,STYLE>
1382  auto ret = left.template createDeviceObject<decltype(T1()||T2())>();
1383  if constexpr (streams_enabled) fence();
1384  c::parallel_for( "YAKL_internal_array_operator||" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i] || right.data()[i]; });
1385  if constexpr (streams_enabled) fence();
1386  return ret;
1387  }
1388  template <class T1, class T2, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1389  YAKL_INLINE SArray<decltype(T1()||T2()),N,D0,D1,D2,D3>
1391  SArray<decltype(T1()||T2()),N,D0,D1,D2,D3> ret;
1392  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] || right.data()[i]; }
1393  return ret;
1394  }
1395  template <class T1, class T2, int N, class B0, class B1, class B2, class B3>
1396  YAKL_INLINE FSArray<decltype(T1()||T2()),N,B0,B1,B2,B3>
1398  FSArray<decltype(T1()||T2()),N,B0,B1,B2,B3> ret;
1399  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i] || right.data()[i]; }
1400  return ret;
1401  }
1402 
1404  // Unary operators
1406 
1407  // logical not !
1408  template <class T1, int N, int STYLE>
1409  inline Array<decltype(!T1()),N,memHost,STYLE>
1411  auto ret = left.template createHostObject<decltype(!T1())>();
1412  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = ! left.data()[i]; }
1413  return ret;
1414  }
1415  template <class T1, int N, int STYLE>
1416  inline Array<decltype(!T1()),N,memDevice,STYLE>
1418  auto ret = left.template createDeviceObject<decltype(!T1())>();
1419  if constexpr (streams_enabled) fence();
1420  c::parallel_for( "YAKL_internal_array_operator!" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = ! left.data()[i]; });
1421  if constexpr (streams_enabled) fence();
1422  return ret;
1423  }
1424  template <class T1, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1425  YAKL_INLINE SArray<decltype(!T1()),N,D0,D1,D2,D3>
1427  SArray<decltype(!T1()),N,D0,D1,D2,D3> ret;
1428  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = ! left.data()[i]; }
1429  return ret;
1430  }
1431  template <class T1, int N, class B0, class B1, class B2, class B3>
1432  YAKL_INLINE FSArray<decltype(!T1()),N,B0,B1,B2,B3>
1434  FSArray<decltype(!T1()),N,B0,B1,B2,B3> ret;
1435  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = ! left.data()[i]; }
1436  return ret;
1437  }
1438 
1439  // increment ++
1440  template <class T1, int N, int STYLE>
1441  inline Array<decltype(T1()+1),N,memHost,STYLE>
1443  auto ret = left.template createHostObject<decltype(T1()+1)>();
1444  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]+1; }
1445  return ret;
1446  }
1447  template <class T1, int N, int STYLE>
1448  inline Array<decltype(T1()+1),N,memDevice,STYLE>
1450  auto ret = left.template createDeviceObject<decltype(T1()+1)>();
1451  if constexpr (streams_enabled) fence();
1452  c::parallel_for( "YAKL_internal_array_operator++" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i]+1; });
1453  if constexpr (streams_enabled) fence();
1454  return ret;
1455  }
1456  template <class T1, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1457  YAKL_INLINE SArray<decltype(T1()+1),N,D0,D1,D2,D3>
1459  SArray<decltype(T1()+1),N,D0,D1,D2,D3> ret;
1460  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]+1; }
1461  return ret;
1462  }
1463  template <class T1, int N, class B0, class B1, class B2, class B3>
1464  YAKL_INLINE FSArray<decltype(T1()+1),N,B0,B1,B2,B3>
1466  FSArray<decltype(T1()+1),N,B0,B1,B2,B3> ret;
1467  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]+1; }
1468  return ret;
1469  }
1470 
1471  // increment ++
1472  template <class T1, int N, int STYLE>
1473  inline Array<decltype(T1()+1),N,memHost,STYLE>
1474  operator++( Array<T1,N,memHost,STYLE> const &left , int dummy) {
1475  auto ret = left.template createHostObject<decltype(T1()+1)>();
1476  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]+1; }
1477  return ret;
1478  }
1479  template <class T1, int N, int STYLE>
1480  inline Array<decltype(T1()+1),N,memDevice,STYLE>
1481  operator++( Array<T1,N,memDevice,STYLE> const &left , int dummy) {
1482  auto ret = left.template createDeviceObject<decltype(T1()+1)>();
1483  if constexpr (streams_enabled) fence();
1484  c::parallel_for( "YAKL_internal_array_operator++" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i]+1; });
1485  if constexpr (streams_enabled) fence();
1486  return ret;
1487  }
1488  template <class T1, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1489  YAKL_INLINE SArray<decltype(T1()+1),N,D0,D1,D2,D3>
1490  operator++( SArray<T1,N,D0,D1,D2,D3> const &left , int dummy) {
1491  SArray<decltype(T1()+1),N,D0,D1,D2,D3> ret;
1492  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]+1; }
1493  return ret;
1494  }
1495  template <class T1, int N, class B0, class B1, class B2, class B3>
1496  YAKL_INLINE FSArray<decltype(T1()+1),N,B0,B1,B2,B3>
1497  operator++( FSArray<T1,N,B0,B1,B2,B3> const &left , int dummy) {
1498  FSArray<decltype(T1()+1),N,B0,B1,B2,B3> ret;
1499  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]+1; }
1500  return ret;
1501  }
1502 
1503  // decrement --
1504  template <class T1, int N, int STYLE>
1505  inline Array<decltype(T1()-1),N,memHost,STYLE>
1507  auto ret = left.template createHostObject<decltype(T1()-1)>();
1508  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]-1; }
1509  return ret;
1510  }
1511  template <class T1, int N, int STYLE>
1512  inline Array<decltype(T1()-1),N,memDevice,STYLE>
1514  auto ret = left.template createDeviceObject<decltype(T1()-1)>();
1515  if constexpr (streams_enabled) fence();
1516  c::parallel_for( "YAKL_internal_array_operator--" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i]-1; });
1517  if constexpr (streams_enabled) fence();
1518  return ret;
1519  }
1520  template <class T1, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1521  YAKL_INLINE SArray<decltype(T1()-1),N,D0,D1,D2,D3>
1523  SArray<decltype(T1()-1),N,D0,D1,D2,D3> ret;
1524  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]-1; }
1525  return ret;
1526  }
1527  template <class T1, int N, class B0, class B1, class B2, class B3>
1528  YAKL_INLINE FSArray<decltype(T1()-1),N,B0,B1,B2,B3>
1530  FSArray<decltype(T1()-1),N,B0,B1,B2,B3> ret;
1531  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]-1; }
1532  return ret;
1533  }
1534 
1535  // decrement --
1536  template <class T1, int N, int STYLE>
1537  inline Array<decltype(T1()-1),N,memHost,STYLE>
1538  operator--( Array<T1,N,memHost,STYLE> const &left , int dummy ) {
1539  auto ret = left.template createHostObject<decltype(T1()-1)>();
1540  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]-1; }
1541  return ret;
1542  }
1543  template <class T1, int N, int STYLE>
1544  inline Array<decltype(T1()-1),N,memDevice,STYLE>
1545  operator--( Array<T1,N,memDevice,STYLE> const &left , int dummy ) {
1546  auto ret = left.template createDeviceObject<decltype(T1()-1)>();
1547  if constexpr (streams_enabled) fence();
1548  c::parallel_for( "YAKL_internal_array_operator--" , ret.totElems() , YAKL_LAMBDA (int i) { ret.data()[i] = left.data()[i]-1; });
1549  if constexpr (streams_enabled) fence();
1550  return ret;
1551  }
1552  template <class T1, int N, unsigned D0, unsigned D1, unsigned D2, unsigned D3>
1553  YAKL_INLINE SArray<decltype(T1()-1),N,D0,D1,D2,D3>
1554  operator--( SArray<T1,N,D0,D1,D2,D3> const &left , int dummy ) {
1555  SArray<decltype(T1()-1),N,D0,D1,D2,D3> ret;
1556  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]-1; }
1557  return ret;
1558  }
1559  template <class T1, int N, class B0, class B1, class B2, class B3>
1560  YAKL_INLINE FSArray<decltype(T1()-1),N,B0,B1,B2,B3>
1561  operator--( FSArray<T1,N,B0,B1,B2,B3> const &left , int dummy ) {
1562  FSArray<decltype(T1()-1),N,B0,B1,B2,B3> ret;
1563  for (index_t i=0; i < ret.totElems(); i++) { ret.data()[i] = left.data()[i]-1; }
1564  return ret;
1565  }
1566 
1567 
1568 
1569  }
1570 
1571 }
1573 
1574 
yakl::componentwise::gt_array_scalar
Array< decltype(T1()>T2()), N, memDevice, STYLE > gt_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:195
yakl::componentwise::add_array_scalar
Array< decltype(T1()+T2()), N, memDevice, STYLE > add_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:31
yakl::componentwise::lt_array_array
Array< bool, N, memDevice, STYLE > lt_array_array(Array< T1, N, memDevice, STYLE > const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:1184
yakl::memDevice
constexpr int memDevice
Specifies a device memory address space for a yakl::Array object.
Definition: YAKL_memory_spaces.h:13
yakl::componentwise::div_scalar_array
Array< decltype(T1()/T2()), N, memDevice, STYLE > div_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:651
yakl::componentwise::ne_scalar_array
Array< decltype(T1()!=T2()), N, memDevice, STYLE > ne_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:897
yakl::componentwise::le_scalar_array
Array< decltype(T1()<=T2()), N, memDevice, STYLE > le_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:815
yakl::componentwise::add_scalar_array
Array< decltype(T1()+T2()), N, memDevice, STYLE > add_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:528
yakl::componentwise::ge_array_scalar
Array< decltype(T1()>=T2()), N, memDevice, STYLE > ge_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:277
yakl::componentwise::operator!
Array< decltype(!T1()), N, memHost, STYLE > operator!(Array< T1, N, memHost, STYLE > const &left)
Definition: YAKL_componentwise.h:1410
yakl::componentwise::le_array_scalar
Array< decltype(T1()<=T2()), N, memDevice, STYLE > le_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:318
yakl::componentwise::operator&&
Array< decltype(T1()&&T2()), N, memHost, STYLE > operator&&(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:434
yakl::componentwise::or_array_scalar
Array< decltype(T1()||T2()), N, memDevice, STYLE > or_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:482
yakl::c::parallel_for
void parallel_for(char const *str, Bounds< N, simple > const &bounds, F const &f, LaunchConfig< VecLen, B4B > config=LaunchConfig<>())
[ASYNCHRONOUS] Launch the passed functor in parallel.
yakl::componentwise::and_array_scalar
Array< decltype(T1()&&T2()), N, memDevice, STYLE > and_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:441
yakl::componentwise::lt_scalar_array
Array< decltype(T1()< T2()), N, memDevice, STYLE > lt_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:733
yakl::componentwise::operator>=
Array< decltype(T1()>=T2()), N, memHost, STYLE > operator>=(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:270
__YAKL_NAMESPACE_WRAPPER_END__
#define __YAKL_NAMESPACE_WRAPPER_END__
Definition: YAKL.h:20
yakl::componentwise::operator||
Array< decltype(T1()||T2()), N, memHost, STYLE > operator||(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:475
yakl::componentwise::div_array_scalar
Array< decltype(T1()/T2()), N, memDevice, STYLE > div_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:154
yakl::componentwise::operator/
Array< decltype(T1()/T2()), N, memHost, STYLE > operator/(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:147
yakl::streams_enabled
constexpr bool streams_enabled
If the CPP Macro YAKL_ENABLE_STREAMS is defined, then this bool is set to true
Definition: YAKL_streams_events.h:11
yakl::componentwise::operator<
Array< decltype(T1()< T2()), N, memHost, STYLE > operator<(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:229
yakl::componentwise::operator*
Array< decltype(T1() *T2()), N, memHost, STYLE > operator*(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:106
__YAKL_NAMESPACE_WRAPPER_BEGIN__
#define __YAKL_NAMESPACE_WRAPPER_BEGIN__
Definition: YAKL.h:19
YAKL_INLINE
#define YAKL_INLINE
Used to decorate functions called from kernels (parallel_for and parallel_outer) or from CPU function...
Definition: YAKL_defines.h:140
yakl::componentwise::ne_array_scalar
Array< decltype(T1()!=T2()), N, memDevice, STYLE > ne_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:400
yakl::componentwise::eq_scalar_array
Array< decltype(T1()==T2()), N, memDevice, STYLE > eq_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:856
yakl::componentwise::sub_scalar_array
Array< decltype(T1() -T2()), N, memDevice, STYLE > sub_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:569
yakl::fence
void fence()
Block the host code until all device code has completed.
Definition: YAKL_fence.h:16
yakl::componentwise::sub_array_scalar
Array< decltype(T1() -T2()), N, memDevice, STYLE > sub_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:72
yakl::componentwise::ge_scalar_array
Array< decltype(T1()>=T2()), N, memDevice, STYLE > ge_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:774
yakl::index_t
unsigned int index_t
Definition: YAKL.h:41
yakl::componentwise::operator!=
Array< decltype(T1()!=T2()), N, memHost, STYLE > operator!=(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:393
yakl::componentwise::eq_array_scalar
Array< decltype(T1()==T2()), N, memDevice, STYLE > eq_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:359
yakl::componentwise::and_scalar_array
Array< decltype(T1()&&T2()), N, memDevice, STYLE > and_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:938
yakl::componentwise::mult_array_scalar
Array< decltype(T1() *T2()), N, memDevice, STYLE > mult_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:113
yakl::componentwise::operator--
Array< decltype(T1() -1), N, memHost, STYLE > operator--(Array< T1, N, memHost, STYLE > const &left)
Definition: YAKL_componentwise.h:1506
yakl::componentwise::mult_scalar_array
Array< decltype(T1() *T2()), N, memDevice, STYLE > mult_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:610
yakl::Array
This declares the yakl::Array class. Please see the yakl::styleC and yakl::styleFortran template spec...
Definition: YAKL_Array.h:40
yakl::componentwise::operator+
Array< decltype(T1()+T2()), N, memHost, STYLE > operator+(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:24
yakl::componentwise::operator<=
Array< decltype(T1()<=T2()), N, memHost, STYLE > operator<=(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:311
yakl::componentwise::operator-
Array< decltype(T1() -T2()), N, memHost, STYLE > operator-(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:65
yakl::CSArray
C-style array on the stack similar in nature to, e.g., float arr[ny][nx];
Definition: YAKL_CSArray.h:30
yakl
yakl::componentwise::operator>
Array< decltype(T1()>T2()), N, memHost, STYLE > operator>(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:188
yakl::componentwise::operator++
Array< decltype(T1()+1), N, memHost, STYLE > operator++(Array< T1, N, memHost, STYLE > const &left)
Definition: YAKL_componentwise.h:1442
yakl::CSArray::data
YAKL_INLINE T * data() const
Get the underlying raw data pointer.
Definition: YAKL_CSArray.h:123
yakl::componentwise::gt_scalar_array
Array< decltype(T1()>T2()), N, memDevice, STYLE > gt_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:692
yakl::FSArray::data
YAKL_INLINE T * data() const
Get the underlying raw data pointer.
Definition: YAKL_FSArray.h:171
yakl::componentwise::operator==
Array< decltype(T1()==T2()), N, memHost, STYLE > operator==(Array< T1, N, memHost, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:352
yakl::componentwise::lt_array_scalar
Array< decltype(T1()< T2()), N, memDevice, STYLE > lt_array_scalar(Array< T1, N, memDevice, STYLE > const &left, T2 const &right)
Definition: YAKL_componentwise.h:236
YAKL_LAMBDA
#define YAKL_LAMBDA
Used to create C++ lambda expressions passed to parallel_for and parallel_outer
Definition: YAKL_defines.h:128
yakl::componentwise::or_scalar_array
Array< decltype(T1()||T2()), N, memDevice, STYLE > or_scalar_array(T1 const &left, Array< T2, N, memDevice, STYLE > const &right)
Definition: YAKL_componentwise.h:979
yakl::FSArray
Fortran-style array on the stack similar in nature to, e.g., float arr[ny][nx];
Definition: YAKL_FSArray.h:53
yakl::memHost
constexpr int memHost
Specifies a device memory address space for a yakl::Array object.
Definition: YAKL_memory_spaces.h:15