mxnet
expr_engine-inl.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
26 #ifndef MSHADOW_EXPR_ENGINE_INL_H_
27 #define MSHADOW_EXPR_ENGINE_INL_H_
28 #include <utility>
29 #include <algorithm>
30 #include "./logging.h"
31 #include "./expression.h"
32 #include "./tensor.h"
33 
34 namespace mshadow {
35 namespace expr {
43 template<typename SubType, typename SrcExp, int dim, typename DType>
45  : public Exp<MakeTensorExp<SubType, SrcExp, dim, DType>,
46  DType, type::kChainer> {
50  inline const SubType& real_self(void) const{
51  return *static_cast<const SubType*>(this);
52  }
53 };
54 //----------------------------------------------------------------------
55 // This part of code gives plan that can be used to carry out execution
56 //---------------------------------------------------------------------
57 // Declarations of plans
58 template<typename ExpType, typename DType>
59 class Plan {
60  public:
65  MSHADOW_XINLINE DType Eval(index_t y, index_t x) const;
66 };
67 // tensor plan
68 template <typename Device, int dim, typename DType>
69 class Plan<Tensor<Device, dim, DType>, DType> {
70  public:
71  explicit Plan(const Tensor<Device, dim, DType> &t)
72  : dptr_(t.dptr_), stride_(t.stride_) {}
73  // for RValue, the return type should be reference
75  return dptr_[y * stride_ + x];
76  }
77  // const evaluation
78  MSHADOW_XINLINE const DType &Eval(index_t y, index_t x) const {
79  return dptr_[y * stride_ + x];
80  }
81 
82  private:
83  DType *dptr_;
84  index_t stride_;
85 };
86 // special evaluation case for 1d tensor, no stride
87 template <typename Device, typename DType>
88 class Plan<Tensor<Device, 1, DType>, DType> {
89  public:
90  explicit Plan(const Tensor<Device, 1, DType> &t) : dptr_(t.dptr_) {}
92  return dptr_[x];
93  }
94  MSHADOW_XINLINE const DType &Eval(index_t y, index_t x) const {
95  return dptr_[x];
96  }
97 
98  private:
99  DType *dptr_;
100 };
101 // scalar
102 template<typename DType>
103 class Plan<ScalarExp<DType>, DType> {
104  public:
105  explicit Plan(DType scalar) : scalar_(scalar) {}
106  MSHADOW_XINLINE DType Eval(index_t y, index_t x) const {
107  return scalar_;
108  }
109 
110  private:
111  DType scalar_;
112 };
113 // unary expression
114 template<typename DstDType, typename SrcDType,
115  typename EType, int etype>
116 class Plan<TypecastExp<DstDType, SrcDType, EType, etype>, DstDType> {
117  public:
118  explicit Plan(const Plan<EType, SrcDType> &src) : src_(src) {}
119  MSHADOW_XINLINE DstDType Eval(index_t y, index_t x) const {
120  return DstDType(src_.Eval(y, x)); // NOLINT(*)
121  }
122 
123  private:
125 };
126 
127 // ternary expression
128 template<typename OP, typename TA, typename TB, typename TC, int etype, typename DType>
129 class Plan<TernaryMapExp<OP, TA, TB, TC, DType, etype>, DType> {
130  public:
131  explicit Plan(const Plan<TA, DType> &item1, const Plan<TB, DType> &item2,
132  const Plan<TC, DType> &item3)
133  : item1_(item1), item2_(item2), item3_(item3) {}
134  MSHADOW_XINLINE DType Eval(index_t y, index_t x) const {
135  return OP::Map(item1_.Eval(y, x), item2_.Eval(y, x), item3_.Eval(y, x));
136  }
137 
138  private:
139  Plan<TA, DType> item1_;
140  Plan<TB, DType> item2_;
141  Plan<TC, DType> item3_;
142 };
143 // binary expression
144 template<typename OP, typename TA, typename TB, int etype, typename DType>
145 class Plan<BinaryMapExp<OP, TA, TB, DType, etype>, DType> {
146  public:
147  explicit Plan(const Plan<TA, DType> &lhs, const Plan<TB, DType> &rhs)
148  : lhs_(lhs), rhs_(rhs) {}
149  MSHADOW_XINLINE DType Eval(index_t y, index_t x) const {
150  return OP::Map(lhs_.Eval(y, x), rhs_.Eval(y, x));
151  }
152 
153  private:
154  Plan<TA, DType> lhs_;
155  Plan<TB, DType> rhs_;
156 };
157 // unary expression
158 template<typename OP, typename TA, int etype, typename DType>
159 class Plan<UnaryMapExp<OP, TA, DType, etype>, DType> {
160  public:
161  explicit Plan(const Plan<TA, DType> &src) : src_(src) {}
162  MSHADOW_XINLINE DType Eval(index_t y, index_t x) const {
163  return OP::Map(src_.Eval(y, x));
164  }
165 
166  private:
167  Plan<TA, DType> src_;
168 };
169 // remaps map tensor expression to subtype's plan
170 template<typename SubType, typename SrcExp, int dim, typename DType>
171 struct Plan<MakeTensorExp<SubType, SrcExp, dim, DType>, DType> {
172  public:
173  Plan(const Plan<SubType, DType> &src) : src_(src) {}
174  MSHADOW_XINLINE DType Eval(index_t y, index_t x) const {
175  return src_.Eval(y, x);
176  }
177 
178  private:
180 };
181 // tranpsoe
182 template<typename EType, typename DType>
183 class Plan<TransposeExp<EType, DType>, DType> {
184  public:
185  explicit Plan(const Plan<EType, DType> &src) : src_(src) {}
186  MSHADOW_XINLINE DType Eval(index_t y, index_t x) const {
187  return src_.Eval(x, y);
188  }
189 
190  private:
191  Plan<EType, DType> src_;
192 };
193 //----------------------------------------------------------------------
194 // Mappings from expression to plans
195 //---------------------------------------------------------------------
196 template<typename OP, typename TA, typename TB, typename DType, int etype>
199 
200 template<typename OP, typename TA, typename TB, typename TC, typename DType, int etype>
203 
204 template<typename DType>
206  return Plan<ScalarExp<DType>, DType>(e.scalar_);
207 }
208 
209 template<typename DstDType, typename SrcDType, typename EType, int etype>
212  return Plan<TypecastExp<DstDType, SrcDType, EType, etype>, DstDType>(MakePlan(e.exp));
213 }
214 
215 template<typename T, typename DType>
217  return Plan<T, DType>(e.self());
218 }
219 
220 template<typename T, typename DType>
221 inline Plan<TransposeExp<T, DType>, DType>
223  return Plan<TransposeExp<T, DType>, DType>(MakePlan(e.exp));
224 }
225 
226 template<typename T, typename SrcExp, int dim, typename DType>
227 inline Plan<T, DType>
229  return Plan<T, DType>(e.real_self());
230 }
231 
232 template<typename OP, typename TA, typename DType, int etype>
235  return Plan<UnaryMapExp<OP, TA, DType, etype>, DType>(MakePlan(e.src_));
236 }
237 
238 template<typename OP, typename TA, typename TB, typename DType, int etype>
239 inline Plan<BinaryMapExp<OP, TA, TB, DType, etype>, DType>
241  return Plan<BinaryMapExp<OP, TA, TB, DType, etype>,
242  DType>(MakePlan(e.lhs_), MakePlan(e.rhs_));
243 }
244 
245 // Ternary
246 template<typename OP, typename TA, typename TB, typename TC, typename DType, int etype>
247 inline Plan<TernaryMapExp<OP, TA, TB, TC, DType, etype>, DType>
249  return Plan<TernaryMapExp<OP, TA, TB, TC, DType, etype>,
250  DType>(MakePlan(e.item1_), MakePlan(e.item2_), MakePlan(e.item3_));
251 }
252 //----------------------------------------------------------------
253 // Static Type inference and Type Checking
254 //----------------------------------------------------------------
262 template<typename E>
263 struct ExpInfo {
264  static const int kDim = -1;
265  static const int kDevMask = 0;
266 };
267 template<typename DType>
268 struct ExpInfo< ScalarExp<DType> > {
269  static const int kDim = 0;
270  static const int kDevMask = 0xffff;
271 };
272 template<typename E, typename DType>
273 struct ExpInfo<TransposeExp<E, DType> > {
274  static const int kDim = ExpInfo<E>::kDim;
275  static const int kDevMask = ExpInfo<E>::kDevMask;
276 };
277 template<typename DstDType, typename SrcDType, typename EType, int etype>
278 struct ExpInfo<TypecastExp<DstDType, SrcDType, EType, etype> > {
279  static const int kDim = ExpInfo<EType>::kDim;
280  static const int kDevMask = ExpInfo<EType>::kDevMask;
281 };
282 template<typename Device, int dim, typename DType>
283 struct ExpInfo<Tensor<Device, dim, DType> > {
284  static const int kDim = dim;
285  static const int kDevMask = Device::kDevMask;
286 };
287 template<typename T, typename SrcExp, int dim, typename DType>
288 struct ExpInfo<MakeTensorExp<T, SrcExp, dim, DType> > {
289  static const int kDimSrc = ExpInfo<SrcExp>::kDim;
290  static const int kDim = kDimSrc >= 0 ? dim : -1;
291  static const int kDevMask = ExpInfo<SrcExp>::kDevMask;
292 };
293 template<typename OP, typename TA, typename DType, int etype>
294 struct ExpInfo<UnaryMapExp<OP, TA, DType, etype> > {
295  static const int kDim = ExpInfo<TA>::kDim;
296  static const int kDevMask = ExpInfo<TA>::kDevMask;
297 };
298 template<typename OP, typename TA, typename TB, typename DType, int etype>
299 struct ExpInfo<BinaryMapExp<OP, TA, TB, DType, etype> > {
300  static const int kDimLhs = ExpInfo<TA>::kDim;
301  static const int kDimRhs = ExpInfo<TB>::kDim;
302  static const int kDim = (kDimLhs >= 0 && kDimRhs >= 0) ?\
303  (kDimLhs == 0 ?\
304  kDimRhs :\
305  ((kDimRhs == 0 || kDimLhs == kDimRhs) ? kDimLhs : -1)) : -1;
306  static const int kDevMask = ExpInfo<TA>::kDevMask & ExpInfo<TB>::kDevMask;
307 };
308 template<typename OP, typename TA, typename TB, typename TC, typename DType, int etype>
309 struct ExpInfo<TernaryMapExp<OP, TA, TB, TC, DType, etype> > {
310  static const int kDimItem1 = ExpInfo<TA>::kDim;
311  static const int kDimItem2 = ExpInfo<TB>::kDim;
312  static const int kDimItem3 = ExpInfo<TC>::kDim;
313  static const int kDim = kDimItem1;
315 };
316 
318 template<typename Device, int dim, typename DType, typename E>
319 struct TypeCheck {
321  static const int kExpDim = ExpInfo<E>::kDim;
323  static const bool kDevPass = (ExpInfo<E>::kDevMask & Device::kDevMask) != 0;
325  static const bool kMapPass = (kExpDim == 0 || kExpDim == dim) && kDevPass;
327  static const bool kRedPass = (kExpDim > dim) && kDevPass;
328 };
330 template<bool kPass>
332 // Todo : add static assert using C++11
333 template<>
334 struct TypeCheckPass<false> {};
335 template<>
336 struct TypeCheckPass<true> {
338  inline static void Error_TypeCheck_Not_Pass_For_Reduce_Exp(void) {}
340 };
341 
342 //----------------------------------------------------------------
343 // Runtime Stream Getting
344 //----------------------------------------------------------------
345 template<typename Device, typename E>
346 struct StreamInfo {
347  inline static Stream<Device> *Get(const E &t);
348 };
349 template<int dim, typename Device, typename DType>
350 struct StreamInfo<Device, Tensor<Device, dim, DType> > {
351  inline static Stream<Device> *Get(const Tensor<Device, dim, DType> &t) {
352  return t.stream_;
353  }
354 };
355 //----------------------------------------------------------------
356 // Runtime Shape Checking
357 //----------------------------------------------------------------
364 template<int dim, typename E>
365 struct ShapeCheck {
366  inline static Shape<dim> Check(const E &t);
367 };
368 template<int dim, typename DType>
369 struct ShapeCheck<dim, ScalarExp<DType> > {
370  inline static Shape<dim> Check(const ScalarExp<DType> &exp) {
371  // use lowest dimension to mark scalar exp
372  Shape<dim> shape;
373  for (int i = 0; i < dim; ++i) {
374  shape[i] = 0;
375  }
376  return shape;
377  }
378 };
379 template<int dim, typename DstDType, typename SrcDType, typename EType, int etype>
380 struct ShapeCheck<dim, TypecastExp<DstDType, SrcDType, EType, etype> > {
381  inline static Shape<dim>
384  }
385 };
386 template<int dim, typename E, typename DType>
387 struct ShapeCheck<dim, TransposeExp<E, DType> > {
388  inline static Shape<dim> Check(const TransposeExp<E, DType> &e) {
389  // swap the lowest two dimensions
391  std::swap(s[0], s[1]);
392  return s;
393  }
394 };
395 template<int dim, typename Device, typename DType>
396 struct ShapeCheck<dim, Tensor<Device, dim, DType> > {
397  inline static Shape<dim> Check(const Tensor<Device, dim, DType> &t) {
398  return t.shape_;
399  }
400 };
401 template<int dim, typename SrcExp, typename T, typename DType>
402 struct ShapeCheck<dim, MakeTensorExp<T, SrcExp, dim, DType> > {
403  inline static Shape<dim>
405  return t.shape_;
406  }
407 };
408 template<int dim, typename OP, typename TA, typename DType, int etype>
409 struct ShapeCheck<dim, UnaryMapExp<OP, TA, DType, etype> > {
412  return s;
413  }
414 };
415 
416 template<int dim, typename OP, typename TA, typename TB,
417  typename DType, int etype>
418 struct ShapeCheck<dim, BinaryMapExp<OP, TA, TB, DType, etype> > {
419  inline static Shape<dim>
423  if (shape1[0] == 0) return shape2;
424  if (shape2[0] == 0) return shape1;
425  CHECK_EQ(shape1, shape2) << "BinaryMapExp: Shapes of operands are not the same, " <<
426  "Shape1=" << shape1 << ", Shape2=" << shape2;
427  return shape1;
428  }
429 };
430 
431 template<int dim, typename OP, typename TA, typename TB, typename TC,
432  typename DType, int etype>
433 struct ShapeCheck<dim, TernaryMapExp<OP, TA, TB, TC, DType, etype> > {
434  inline static Shape<dim>
439  bool same = (shape1 == shape2) && (shape2 == shape3);
440  CHECK(same) << "TernaryMapExp: Shapes of operands are not the same, " <<
441  "Shape1=" << shape1 << ", Shape2=" << shape2 << ", Shape3=" << shape3;
442 
443  return shape1;
444  }
445 };
446 } // namespace expr
447 
448 } // namespace mshadow
449 // include definition of dot engine
450 #include "./dot_engine-inl.h"
451 
452 namespace mshadow {
453 namespace expr {
455 template<typename SV, typename RV, typename E, typename DType>
457  inline static void Eval(RV *dst, const E &exp);
458 };
460 template<typename SV, typename RV, typename DType>
461 struct ExpEngine {
462  template<typename E>
463  inline static void Eval(RV *dst,
464  const Exp<E, DType, type::kMapper> &exp) {
465  MapExp<SV>(dst, exp);
466  }
467  template<typename E>
468  inline static void Eval(RV *dst,
469  const Exp<E, DType, type::kChainer> &exp) {
470  MapExp<SV>(dst, exp);
471  }
472  template<typename E>
473  inline static void Eval(RV *dst,
474  const Exp<E, DType, type::kRValue> &exp) {
475  MapExp<SV>(dst, exp);
476  }
477  template<typename E>
478  inline static void Eval(RV *dst,
479  const Exp<E, DType, type::kComplex> &exp) {
480  ExpComplexEngine<SV, RV, E, DType>::Eval(dst->ptrself(), exp.self());
481  }
482 };
483 template<typename SV, typename Device, int dim, int ldim,
484  int rdim, bool ltrans, bool rtrans, typename DType>
486  Tensor<Device, dim, DType>,
487  DotExp<Tensor<Device, ldim, DType>,
488  Tensor<Device, rdim, DType>,
489  ltrans, rtrans, DType>,
490  DType> {
491  inline static void Eval(Tensor<Device, dim, DType> *dst,
494  ltrans, rtrans, DType> &exp) {
495  DotEngine<SV, Device, dim, ldim, rdim,
496  ltrans, rtrans, DType>::Eval(dst, exp.lhs_, exp.rhs_, exp.scale_);
497  }
498 };
499 } // namespace expr
500 } // namespace mshadow
501 #endif // MSHADOW_EXPR_ENGINE_INL_H_
Plan(const Plan< TA, DType > &src)
Definition: expr_engine-inl.h:161
static Shape< dim > Check(const UnaryMapExp< OP, TA, DType, etype > &t)
Definition: expr_engine-inl.h:410
static void Eval(RV *dst, const Exp< E, DType, type::kRValue > &exp)
Definition: expr_engine-inl.h:473
static Shape< dim > Check(const MakeTensorExp< T, SrcExp, dim, DType > &t)
Definition: expr_engine-inl.h:404
static Shape< dim > Check(const Tensor< Device, dim, DType > &t)
Definition: expr_engine-inl.h:397
ScalarExp< DType > scalar(DType s)
create an scalar expression
Definition: expression.h:104
static Shape< dim > Check(const BinaryMapExp< OP, TA, TB, DType, etype > &t)
Definition: expr_engine-inl.h:420
Definition: expr_engine-inl.h:59
Plan(const Tensor< Device, 1, DType > &t)
Definition: expr_engine-inl.h:90
used to help static type check
Definition: expr_engine-inl.h:331
template to do type check
Definition: expr_engine-inl.h:319
const TB & rhs_
right operand
Definition: expression.h:340
Plan(const Tensor< Device, dim, DType > &t)
Definition: expr_engine-inl.h:71
Shape< dimension > shape_
shape of the tensor
Definition: tensor.h:437
ternary map expression
Definition: expression.h:280
static void Error_All_Tensor_in_Exp_Must_Have_Same_Type(void)
Definition: expr_engine-inl.h:337
binary map expression lhs [op] rhs
Definition: expression.h:335
Plan(DType scalar)
Definition: expr_engine-inl.h:105
static void Eval(Tensor< Device, dim, DType > *dst, const DotExp< Tensor< Device, ldim, DType >, Tensor< Device, rdim, DType >, ltrans, rtrans, DType > &exp)
Definition: expr_engine-inl.h:491
MSHADOW_XINLINE DType Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:174
static void Eval(RV *dst, const E &exp)
base class of all rvalues
Definition: expression.h:149
Definition: dot_engine-inl.h:71
DType scalar_
scalar value
Definition: expression.h:98
MSHADOW_XINLINE DType & REval(index_t y, index_t x)
Definition: expr_engine-inl.h:74
const EType & exp
expression to be transposed
Definition: expression.h:135
static void Error_TypeCheck_Not_Pass_For_Reduce_Exp(void)
Definition: expr_engine-inl.h:338
MSHADOW_XINLINE DType Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:134
MSHADOW_XINLINE const DType & Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:78
static Shape< dim > Check(const E &t)
header file of tensor data structure and functions This lib requires explicit memory allocation and d...
static void Eval(RV *dst, const Exp< E, DType, type::kChainer > &exp)
Definition: expr_engine-inl.h:468
#define MSHADOW_XINLINE
Definition: base.h:223
const TB & item2_
second operand
Definition: expression.h:285
static type inference template, used to get the dimension of each expression, if ExpInfo<E>::kDim == ...
Definition: expr_engine-inl.h:263
Definition: expr_engine-inl.h:346
definitions of abstract expressions and expressions template
static void Eval(RV *dst, const Exp< E, DType, type::kComplex > &exp)
Definition: expr_engine-inl.h:478
static Shape< dim > Check(const TernaryMapExp< OP, TA, TB, TC, DType, etype > &t)
Definition: expr_engine-inl.h:435
static void Error_Expression_Does_Not_Meet_Dimension_Req(void)
Definition: expr_engine-inl.h:339
MSHADOW_XINLINE const DType & Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:94
int32_t index_t
type that will be used for index
Definition: base.h:336
Plan(const Plan< EType, DType > &src)
Definition: expr_engine-inl.h:185
static Shape< dim > Check(const TypecastExp< DstDType, SrcDType, EType, etype > &exp)
Definition: expr_engine-inl.h:382
Plan(const Plan< TA, DType > &item1, const Plan< TB, DType > &item2, const Plan< TC, DType > &item3)
Definition: expr_engine-inl.h:131
const TA & item1_
first operand
Definition: expression.h:283
typecast expression, cast the type of elements
Definition: expression.h:115
static Shape< dim > Check(const ScalarExp< DType > &exp)
Definition: expr_engine-inl.h:370
runtime shape checking template get the shape of an expression, report error if shape mismatch ...
Definition: expr_engine-inl.h:365
MSHADOW_XINLINE DType Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:162
represent a transpose expression of a container
Definition: expression.h:132
some engine that evaluate complex expression
Definition: expr_engine-inl.h:456
const TA & src_
source expression
Definition: expression.h:408
MSHADOW_XINLINE DType Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:186
unary map expression op(src)
Definition: expression.h:405
matrix multiplication expression dot(lhs[.T], rhs[.T])
Definition: expression.h:225
Plan(const Plan< EType, SrcDType > &src)
Definition: expr_engine-inl.h:118
scalar expression
Definition: expression.h:96
Plan(const Plan< SubType, DType > &src)
Definition: expr_engine-inl.h:173
defines how expression exp can be evaluated and stored into dst
Definition: expression.h:80
MSHADOW_XINLINE DType Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:106
const EType & exp
expression to be typecasted
Definition: expression.h:119
const Container & self(void) const
Definition: expression.h:83
Plan< BinaryMapExp< OP, TA, TB, DType, etype >, DType > MakePlan(const BinaryMapExp< OP, TA, TB, DType, etype > &e)
Definition: expr_engine-inl.h:240
const TC & item3_
third operand
Definition: expression.h:287
MSHADOW_XINLINE DstDType Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:119
const SubType & real_self(void) const
true self of subtype
Definition: expr_engine-inl.h:50
MSHADOW_XINLINE DType Eval(index_t y, index_t x) const
Definition: expr_engine-inl.h:149
Definition: tensor.h:569
a general class that allows extension that makes tensors of some shape
Definition: expr_engine-inl.h:44
const TA & lhs_
left operand
Definition: expression.h:338
overloaded + operator between half_t and bf16_t
Definition: base.h:327
static Shape< dim > Check(const TransposeExp< E, DType > &e)
Definition: expr_engine-inl.h:388
the engine that dispatches simple operations
Definition: expr_engine-inl.h:461
Shape< dim > shape_
the shape of this expression
Definition: expr_engine-inl.h:48
general tensor
Definition: tensor.h:421
static void Eval(RV *dst, const Exp< E, DType, type::kMapper > &exp)
Definition: expr_engine-inl.h:463
Stream< Device > * stream_
stream where the computation lies stream is a device dependency concept where each computation ...
Definition: tensor.h:447
definitions of how Matrix Multiplications can be evaluated
Plan(const Plan< TA, DType > &lhs, const Plan< TB, DType > &rhs)
Definition: expr_engine-inl.h:147
MSHADOW_XINLINE DType & REval(index_t y, index_t x)
Definition: expr_engine-inl.h:91
static Stream< Device > * Get(const Tensor< Device, dim, DType > &t)
Definition: expr_engine-inl.h:351
computaion stream structure, used for asynchronous computations
Definition: tensor.h:384