mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 08:34:37 +08:00
Bugfix to CUDA workspace handling
* Fix workspace type in CUDADenseQR and CUDADenseCholesky -- Workspace sizes are in terms of number of elements, not bytes. * Add cuda-memcheck tests to catch such CUDA memory errors in the future. Change-Id: I3dd0f0947daba9e4c6cd0216bef81d694547d505
This commit is contained in:
committed by
Sameer Agarwal
parent
779634164d
commit
f59059fffb
@@ -136,6 +136,14 @@ if (CUDA_FOUND)
|
||||
${CUDA_cublas_LIBRARY}
|
||||
${CUDA_cusolver_LIBRARY}
|
||||
${CUDA_cusparse_LIBRARY})
|
||||
add_test(
|
||||
NAME cuda_memcheck_dense_qr_test
|
||||
COMMAND cuda-memcheck --leak-check full
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cuda_dense_qr_test)
|
||||
add_test(
|
||||
NAME cuda_memcheck_dense_cholesky_test
|
||||
COMMAND cuda-memcheck --leak-check full
|
||||
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cuda_dense_cholesky_test)
|
||||
endif (CUDA_FOUND)
|
||||
|
||||
if (LAPACK_FOUND)
|
||||
|
||||
@@ -128,6 +128,48 @@ TEST(CUDADenseCholesky, MustFactorizeBeforeSolve) {
|
||||
LinearSolverTerminationType::LINEAR_SOLVER_FATAL_ERROR);
|
||||
}
|
||||
|
||||
TEST(CUDADenseCholesky, Randomized1600x1600Tests) {
|
||||
const int kNumCols = 1600;
|
||||
using LhsType = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using RhsType = Eigen::Matrix<double, Eigen::Dynamic, 1>;
|
||||
using SolutionType = Eigen::Matrix<double, Eigen::Dynamic, 1>;
|
||||
|
||||
LinearSolver::Options options;
|
||||
ContextImpl context;
|
||||
options.context = &context;
|
||||
options.dense_linear_algebra_library_type = ceres::CUDA;
|
||||
std::unique_ptr<DenseCholesky> dense_cholesky = CUDADenseCholesky::Create(options);
|
||||
|
||||
const int kNumTrials = 20;
|
||||
for (int i = 0; i < kNumTrials; ++i) {
|
||||
LhsType lhs = LhsType::Random(kNumCols, kNumCols);
|
||||
lhs = lhs.transpose() * lhs;
|
||||
lhs += 1e-3 * LhsType::Identity(kNumCols, kNumCols);
|
||||
SolutionType x_expected = SolutionType::Random(kNumCols);
|
||||
RhsType rhs = lhs * x_expected;
|
||||
SolutionType x_computed = SolutionType::Zero(kNumCols);
|
||||
// Sanity check the random matrix sizes.
|
||||
EXPECT_EQ(lhs.rows(), kNumCols);
|
||||
EXPECT_EQ(lhs.cols(), kNumCols);
|
||||
EXPECT_EQ(rhs.rows(), kNumCols);
|
||||
EXPECT_EQ(rhs.cols(), 1);
|
||||
EXPECT_EQ(x_expected.rows(), kNumCols);
|
||||
EXPECT_EQ(x_expected.cols(), 1);
|
||||
EXPECT_EQ(x_computed.rows(), kNumCols);
|
||||
EXPECT_EQ(x_computed.cols(), 1);
|
||||
LinearSolver::Summary summary;
|
||||
summary.termination_type = dense_cholesky->FactorAndSolve(kNumCols,
|
||||
lhs.data(),
|
||||
rhs.data(),
|
||||
x_computed.data(),
|
||||
&summary.message);
|
||||
ASSERT_EQ(summary.termination_type, LINEAR_SOLVER_SUCCESS);
|
||||
ASSERT_NEAR((x_computed - x_expected).norm() / x_expected.norm(),
|
||||
0.0,
|
||||
1e-10);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CERES_NO_CUDA
|
||||
|
||||
} // namespace internal
|
||||
|
||||
@@ -135,10 +135,6 @@ TEST(CUDADenseQR, Randomized1600x100Tests) {
|
||||
std::unique_ptr<DenseQR> dense_qr = CUDADenseQR::Create(options);
|
||||
|
||||
const int kNumTrials = 100;
|
||||
const int kMinNumCols = 1;
|
||||
const int kMaxNumCols = 10;
|
||||
const int kMinRowsFactor = 1;
|
||||
const int kMaxRowsFactor = 3;
|
||||
for (int i = 0; i < kNumTrials; ++i) {
|
||||
LhsType lhs = LhsType::Random(kNumRows, kNumCols);
|
||||
SolutionType x_expected = SolutionType::Random(kNumCols);
|
||||
|
||||
@@ -167,7 +167,7 @@ class CERES_NO_EXPORT CUDADenseCholesky final : public DenseCholesky {
|
||||
// GPU memory allocated for the B matrix (rhs vector).
|
||||
CudaBuffer<double> rhs_;
|
||||
// Scratch space for cuSOLVER on the GPU.
|
||||
CudaBuffer<uint8_t> device_workspace_;
|
||||
CudaBuffer<double> device_workspace_;
|
||||
// Required for error handling with cuSOLVER.
|
||||
CudaBuffer<int> error_;
|
||||
// Cache the result of Factorize to ensure that when Solve is called, the
|
||||
|
||||
@@ -189,7 +189,7 @@ class CERES_NO_EXPORT CUDADenseQR final : public DenseQR {
|
||||
// GPU memory allocated for the TAU matrix (scaling of householder vectors).
|
||||
CudaBuffer<double> tau_;
|
||||
// Scratch space for cuSOLVER on the GPU.
|
||||
CudaBuffer<uint8_t> device_workspace_;
|
||||
CudaBuffer<double> device_workspace_;
|
||||
// Required for error handling with cuSOLVER.
|
||||
CudaBuffer<int> error_;
|
||||
// Cache the result of Factorize to ensure that when Solve is called, the
|
||||
|
||||
Reference in New Issue
Block a user