未验证 提交 b6eb37f5 编写于 作者: S ShenLiang 提交者: GitHub

add error message for cholesky (#26444)

* add error message
上级 138ecf24
...@@ -63,7 +63,6 @@ class CholeskyGPUKernel : public framework::OpKernel<T> { ...@@ -63,7 +63,6 @@ class CholeskyGPUKernel : public framework::OpKernel<T> {
for_range(matrix_band_part_functor); for_range(matrix_band_part_functor);
} }
// TODO(guosheng): Add callback to check info
auto info = memory::Alloc(dev_ctx, sizeof(int) * batch_count); auto info = memory::Alloc(dev_ctx, sizeof(int) * batch_count);
auto* info_ptr = reinterpret_cast<int*>(info->ptr()); auto* info_ptr = reinterpret_cast<int*>(info->ptr());
...@@ -96,6 +95,20 @@ class CholeskyGPUKernel : public framework::OpKernel<T> { ...@@ -96,6 +95,20 @@ class CholeskyGPUKernel : public framework::OpKernel<T> {
#if CUDA_VERSION >= 9020 && !defined(_WIN32) #if CUDA_VERSION >= 9020 && !defined(_WIN32)
} }
#endif #endif
// check the info
std::vector<int> error_info; // only for checking positive matrix
error_info.resize(batch_count);
memory::Copy(platform::CPUPlace(), error_info.data(),
BOOST_GET_CONST(platform::CUDAPlace, dev_ctx.GetPlace()),
info_ptr, sizeof(int) * batch_count, dev_ctx.stream());
for (int i = 0; i < batch_count; ++i) {
PADDLE_ENFORCE_EQ(error_info[i], 0,
platform::errors::PreconditionNotMet(
"For batch [%d]: U(%d, %d) is zero, singular U.", i,
error_info[i], error_info[i]));
}
} }
void Potrf(const platform::CUDADeviceContext& dev_ctx, cublasFillMode_t uplo, void Potrf(const platform::CUDADeviceContext& dev_ctx, cublasFillMode_t uplo,
......
...@@ -59,22 +59,24 @@ class CholeskyCPUKernel : public framework::OpKernel<T> { ...@@ -59,22 +59,24 @@ class CholeskyCPUKernel : public framework::OpKernel<T> {
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>,
Eigen::UpLoType::Upper> Eigen::UpLoType::Upper>
llt_decomposition(input); llt_decomposition(input);
PADDLE_ENFORCE_EQ( PADDLE_ENFORCE_EQ(llt_decomposition.info(), Eigen::Success,
llt_decomposition.info(), Eigen::Success, platform::errors::InvalidArgument(
platform::errors::InvalidArgument( "Cholesky decomposition was not successful. The "
"Cholesky decomposition was not successful. The input matrice " "%d-th input matrice "
"might not be not be positive definite.")); "might not be not be positive definite.",
i));
output = llt_decomposition.matrixU(); output = llt_decomposition.matrixU();
} else { } else {
Eigen::LLT< Eigen::LLT<
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>,
Eigen::UpLoType::Lower> Eigen::UpLoType::Lower>
llt_decomposition(input); llt_decomposition(input);
PADDLE_ENFORCE_EQ( PADDLE_ENFORCE_EQ(llt_decomposition.info(), Eigen::Success,
llt_decomposition.info(), Eigen::Success, platform::errors::InvalidArgument(
platform::errors::InvalidArgument( "Cholesky decomposition was not successful. The "
"Cholesky decomposition was not successful. The input matrice " "%d-th input matrice "
"might not be not be positive definite.")); "might not be not be positive definite.",
i));
output = llt_decomposition.matrixL(); output = llt_decomposition.matrixL();
} }
} }
......
...@@ -100,5 +100,45 @@ class TestDygraph(unittest.TestCase): ...@@ -100,5 +100,45 @@ class TestDygraph(unittest.TestCase):
out = paddle.cholesky(x, upper=False) out = paddle.cholesky(x, upper=False)
class TestCholeskySingularAPI(unittest.TestCase):
def setUp(self):
self.places = [fluid.CPUPlace()]
if core.is_compiled_with_cuda():
self.places.append(fluid.CUDAPlace(0))
def check_static_result(self, place, with_out=False):
with fluid.program_guard(fluid.Program(), fluid.Program()):
input = fluid.data(name="input", shape=[4, 4], dtype="float64")
result = paddle.cholesky(input)
input_np = np.zeros([4, 4]).astype("float64")
exe = fluid.Executor(place)
try:
fetches = exe.run(fluid.default_main_program(),
feed={"input": input_np},
fetch_list=[result])
except fluid.core.EnforceNotMet as ex:
print("The mat is singular")
pass
def test_static(self):
for place in self.places:
self.check_static_result(place=place)
def test_dygraph(self):
for place in self.places:
with fluid.dygraph.guard(place):
input_np = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
[[10, 11, 12], [13, 14, 15],
[16, 17, 18]]]).astype("float64")
input = fluid.dygraph.to_variable(input_np)
try:
result = paddle.cholesky(input)
except fluid.core.EnforceNotMet as ex:
print("The mat is singular")
pass
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册