BlackCat_Tensors
A GPU-supported autograd and linear algebra library, designed for neural network construction
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
tensor_accessor.h
Go to the documentation of this file.
1 /* Project: BlackCat_Tensors
2  * Author: JosephJaspers
3  * Copyright 2018
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 
9 /*
10 * Note const methods must come second to support cppyy (python bindings)
11 * Issue: https://bitbucket.org/wlav/cppyy/issues/224/overload-resolution-of-const-non-const
12 */
13 #ifndef BLACKCAT_TENSORS_TENSOR_ACCESSOR_H_
14 #define BLACKCAT_TENSORS_TENSOR_ACCESSOR_H_
15 
16 namespace bc {
17 namespace tensors {
18 
19 template<class>
20 struct Tensor_Base;
21 
22 template<int TensorDimension, class ExpressionTemplate>
24 
26  void operator [] (int index) const {
27  throw std::invalid_argument("[] not supported for scalars");
28  }
29 
30  void operator () (int index) const {
31  throw std::invalid_argument("() not supported for scalars");
32  }
33 
34 };
35 
36 template<class ExpressionTemplate>
37 using Tensor_Accessor = std::conditional_t<
38  ExpressionTemplate::tensor_dim == 0,
41  ExpressionTemplate::tensor_dim,
43 
44 template<int TensorDimension, class Derived>
46 {
47  // static_assert(TensorDimension != 0);
48  static constexpr int tensor_dim = TensorDimension;
49  Derived& derived() { return static_cast<Derived&>(*this); }
50  const Derived& derived() const { return static_cast<const Derived&>(*this); }
51 public:
52 
54  return slice(i);
55  }
56 
57  const auto operator [](bc::size_t i) const {
58  return slice(i);
59  }
60 
61  //enables syntax: `tensor[{start, end}]`
63  return slice(range[0], range[1]);
64  }
65 
66  const auto operator [](bc::Dim<2> range) const {
67  return slice(range[0], range[1]);
68  }
69 
70  auto slice(bc::size_t i)
71  {
72  BC_ASSERT(i >= 0 && i < derived().outer_dim(),
73  "slice index must be between 0 and outer_dim()");
74  return make_tensor(exprs::make_slice(derived(), i));
75  }
76 
77  auto slice(bc::size_t i) const {
78  BC_ASSERT(i >= 0 && i < derived().outer_dim(),
79  "slice index must be between 0 and outer_dim()");
80  return make_tensor(exprs::make_slice(derived(), i));
81  }
82 
83  auto slice(bc::size_t from, bc::size_t to)
84  {
85  BC_ASSERT(from >= 0 && to <= derived().outer_dim(),
86  "slice `from` must be between 0 and outer_dim()");
87  BC_ASSERT(to > from && to <= derived().outer_dim(),
88  "slice `to` must be between `from` and outer_dim()");
89  return make_tensor(exprs::make_ranged_slice(derived(), from, to));
90  }
91 
92  auto slice(bc::size_t from, bc::size_t to) const
93  {
94  BC_ASSERT(from >= 0 && to <= derived().outer_dim(),
95  "slice `from` must be between 0 and outer_dim()");
96  BC_ASSERT(to > from && to <= derived().outer_dim(),
97  "slice `to` must be between `from` and outer_dim()");
98  return make_tensor(exprs::make_ranged_slice(derived(), from, to));
99  }
100 
102  {
103  BC_ASSERT(i >= 0 && i < derived().size(),
104  "Scalar index must be between 0 and size()");
105  return make_tensor(exprs::make_scalar(derived(), i));
106  }
107 
108  auto scalar(bc::size_t i) const
109  {
110  BC_ASSERT(i >= 0 && i < derived().size(),
111  "Scalar index must be between 0 and size()");
112  return make_tensor(exprs::make_scalar(derived(), i));
113  }
114 
115  auto diagnol(bc::size_t index = 0)
116  {
117  static_assert(tensor_dim == 2,
118  "diagnol method is only available to matrices");
119  BC_ASSERT(index > -derived().rows() && index < derived().rows(),
120  "diagnol `index` must be -rows() and rows())");
121  return make_tensor(exprs::make_diagnol(derived(), index));
122  }
123 
124  auto diagnol(bc::size_t index = 0) const
125  {
126  static_assert(tensor_dim == 2,
127  "diagnol method is only available to matrices");
128  BC_ASSERT(index > -derived().rows() && index < derived().rows(),
129  "diagnol `index` must be -rows() and rows())");
130  return make_tensor(exprs::make_diagnol(derived(), index));
131  }
132 
133  //returns a copy of the tensor without actually copying the elements
135  {
136  return make_tensor(exprs::make_view(derived(), derived().get_shape()));
137  }
138 
139  auto shallow_copy() const
140  {
141  return make_tensor(exprs::make_view(derived(), derived().get_shape()));
142  }
143 
144  auto col(bc::size_t i)
145  {
146  static_assert(tensor_dim == 2,
147  "MATRIX COL ONLY AVAILABLE TO MATRICES OF ORDER 2");
148  return slice(i);
149  }
150 
151  auto col(bc::size_t i) const
152  {
153  static_assert(tensor_dim == 2,
154  "MATRIX COL ONLY AVAILABLE TO MATRICES OF ORDER 2");
155  return slice(i);
156  }
157 
158  auto row(bc::size_t index)
159  {
160  static_assert(tensor_dim == 2,
161  "MATRIX ROW ONLY AVAILABLE TO MATRICES OF ORDER 2");
162  BC_ASSERT(index >= 0 && index < derived().rows(),
163  "Row index must be between 0 and rows()");
164  return make_tensor(exprs::make_row(derived(), index));
165  }
166 
167  auto row(bc::size_t index) const
168  {
169  static_assert(tensor_dim == 2,
170  "MATRIX ROW ONLY AVAILABLE TO MATRICES OF ORDER 2");
171  BC_ASSERT(index >= 0 && index < derived().rows(),
172  "Row index must be between 0 and rows()");
173  return make_tensor(exprs::make_row(derived(), index));
174  }
175 
177  {
178  BC_ASSERT((index.reversed() + shape <= derived().inner_shape()).all(),
179  "Index + Shape must be less parent shape");
180  BC_ASSERT(((index>=0).all() && (shape>=0).all()),
181  "Shape and Index must be greater than 0");
182  return make_tensor(exprs::make_chunk(derived(), index, shape));
183  }
184 
186  {
187  BC_ASSERT((index.reversed() + shape <= derived().inner_shape()).all(),
188  "Index + Shape must be less parent shape");
189  BC_ASSERT(((index>=0).all() && (shape>=0).all()),
190  "Shape and Index must be greater than 0");
191  return make_tensor(exprs::make_chunk(derived(), index, shape));
192  }
193 
195  std::tuple<Dim<tensor_dim>, Dim<tensor_dim>> index_shape) {
196  return subblock(std::get<0>(index_shape), std::get<1>(index_shape));
197  }
198 
200  std::tuple<Dim<tensor_dim>, Dim<tensor_dim>> index_shape) const {
201  return subblock(std::get<0>(index_shape), std::get<1>(index_shape));
202  }
203 
204  auto operator() (bc::size_t i) { return scalar(i); }
205  const auto operator() (bc::size_t i) const { return scalar(i); }
206 
207  template<int X>
209  {
210  static_assert(Derived::tensor_iterator_dim <= 1,
211  "Reshape is only available to continuous tensors");
212 
213  BC_ASSERT(shape.size() == derived().size(),
214  "Reshape requires the new and old shape be same sizes");
215 
216  return make_tensor(exprs::make_view(derived(), shape));
217  }
218 
219  template<int X>
221  {
222  static_assert(Derived::tensor_iterator_dim <= 1,
223  "Reshape is only available to continuous tensors");
224 
225  BC_ASSERT(shape.size() == derived().size(),
226  "Reshape requires the new and old shape be same sizes");
227 
228  return make_tensor(exprs::make_view(derived(), shape));
229  }
230 
231  template<class... Integers>
232  auto reshaped(Integers... ints) {
233  return reshaped(bc::dim(ints...));
234  }
235 
236  template<class... Integers>
237  auto reshaped(Integers... ints) const {
238  return reshaped(bc::dim(ints...));
239  }
240 
241  auto flattened() {
242  return this->reshaped(derived().size());
243  }
244 
245  const auto flattened() const {
246  return this->reshaped(derived().size());
247  }
248 };
249 
250 }
251 }
252 
253 #endif
auto shallow_copy()
Definition: tensor_accessor.h:134
auto slice(bc::size_t i)
Definition: tensor_accessor.h:70
Definition: tensor_accessor.h:25
auto subblock(Dim< tensor_dim > index, Dim< tensor_dim > shape)
Definition: tensor_accessor.h:176
auto flattened()
Definition: tensor_accessor.h:241
auto reshaped(Integers... ints) const
Definition: tensor_accessor.h:237
const auto flattened() const
Definition: tensor_accessor.h:245
auto slice(bc::size_t from, bc::size_t to) const
Definition: tensor_accessor.h:92
auto make_diagnol(Parent &parent, bc::size_t diagnol_index)
Definition: array_slice.h:98
auto make_chunk(Parent &parent, bc::Dim< Parent::tensor_dim > index_points, ShapeLike shape)
Definition: array_slice.h:203
BCINLINE auto dim(const Integers &... ints)
Definition: dim.h:336
auto scalar(bc::size_t i)
Definition: tensor_accessor.h:101
Definition: tensor_accessor.h:23
auto subblock(Dim< tensor_dim > index, Dim< tensor_dim > shape) const
Definition: tensor_accessor.h:185
auto reshaped(Integers... ints)
Definition: tensor_accessor.h:232
auto make_row(Parent &parent, bc::size_t index)
Definition: array_slice.h:86
BCINLINE value_type size() const
Definition: dim.h:28
void operator[](int index) const
Definition: tensor_accessor.h:26
BCINLINE Dim reversed() const
Definition: dim.h:257
int size_t
Definition: common.h:283
auto diagnol(bc::size_t index=0) const
Definition: tensor_accessor.h:124
auto row(bc::size_t index) const
Definition: tensor_accessor.h:167
std::conditional_t< ExpressionTemplate::tensor_dim==0, Scalar_Accessor, Tensor_Accessor_Base< ExpressionTemplate::tensor_dim, Tensor_Base< ExpressionTemplate > >> Tensor_Accessor
Definition: tensor_accessor.h:42
auto row(bc::size_t index)
Definition: tensor_accessor.h:158
auto scalar(bc::size_t i) const
Definition: tensor_accessor.h:108
auto reshaped(bc::Dim< X > shape)
Definition: tensor_accessor.h:208
auto slice(bc::size_t from, bc::size_t to)
Definition: tensor_accessor.h:83
auto reshaped(bc::Dim< X > shape) const
Definition: tensor_accessor.h:220
Definition: cmath.h:17
auto range(T begin, T end=T())
Definition: io.h:46
#define BC_ASSERT(condition, message)
Definition: common.h:185
BCINLINE auto shape(Integers... ints)
Definition: shape.h:264
auto slice(bc::size_t i) const
Definition: tensor_accessor.h:77
auto diagnol(bc::size_t index=0)
Definition: tensor_accessor.h:115
auto col(bc::size_t i) const
Definition: tensor_accessor.h:151
auto shallow_copy() const
Definition: tensor_accessor.h:139
auto make_tensor(ExpressionTemplate expression)
Definition: common.h:29
auto col(bc::size_t i)
Definition: tensor_accessor.h:144
The Evaluator determines if an expression needs to be greedily optimized.
Definition: algorithms.h:22
void operator()(int index) const
Definition: tensor_accessor.h:30