CUDA SDK Version-based SpMV Selection

* The algorithm enum value for SpMV is now selected based on the
  version of the CUDA runtime that Ceres is compiled against.

Change-Id: I2e0e39f1cbdb8ac26d2a9d45f4ebfc09b96d872b
diff --git a/internal/ceres/cuda_sparse_matrix.cc b/internal/ceres/cuda_sparse_matrix.cc
index 1d8d0b0..a3ed019 100644
--- a/internal/ceres/cuda_sparse_matrix.cc
+++ b/internal/ceres/cuda_sparse_matrix.cc
@@ -54,6 +54,7 @@
 #include "ceres/cuda_buffer.h"
 #include "ceres/cuda_kernels.h"
 #include "ceres/cuda_vector.h"
+#include "cuda_runtime_api.h"
 #include "cusparse.h"
 
 namespace ceres::internal {
@@ -105,6 +106,14 @@
   const double alpha = 1.0;
   const double beta = 1.0;
 
+  // Starting in CUDA 11.2.1, CUSPARSE_MV_ALG_DEFAULT was deprecated in favor of
+  // CUSPARSE_SPMV_ALG_DEFAULT.
+#if CUDART_VERSION >= 11021
+  const auto algorithm = CUSPARSE_SPMV_ALG_DEFAULT;
+#else  // CUDART_VERSION >= 11021
+  const auto algorithm = CUSPARSE_MV_ALG_DEFAULT;
+#endif  // CUDART_VERSION >= 11021
+
   CHECK_EQ(cusparseSpMV_bufferSize(context_->cusparse_handle_,
                                    op,
                                    &alpha,
@@ -113,7 +122,7 @@
                                    &beta,
                                    y->descr(),
                                    CUDA_R_64F,
-                                   CUSPARSE_SPMV_ALG_DEFAULT,
+                                   algorithm,
                                    &buffer_size),
            CUSPARSE_STATUS_SUCCESS);
   spmv_buffer_.Reserve(buffer_size);
@@ -125,7 +134,7 @@
                         &beta,
                         y->descr(),
                         CUDA_R_64F,
-                        CUSPARSE_SPMV_ALG_DEFAULT,
+                        algorithm,
                         spmv_buffer_.data()),
            CUSPARSE_STATUS_SUCCESS);
 }