Skip to main content

singe_cusolver/
types.rs

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