mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-21 07:19:46 +08:00
Don't crash when attempting to slice an empty tensor.
This commit is contained in:
parent
113e61f364
commit
f284c8592b
@ -451,6 +451,7 @@ struct TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Devi
|
||||
}
|
||||
|
||||
m_is_identity = true;
|
||||
bool degenerate = false;
|
||||
for (int i = 0; i < internal::array_size<Dimensions>::value; ++i) {
|
||||
eigen_assert(m_impl.dimensions()[i] >=
|
||||
op.sizes()[i] + op.startIndices()[i]);
|
||||
@ -458,6 +459,9 @@ struct TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Devi
|
||||
op.startIndices()[i] != 0) {
|
||||
m_is_identity = false;
|
||||
}
|
||||
if (op.sizes()[i] == 0) { // we have an empty size
|
||||
degenerate = true;
|
||||
}
|
||||
}
|
||||
|
||||
// No strides for scalars.
|
||||
@ -475,8 +479,8 @@ struct TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Devi
|
||||
m_outputStrides[0] = 1;
|
||||
for (int i = 1; i < NumDims; ++i) {
|
||||
m_outputStrides[i] = m_outputStrides[i-1] * output_dims[i-1];
|
||||
m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]);
|
||||
}
|
||||
// NOTE: if tensor is degenerate, we send 1 to prevent TensorIntDivisor constructor crash
|
||||
m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(degenerate ? 1 : m_outputStrides[i]); }
|
||||
} else {
|
||||
m_inputStrides[NumDims-1] = 1;
|
||||
for (int i = NumDims - 2; i >= 0; --i) {
|
||||
@ -487,8 +491,8 @@ struct TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Devi
|
||||
m_outputStrides[NumDims-1] = 1;
|
||||
for (int i = NumDims - 2; i >= 0; --i) {
|
||||
m_outputStrides[i] = m_outputStrides[i+1] * output_dims[i+1];
|
||||
m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]);
|
||||
}
|
||||
// NOTE: if tensor is degenerate, we send 1 to prevent TensorIntDivisor constructor crash
|
||||
m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(degenerate ? 1 : m_outputStrides[i]); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,6 +479,66 @@ static void test_composition()
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, int DataLayout>
|
||||
static void test_empty_slice()
|
||||
{
|
||||
Tensor<T, 3, DataLayout> tensor(2,3,5);
|
||||
tensor.setRandom();
|
||||
Tensor<T, 3, DataLayout> copy = tensor;
|
||||
|
||||
// empty size in first dimension
|
||||
Eigen::DSizes<ptrdiff_t, 3> indices1(1,2,3);
|
||||
Eigen::DSizes<ptrdiff_t, 3> sizes1(0,1,2);
|
||||
Tensor<T, 3, DataLayout> slice1(0,1,2);
|
||||
slice1.setRandom();
|
||||
tensor.slice(indices1, sizes1) = slice1;
|
||||
|
||||
// empty size in second dimension
|
||||
Eigen::DSizes<ptrdiff_t, 3> indices2(1,2,3);
|
||||
Eigen::DSizes<ptrdiff_t, 3> sizes2(1,0,2);
|
||||
Tensor<T, 3, DataLayout> slice2(1,0,2);
|
||||
slice2.setRandom();
|
||||
tensor.slice(indices2, sizes2) = slice2;
|
||||
|
||||
// empty size in third dimension
|
||||
Eigen::DSizes<ptrdiff_t, 3> indices3(1,2,3);
|
||||
Eigen::DSizes<ptrdiff_t, 3> sizes3(1,1,0);
|
||||
Tensor<T, 3, DataLayout> slice3(1,1,0);
|
||||
slice3.setRandom();
|
||||
tensor.slice(indices3, sizes3) = slice3;
|
||||
|
||||
// empty size in first and second dimension
|
||||
Eigen::DSizes<ptrdiff_t, 3> indices4(1,2,3);
|
||||
Eigen::DSizes<ptrdiff_t, 3> sizes4(0,0,2);
|
||||
Tensor<T, 3, DataLayout> slice4(0,0,2);
|
||||
slice4.setRandom();
|
||||
tensor.slice(indices4, sizes4) = slice4;
|
||||
|
||||
// empty size in second and third dimension
|
||||
Eigen::DSizes<ptrdiff_t, 3> indices5(1,2,3);
|
||||
Eigen::DSizes<ptrdiff_t, 3> sizes5(1,0,0);
|
||||
Tensor<T, 3, DataLayout> slice5(1,0,0);
|
||||
slice5.setRandom();
|
||||
tensor.slice(indices5, sizes5) = slice5;
|
||||
|
||||
// empty size in all dimensions
|
||||
Eigen::DSizes<ptrdiff_t, 3> indices6(1,2,3);
|
||||
Eigen::DSizes<ptrdiff_t, 3> sizes6(0,0,0);
|
||||
Tensor<T, 3, DataLayout> slice6(0,0,0);
|
||||
slice6.setRandom();
|
||||
tensor.slice(indices6, sizes6) = slice6;
|
||||
|
||||
// none of these operations should change the tensor's components
|
||||
// because all of the rvalue slices have at least one zero dimension
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
for (int k = 0; k < 5; ++k) {
|
||||
VERIFY_IS_EQUAL(tensor(i,j,k), copy(i,j,k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define CALL_SUBTEST_PART(PART) \
|
||||
CALL_SUBTEST_##PART
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user