16 #include <Eigen/CXX11/Tensor> 32 return internal::random<bool>()
33 ? TensorBlockShapeType::kUniformAllDims
34 : TensorBlockShapeType::kSkewedInnerDims;
37 template <
int NumDims>
39 return internal::random<size_t>(1, dims.
TotalSize());
42 template <
int NumDims>
45 for (
int i = 0;
i < NumDims; ++
i) {
46 dims[
i] = internal::random<int>(1, 20);
54 for (
int i = 0;
i <
size; ++
i) {
55 data[
i] = internal::random<T>();
60 template <
int NumDims>
62 for (
int i = 0;
i < NumDims; ++
i) {
63 std::cout << dims[
i] <<
"; ";
65 std::cout << std::endl;
71 typedef internal::TensorBlockMapper<2, Layout> TensorBlockMapper;
76 TensorBlockMapper uniform_block_mapper(
77 tensor_dims, {TensorBlockShapeType::kUniformAllDims, 100,
zeroCost()});
83 auto uniform_b0 = uniform_block_mapper.blockDescriptor(0);
88 TensorBlockMapper skewed_block_mapper(
89 tensor_dims, {TensorBlockShapeType::kSkewedInnerDims, 100,
zeroCost()});
95 auto skewed_b0 = skewed_block_mapper.blockDescriptor(0);
102 template<
int NumDims,
int Layout>
105 const internal::TensorBlockDescriptor<NumDims>&
block,
106 Index first_coeff_index,
int dim_index, std::set<Index>* visited_coeffs) {
109 for (
int i = 0;
i < block_sizes[dim_index]; ++
i) {
110 if (tensor_strides[dim_index] == 1) {
111 typedef std::pair<std::set<Index>::iterator,
bool> ReturnType;
112 ReturnType inserted = visited_coeffs->insert(first_coeff_index +
i);
115 int next_dim_index = dim_index +
choose(Layout, -1, 1);
116 UpdateCoeffSet<NumDims, Layout>(tensor_strides,
block, first_coeff_index,
117 next_dim_index, visited_coeffs);
118 first_coeff_index += tensor_strides[dim_index];
123 template <
typename T,
int NumDims,
int Layout>
125 typedef internal::TensorBlockMapper<NumDims, Layout> TensorBlockMapper;
131 std::set<Index> coeff_set;
134 TensorBlockMapper block_mapper(
137 for (
int i = 0;
i < block_mapper.blockCount(); ++
i) {
138 auto block = block_mapper.blockDescriptor(
i);
139 UpdateCoeffSet<NumDims, Layout>(
strides,
block, block.offset(),
140 choose(Layout, NumDims - 1, 0),
152 template <
int Layout,
int NumDims>
159 for (
int i = NumDims - 1;
i > 0; --
i) {
160 const Index idx = output_index / output_strides[
i];
161 input_index += idx * input_strides[output_to_input_dim_map[
i]];
162 output_index -= idx * output_strides[
i];
165 output_index * input_strides[output_to_input_dim_map[0]];
167 for (
int i = 0;
i < NumDims - 1; ++
i) {
168 const Index idx = output_index / output_strides[
i];
169 input_index += idx * input_strides[output_to_input_dim_map[
i]];
170 output_index -= idx * output_strides[
i];
173 output_index * input_strides[output_to_input_dim_map[NumDims - 1]];
177 template <
int Layout,
int NumDims>
183 for (
int i = 1;
i < NumDims; ++
i) {
184 strides[
i] = strides[
i - 1] * sizes[
i - 1];
187 strides[NumDims - 1] = 1;
188 for (
int i = NumDims - 2;
i >= 0; --
i) {
189 strides[
i] = strides[
i + 1] * sizes[
i + 1];
195 template<
typename Scalar,
typename StorageIndex,
int Dim>
208 for(
int i=0;
i<output_dims[
depth]; ++
i)
217 : input_data(input_data_)
218 , input_dims(input_dims_), input_strides(input_strides_)
219 , output_dims(output_dims_), output_strides(output_strides_)
228 template <
int Layout>
231 typedef internal::TensorBlockDescriptor<5> TensorBlock;
232 typedef internal::TensorBlockMapper<5, Layout> TensorBlockMapper;
237 const Index max_coeff_count = 5 * 5 * 5 * 5 * 5;
238 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
240 TensorBlock
block = block_mapper.blockDescriptor(0);
241 for (
int i = 0;
i < 5; ++
i) {
244 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
251 const Index max_coeff_count = 7 * 5 * 5 * 5 * 5;
252 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
254 TensorBlock
block = block_mapper.blockDescriptor(0);
256 for (
int i = 1;
i < 5; ++
i) {
259 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
262 const Index max_coeff_count = 5 * 5 * 5 * 5 * 6;
263 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
265 TensorBlock
block = block_mapper.blockDescriptor(0);
267 for (
int i = 3;
i >= 0; --
i) {
270 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
277 const Index max_coeff_count = 11 * 5 * 5 * 5 * 5;
278 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
280 TensorBlock
block = block_mapper.blockDescriptor(0);
282 for (
int i = 1;
i < 5; ++
i) {
285 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
288 const Index max_coeff_count = 5 * 5 * 5 * 5 * 7;
289 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
291 TensorBlock
block = block_mapper.blockDescriptor(0);
293 for (
int i = 3;
i >= 0; --
i) {
296 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
303 const Index max_coeff_count = 7 * 5 * 6 * 7 * 5;
304 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
306 TensorBlock
block = block_mapper.blockDescriptor(0);
312 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
315 const Index max_coeff_count = 5 * 5 * 5 * 6 * 7;
316 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
318 TensorBlock
block = block_mapper.blockDescriptor(0);
324 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
330 const Index max_coeff_count = 7 * 5 * 6 * 17 * 7;
331 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
333 TensorBlock
block = block_mapper.blockDescriptor(0);
339 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
342 const Index max_coeff_count = 7 * 5 * 6 * 9 * 7;
343 TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims,
345 TensorBlock
block = block_mapper.blockDescriptor(0);
351 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
355 template <
int Layout>
358 typedef internal::TensorBlockDescriptor<5> TensorBlock;
359 typedef internal::TensorBlockMapper<5, Layout> TensorBlockMapper;
364 const Index max_coeff_count = 10 * 1 * 1 * 1 * 1;
365 TensorBlockMapper block_mapper(
367 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
368 TensorBlock
block = block_mapper.blockDescriptor(0);
370 for (
int i = 1;
i < 5; ++
i) {
373 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
376 const Index max_coeff_count = 1 * 1 * 1 * 1 * 6;
377 TensorBlockMapper block_mapper(
379 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
380 TensorBlock
block = block_mapper.blockDescriptor(0);
382 for (
int i = 3;
i >= 0; --
i) {
385 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
391 const Index max_coeff_count = 11 * 1 * 1 * 1 * 1;
392 TensorBlockMapper block_mapper(
394 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
395 TensorBlock
block = block_mapper.blockDescriptor(0);
397 for (
int i = 1;
i < 5; ++
i) {
400 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
403 const Index max_coeff_count = 1 * 1 * 1 * 1 * 7;
404 TensorBlockMapper block_mapper(
406 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
407 TensorBlock
block = block_mapper.blockDescriptor(0);
409 for (
int i = 3;
i >= 0; --
i) {
412 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
419 const Index max_coeff_count = 11 * 3 * 1 * 1 * 1;
420 TensorBlockMapper block_mapper(
422 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
423 TensorBlock
block = block_mapper.blockDescriptor(0);
426 for (
int i = 2;
i < 5; ++
i) {
429 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
432 const Index max_coeff_count = 1 * 1 * 1 * 15 * 7;
433 TensorBlockMapper block_mapper(
435 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
436 TensorBlock
block = block_mapper.blockDescriptor(0);
439 for (
int i = 2;
i >= 0; --
i) {
442 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
449 const Index max_coeff_count = 11 * 5 * 5 * 1 * 1;
450 TensorBlockMapper block_mapper(
452 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
453 TensorBlock
block = block_mapper.blockDescriptor(0);
457 for (
int i = 3;
i < 5; ++
i) {
460 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
463 const Index max_coeff_count = 1 * 1 * 5 * 17 * 7;
464 TensorBlockMapper block_mapper(
466 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
467 TensorBlock
block = block_mapper.blockDescriptor(0);
471 for (
int i = 1;
i >= 0; --
i) {
474 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
480 const Index max_coeff_count = 11 * 5 * 6 * 17 * 7;
481 TensorBlockMapper block_mapper(
483 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
484 TensorBlock
block = block_mapper.blockDescriptor(0);
490 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
493 const Index max_coeff_count = 11 * 5 * 6 * 17 * 7;
494 TensorBlockMapper block_mapper(
496 {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count,
zeroCost()});
497 TensorBlock
block = block_mapper.blockDescriptor(0);
503 VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
507 template <
int Layout>
516 typedef internal::TensorBlockMapper<1, Layout> TensorBlockMapper;
519 for (
size_t max_coeff_count = 0; max_coeff_count < 2; ++max_coeff_count) {
520 TensorBlockMapper block_mapper(
521 dims, {block_shape, max_coeff_count,
zeroCost()});
523 VERIFY(block_mapper.blockTotalSize() >= 1);
528 typedef internal::TensorBlockMapper<2, Layout> TensorBlockMapper;
530 for (
int dim1 = 0; dim1 < 3; ++dim1) {
531 for (
int dim2 = 0; dim2 < 3; ++dim2) {
533 for (
size_t max_coeff_count = 0; max_coeff_count < 2; ++max_coeff_count) {
534 TensorBlockMapper block_mapper(
535 dims, {block_shape, max_coeff_count,
zeroCost()});
536 if (dim1 * dim2 == 0) {
539 VERIFY(block_mapper.blockTotalSize() >= 1);
546 #define TEST_LAYOUTS(NAME) \ 547 CALL_SUBTEST(NAME<ColMajor>()); \ 548 CALL_SUBTEST(NAME<RowMajor>()) 550 #define TEST_LAYOUTS_AND_DIMS(TYPE, NAME) \ 551 CALL_SUBTEST((NAME<TYPE, 1, ColMajor>())); \ 552 CALL_SUBTEST((NAME<TYPE, 1, RowMajor>())); \ 553 CALL_SUBTEST((NAME<TYPE, 2, ColMajor>())); \ 554 CALL_SUBTEST((NAME<TYPE, 2, RowMajor>())); \ 555 CALL_SUBTEST((NAME<TYPE, 3, ColMajor>())); \ 556 CALL_SUBTEST((NAME<TYPE, 3, RowMajor>())); \ 557 CALL_SUBTEST((NAME<TYPE, 4, ColMajor>())); \ 558 CALL_SUBTEST((NAME<TYPE, 4, RowMajor>())); \ 559 CALL_SUBTEST((NAME<TYPE, 5, ColMajor>())); \ 560 CALL_SUBTEST((NAME<TYPE, 5, RowMajor>())) 562 #define TEST_LAYOUTS_WITH_ARG(NAME, ARG) \ 563 CALL_SUBTEST(NAME<ColMajor>(ARG)); \ 564 CALL_SUBTEST(NAME<RowMajor>(ARG)) 576 #undef TEST_LAYOUTS_WITH_ARG static TensorBlockShapeType RandomShape()
static size_t RandomTargetSize(const DSizes< Index, NumDims > &dims)
const DSizes< StorageIndex, Dim > & input_dims
m m block(1, 0, 2, 2)<< 4
#define TEST_LAYOUTS_WITH_ARG(NAME, ARG)
std::vector< Array2i > sizes
#define TEST_LAYOUTS(NAME)
static const T & choose(int layout, const T &col, const T &row)
static void test_block_mapper_sanity()
static array< Index, NumDims > ComputeStrides(const array< Index, NumDims > &sizes)
const DSizes< StorageIndex, Dim > & output_strides
#define VERIFY_IS_EQUAL(a, b)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex TotalSize() const
static Index GetInputIndex(Index output_index, const array< Index, NumDims > &output_to_input_dim_map, const array< Index, NumDims > &input_strides, const array< Index, NumDims > &output_strides)
EqualityChecker(const Scalar *input_data_, const DSizes< StorageIndex, Dim > &input_dims_, const DSizes< StorageIndex, Dim > &input_strides_, const DSizes< StorageIndex, Dim > &output_dims_, const DSizes< StorageIndex, Dim > &output_strides_)
static void test_skewed_inner_dim_block_shape()
const Scalar * input_data
static void test_uniform_block_shape()
EIGEN_ALWAYS_INLINE DSizes< IndexType, NumDims > strides(const DSizes< IndexType, NumDims > &dimensions)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
static DSizes< Index, NumDims > RandomDims()
static TensorOpCost zeroCost()
static void test_block_mapper_maps_every_element()
EIGEN_DECLARE_TEST(cxx11_tensor_block_access)
static void test_empty_dims(const internal::TensorBlockShapeType block_shape)
void operator()(const Scalar *output_data) const
const DSizes< StorageIndex, Dim > & input_strides
static void Debug(DSizes< Index, NumDims > dims)
void check_recursive(const Scalar *input, const Scalar *output, int depth=0) const
static void UpdateCoeffSet(const DSizes< Index, NumDims > &tensor_strides, const internal::TensorBlockDescriptor< NumDims > &block, Index first_coeff_index, int dim_index, std::set< Index > *visited_coeffs)
static T * GenerateRandomData(const Index &size)
#define TEST_LAYOUTS_AND_DIMS(TYPE, NAME)
const DSizes< StorageIndex, Dim > & output_dims