CUDA CGNR, Part 4: CudaCgnrSolver

* Added CudaCgnrSolver, a new CUDA-accelerated CGNR.
* To use CudaCgnrSolver, the user must select CGNR as the linear_solver
  and CUDA_SPARSE as the sparse_linear_algebra_library.
* Updated ConjugateGradientSolver to work with an array of pointers to
  scratch to support CudaVectors as scratch.
* Moved CUDA initialization to run in Solver::Solve as needed.

Some performance comparisons on an Ubuntu 20.04 desktop with an
Intel i9-9940X CPU @ 3.30GHz, and an nVidia Quadro RTX 6000,
all configurations run with 24 threads, and 10 iterations.

=================================================
CGNR + CUDA_SPARSE + IDENTITY Preconditioner
problem-1778-993923-pre.txt
=================================================
Cost:
Initial                          2.563973e+08
Final                            1.724755e+06
Change                           2.546725e+08

Minimizer iterations                       11
Successful steps                            7
Unsuccessful steps                          4

Time (in seconds):
Preprocessor                         4.020158

  Residual only evaluation           1.567092 (10)
  Jacobian & residual evaluation     7.847130 (7)
  Linear solver                     31.688898 (10)
Minimizer                           46.834987

Postprocessor                        0.353974
Total                               51.209120

=================================================
SPARSE_SCHUR (CPU) + SUITE_SPARSE + AMD
problem-1778-993923-pre.txt
=================================================
Cost:
Initial                          2.563973e+08
Final                            1.651617e+06
Change                           2.547457e+08

Minimizer iterations                       11
Successful steps                           11
Unsuccessful steps                          0

Time (in seconds):
Preprocessor                        35.812003

  Residual only evaluation           1.658980 (10)
  Jacobian & residual evaluation    12.218799 (11)
  Linear solver                     76.409992 (10)
Minimizer                           98.809773

Postprocessor                        0.372712
Total                              134.994489

=================================================
ITERATIVE_SCHUR (CPU) + JACOBI Preconditioner
problem-1778-993923-pre.txt
=================================================
Cost:
Initial                          2.563973e+08
Final                            1.684447e+06
Change                           2.547128e+08

Minimizer iterations                       11
Successful steps                            8
Unsuccessful steps                          3

Time (in seconds):
Preprocessor                        15.331614

  Residual only evaluation           1.606114 (10)
  Jacobian & residual evaluation     8.502166 (8)
  Linear solver                    351.910080 (10)
Minimizer                          368.797327

Postprocessor                        0.363536
Total                              384.492478

=================================================
CGNR + CUDA_SPARSE + IDENTITY Preconditioner
problem-13682-4456117-pre.txt
=================================================
Cost:
Initial                          1.126372e+09
Final                            2.269329e+07
Change                           1.103678e+09

Minimizer iterations                       11
Successful steps                            7
Unsuccessful steps                          4

Time (in seconds):
Preprocessor                        19.140087

  Residual only evaluation           8.721920 (10)
  Jacobian & residual evaluation    41.955923 (7)
  Linear solver                    214.121861 (10)
Minimizer                          296.636890

Postprocessor                        1.971827
Total                              317.748804

Change-Id: I3a09f31aa6903f661e91f595afd39d427583e856
This commit is contained in:
Joydeep Biswas
2022-08-14 19:14:04 -05:00
parent 6ab435d774
commit 829089053e
21 changed files with 413 additions and 59 deletions
+34 -1
View File
@@ -33,6 +33,8 @@
#include <memory>
#include "ceres/cuda_sparse_matrix.h"
#include "ceres/cuda_vector.h"
#include "ceres/internal/export.h"
#include "ceres/linear_solver.h"
@@ -65,9 +67,40 @@ class CERES_NO_EXPORT CgnrSolver final : public BlockSparseMatrixSolver {
const LinearSolver::Options options_;
std::unique_ptr<Preconditioner> preconditioner_;
Vector cg_solution_;
Vector scratch_[4];
Vector* scratch_[4] = {nullptr, nullptr, nullptr, nullptr};
};
#ifndef CERES_NO_CUDA
// A Cuda-accelerated version of CgnrSolver.
// This solver assumes that the sparsity structure of A remains constant for its
// lifetime.
class CERES_NO_EXPORT CudaCgnrSolver final : public CompressedRowSparseMatrixSolver {
public:
explicit CudaCgnrSolver(LinearSolver::Options options);
static std::unique_ptr<CudaCgnrSolver> Create(
LinearSolver::Options options, std::string* error);
~CudaCgnrSolver() override;
Summary SolveImpl(CompressedRowSparseMatrix* A,
const double* b,
const LinearSolver::PerSolveOptions& per_solve_options,
double* x) final;
private:
void CpuToGpuTransfer(
const CompressedRowSparseMatrix& A, const double* b, const double* D);
LinearSolver::Options options_;
std::unique_ptr<CudaSparseMatrix> A_;
std::unique_ptr<CudaVector> b_;
std::unique_ptr<CudaVector> x_;
std::unique_ptr<CudaVector> Atb_;
std::unique_ptr<CudaVector> Ax_;
std::unique_ptr<CudaVector> D_;
CudaVector* scratch_[4] = {nullptr, nullptr, nullptr, nullptr};
};
#endif // CERES_NO_CUDA
} // namespace ceres::internal
#endif // CERES_INTERNAL_CGNR_SOLVER_H_