Apache SINGA
A distributed deep learning platform .
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Macros
tensor_cpu-inl.hpp
Go to the documentation of this file.
1 #ifndef MSHADOW_TENSOR_CPU_INL_HPP
2 #define MSHADOW_TENSOR_CPU_INL_HPP
3 
8 #include <cstring>
9 #include "tensor_base.h"
10 #include "tensor_sse-inl.hpp"
11 
12 namespace mshadow {
13  template<int dim>
14  inline void AllocSpace(Tensor<cpu,dim> &obj, bool pad ){
15  size_t pitch;
16  if( pad ){
18  ( pitch, obj.shape[0] * sizeof(real_t), obj.FlatTo2D().shape[1] );
19  obj.shape.stride_ = static_cast<index_t>( pitch / sizeof(real_t) );
20  }else{
21  obj.shape.stride_ = obj.shape[0];
23  ( pitch, obj.shape.Size() * sizeof(real_t), 1 );
24  }
25  }
26 
27  template<typename Device, int dim>
28  inline Tensor<Device,dim> NewTensor(const Shape<dim> &shape, real_t initv, bool pad ){
29  Tensor<Device, dim> obj( shape );
30  AllocSpace( obj, pad );
31  MapExp<sv::saveto>( obj, expr::ScalarExp( initv ) );
32  return obj;
33  }
34 
35  template<int dim>
36  inline void FreeSpace(Tensor<cpu,dim> &obj){
37  sse2::AlignedFree( obj.dptr );
38  obj.dptr = NULL;
39  }
40 
41  template<int dim>
42  inline void Copy(Tensor<cpu,dim> _dst, const Tensor<cpu,dim> &_src ){
43  utils::Assert( _dst.shape == _src.shape, "Copy:shape mismatch" );
44  Tensor<cpu,2> dst = _dst.FlatTo2D();
45  Tensor<cpu,2> src = _src.FlatTo2D();
46  for (index_t y = 0; y < dst.shape[1]; ++y ) {
47  memcpy( dst[y].dptr, src[y].dptr, sizeof(real_t) * dst.shape[0] );
48  }
49  }
50 
51  template<typename Saver, typename E, int dim>
52  inline void MapPlan(Tensor<cpu,dim> _dst, const expr::Plan<E> &plan){
53  Tensor<cpu,2> dst = _dst.FlatTo2D();
54  for (index_t y = 0; y < dst.shape[1]; ++y ) {
55  for (index_t x = 0; x < dst.shape[0]; ++x ) {
56  // trust your compiler! -_- they will optimize it
57  Saver::Save(dst[y][x], plan.Eval( y, x ) );
58  }
59  }
60  }
61 
62  // code to handle SSE optimization
63  template<bool pass_check,typename Saver, int dim, typename E, int etype>
65  template<typename SV, int dim, typename E, int etype>
66  struct MapExpCPUEngine<false,SV,dim,E,etype>{
67  inline static void Map(Tensor<cpu,dim> dst, const expr::Exp<E,etype> &exp ){
68  MapPlan<SV>( dst, MakePlan( exp.self() ) );
69  }
70  };
71 
72  #if MSHADOW_USE_SSE
73  template<typename SV, int dim, typename E, int etype>
74  struct MapExpCPUEngine<true,SV,dim,E,etype>{
75  inline static void Map(Tensor<cpu,dim> dst, const expr::Exp<E,etype> &exp ){
76  using namespace expr;
77  if( SSEAlignCheck<dim,E>::Check( exp.self() ) && SSEAlignCheck< dim,Tensor<cpu,dim> >::Check(dst) ){
78  MapSSEPlan<SV>( dst, MakeSSEPlan( exp.self() ) );
79  }else{
80  MapPlan<SV>( dst, MakePlan( exp.self() ) );
81  }
82  }
83  };
84  #endif
85 
86  template<typename Saver, int dim, typename E, int etype>
87  inline void MapExp(Tensor<cpu,dim> dst, const expr::Exp<E,etype> &exp ){
88  using namespace expr;
89  TypeCheckPass< TypeCheck<cpu,dim,E>::kMapPass >::Error_All_Tensor_in_Exp_Must_Have_Same_Type();
90  Shape<dim> eshape = ShapeCheck<dim,E>::Check( exp.self() );
91  utils::Assert( eshape[0] == 0 || eshape == dst.shape, "Assignment: Shape of Tensors in expression is not consistent with target" );
92  #if MSHADOW_USE_SSE
93  MapExpCPUEngine< SSECheck<E>::kPass,Saver,dim,E,etype >::Map( dst, exp );
94  #else
96  #endif
97  }
98 
99  template<typename Saver, typename Reducer, typename E, int etype>
100  inline void MapReduceKeepLowest( Tensor<cpu,1> dst, const expr::Exp<E,etype> &exp, real_t scale ){
101  using namespace expr;
102  TypeCheckPass< TypeCheck<cpu,1,E>::kRedPass >::Error_TypeCheck_Not_Pass_For_Reduce_Exp();
103  Shape<2> eshape = ShapeCheck< ExpInfo<E>::kDim, E >::Check( exp.self() ).FlatTo2D();
104 
105  utils::Assert( eshape[0] == dst.shape[0], "reduction dimension do not match" );
106  utils::Assert( eshape[1] != 0, "can not reduce over empty tensor" );
107  // execution
108  expr::Plan<E> plan = MakePlan( exp.self() );
109  for( index_t x = 0; x < eshape[0]; ++x ){
110  real_t res = plan.Eval( 0, x );
111  for( index_t y = 1; y < eshape[1]; ++y ){
112  Reducer::Reduce( res, plan.Eval( y, x ) );
113  }
114  Saver::Save( dst[x], res*scale );
115  }
116  }
117 
118  template<typename Saver, typename Reducer, int dimkeep, typename E, int etype>
119  inline void MapReduceKeepHighDim( Tensor<cpu,1> dst, const expr::Exp<E,etype> &exp, real_t scale ){
120  using namespace expr;
121  TypeCheckPass< TypeCheck<cpu,dimkeep,E>::kRedPass >::Error_TypeCheck_Not_Pass_For_Reduce_Exp();
122  typedef Shape< ExpInfo<E>::kDim > EShape;
123  EShape eshape = ShapeCheck< ExpInfo<E>::kDim, E >::Check( exp.self() );
124  utils::Assert( eshape[dimkeep] == dst.shape[0], "reduction dimension do not match" );
125  // use equvalent form
126  Shape<4> pshape = Shape4( eshape.ProdShape(dimkeep+1,EShape::kMaxShape), eshape[dimkeep],
127  eshape.ProdShape(1,dimkeep), eshape[0] );
128 
129  // execution
130  expr::Plan<E> plan = MakePlan( exp.self() );
131 
132  for( index_t c = 0; c < pshape[2]; ++c ){
133  real_t res = Reducer::kInitV;
134  for( index_t n = 0; n < pshape[3]; ++n ){
135  real_t tres = Reducer::kInitV;
136  for( index_t y = 0; y < pshape[1]; ++y ){
137  for( index_t x = 0; x < pshape[0]; ++x ){
138  Reducer::Reduce( tres, plan.Eval( (n*pshape[2] + c) * pshape[1] + y, x ) );
139  }
140  }
141  Reducer::Reduce( res, tres );
142  }
143  Saver::Save( dst[c], res*scale );
144  }
145  }
146 
147  inline void Softmax( Tensor<cpu,1> dst, const Tensor<cpu,1>& energy ){
148  real_t mmax = energy[0];
149  for( real_t x = 1; x < dst.shape[0]; ++x )
150  if( mmax < energy[x] ) mmax = energy[x];
151  real_t sum = 0.0f;
152  for( index_t x = 0; x < dst.shape[0]; ++x ){
153  dst[x] = std::exp( energy[x] - mmax );
154  sum += dst[x];
155  }
156  for( index_t x = 0; x < dst.shape[0]; ++x ){
157  dst[x] /= sum;
158  }
159  }
160  inline void Softmax( Tensor<cpu,2> dst, const Tensor<cpu,2>& energy ){
161  utils::Assert( dst.shape == energy.shape, "Softmax: shape mismatch" );
162  for( index_t y = 0; y < dst.shape[1]; ++y ){
163  Softmax( dst[y], energy[y] );
164  }
165  }
166 }; // namespace mshadow
167 
168 #endif // TENSOR_CPU_INL_HPP
void MapExp(Tensor< cpu, dim > dst, const expr::Exp< E, etype > &exp)
CPU/GPU: map a expression to a tensor, this function calls MapPlan.
Definition: tensor_cpu-inl.hpp:87
unsigned index_t
type that will be used for index
Definition: tensor_base.h:123
Tensor< Device, dim > NewTensor(const Shape< dim > &shape, real_t initv, bool pad=MSHADOW_ALLOC_PAD)
CPU/GPU: short cut to allocate and initialize a Tensor.
Definition: tensor_cpu-inl.hpp:28
void MapReduceKeepLowest(Tensor< cpu, 1 > dst, const expr::Exp< E, etype > &exp, real_t scale=1.0f)
CPU/GPU: map a expression, do reduction to 1D Tensor in lowest dimension (dimension 0) ...
Definition: tensor_cpu-inl.hpp:100
This part of code gives plan that can be used to carry out execution.
Definition: tensor_expr_engine-inl.hpp:33
void * AlignedMallocPitch(size_t &pitch, size_t lspace, size_t num_line)
analog to cudaMallocPitch, allocate a aligned space with num_line * lspace cells
Definition: tensor_sse-inl.hpp:26
MSHADOW_XINLINE Shape< 4 > Shape4(index_t s3, index_t s2, index_t s1, index_t s0)
construct a four dimension shape, stride will equal s0
Definition: tensor.h:176
void FreeSpace(Tensor< cpu, dim > &obj)
CPU/GPU: free the space of tensor, will set obj.dptr to NULL.
Definition: tensor_cpu-inl.hpp:36
void Assert(bool exp)
assert a expression is true
Definition: tensor_base.h:285
void MapReduceKeepHighDim(Tensor< cpu, 1 > dst, const expr::Exp< E, etype > &exp, real_t scale=1.0f)
CPU/GPU: map a expression, do reduction to 1D Tensor in third dimension (dimension 2) ...
Definition: tensor_cpu-inl.hpp:119
support of sse2 optimization of some operations
float real_t
type that will be used for content
Definition: tensor_base.h:118
void Softmax(Tensor< cpu, 2 > dst, const Tensor< cpu, 2 > &energy)
CPU/GPU: normalize softmax: dst[i][j] = exp( energy[i][j] ) /( sum_j exp( energy[i][j] ) ) ...
Definition: tensor_cpu-inl.hpp:160
const SubType & self(void) const
Definition: tensor_expr.h:52
definitions of base types, macros functions
real_t * dptr
pointer to the data
Definition: tensor.h:215
MSHADOW_XINLINE Tensor< Device, 2 > FlatTo2D(void) const
flatten the tensor to 2 dimension, collapse the higher dimensions together
Definition: tensor.h:229
Definition: tensor_cpu-inl.hpp:64
void Copy(Tensor< cpu, dim > dst, const Tensor< cpu, dim > &src)
copy data from one tensor to another, with same shape
Definition: tensor_cpu-inl.hpp:42
Shape< dimension > shape
shape of the tensor
Definition: tensor.h:217
void AllocSpace(Tensor< cpu, dim > &obj, bool pad=MSHADOW_ALLOC_PAD)
CPU/CPU: allocate space for CTensor, according to the shape in the obj this function is responsible t...
Definition: tensor_cpu-inl.hpp:14
scalar expression
Definition: tensor_expr.h:62
base class for expression
Definition: tensor_expr.h:49
void AlignedFree(void *ptr)
free aligned space
Definition: tensor_sse-inl.hpp:44
general tensor
Definition: tensor.h:206
PaddingExp< SrcExp, ExpInfo< SrcExp >::kDim > pad(const Exp< SrcExp, etype > &src, index_t pad)
padding expression, pad a image with zeros on boundaries, padding affects shape[0], and shape[1]
Definition: tensor_expr_ext.h:496