eigen_spatial_convolutions_test.cc
// A test case discovered when testing backward spatial convolution where the
// special tensor contraction mapper for spatial convolution contains a bug.

A test case discovered when testing backward spatial convolution where the
special tensor contraction mapper for spatial convolution contains a bug.
A test case discovered when testing backward spatial convolution where the special tensor contraction mapper for spatial convolution contains a bug .
TEST(EigenSpatialConvolutionsTest, SpatialConvContractionMapper) {
  typedef Tensor<float, 1>::DimensionPair DimPair;
  Tensor<float, 4> out(1, 1, 2, 1);
  Tensor<float, 4> kern(1, 1, 2, 2);
  for (int i = 0; i < kern.size(); ++i) {
    kern.coeffRef(i) = static_cast<float>(i) + 1;
  }
  for (int i = 0; i < out.size(); ++i) {
    out.coeffRef(i) = static_cast<float>(i) + 1;
  }
  DSizes<ptrdiff_t, 4> strides;
  strides[0] = 1;
  strides[1] = 2;
  strides[2] = 2;
  strides[3] = 1;
  array<std::pair<ptrdiff_t, ptrdiff_t>, 4> paddings;
  paddings[0] = std::make_pair(0, 0);
  paddings[1] = std::make_pair(1, 2);
  paddings[2] = std::make_pair(1, 1);
  paddings[3] = std::make_pair(0, 0);
  DSizes<ptrdiff_t, 3> out_dim;
  out_dim[0] = 1;
  out_dim[1] = 4;
  out_dim[2] = 12;
  array<bool, 4> kernel_reverse;
  kernel_reverse[0] = false;
  kernel_reverse[1] = false;
  kernel_reverse[2] = true;
  kernel_reverse[3] = true;
  DSizes<ptrdiff_t, 3> k_dims;
  k_dims[0] = 1;
  k_dims[1] = 1;
  k_dims[2] = 4;
  array<DimPair, 2> contract_dims;
  contract_dims[0] = DimPair(0, 0);
  contract_dims[1] = DimPair(2, 1);
  DSizes<ptrdiff_t, 4> in_dim;
  in_dim[0] = 1;
  in_dim[1] = 3;
  in_dim[2] = 4;
  in_dim[3] = 1;
  DSizes<ptrdiff_t, 2> in_dbg_dim;
  in_dbg_dim[0] = 3;
  in_dbg_dim[1] = 4;
  DSizes<ptrdiff_t, 2> out_dbg_dim;
  out_dbg_dim[0] = 4;
  out_dbg_dim[1] = 12;
  Tensor<float, 4> direct =
      kern.reverse(kernel_reverse)
          .reshape(k_dims)
          .contract(
              out.extract_image_patches(2, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 0)
                  .reshape(out_dim),
              contract_dims)
          .reshape(in_dim);
  Tensor<float, 4> indirect =
      kern.reverse(kernel_reverse)
          .reshape(k_dims)
          .contract(
              out.inflate(strides)
                  .pad(paddings)
                  .extract_image_patches(2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0)
                  .reshape(out_dim),
              contract_dims)
          .reshape(in_dim);
  eigen_assert(dimensions_match(direct.dimensions(), indirect.dimensions()));
  for (size_t i = 0; i < direct.dimensions().TotalSize(); ++i) {
    EigenApprox(direct.data()[i], indirect.data()[i]);
  }
  EigenApprox(1.0f, direct(0, 0, 0, 0));
  EigenApprox(3.0f, direct(0, 0, 1, 0));
  EigenApprox(2.0f, direct(0, 0, 2, 0));
  EigenApprox(6.0f, direct(0, 0, 3, 0));
  EigenApprox(2.0f, direct(0, 1, 0, 0));
  EigenApprox(4.0f, direct(0, 1, 1, 0));
  EigenApprox(4.0f, direct(0, 1, 2, 0));
  EigenApprox(8.0f, direct(0, 1, 3, 0));
}
TEST ( EigenSpatialConvolutionsTest , SpatialConvContractionMapper ) { typedef Tensor < float , 1 > :: DimensionPair DimPair ; Tensor < float , 4 > out ( 1 , 1 , 2 , 1 ) ; Tensor < float , 4 > kern ( 1 , 1 , 2 , 2 ) ; for ( int i = 0 ; i < kern . size ( ) ; ++ i ) { kern . coeffRef ( i ) = static_cast < float > ( i ) + 1 ; } for ( int i = 0 ; i < out . size ( ) ; ++ i ) { out . coeffRef ( i ) = static_cast < float > ( i ) + 1 ; } DSizes < ptrdiff_t , 4 > strides ; strides [ 0 ] = 1 ; strides [ 1 ] = 2 ; strides [ 2 ] = 2 ; strides [ 3 ] = 1 ; array < std :: pair < ptrdiff_t , ptrdiff_t > , 4 > paddings ; paddings [ 0 ] = std :: make_pair ( 0 , 0 ) ; paddings [ 1 ] = std :: make_pair ( 1 , 2 ) ; paddings [ 2 ] = std :: make_pair ( 1 , 1 ) ; paddings [ 3 ] = std :: make_pair ( 0 , 0 ) ; DSizes < ptrdiff_t , 3 > out_dim ; out_dim [ 0 ] = 1 ; out_dim [ 1 ] = 4 ; out_dim [ 2 ] = 12 ; array < bool , 4 > kernel_reverse ; kernel_reverse [ 0 ] = false ; kernel_reverse [ 1 ] = false ; kernel_reverse [ 2 ] = true ; kernel_reverse [ 3 ] = true ; DSizes < ptrdiff_t , 3 > k_dims ; k_dims [ 0 ] = 1 ; k_dims [ 1 ] = 1 ; k_dims [ 2 ] = 4 ; array < DimPair , 2 > contract_dims ; contract_dims [ 0 ] = DimPair ( 0 , 0 ) ; contract_dims [ 1 ] = DimPair ( 2 , 1 ) ; DSizes < ptrdiff_t , 4 > in_dim ; in_dim [ 0 ] = 1 ; in_dim [ 1 ] = 3 ; in_dim [ 2 ] = 4 ; in_dim [ 3 ] = 1 ; DSizes < ptrdiff_t , 2 > in_dbg_dim ; in_dbg_dim [ 0 ] = 3 ; in_dbg_dim [ 1 ] = 4 ; DSizes < ptrdiff_t , 2 > out_dbg_dim ; out_dbg_dim [ 0 ] = 4 ; out_dbg_dim [ 1 ] = 12 ; Tensor < float , 4 > direct = kern . reverse ( kernel_reverse ) . reshape ( k_dims ) . contract ( out . extract_image_patches ( 2 , 2 , 1 , 1 , 1 , 1 , 2 , 2 , 1 , 2 , 1 , 1 , 0 ) . reshape ( out_dim ) , contract_dims ) . reshape ( in_dim ) ; Tensor < float , 4 > indirect = kern . reverse ( kernel_reverse ) . reshape ( k_dims ) . contract ( out . inflate ( strides ) . pad ( paddings ) . extract_image_patches ( 2 , 2 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 ) . reshape ( out_dim ) , contract_dims ) . reshape ( in_dim ) ; eigen_assert ( dimensions_match ( direct . dimensions ( ) , indirect . dimensions ( ) ) ) ; for ( size_t i = 0 ; i < direct . dimensions ( ) . TotalSize ( ) ; ++ i ) { EigenApprox ( direct . data ( ) [ i ] , indirect . data ( ) [ i ] ) ; } EigenApprox ( 1.0f , direct ( 0 , 0 , 0 , 0 ) ) ; EigenApprox ( 3.0f , direct ( 0 , 0 , 1 , 0 ) ) ; EigenApprox ( 2.0f , direct ( 0 , 0 , 2 , 0 ) ) ; EigenApprox ( 6.0f , direct ( 0 , 0 , 3 , 0 ) ) ; EigenApprox ( 2.0f , direct ( 0 , 1 , 0 , 0 ) ) ; EigenApprox ( 4.0f , direct ( 0 , 1 , 1 , 0 ) ) ; EigenApprox ( 4.0f , direct ( 0 , 1 , 2 , 0 ) ) ; EigenApprox ( 8.0f , direct ( 0 , 1 , 3 , 0 ) ) ; }
A test case discovered when testing backward spatial convolution where the
special tensor contraction mapper for spatial convolution contains a bug.
A test case discovered when testing backward spatial convolution where the special tensor contraction mapper for spatial convolution contains a bug .
// We have a 3x4 input image with 2x2 patch and stride of 2.
 // The output has size 1x2.
 // This is the formula for computing the backward prop for input with a
 // spatial convolution.
