Skip to main content

singe_cusolver/
types.rs

1#[allow(unused_imports)]
2use crate::irs::xgesv;
3
4use num_enum::{IntoPrimitive, TryFromPrimitive};
5use singe_core::{impl_enum_conversion, impl_enum_display};
6use singe_cuda::data_type::DataType;
7use singe_cusolver_sys as sys;
8
9/// Selects the generalized eigenvalue problem type.
10///
11/// This corresponds to LAPACK integer `1` (`A*x = lambda*B*x`), `2`
12/// (`A*B*x = lambda*x`), and `3` (`B*A*x = lambda*x`) arguments.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
14#[repr(u32)]
15#[non_exhaustive]
16pub enum EigenType {
17    /// A\*x = lambda\*B\*x.
18    Type1 = sys::cusolverEigType_t::CUSOLVER_EIG_TYPE_1 as _,
19    /// A\*B\*x = lambda\*x.
20    Type2 = sys::cusolverEigType_t::CUSOLVER_EIG_TYPE_2 as _,
21    /// B\*A\*x = lambda\*x.
22    Type3 = sys::cusolverEigType_t::CUSOLVER_EIG_TYPE_3 as _,
23}
24
25impl_enum_conversion!(sys::cusolverEigType_t, EigenType);
26
27/// Selects whether to compute eigenvectors.
28///
29/// This corresponds to LAPACK `N` (eigenvalues only) and `V` (eigenvalues and
30/// eigenvectors) arguments.
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
32#[repr(u32)]
33#[non_exhaustive]
34pub enum EigenMode {
35    /// Compute only eigenvalues.
36    NoVector = sys::cusolverEigMode_t::CUSOLVER_EIG_MODE_NOVECTOR as _,
37    /// Compute both eigenvalues and eigenvectors.
38    Vector = sys::cusolverEigMode_t::CUSOLVER_EIG_MODE_VECTOR as _,
39}
40
41impl_enum_conversion!(sys::cusolverEigMode_t, EigenMode);
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
44#[repr(u32)]
45#[non_exhaustive]
46pub enum EigenRange {
47    All = sys::cusolverEigRange_t::CUSOLVER_EIG_RANGE_ALL as _,
48    Index = sys::cusolverEigRange_t::CUSOLVER_EIG_RANGE_I as _,
49    Value = sys::cusolverEigRange_t::CUSOLVER_EIG_RANGE_V as _,
50}
51
52impl_enum_conversion!(sys::cusolverEigRange_t, EigenRange);
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
55#[repr(u32)]
56#[non_exhaustive]
57pub enum Norm {
58    Infinity = sys::cusolverNorm_t::CUSOLVER_INF_NORM as _,
59    Maximum = sys::cusolverNorm_t::CUSOLVER_MAX_NORM as _,
60    One = sys::cusolverNorm_t::CUSOLVER_ONE_NORM as _,
61    Frobenius = sys::cusolverNorm_t::CUSOLVER_FRO_NORM as _,
62}
63
64impl_enum_conversion!(sys::cusolverNorm_t, Norm);
65
66/// Indicates which IRS refinement solver to use for a cuSOLVER operation.
67/// Empirically, [`IrsRefinement::Gmres`] is often the best option.
68///
69/// More details about the refinement process are available in Azzam Haidar,
70/// Stanimire Tomov, Jack Dongarra, and Nicholas J. Higham, "Harnessing GPU
71/// tensor cores for fast FP16 arithmetic to speed up mixed-precision iterative
72/// refinement solvers," SC '18.
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
74#[repr(u32)]
75#[non_exhaustive]
76pub enum IrsRefinement {
77    /// Solver is not set; this value is what is set when creating the `params` structure.
78    /// The IRS solver returns an error if this value is used.
79    NotSet = sys::cusolverIRSRefinement_t::CUSOLVER_IRS_REFINE_NOT_SET as _,
80    /// No refinement solver; the IRS solver performs a factorization followed by a solve without any refinement.
81    /// For example, when used with [`xgesv`], this matches the non-refined solver path with the factorization carried out in the lowest precision.
82    /// If both the main and lowest precision are [`PrecisionType::R64F`], this is equivalent to solving entirely in `f64`.
83    None = sys::cusolverIRSRefinement_t::CUSOLVER_IRS_REFINE_NONE as _,
84    /// Classical iterative refinement solver.
85    /// Similar to the value used in LAPACK operations.
86    Classical = sys::cusolverIRSRefinement_t::CUSOLVER_IRS_REFINE_CLASSICAL as _,
87    /// Classical iterative refinement solver that uses the GMRES (Generalized Minimal Residual) internally to solve the correction equation at each iteration.
88    /// The classical refinement iteration is the outer iteration, and GMRES is the inner iteration.
89    /// If the tolerance of the inner GMRES is very low, for example near machine precision, the outer *classical refinement iteration* performs only one iteration and this option behaves like [`IrsRefinement::Gmres`].
90    ClassicalGmres = sys::cusolverIRSRefinement_t::CUSOLVER_IRS_REFINE_CLASSICAL_GMRES as _,
91    /// GMRES (Generalized Minimal Residual) based iterative refinement solver.
92    /// Recent studies use GMRES as a refinement solver that can outperform classical iterative refinement.
93    /// Recommended setting based on cuSOLVER experimentation.
94    Gmres = sys::cusolverIRSRefinement_t::CUSOLVER_IRS_REFINE_GMRES as _,
95    /// GMRES-based iterative refinement solver that uses another GMRES solve internally for the preconditioned system.
96    GmresGmres = sys::cusolverIRSRefinement_t::CUSOLVER_IRS_REFINE_GMRES_GMRES as _,
97    GmresNoPcond = sys::cusolverIRSRefinement_t::CUSOLVER_IRS_REFINE_GMRES_NOPCOND as _,
98    PrecDd = sys::cusolverIRSRefinement_t::CUSOLVER_PREC_DD as _,
99    PrecSs = sys::cusolverIRSRefinement_t::CUSOLVER_PREC_SS as _,
100    PrecSht = sys::cusolverIRSRefinement_t::CUSOLVER_PREC_SHT as _,
101}
102
103impl_enum_conversion!(sys::cusolverIRSRefinement_t, IrsRefinement);
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
106#[repr(u32)]
107#[non_exhaustive]
108pub enum PrecisionType {
109    R8I = sys::cusolverPrecType_t::CUSOLVER_R_8I as _,
110    R8U = sys::cusolverPrecType_t::CUSOLVER_R_8U as _,
111    R64F = sys::cusolverPrecType_t::CUSOLVER_R_64F as _,
112    R32F = sys::cusolverPrecType_t::CUSOLVER_R_32F as _,
113    R16F = sys::cusolverPrecType_t::CUSOLVER_R_16F as _,
114    R16Bf = sys::cusolverPrecType_t::CUSOLVER_R_16BF as _,
115    RTf32 = sys::cusolverPrecType_t::CUSOLVER_R_TF32 as _,
116    RAp = sys::cusolverPrecType_t::CUSOLVER_R_AP as _,
117    C8I = sys::cusolverPrecType_t::CUSOLVER_C_8I as _,
118    C8U = sys::cusolverPrecType_t::CUSOLVER_C_8U as _,
119    C64F = sys::cusolverPrecType_t::CUSOLVER_C_64F as _,
120    C32F = sys::cusolverPrecType_t::CUSOLVER_C_32F as _,
121    C16F = sys::cusolverPrecType_t::CUSOLVER_C_16F as _,
122    C16Bf = sys::cusolverPrecType_t::CUSOLVER_C_16BF as _,
123    CTf32 = sys::cusolverPrecType_t::CUSOLVER_C_TF32 as _,
124    CAp = sys::cusolverPrecType_t::CUSOLVER_C_AP as _,
125}
126
127impl_enum_conversion!(sys::cusolverPrecType_t, PrecisionType);
128
129impl PrecisionType {
130    pub const fn from_data_type(data_type: DataType) -> Option<Self> {
131        match data_type {
132            DataType::F64 => Some(Self::R64F),
133            DataType::F32 => Some(Self::R32F),
134            DataType::F16 => Some(Self::R16F),
135            DataType::Bf16 => Some(Self::R16Bf),
136            DataType::ComplexF64 => Some(Self::C64F),
137            DataType::ComplexF32 => Some(Self::C32F),
138            DataType::ComplexF16 => Some(Self::C16F),
139            DataType::ComplexBf16 => Some(Self::C16Bf),
140            _ => None,
141        }
142    }
143}
144
145/// Algorithm selected by [`Params::set_adv_options`](crate::params::Params::set_adv_options).
146/// The set of algorithms supported for each operation is described with that
147/// operation's documentation.
148///
149/// The default algorithm is [`AlgorithmMode::Default`].
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
151#[repr(u32)]
152#[non_exhaustive]
153pub enum AlgorithmMode {
154    Default = sys::cusolverAlgMode_t::CUSOLVER_ALG_0 as _,
155    Algorithm1 = sys::cusolverAlgMode_t::CUSOLVER_ALG_1 as _,
156    Algorithm2 = sys::cusolverAlgMode_t::CUSOLVER_ALG_2 as _,
157}
158
159impl_enum_conversion!(sys::cusolverAlgMode_t, AlgorithmMode);
160
161/// Specifies how the vectors which define the elementary reflectors are stored.
162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
163#[repr(u32)]
164#[non_exhaustive]
165pub enum StorevMode {
166    /// Columnwise.
167    Columnwise = sys::cusolverStorevMode_t::CUBLAS_STOREV_COLUMNWISE as _,
168    /// Rowwise.
169    Rowwise = sys::cusolverStorevMode_t::CUBLAS_STOREV_ROWWISE as _,
170}
171
172impl_enum_conversion!(sys::cusolverStorevMode_t, StorevMode);
173
174/// Specifies the order in which the elementary reflectors are multiplied to form the block reflector.
175#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
176#[repr(u32)]
177#[non_exhaustive]
178pub enum DirectMode {
179    /// Forward.
180    Forward = sys::cusolverDirectMode_t::CUBLAS_DIRECT_FORWARD as _,
181    /// Backward.
182    Backward = sys::cusolverDirectMode_t::CUBLAS_DIRECT_BACKWARD as _,
183}
184
185impl_enum_conversion!(sys::cusolverDirectMode_t, DirectMode);
186
187/// Indicates whether repeated cuSOLVER executions with the same input are
188/// required to produce bitwise-identical results.
189///
190/// Compared with cuBLAS atomics mode, [`DeterministicMode`] covers
191/// non-determinism beyond atomic operations.
192///
193/// Use [`Context::set_deterministic_mode`](crate::context::Context::set_deterministic_mode)
194/// and [`Context::deterministic_mode`](crate::context::Context::deterministic_mode)
195/// to configure and query this setting.
196#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
197#[repr(u32)]
198#[non_exhaustive]
199pub enum DeterministicMode {
200    /// Compute deterministic results.
201    Deterministic = sys::cusolverDeterministicMode_t::CUSOLVER_DETERMINISTIC_RESULTS as _,
202    /// Allow non-deterministic results.
203    AllowNonDeterministic =
204        sys::cusolverDeterministicMode_t::CUSOLVER_ALLOW_NON_DETERMINISTIC_RESULTS as _,
205}
206
207impl_enum_conversion!(sys::cusolverDeterministicMode_t, DeterministicMode);
208
209/// Compute precision mode selected by [`set_math_mode`](crate::context::Context::set_math_mode).
210///
211/// The following combinations of [`MathMode`] using the bitwise OR operator are allowed.
212/// Math mode selection for cuSOLVER operations.
213#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
214#[repr(u32)]
215#[non_exhaustive]
216pub enum MathMode {
217    /// Default math mode.
218    /// Tensor Cores are used whenever possible.
219    Default = sys::cusolverMathMode_t::CUSOLVER_DEFAULT_MATH as _,
220    /// Use FP32 emulation according to the configured emulation strategy (see [`set_emulation_strategy`](crate::context::Context::set_emulation_strategy)).
221    Fp32EmulatedBf16x9 = sys::cusolverMathMode_t::CUSOLVER_FP32_EMULATED_BF16X9_MATH as _,
222}
223
224impl_enum_conversion!(sys::cusolverMathMode_t, MathMode);
225
226/// Selects which filled part of a dense matrix is used by the operation.
227///
228/// This corresponds to BLAS `L`/`l` (lower) and `U`/`u` (upper) arguments.
229#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
230#[repr(u32)]
231#[non_exhaustive]
232pub enum FillMode {
233    /// The lower part of the matrix is filled.
234    Lower = sys::cublasFillMode_t::CUBLAS_FILL_MODE_LOWER as _,
235    /// The upper part of the matrix is filled.
236    Upper = sys::cublasFillMode_t::CUBLAS_FILL_MODE_UPPER as _,
237    /// The full matrix is filled.
238    Full = sys::cublasFillMode_t::CUBLAS_FILL_MODE_FULL as _,
239}
240
241impl_enum_conversion!(sys::cublasFillMode_t, FillMode);
242
243#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
244#[repr(u32)]
245#[non_exhaustive]
246pub enum DiagonalType {
247    NonUnit = sys::cublasDiagType_t::CUBLAS_DIAG_NON_UNIT as _,
248    Unit = sys::cublasDiagType_t::CUBLAS_DIAG_UNIT as _,
249}
250
251impl_enum_conversion!(sys::cublasDiagType_t, DiagonalType);
252
253#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
254#[repr(u32)]
255#[non_exhaustive]
256pub enum SideMode {
257    Left = sys::cublasSideMode_t::CUBLAS_SIDE_LEFT as _,
258    Right = sys::cublasSideMode_t::CUBLAS_SIDE_RIGHT as _,
259}
260
261impl_enum_conversion!(sys::cublasSideMode_t, SideMode);
262
263/// Selects the operation to perform with a dense matrix.
264///
265/// This corresponds to BLAS `N`/`n` (non-transpose), `T`/`t` (transpose), and
266/// `C`/`c` (conjugate transpose) arguments.
267#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
268#[repr(u32)]
269#[non_exhaustive]
270pub enum Operation {
271    /// Non-transpose operation.
272    NonTranspose = sys::cublasOperation_t::CUBLAS_OP_N as _,
273    /// Transpose operation.
274    Transpose = sys::cublasOperation_t::CUBLAS_OP_T as _,
275    /// Conjugate transpose operation.
276    ConjugateTranspose = sys::cublasOperation_t::CUBLAS_OP_C as _,
277    Conjugate = sys::cublasOperation_t::CUBLAS_OP_CONJG as _,
278}
279
280impl Operation {
281    pub const HERMITIAN: Self = Self::ConjugateTranspose;
282}
283
284impl_enum_conversion!(sys::cublasOperation_t, Operation);
285
286#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
287#[non_exhaustive]
288pub enum SvdMode {
289    All,
290    Some,
291    Overwrite,
292    None,
293}
294
295impl SvdMode {
296    pub const fn as_raw(self) -> i8 {
297        match self {
298            Self::All => b'A' as i8,
299            Self::Some => b'S' as i8,
300            Self::Overwrite => b'O' as i8,
301            Self::None => b'N' as i8,
302        }
303    }
304}
305
306#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
307#[non_exhaustive]
308pub enum TruncatedSvdMode {
309    Some,
310    None,
311}
312
313impl TruncatedSvdMode {
314    pub const fn as_raw(self) -> i8 {
315        match self {
316            Self::Some => b'S' as i8,
317            Self::None => b'N' as i8,
318        }
319    }
320}
321
322/// Indicates which operation is configured by
323/// [`Params::set_adv_options`](crate::params::Params::set_adv_options).
324/// [`Function::Getrf`] corresponds to the `getrf` operation.
325#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive, IntoPrimitive)]
326#[repr(u32)]
327#[non_exhaustive]
328pub enum Function {
329    /// Corresponds to `Getrf`.
330    Getrf = sys::cusolverDnFunction_t::CUSOLVERDN_GETRF as _,
331    Potrf = sys::cusolverDnFunction_t::CUSOLVERDN_POTRF as _,
332    SyevBatched = sys::cusolverDnFunction_t::CUSOLVERDN_SYEVBATCHED as _,
333}
334
335impl_enum_conversion!(sys::cusolverDnFunction_t, Function);
336
337impl_enum_display!(EigenType, {
338    EigenType::Type1 => "CUSOLVER_EIG_TYPE_1",
339    EigenType::Type2 => "CUSOLVER_EIG_TYPE_2",
340    EigenType::Type3 => "CUSOLVER_EIG_TYPE_3",
341});
342
343impl_enum_display!(EigenMode, {
344    EigenMode::NoVector => "CUSOLVER_EIG_MODE_NOVECTOR",
345    EigenMode::Vector => "CUSOLVER_EIG_MODE_VECTOR",
346});
347
348impl_enum_display!(EigenRange, {
349    EigenRange::All => "CUSOLVER_EIG_RANGE_ALL",
350    EigenRange::Index => "CUSOLVER_EIG_RANGE_I",
351    EigenRange::Value => "CUSOLVER_EIG_RANGE_V",
352});
353
354impl_enum_display!(Norm, {
355    Norm::Infinity => "CUSOLVER_INF_NORM",
356    Norm::Maximum => "CUSOLVER_MAX_NORM",
357    Norm::One => "CUSOLVER_ONE_NORM",
358    Norm::Frobenius => "CUSOLVER_FRO_NORM",
359});
360
361impl_enum_display!(IrsRefinement, {
362    IrsRefinement::NotSet => "CUSOLVER_IRS_REFINE_NOT_SET",
363    IrsRefinement::None => "CUSOLVER_IRS_REFINE_NONE",
364    IrsRefinement::Classical => "CUSOLVER_IRS_REFINE_CLASSICAL",
365    IrsRefinement::ClassicalGmres => "CUSOLVER_IRS_REFINE_CLASSICAL_GMRES",
366    IrsRefinement::Gmres => "CUSOLVER_IRS_REFINE_GMRES",
367    IrsRefinement::GmresGmres => "CUSOLVER_IRS_REFINE_GMRES_GMRES",
368    IrsRefinement::GmresNoPcond => "CUSOLVER_IRS_REFINE_GMRES_NOPCOND",
369    IrsRefinement::PrecDd => "CUSOLVER_PREC_DD",
370    IrsRefinement::PrecSs => "CUSOLVER_PREC_SS",
371    IrsRefinement::PrecSht => "CUSOLVER_PREC_SHT",
372});
373
374impl_enum_display!(PrecisionType, {
375    PrecisionType::R8I => "CUSOLVER_R_8I",
376    PrecisionType::R8U => "CUSOLVER_R_8U",
377    PrecisionType::R64F => "CUSOLVER_R_64F",
378    PrecisionType::R32F => "CUSOLVER_R_32F",
379    PrecisionType::R16F => "CUSOLVER_R_16F",
380    PrecisionType::R16Bf => "CUSOLVER_R_16BF",
381    PrecisionType::RTf32 => "CUSOLVER_R_TF32",
382    PrecisionType::RAp => "CUSOLVER_R_AP",
383    PrecisionType::C8I => "CUSOLVER_C_8I",
384    PrecisionType::C8U => "CUSOLVER_C_8U",
385    PrecisionType::C64F => "CUSOLVER_C_64F",
386    PrecisionType::C32F => "CUSOLVER_C_32F",
387    PrecisionType::C16F => "CUSOLVER_C_16F",
388    PrecisionType::C16Bf => "CUSOLVER_C_16BF",
389    PrecisionType::CTf32 => "CUSOLVER_C_TF32",
390    PrecisionType::CAp => "CUSOLVER_C_AP",
391});
392
393impl_enum_display!(AlgorithmMode, {
394    AlgorithmMode::Default => "CUSOLVER_ALG_0",
395    AlgorithmMode::Algorithm1 => "CUSOLVER_ALG_1",
396    AlgorithmMode::Algorithm2 => "CUSOLVER_ALG_2",
397});
398
399impl_enum_display!(StorevMode, {
400    StorevMode::Columnwise => "CUBLAS_STOREV_COLUMNWISE",
401    StorevMode::Rowwise => "CUBLAS_STOREV_ROWWISE",
402});
403
404impl_enum_display!(DirectMode, {
405    DirectMode::Forward => "CUBLAS_DIRECT_FORWARD",
406    DirectMode::Backward => "CUBLAS_DIRECT_BACKWARD",
407});
408
409impl_enum_display!(DeterministicMode, {
410    DeterministicMode::Deterministic => "CUSOLVER_DETERMINISTIC_RESULTS",
411    DeterministicMode::AllowNonDeterministic => "CUSOLVER_ALLOW_NON_DETERMINISTIC_RESULTS",
412});
413
414impl_enum_display!(MathMode, {
415    MathMode::Default => "CUSOLVER_DEFAULT_MATH",
416    MathMode::Fp32EmulatedBf16x9 => "CUSOLVER_FP32_EMULATED_BF16X9_MATH",
417});
418
419impl_enum_display!(FillMode, {
420    FillMode::Lower => "CUBLAS_FILL_MODE_LOWER",
421    FillMode::Upper => "CUBLAS_FILL_MODE_UPPER",
422    FillMode::Full => "CUBLAS_FILL_MODE_FULL",
423});
424
425impl_enum_display!(DiagonalType, {
426    DiagonalType::NonUnit => "CUBLAS_DIAG_NON_UNIT",
427    DiagonalType::Unit => "CUBLAS_DIAG_UNIT",
428});
429
430impl_enum_display!(SideMode, {
431    SideMode::Left => "CUBLAS_SIDE_LEFT",
432    SideMode::Right => "CUBLAS_SIDE_RIGHT",
433});
434
435impl_enum_display!(Operation, {
436    Operation::NonTranspose => "CUBLAS_OP_N",
437    Operation::Transpose => "CUBLAS_OP_T",
438    Operation::ConjugateTranspose => "CUBLAS_OP_C",
439    Operation::Conjugate => "CUBLAS_OP_CONJG",
440});
441
442impl_enum_display!(SvdMode, {
443    SvdMode::All => "A",
444    SvdMode::Some => "S",
445    SvdMode::Overwrite => "O",
446    SvdMode::None => "N",
447});
448
449impl_enum_display!(TruncatedSvdMode, {
450    TruncatedSvdMode::Some => "S",
451    TruncatedSvdMode::None => "N",
452});
453
454impl_enum_display!(Function, {
455    Function::Getrf => "CUSOLVERDN_GETRF",
456    Function::Potrf => "CUSOLVERDN_POTRF",
457    Function::SyevBatched => "CUSOLVERDN_SYEVBATCHED",
458});