cxx11_tensor_block_access.cpp File Reference
#include "main.h"
#include <algorithm>
#include <set>
#include <Eigen/CXX11/Tensor>

Classes

class  EqualityChecker< Scalar, StorageIndex, Dim >
 

Macros

#define TEST_LAYOUTS(NAME)
 
#define TEST_LAYOUTS_AND_DIMS(TYPE, NAME)
 
#define TEST_LAYOUTS_WITH_ARG(NAME, ARG)
 

Functions

static TensorOpCost zeroCost ()
 
template<typename T >
static const Tchoose (int layout, const T &col, const T &row)
 
static TensorBlockShapeType RandomShape ()
 
template<int NumDims>
static size_t RandomTargetSize (const DSizes< Index, NumDims > &dims)
 
template<int NumDims>
static DSizes< Index, NumDims > RandomDims ()
 
template<typename T >
static TGenerateRandomData (const Index &size)
 
template<int NumDims>
static void Debug (DSizes< Index, NumDims > dims)
 
template<int Layout>
static void test_block_mapper_sanity ()
 
template<int NumDims, int Layout>
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)
 
template<typename T , int NumDims, int Layout>
static void test_block_mapper_maps_every_element ()
 
template<int Layout, int NumDims>
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)
 
template<int Layout, int NumDims>
static array< Index, NumDims > ComputeStrides (const array< Index, NumDims > &sizes)
 
template<int Layout>
static void test_uniform_block_shape ()
 
template<int Layout>
static void test_skewed_inner_dim_block_shape ()
 
template<int Layout>
static void test_empty_dims (const internal::TensorBlockShapeType block_shape)
 
 EIGEN_DECLARE_TEST (cxx11_tensor_block_access)
 

Macro Definition Documentation

◆ TEST_LAYOUTS

#define TEST_LAYOUTS (   NAME)
Value:
CALL_SUBTEST(NAME<ColMajor>()); \
CALL_SUBTEST(NAME<RowMajor>())
#define CALL_SUBTEST(FUNC)
Definition: main.h:382

◆ TEST_LAYOUTS_AND_DIMS

#define TEST_LAYOUTS_AND_DIMS (   TYPE,
  NAME 
)
Value:
CALL_SUBTEST((NAME<TYPE, 1, ColMajor>())); \
CALL_SUBTEST((NAME<TYPE, 1, RowMajor>())); \
CALL_SUBTEST((NAME<TYPE, 2, ColMajor>())); \
CALL_SUBTEST((NAME<TYPE, 2, RowMajor>())); \
CALL_SUBTEST((NAME<TYPE, 3, ColMajor>())); \
CALL_SUBTEST((NAME<TYPE, 3, RowMajor>())); \
CALL_SUBTEST((NAME<TYPE, 4, ColMajor>())); \
CALL_SUBTEST((NAME<TYPE, 4, RowMajor>())); \
CALL_SUBTEST((NAME<TYPE, 5, ColMajor>())); \
CALL_SUBTEST((NAME<TYPE, 5, RowMajor>()))

◆ TEST_LAYOUTS_WITH_ARG

#define TEST_LAYOUTS_WITH_ARG (   NAME,
  ARG 
)
Value:
CALL_SUBTEST(NAME<ColMajor>(ARG)); \
CALL_SUBTEST(NAME<RowMajor>(ARG))

Function Documentation

◆ choose()

template<typename T >
static const T& choose ( int  layout,
const T col,
const T row 
)
static
27  {
28  return layout == ColMajor ? col : row;
29 }
m col(1)
m row(1)
@ ColMajor
Definition: Constants.h:318

References col(), Eigen::ColMajor, and row().

Referenced by test_block_mapper_maps_every_element(), test_block_mapper_sanity(), and UpdateCoeffSet().

◆ ComputeStrides()

template<int Layout, int NumDims>
static array<Index, NumDims> ComputeStrides ( const array< Index, NumDims > &  sizes)
static
164  {
166  if (Layout == ColMajor) {
167  strides[0] = 1;
168  for (int i = 1; i < NumDims; ++i) {
169  strides[i] = strides[i - 1] * sizes[i - 1];
170  }
171  } else {
172  strides[NumDims - 1] = 1;
173  for (int i = NumDims - 2; i >= 0; --i) {
174  strides[i] = strides[i + 1] * sizes[i + 1];
175  }
176  }
177  return strides;
178 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
std::vector< Array2i > sizes
Definition: dense_solvers.cpp:12
EIGEN_ALWAYS_INLINE DSizes< IndexType, NumDims > strides(const DSizes< IndexType, NumDims > &dimensions)
Definition: TensorBlock.h:29
std::array< T, N > array
Definition: EmulateArray.h:231

References Eigen::ColMajor, i, sizes, and Eigen::internal::strides().

◆ Debug()

template<int NumDims>
static void Debug ( DSizes< Index, NumDims >  dims)
static
59  {
60  for (int i = 0; i < NumDims; ++i) {
61  std::cout << dims[i] << "; ";
62  }
63  std::cout << std::endl;
64 }

References i.

◆ EIGEN_DECLARE_TEST()

EIGEN_DECLARE_TEST ( cxx11_tensor_block_access  )
513  {
518  TEST_LAYOUTS_WITH_ARG(test_empty_dims, TensorBlockShapeType::kUniformAllDims);
519  TEST_LAYOUTS_WITH_ARG(test_empty_dims, TensorBlockShapeType::kSkewedInnerDims);
520 }
static void test_block_mapper_sanity()
Definition: cxx11_tensor_block_access.cpp:67
static void test_uniform_block_shape()
Definition: cxx11_tensor_block_access.cpp:210
#define TEST_LAYOUTS(NAME)
Definition: cxx11_tensor_block_access.cpp:493
static void test_skewed_inner_dim_block_shape()
Definition: cxx11_tensor_block_access.cpp:327
static void test_block_mapper_maps_every_element()
Definition: cxx11_tensor_block_access.cpp:117
#define TEST_LAYOUTS_WITH_ARG(NAME, ARG)
Definition: cxx11_tensor_block_access.cpp:509
#define TEST_LAYOUTS_AND_DIMS(TYPE, NAME)
Definition: cxx11_tensor_block_access.cpp:497
static void test_empty_dims(const internal::TensorBlockShapeType block_shape)
Definition: cxx11_tensor_block_access.cpp:458

References test_block_mapper_maps_every_element(), test_block_mapper_sanity(), test_empty_dims(), TEST_LAYOUTS, TEST_LAYOUTS_AND_DIMS, TEST_LAYOUTS_WITH_ARG, test_skewed_inner_dim_block_shape(), and test_uniform_block_shape().

◆ GenerateRandomData()

template<typename T >
static T* GenerateRandomData ( const Index &  size)
static
50  {
51  T* data = new T[size];
52  for (int i = 0; i < size; ++i) {
53  data[i] = internal::random<T>();
54  }
55  return data;
56 }
int data[]
Definition: Map_placement_new.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17

References data, i, and size.

◆ GetInputIndex()

template<int Layout, int NumDims>
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 
)
static
144  {
145  int input_index = 0;
146  if (Layout == ColMajor) {
147  for (int i = NumDims - 1; i > 0; --i) {
148  const Index idx = output_index / output_strides[i];
149  input_index += idx * input_strides[output_to_input_dim_map[i]];
150  output_index -= idx * output_strides[i];
151  }
152  return input_index + output_index * input_strides[output_to_input_dim_map[0]];
153  } else {
154  for (int i = 0; i < NumDims - 1; ++i) {
155  const Index idx = output_index / output_strides[i];
156  input_index += idx * input_strides[output_to_input_dim_map[i]];
157  output_index -= idx * output_strides[i];
158  }
159  return input_index + output_index * input_strides[output_to_input_dim_map[NumDims - 1]];
160  }
161 }
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83

References Eigen::ColMajor, and i.

◆ RandomDims()

template<int NumDims>
static DSizes<Index, NumDims> RandomDims ( )
static
41  {
43  for (int i = 0; i < NumDims; ++i) {
44  dims[i] = internal::random<int>(1, 20);
45  }
46  return DSizes<Index, NumDims>(dims);
47 }

References i.

◆ RandomShape()

static TensorBlockShapeType RandomShape ( )
static
31  {
32  return internal::random<bool>() ? TensorBlockShapeType::kUniformAllDims : TensorBlockShapeType::kSkewedInnerDims;
33 }

Referenced by test_block_mapper_maps_every_element().

◆ RandomTargetSize()

template<int NumDims>
static size_t RandomTargetSize ( const DSizes< Index, NumDims > &  dims)
static
36  {
37  return internal::random<size_t>(1, dims.TotalSize());
38 }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex TotalSize() const
Definition: TensorDimensions.h:167

References Eigen::DSizes< DenseIndex, NumDims >::TotalSize().

Referenced by test_block_mapper_maps_every_element().

◆ test_block_mapper_maps_every_element()

template<typename T , int NumDims, int Layout>
static void test_block_mapper_maps_every_element ( )
static
117  {
118  typedef internal::TensorBlockMapper<NumDims, Layout> TensorBlockMapper;
119 
120  DSizes<Index, NumDims> dims = RandomDims<NumDims>();
121  DSizes<Index, NumDims> strides = internal::strides<Layout>(dims);
122 
123  // Keep track of elements indices available via block access.
124  std::set<Index> coeff_set;
125 
126  // Try different combinations of block types and sizes.
127  TensorBlockMapper block_mapper(dims, {RandomShape(), RandomTargetSize(dims), zeroCost()});
128 
129  for (int i = 0; i < block_mapper.blockCount(); ++i) {
130  auto block = block_mapper.blockDescriptor(i);
131  UpdateCoeffSet<NumDims, Layout>(strides, block, block.offset(), choose(Layout, NumDims - 1, 0), &coeff_set);
132  }
133 
134  // Verify that every coefficient in the original Tensor is accessible through
135  // TensorBlock only once.
136  Index total_coeffs = dims.TotalSize();
137  VERIFY_IS_EQUAL(Index(coeff_set.size()), total_coeffs);
138  VERIFY_IS_EQUAL(*coeff_set.begin(), 0);
139  VERIFY_IS_EQUAL(*coeff_set.rbegin(), total_coeffs - 1);
140 }
m m block(1, 0, 2, 2)<< 4
static const T & choose(int layout, const T &col, const T &row)
Definition: cxx11_tensor_block_access.cpp:27
static TensorOpCost zeroCost()
Definition: cxx11_tensor_block_access.cpp:24
static TensorBlockShapeType RandomShape()
Definition: cxx11_tensor_block_access.cpp:31
static size_t RandomTargetSize(const DSizes< Index, NumDims > &dims)
Definition: cxx11_tensor_block_access.cpp:36
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:367

References block(), choose(), i, RandomShape(), RandomTargetSize(), Eigen::internal::strides(), Eigen::DSizes< DenseIndex, NumDims >::TotalSize(), VERIFY_IS_EQUAL, and zeroCost().

Referenced by EIGEN_DECLARE_TEST().

◆ test_block_mapper_sanity()

template<int Layout>
static void test_block_mapper_sanity ( )
static
67  {
68  typedef internal::TensorBlockMapper<2, Layout> TensorBlockMapper;
69 
70  DSizes<Index, 2> tensor_dims(100, 100);
71 
72  // Test uniform blocks.
73  TensorBlockMapper uniform_block_mapper(tensor_dims, {TensorBlockShapeType::kUniformAllDims, 100, zeroCost()});
74 
75  VERIFY_IS_EQUAL(uniform_block_mapper.blockCount(), 100);
76  VERIFY_IS_EQUAL(uniform_block_mapper.blockTotalSize(), 100);
77 
78  // 10x10 blocks
79  auto uniform_b0 = uniform_block_mapper.blockDescriptor(0);
80  VERIFY_IS_EQUAL(uniform_b0.dimensions().at(0), 10);
81  VERIFY_IS_EQUAL(uniform_b0.dimensions().at(1), 10);
82 
83  // Test skewed to inner dims blocks.
84  TensorBlockMapper skewed_block_mapper(tensor_dims, {TensorBlockShapeType::kSkewedInnerDims, 100, zeroCost()});
85 
86  VERIFY_IS_EQUAL(skewed_block_mapper.blockCount(), 100);
87  VERIFY_IS_EQUAL(skewed_block_mapper.blockTotalSize(), 100);
88 
89  // 1x100 (100x1) rows/cols depending on a tensor layout.
90  auto skewed_b0 = skewed_block_mapper.blockDescriptor(0);
91  VERIFY_IS_EQUAL(skewed_b0.dimensions().at(0), choose(Layout, 100, 1));
92  VERIFY_IS_EQUAL(skewed_b0.dimensions().at(1), choose(Layout, 1, 100));
93 }

References choose(), VERIFY_IS_EQUAL, and zeroCost().

Referenced by EIGEN_DECLARE_TEST().

◆ test_empty_dims()

template<int Layout>
static void test_empty_dims ( const internal::TensorBlockShapeType  block_shape)
static
458  {
459  // Test blocking of tensors with zero dimensions:
460  // - we must not crash on asserts and divisions by zero
461  // - we must not return block with zero dimensions
462  // (recipe for overflows/underflows, divisions by zero and NaNs later)
463  // - total block count must be zero
464  {
465  typedef internal::TensorBlockMapper<1, Layout> TensorBlockMapper;
466 
467  DSizes<Index, 1> dims(0);
468  for (size_t max_coeff_count = 0; max_coeff_count < 2; ++max_coeff_count) {
469  TensorBlockMapper block_mapper(dims, {block_shape, max_coeff_count, zeroCost()});
470  VERIFY_IS_EQUAL(block_mapper.blockCount(), 0);
471  VERIFY(block_mapper.blockTotalSize() >= 1);
472  }
473  }
474 
475  {
476  typedef internal::TensorBlockMapper<2, Layout> TensorBlockMapper;
477 
478  for (int dim1 = 0; dim1 < 3; ++dim1) {
479  for (int dim2 = 0; dim2 < 3; ++dim2) {
480  DSizes<Index, 2> dims(dim1, dim2);
481  for (size_t max_coeff_count = 0; max_coeff_count < 2; ++max_coeff_count) {
482  TensorBlockMapper block_mapper(dims, {block_shape, max_coeff_count, zeroCost()});
483  if (dim1 * dim2 == 0) {
484  VERIFY_IS_EQUAL(block_mapper.blockCount(), 0);
485  }
486  VERIFY(block_mapper.blockTotalSize() >= 1);
487  }
488  }
489  }
490  }
491 }
#define VERIFY(a)
Definition: main.h:362

References VERIFY, VERIFY_IS_EQUAL, and zeroCost().

Referenced by EIGEN_DECLARE_TEST().

◆ test_skewed_inner_dim_block_shape()

template<int Layout>
static void test_skewed_inner_dim_block_shape ( )
static
327  {
328  typedef internal::TensorBlockDescriptor<5> TensorBlock;
329  typedef internal::TensorBlockMapper<5, Layout> TensorBlockMapper;
330 
331  // Test shape 'SkewedInnerDims' with partial allocation to inner-most dim.
332  if (Layout == ColMajor) {
333  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
334  const Index max_coeff_count = 10 * 1 * 1 * 1 * 1;
335  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
336  TensorBlock block = block_mapper.blockDescriptor(0);
337  VERIFY_IS_EQUAL(10, block.dimensions()[0]);
338  for (int i = 1; i < 5; ++i) {
339  VERIFY_IS_EQUAL(1, block.dimensions()[i]);
340  }
341  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
342  } else {
343  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
344  const Index max_coeff_count = 1 * 1 * 1 * 1 * 6;
345  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
346  TensorBlock block = block_mapper.blockDescriptor(0);
347  VERIFY_IS_EQUAL(6, block.dimensions()[4]);
348  for (int i = 3; i >= 0; --i) {
349  VERIFY_IS_EQUAL(1, block.dimensions()[i]);
350  }
351  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
352  }
353 
354  // Test shape 'SkewedInnerDims' with full allocation to inner-most dim.
355  if (Layout == ColMajor) {
356  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
357  const Index max_coeff_count = 11 * 1 * 1 * 1 * 1;
358  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
359  TensorBlock block = block_mapper.blockDescriptor(0);
360  VERIFY_IS_EQUAL(11, block.dimensions()[0]);
361  for (int i = 1; i < 5; ++i) {
362  VERIFY_IS_EQUAL(1, block.dimensions()[i]);
363  }
364  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
365  } else {
366  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
367  const Index max_coeff_count = 1 * 1 * 1 * 1 * 7;
368  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
369  TensorBlock block = block_mapper.blockDescriptor(0);
370  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
371  for (int i = 3; i >= 0; --i) {
372  VERIFY_IS_EQUAL(1, block.dimensions()[i]);
373  }
374  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
375  }
376 
377  // Test shape 'SkewedInnerDims' with full allocation to inner-most dim,
378  // and partial allocation to second inner-dim.
379  if (Layout == ColMajor) {
380  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
381  const Index max_coeff_count = 11 * 3 * 1 * 1 * 1;
382  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
383  TensorBlock block = block_mapper.blockDescriptor(0);
384  VERIFY_IS_EQUAL(11, block.dimensions()[0]);
385  VERIFY_IS_EQUAL(3, block.dimensions()[1]);
386  for (int i = 2; i < 5; ++i) {
387  VERIFY_IS_EQUAL(1, block.dimensions()[i]);
388  }
389  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
390  } else {
391  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
392  const Index max_coeff_count = 1 * 1 * 1 * 15 * 7;
393  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
394  TensorBlock block = block_mapper.blockDescriptor(0);
395  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
396  VERIFY_IS_EQUAL(15, block.dimensions()[3]);
397  for (int i = 2; i >= 0; --i) {
398  VERIFY_IS_EQUAL(1, block.dimensions()[i]);
399  }
400  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
401  }
402 
403  // Test shape 'SkewedInnerDims' with full allocation to inner-most dim,
404  // and partial allocation to third inner-dim.
405  if (Layout == ColMajor) {
406  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
407  const Index max_coeff_count = 11 * 5 * 5 * 1 * 1;
408  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
409  TensorBlock block = block_mapper.blockDescriptor(0);
410  VERIFY_IS_EQUAL(11, block.dimensions()[0]);
411  VERIFY_IS_EQUAL(5, block.dimensions()[1]);
412  VERIFY_IS_EQUAL(5, block.dimensions()[2]);
413  for (int i = 3; i < 5; ++i) {
414  VERIFY_IS_EQUAL(1, block.dimensions()[i]);
415  }
416  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
417  } else {
418  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
419  const Index max_coeff_count = 1 * 1 * 5 * 17 * 7;
420  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
421  TensorBlock block = block_mapper.blockDescriptor(0);
422  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
423  VERIFY_IS_EQUAL(17, block.dimensions()[3]);
424  VERIFY_IS_EQUAL(5, block.dimensions()[2]);
425  for (int i = 1; i >= 0; --i) {
426  VERIFY_IS_EQUAL(1, block.dimensions()[i]);
427  }
428  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
429  }
430 
431  // Test shape 'SkewedInnerDims' with full allocation to all dims.
432  if (Layout == ColMajor) {
433  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
434  const Index max_coeff_count = 11 * 5 * 6 * 17 * 7;
435  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
436  TensorBlock block = block_mapper.blockDescriptor(0);
437  VERIFY_IS_EQUAL(11, block.dimensions()[0]);
438  VERIFY_IS_EQUAL(5, block.dimensions()[1]);
439  VERIFY_IS_EQUAL(6, block.dimensions()[2]);
440  VERIFY_IS_EQUAL(17, block.dimensions()[3]);
441  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
442  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
443  } else {
444  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
445  const Index max_coeff_count = 11 * 5 * 6 * 17 * 7;
446  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
447  TensorBlock block = block_mapper.blockDescriptor(0);
448  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
449  VERIFY_IS_EQUAL(17, block.dimensions()[3]);
450  VERIFY_IS_EQUAL(6, block.dimensions()[2]);
451  VERIFY_IS_EQUAL(5, block.dimensions()[1]);
452  VERIFY_IS_EQUAL(11, block.dimensions()[0]);
453  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
454  }
455 }

References block(), Eigen::ColMajor, i, VERIFY, VERIFY_IS_EQUAL, and zeroCost().

Referenced by EIGEN_DECLARE_TEST().

◆ test_uniform_block_shape()

template<int Layout>
static void test_uniform_block_shape ( )
static
210  {
211  typedef internal::TensorBlockDescriptor<5> TensorBlock;
212  typedef internal::TensorBlockMapper<5, Layout> TensorBlockMapper;
213 
214  {
215  // Test shape 'UniformAllDims' with uniform 'max_coeff count'.
216  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
217  const Index max_coeff_count = 5 * 5 * 5 * 5 * 5;
218  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
219  TensorBlock block = block_mapper.blockDescriptor(0);
220  for (int i = 0; i < 5; ++i) {
221  VERIFY_IS_EQUAL(5, block.dimensions()[i]);
222  }
223  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
224  }
225 
226  // Test shape 'UniformAllDims' with larger 'max_coeff count' which spills
227  // partially into first inner-most dimension.
228  if (Layout == ColMajor) {
229  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
230  const Index max_coeff_count = 7 * 5 * 5 * 5 * 5;
231  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
232  TensorBlock block = block_mapper.blockDescriptor(0);
233  VERIFY_IS_EQUAL(7, block.dimensions()[0]);
234  for (int i = 1; i < 5; ++i) {
235  VERIFY_IS_EQUAL(5, block.dimensions()[i]);
236  }
237  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
238  } else {
239  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
240  const Index max_coeff_count = 5 * 5 * 5 * 5 * 6;
241  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
242  TensorBlock block = block_mapper.blockDescriptor(0);
243  VERIFY_IS_EQUAL(6, block.dimensions()[4]);
244  for (int i = 3; i >= 0; --i) {
245  VERIFY_IS_EQUAL(5, block.dimensions()[i]);
246  }
247  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
248  }
249 
250  // Test shape 'UniformAllDims' with larger 'max_coeff count' which spills
251  // fully into first inner-most dimension.
252  if (Layout == ColMajor) {
253  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
254  const Index max_coeff_count = 11 * 5 * 5 * 5 * 5;
255  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
256  TensorBlock block = block_mapper.blockDescriptor(0);
257  VERIFY_IS_EQUAL(11, block.dimensions()[0]);
258  for (int i = 1; i < 5; ++i) {
259  VERIFY_IS_EQUAL(5, block.dimensions()[i]);
260  }
261  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
262  } else {
263  DSizes<Index, 5> dims(11, 5, 6, 17, 7);
264  const Index max_coeff_count = 5 * 5 * 5 * 5 * 7;
265  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
266  TensorBlock block = block_mapper.blockDescriptor(0);
267  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
268  for (int i = 3; i >= 0; --i) {
269  VERIFY_IS_EQUAL(5, block.dimensions()[i]);
270  }
271  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
272  }
273 
274  // Test shape 'UniformAllDims' with larger 'max_coeff count' which spills
275  // fully into first few inner-most dimensions.
276  if (Layout == ColMajor) {
277  DSizes<Index, 5> dims(7, 5, 6, 17, 7);
278  const Index max_coeff_count = 7 * 5 * 6 * 7 * 5;
279  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
280  TensorBlock block = block_mapper.blockDescriptor(0);
281  VERIFY_IS_EQUAL(7, block.dimensions()[0]);
282  VERIFY_IS_EQUAL(5, block.dimensions()[1]);
283  VERIFY_IS_EQUAL(6, block.dimensions()[2]);
284  VERIFY_IS_EQUAL(7, block.dimensions()[3]);
285  VERIFY_IS_EQUAL(5, block.dimensions()[4]);
286  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
287  } else {
288  DSizes<Index, 5> dims(7, 5, 6, 9, 7);
289  const Index max_coeff_count = 5 * 5 * 5 * 6 * 7;
290  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
291  TensorBlock block = block_mapper.blockDescriptor(0);
292  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
293  VERIFY_IS_EQUAL(6, block.dimensions()[3]);
294  VERIFY_IS_EQUAL(5, block.dimensions()[2]);
295  VERIFY_IS_EQUAL(5, block.dimensions()[1]);
296  VERIFY_IS_EQUAL(5, block.dimensions()[0]);
297  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
298  }
299 
300  // Test shape 'UniformAllDims' with full allocation to all dims.
301  if (Layout == ColMajor) {
302  DSizes<Index, 5> dims(7, 5, 6, 17, 7);
303  const Index max_coeff_count = 7 * 5 * 6 * 17 * 7;
304  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
305  TensorBlock block = block_mapper.blockDescriptor(0);
306  VERIFY_IS_EQUAL(7, block.dimensions()[0]);
307  VERIFY_IS_EQUAL(5, block.dimensions()[1]);
308  VERIFY_IS_EQUAL(6, block.dimensions()[2]);
309  VERIFY_IS_EQUAL(17, block.dimensions()[3]);
310  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
311  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
312  } else {
313  DSizes<Index, 5> dims(7, 5, 6, 9, 7);
314  const Index max_coeff_count = 7 * 5 * 6 * 9 * 7;
315  TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
316  TensorBlock block = block_mapper.blockDescriptor(0);
317  VERIFY_IS_EQUAL(7, block.dimensions()[4]);
318  VERIFY_IS_EQUAL(9, block.dimensions()[3]);
319  VERIFY_IS_EQUAL(6, block.dimensions()[2]);
320  VERIFY_IS_EQUAL(5, block.dimensions()[1]);
321  VERIFY_IS_EQUAL(7, block.dimensions()[0]);
322  VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
323  }
324 }

References block(), Eigen::ColMajor, i, VERIFY, VERIFY_IS_EQUAL, and zeroCost().

Referenced by EIGEN_DECLARE_TEST().

◆ UpdateCoeffSet()

template<int NumDims, int Layout>
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
100  {
101  const DSizes<Index, NumDims>& block_sizes = block.dimensions();
102 
103  for (int i = 0; i < block_sizes[dim_index]; ++i) {
104  if (tensor_strides[dim_index] == 1) {
105  typedef std::pair<std::set<Index>::iterator, bool> ReturnType;
106  ReturnType inserted = visited_coeffs->insert(first_coeff_index + i);
107  VERIFY_IS_EQUAL(inserted.second, true);
108  } else {
109  int next_dim_index = dim_index + choose(Layout, -1, 1);
110  UpdateCoeffSet<NumDims, Layout>(tensor_strides, block, first_coeff_index, next_dim_index, visited_coeffs);
111  first_coeff_index += tensor_strides[dim_index];
112  }
113  }
114 }

References block(), choose(), i, and VERIFY_IS_EQUAL.

◆ zeroCost()