Eigen-Contrib  5.0.1
 
Loading...
Searching...
No Matches
CuSparseSupport.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2026 Rasmus Munk Larsen <rmlarsen@gmail.com>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11// cuSPARSE-specific support types.
12
13#ifndef EIGEN_GPU_CUSPARSE_SUPPORT_H
14#define EIGEN_GPU_CUSPARSE_SUPPORT_H
15
16// IWYU pragma: private
17#include "./InternalHeaderCheck.h"
18
19#include "./GpuSupport.h"
20#include "./Meta.h"
21#include <cusparse.h>
22
30#if defined(CUSPARSE_VERSION) && CUSPARSE_VERSION >= 12603
31#define EIGEN_HAS_CUSPARSE_BSR 1
32#else
33#define EIGEN_HAS_CUSPARSE_BSR 0
34#endif
35
36namespace Eigen {
37namespace gpu {
38namespace internal {
39
40#define EIGEN_CUSPARSE_CHECK(x) \
41 do { \
42 const cusparseStatus_t _s = (x); \
43 if (_s != CUSPARSE_STATUS_SUCCESS) EIGEN_GPU_CHECK_FAILED(cusparseGetErrorName(_s), #x, __FILE__, __LINE__); \
44 } while (0)
45
46// cuSPARSE rejects CUSPARSE_OPERATION_CONJUGATE_TRANSPOSE for real scalar
47// types; for real Scalar, ConjTrans is mathematically equivalent to Trans and
48// is silently demoted. Complex Scalar passes through unchanged.
49template <typename Scalar>
50constexpr cusparseOperation_t to_cusparse_op(GpuOp op) {
51 const auto op_ = (op == GpuOp::ConjTrans && !NumTraits<Scalar>::IsComplex) ? GpuOp::Trans : op;
52 switch (op_) {
53 case GpuOp::Trans:
54 return CUSPARSE_OPERATION_TRANSPOSE;
55 case GpuOp::ConjTrans:
56 return CUSPARSE_OPERATION_CONJUGATE_TRANSPOSE;
57 default:
58 return CUSPARSE_OPERATION_NON_TRANSPOSE;
59 }
60}
61
62// Bind without copying when the input already has the target sparse format
63// and is compressed; otherwise convert/compress into `storage` and return
64// that. Avoids a full host copy + format conversion on the common
65// already-matching path. The SFINAE split (rather than plain overloading on
66// `const SpMatType&`) is load-bearing: an exact-match overload would bind a
67// converted temporary for other input types and return a dangling reference.
68template <typename SpMatType, typename InputType, require_same_t<SpMatType, InputType> = 0>
69const SpMatType& bind_sparse(const InputType& A, SpMatType& storage) {
70 if (A.isCompressed()) return A;
71 storage = A;
72 storage.makeCompressed();
73 return storage;
74}
75
76template <typename SpMatType, typename InputType, require_not_same_t<SpMatType, InputType> = 0>
77const SpMatType& bind_sparse(const InputType& A, SpMatType& storage) {
78 storage = A;
79 storage.makeCompressed();
80 return storage;
81}
82
83// Shared guard for the 32-bit index limits of the CUDA sparse libraries
84// (cuSPARSE, cuDSS): matrix dimensions and nonzero count must fit StorageIndex.
85template <typename StorageIndex>
86inline void check_storage_index_bounds(Index rows, Index cols, Index nnz) {
87 const Index max_storage_index = static_cast<Index>((std::numeric_limits<StorageIndex>::max)());
88 eigen_assert(rows <= max_storage_index && cols <= max_storage_index && nnz <= max_storage_index &&
89 "matrix dimensions or nonzeros exceed the index range supported by the CUDA sparse libraries");
90 EIGEN_UNUSED_VARIABLE(rows);
91 EIGEN_UNUSED_VARIABLE(cols);
92 EIGEN_UNUSED_VARIABLE(nnz);
93 EIGEN_UNUSED_VARIABLE(max_storage_index);
94}
95
96} // namespace internal
97} // namespace gpu
98} // namespace Eigen
99
100#endif // EIGEN_GPU_CUSPARSE_SUPPORT_H
Namespace containing all symbols from the Eigen library.