DLPrimitives
tensor.hpp
1 #pragma once
2 #include <dlprim/context.hpp>
3 #include <dlprim/shape.hpp>
4 #include <memory>
5 namespace dlprim {
6 
7  class Tensor;
11  class TensorSpecs {
12  public:
20  TensorSpecs(Shape const &s=Shape(),DataType d=float_data,bool trainable = true) :
21  shape_(s),
22  dtype_(d)
23  {
24  is_trainable_ = trainable && is_floating_point_data_type(d);
25  }
26 
27  bool operator==(TensorSpecs const &other) const
28  {
29  return shape_ == other.shape_ && dtype_ == other.dtype_ && is_trainable_ == other.is_trainable_;
30  }
31 
32  bool operator!=(TensorSpecs const &other) const
33  {
34  return !(*this == other);
35  }
36 
38  Shape const &shape() const
39  {
40  return shape_;
41  }
42 
43  void shape(Shape const &s)
44  {
45  shape_=s;
46  }
47 
51  bool is_trainable() const
52  {
53  return is_trainable_;
54  }
55 
59  void freeze()
60  {
61  is_trainable_ = false;
62  }
63 
67  void is_trainable(bool v)
68  {
69  is_trainable_ = v;
70  }
71 
75  size_t memory_size() const
76  {
77  return shape_.total_size() * size_of_data_type(dtype_);
78  }
79 
80 
81  DataType dtype() const
82  {
83  return dtype_;
84  }
85  private:
86  friend class Tensor;
87  Shape shape_;
88  DataType dtype_;
89  bool is_trainable_;
90  };
91 
92 
99  class Tensor {
100  public:
101 
105  Tensor(Context &ctx,Shape const &s,DataType d=float_data,bool is_trainable=true);
106 
110  Tensor(cl::Buffer const &buffer,cl_ulong offset,Shape const &s,DataType d=float_data,bool is_trainable=true);
111 
115  Tensor();
119  Tensor(Tensor const &) = default;
123  Tensor &operator=(Tensor const &) = default;
124  Tensor(Tensor &&) = default;
125  Tensor &operator=(Tensor &&) = default;
126  ~Tensor() {}
127 
128  TensorSpecs const &specs() const
129  {
130  return *specs_;
131  }
132 
134  Shape const &shape() const
135  {
136  return specs_->shape();
137  }
138 
142  bool is_trainable() const
143  {
144  return specs_->is_trainable();
145  }
146 
150  size_t memory_size() const
151  {
152  return shape().total_size() * size_of_data_type(dtype());
153  }
154 
155 
156  DataType dtype() const
157  {
158  return specs_->dtype();
159  }
160 
161 
165  void reshape(Shape const &ns);
166 
170  cl::Buffer &device_buffer()
171  {
172  return buffer_;
173  }
180  cl_ulong device_offset()
181  {
182  return offset_;
183  }
187  void *host_data();
188 
189 
193  Tensor workspace_as_type(DataType d=float_data) const
194  {
195  size_t size = memory_size() / size_of_data_type(d);
196  return sub_tensor(0,Shape(size),d);
197  }
198 
207  Tensor sub_tensor_target_offset(size_t offset,Shape const &s,DataType d=float_data,bool trainable = true) const
208  {
209  size_t bytes = offset * size_of_data_type(d);
210  int this_sizeof = size_of_data_type(dtype());
211  DLPRIM_CHECK(bytes % this_sizeof == 0);
212  return sub_tensor(bytes / this_sizeof,s,d,trainable);
213  }
222  Tensor sub_tensor(size_t offset,Shape const &s,DataType d=float_data,bool trainable = true) const;
223 
228  Tensor alias() const
229  {
230  return sub_tensor(0,shape(),dtype(),is_trainable());
231  }
235  Tensor alias(Shape const &new_shape) const
236  {
237  Tensor t = alias();
238  t.reshape(new_shape);
239  return t;
240  }
241 
245  template<typename T>
246  T *data()
247  {
248  DLPRIM_CHECK(TypeTraits<T>::data_type == dtype());
249  return static_cast<T*>(host_data());
250  }
251 
255  void to_device(ExecutionContext const &c,void *host_memory,bool sync=true);
259  void to_host(ExecutionContext const &c,void *host_memory,bool sync=true);
263  void to_device(ExecutionContext const &c,bool sync=true);
267  void to_host(ExecutionContext const &c,bool sync=true);
268 
272  void set_arg(cl::Kernel &k,int &pos)
273  {
274  k.setArg(pos++,device_buffer());
275  k.setArg(pos++,device_offset());
276  }
277 
278  private:
279  struct HostMem;
280  std::shared_ptr<TensorSpecs> specs_;
281  std::shared_ptr<HostMem> host_;
282  bool cpu_tensor_;
283  int offset_;
284  cl::Buffer buffer_;
285  size_t capacity_;
286  size_t full_capacity_;
287  };
288 
293  bool requires_gradient=true;
294  float accumulate_gradient=0.0;
295  Tensor data;
297  };
298 
299  inline std::ostream &operator<<(std::ostream &out,TensorSpecs const &ts)
300  {
301  out << '[' << ts.shape() << ",dtype=" << data_type_to_string(ts.dtype()) << ']';
302  return out;
303  }
304 
305  inline std::ostream &operator<<(std::ostream &out,Tensor const &ts)
306  {
307  out << ts.specs();
308  return out;
309  }
310 
311 }
313 
TensorSpecs(Shape const &s=Shape(), DataType d=float_data, bool trainable=true)
Specifications defined by shape, data type,.
Definition: tensor.hpp:20
Definition of Tensor without actual memory/object.
Definition: tensor.hpp:11
size_t total_size() const
Total number of elements - product of all items.
Definition: shape.hpp:72
void set_arg(cl::Kernel &k, int &pos)
Assign buffer and offset as kernel argumnets, at position pos and pos+1, pos incrementeded twice...
Definition: tensor.hpp:272
Tensor sub_tensor_target_offset(size_t offset, Shape const &s, DataType d=float_data, bool trainable=true) const
Create tensor on the memory of existing tensor.
Definition: tensor.hpp:207
Tensor workspace_as_type(DataType d=float_data) const
Create tensor over all avalible size for data type d.
Definition: tensor.hpp:193
Tensor shape.
Definition: shape.hpp:18
Tensor diff
value
Definition: tensor.hpp:296
T * data()
get pointer to the host pointer and cast to relevant type
Definition: tensor.hpp:246
cl_ulong device_offset()
Get offset - you should always bind both buffer and offset since there is no pointer arithmetics at h...
Definition: tensor.hpp:180
Tensor alias() const
Create a tensor with same memory but shape isn&#39;t connected to original - it is alias to same data but...
Definition: tensor.hpp:228
bool is_trainable() const
return if tensor need to participate in gradient decent
Definition: tensor.hpp:142
void freeze()
Mark tensor as one that does not participate in gradients calculations.
Definition: tensor.hpp:59
Shape const & shape() const
get tensor shape
Definition: tensor.hpp:134
Shape const & shape() const
get tensor shape
Definition: tensor.hpp:38
This is main object that represent the pair of OpenCL platform and device all other objects use it...
Definition: context.hpp:302
Tensor alias(Shape const &new_shape) const
same as t=alias(); t.reshape(s); return t;
Definition: tensor.hpp:235
DataType
type definition
Definition: definitions.hpp:70
size_t memory_size() const
Get reuired memory size for the tensor.
Definition: tensor.hpp:75
cl::Buffer & device_buffer()
Get cl::Buffer for the tensor.
Definition: tensor.hpp:170
Definition: definitions.hpp:95
Pair of tensor and its gradient for backpropogation.
Definition: tensor.hpp:292
void is_trainable(bool v)
set - non-trainable property
Definition: tensor.hpp:67
size_t memory_size() const
Get reuired memory size for the tensor.
Definition: tensor.hpp:150
Mane namespace.
Definition: context.hpp:9
bool is_floating_point_data_type(DataType d)
returns true of data is double, float, half or bfloat16 type
Definition: definitions.hpp:89
Central Data Contrainer - Tensor.
Definition: tensor.hpp:99
bool is_trainable() const
return if tensor need to participate in gradient decent
Definition: tensor.hpp:51
void reshape(Shape const &ns)
Reshape the tensor, the only requirement that ns.total_size() <= shape().total_size() ...
This class is used to pass cl::Events that the kernel should wait for and/or signal event completion...
Definition: context.hpp:121