Skip to main content

singe_cusolver/dense/
operations.rs

1use std::marker::PhantomData;
2
3use singe_cuda::{
4    data_type::{DataType, DataTypeLike},
5    memory::DeviceMemory,
6};
7
8use crate::{
9    context::Context,
10    dense::{
11        GebrdScalar, OrgbrScalar, OrgqrScalar, OrgtrScalar, OrmqrScalar, OrmtrScalar,
12        PotrfBatchedScalar, PotriScalar, PotrsBatchedScalar, SytrdScalar, SytrfScalar,
13        legacy::qr::{xgeqrf, xgeqrf_buffer_size},
14        xgetrf, xgetrf_buffer_size, xgetrs, xlarft, xlarft_buffer_size, xpotrf, xpotrf_buffer_size,
15        xpotrs, xsytrs, xsytrs_buffer_size, xtrtri, xtrtri_buffer_size,
16    },
17    error::Result,
18    layout::{
19        BatchedMatrixRef, BatchedVectorRef, ByteWorkspaceMut, MatrixMut, MatrixRef, VectorMut,
20        VectorRef, WorkspaceSizes,
21    },
22    params::Params,
23    types::{DiagonalType, DirectMode, FillMode, Operation, SideMode, StorevMode},
24};
25
26/// Typed Cholesky factorization operation.
27///
28/// This is the preferred operation-family API for POTRF. It keeps matrix
29/// metadata grouped in [`MatrixRef`] and [`MatrixMut`] instead of exposing the
30/// cuSOLVER `S`/`D`/`C`/`Z` entry point names and separate `a`/`lda` arguments.
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub struct Potrf<T> {
33    fill_mode: FillMode,
34    n: usize,
35    compute_type: DataType,
36    _ty: PhantomData<T>,
37}
38
39/// Runtime buffers for [`Potrf::run`].
40#[derive(Debug)]
41pub struct PotrfArgs<'a, T> {
42    pub a: MatrixMut<'a, T>,
43    pub workspace: ByteWorkspaceMut<'a>,
44    pub dev_info: &'a mut DeviceMemory<i32>,
45}
46
47/// Typed Cholesky solve operation.
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub struct Potrs<T> {
50    fill_mode: FillMode,
51    n: usize,
52    right_hand_sides: usize,
53    _ty: PhantomData<T>,
54}
55
56/// Runtime buffers for [`Potrs::run`].
57#[derive(Debug)]
58pub struct PotrsArgs<'a, T> {
59    pub factor: MatrixRef<'a, T>,
60    pub rhs: MatrixMut<'a, T>,
61    pub dev_info: &'a mut DeviceMemory<i32>,
62}
63
64/// Typed Cholesky inverse operation.
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub struct Potri<T> {
67    fill_mode: FillMode,
68    n: usize,
69    _ty: PhantomData<T>,
70}
71
72/// Runtime buffers for [`Potri::run`].
73#[derive(Debug)]
74pub struct PotriArgs<'a, T> {
75    pub factor: MatrixMut<'a, T>,
76    pub workspace: &'a mut DeviceMemory<T>,
77    pub dev_info: &'a mut DeviceMemory<i32>,
78}
79
80/// Typed batched Cholesky factorization operation.
81#[derive(Debug, Clone, Copy, PartialEq, Eq)]
82pub struct BatchedPotrf<T> {
83    fill_mode: FillMode,
84    n: usize,
85    _ty: PhantomData<T>,
86}
87
88/// Runtime buffers for [`BatchedPotrf::run`].
89#[derive(Debug)]
90pub struct BatchedPotrfArgs<'a, T> {
91    pub a: BatchedMatrixRef<'a, T>,
92    pub info: &'a mut DeviceMemory<i32>,
93}
94
95/// Typed batched Cholesky solve operation.
96#[derive(Debug, Clone, Copy, PartialEq, Eq)]
97pub struct BatchedPotrs<T> {
98    fill_mode: FillMode,
99    n: usize,
100    _ty: PhantomData<T>,
101}
102
103/// Runtime buffers for [`BatchedPotrs::run`].
104#[derive(Debug)]
105pub struct BatchedPotrsArgs<'a, T> {
106    pub factors: BatchedMatrixRef<'a, T>,
107    pub rhs: BatchedVectorRef<'a, T>,
108    pub info: &'a mut DeviceMemory<i32>,
109}
110
111/// Typed LU factorization operation.
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub struct Getrf<T> {
114    rows: usize,
115    cols: usize,
116    compute_type: DataType,
117    _ty: PhantomData<T>,
118}
119
120/// Runtime buffers for [`Getrf::run`].
121#[derive(Debug)]
122pub struct GetrfArgs<'a, T> {
123    pub a: MatrixMut<'a, T>,
124    pub pivots: Option<&'a mut DeviceMemory<i64>>,
125    pub workspace: ByteWorkspaceMut<'a>,
126    pub dev_info: &'a mut DeviceMemory<i32>,
127}
128
129/// Typed LU solve operation.
130#[derive(Debug, Clone, Copy, PartialEq, Eq)]
131pub struct Getrs<TA, TB = TA> {
132    operation: Operation,
133    n: usize,
134    right_hand_sides: usize,
135    _ty: PhantomData<(TA, TB)>,
136}
137
138/// Runtime buffers for [`Getrs::run`].
139#[derive(Debug)]
140pub struct GetrsArgs<'a, TA, TB = TA> {
141    pub factor: MatrixRef<'a, TA>,
142    pub pivots: &'a DeviceMemory<i64>,
143    pub rhs: MatrixMut<'a, TB>,
144    pub dev_info: &'a mut DeviceMemory<i32>,
145}
146
147/// Typed triangular inverse operation.
148#[derive(Debug, Clone, Copy, PartialEq, Eq)]
149pub struct Trtri<T> {
150    fill_mode: FillMode,
151    diagonal_type: DiagonalType,
152    n: usize,
153    _ty: PhantomData<T>,
154}
155
156/// Runtime buffers for [`Trtri::run`].
157#[derive(Debug)]
158pub struct TrtriArgs<'a, T> {
159    pub a: MatrixMut<'a, T>,
160    pub workspace: ByteWorkspaceMut<'a>,
161    pub dev_info: &'a mut DeviceMemory<i32>,
162}
163
164/// Typed symmetric or Hermitian solve operation.
165#[derive(Debug, Clone, Copy, PartialEq, Eq)]
166pub struct Sytrs<TA, TB = TA> {
167    fill_mode: FillMode,
168    n: usize,
169    right_hand_sides: usize,
170    _ty: PhantomData<(TA, TB)>,
171}
172
173/// Runtime buffers for [`Sytrs::run`].
174#[derive(Debug)]
175pub struct SytrsArgs<'a, TA, TB = TA> {
176    pub factor: MatrixRef<'a, TA>,
177    pub pivots: Option<&'a DeviceMemory<i64>>,
178    pub rhs: MatrixMut<'a, TB>,
179    pub workspace: ByteWorkspaceMut<'a>,
180    pub dev_info: &'a mut DeviceMemory<i32>,
181}
182
183/// Typed symmetric or Hermitian indefinite factorization operation.
184#[derive(Debug, Clone, Copy, PartialEq, Eq)]
185pub struct Sytrf<T> {
186    fill_mode: FillMode,
187    n: usize,
188    _ty: PhantomData<T>,
189}
190
191/// Runtime buffers for [`Sytrf::run`].
192#[derive(Debug)]
193pub struct SytrfArgs<'a, T> {
194    pub a: MatrixMut<'a, T>,
195    pub pivots: Option<&'a mut DeviceMemory<i32>>,
196    pub workspace: &'a mut DeviceMemory<T>,
197    pub dev_info: &'a mut DeviceMemory<i32>,
198}
199
200/// Typed symmetric or Hermitian tridiagonal reduction operation.
201#[derive(Debug, Clone, Copy, PartialEq, Eq)]
202pub struct Sytrd<T> {
203    fill_mode: FillMode,
204    n: usize,
205    _ty: PhantomData<T>,
206}
207
208/// Runtime buffers for [`Sytrd::run`].
209#[derive(Debug)]
210pub struct SytrdArgs<'a, T>
211where
212    T: SytrdScalar,
213{
214    pub a: MatrixMut<'a, T>,
215    pub diagonal: VectorMut<'a, T::Real>,
216    pub off_diagonal: VectorMut<'a, T::Real>,
217    pub tau: VectorMut<'a, T>,
218    pub workspace: &'a mut DeviceMemory<T>,
219    pub dev_info: &'a mut DeviceMemory<i32>,
220}
221
222/// Typed operation that forms explicit tridiagonalization factors.
223#[derive(Debug, Clone, Copy, PartialEq, Eq)]
224pub struct Orgtr<T> {
225    fill_mode: FillMode,
226    n: usize,
227    _ty: PhantomData<T>,
228}
229
230/// Runtime buffers for [`Orgtr::run`].
231#[derive(Debug)]
232pub struct OrgtrArgs<'a, T> {
233    pub a: MatrixMut<'a, T>,
234    pub tau: VectorRef<'a, T>,
235    pub workspace: &'a mut DeviceMemory<T>,
236    pub dev_info: &'a mut DeviceMemory<i32>,
237}
238
239/// Typed operation that applies tridiagonalization factors to a matrix.
240#[derive(Debug, Clone, Copy, PartialEq, Eq)]
241pub struct Ormtr<T> {
242    side: SideMode,
243    fill_mode: FillMode,
244    operation: Operation,
245    rows: usize,
246    cols: usize,
247    _ty: PhantomData<T>,
248}
249
250/// Runtime buffers for [`Ormtr::run`].
251#[derive(Debug)]
252pub struct OrmtrArgs<'a, T> {
253    pub reflectors: MatrixMut<'a, T>,
254    pub tau: VectorMut<'a, T>,
255    pub matrix: MatrixMut<'a, T>,
256    pub workspace: &'a mut DeviceMemory<T>,
257    pub dev_info: &'a mut DeviceMemory<i32>,
258}
259
260/// Typed LARFT triangular-factor operation.
261#[derive(Debug, Clone, Copy, PartialEq, Eq)]
262pub struct Larft<TV, TTau = TV, TT = TV> {
263    direct: DirectMode,
264    storev: StorevMode,
265    n: usize,
266    k: usize,
267    compute_type: DataType,
268    _ty: PhantomData<(TV, TTau, TT)>,
269}
270
271/// Runtime buffers for [`Larft::run`].
272#[derive(Debug)]
273pub struct LarftArgs<'a, TV, TTau = TV, TT = TV> {
274    pub v: MatrixRef<'a, TV>,
275    pub tau: VectorRef<'a, TTau>,
276    pub t: MatrixMut<'a, TT>,
277    pub workspace: ByteWorkspaceMut<'a>,
278}
279
280/// Typed QR factorization operation.
281#[derive(Debug, Clone, Copy, PartialEq, Eq)]
282pub struct Geqrf<TA, TTau = TA> {
283    rows: usize,
284    cols: usize,
285    compute_type: DataType,
286    _ty: PhantomData<(TA, TTau)>,
287}
288
289/// Runtime buffers for [`Geqrf::run`].
290#[derive(Debug)]
291pub struct GeqrfArgs<'a, TA, TTau = TA> {
292    pub a: MatrixMut<'a, TA>,
293    pub tau: VectorMut<'a, TTau>,
294    pub workspace: ByteWorkspaceMut<'a>,
295    pub dev_info: &'a mut DeviceMemory<i32>,
296}
297
298/// Typed operation that applies QR reflectors to a matrix.
299#[derive(Debug, Clone, Copy, PartialEq, Eq)]
300pub struct Ormqr<T> {
301    side: SideMode,
302    operation: Operation,
303    rows: usize,
304    cols: usize,
305    reflectors: usize,
306    _ty: PhantomData<T>,
307}
308
309/// Runtime buffers for [`Ormqr::run`].
310#[derive(Debug)]
311pub struct OrmqrArgs<'a, T> {
312    pub reflectors: MatrixRef<'a, T>,
313    pub tau: VectorRef<'a, T>,
314    pub matrix: MatrixMut<'a, T>,
315    pub workspace: &'a mut DeviceMemory<T>,
316    pub dev_info: &'a mut DeviceMemory<i32>,
317}
318
319/// Typed operation that forms explicit QR factors.
320#[derive(Debug, Clone, Copy, PartialEq, Eq)]
321pub struct Orgqr<T> {
322    rows: usize,
323    cols: usize,
324    reflectors: usize,
325    _ty: PhantomData<T>,
326}
327
328/// Runtime buffers for [`Orgqr::run`].
329#[derive(Debug)]
330pub struct OrgqrArgs<'a, T> {
331    pub a: MatrixMut<'a, T>,
332    pub tau: VectorRef<'a, T>,
333    pub workspace: &'a mut DeviceMemory<T>,
334    pub dev_info: &'a mut DeviceMemory<i32>,
335}
336
337/// Typed bidiagonal reduction operation.
338#[derive(Debug, Clone, Copy, PartialEq, Eq)]
339pub struct Gebrd<T> {
340    rows: usize,
341    cols: usize,
342    _ty: PhantomData<T>,
343}
344
345/// Runtime buffers for [`Gebrd::run`].
346#[derive(Debug)]
347pub struct GebrdArgs<'a, T>
348where
349    T: GebrdScalar,
350{
351    pub a: MatrixMut<'a, T>,
352    pub diagonal: VectorMut<'a, T::Real>,
353    pub off_diagonal: VectorMut<'a, T::Real>,
354    pub tau_q: VectorMut<'a, T>,
355    pub tau_p: VectorMut<'a, T>,
356    pub workspace: &'a mut DeviceMemory<T>,
357    pub dev_info: &'a mut DeviceMemory<i32>,
358}
359
360/// Typed operation that forms explicit bidiagonalization factors.
361#[derive(Debug, Clone, Copy, PartialEq, Eq)]
362pub struct Orgbr<T> {
363    side: SideMode,
364    rows: usize,
365    cols: usize,
366    reflectors: usize,
367    _ty: PhantomData<T>,
368}
369
370/// Runtime buffers for [`Orgbr::run`].
371#[derive(Debug)]
372pub struct OrgbrArgs<'a, T> {
373    pub a: MatrixMut<'a, T>,
374    pub tau: VectorRef<'a, T>,
375    pub workspace: &'a mut DeviceMemory<T>,
376    pub dev_info: &'a mut DeviceMemory<i32>,
377}
378
379impl<T> Potrf<T>
380where
381    T: DataTypeLike,
382{
383    /// Creates a typed POTRF operation using the matrix data type as compute type.
384    pub fn new(fill_mode: FillMode, n: usize) -> Self {
385        Self {
386            fill_mode,
387            n,
388            compute_type: T::data_type(),
389            _ty: PhantomData,
390        }
391    }
392
393    /// Sets the compute type passed to the generic cuSOLVER X API.
394    pub const fn with_compute_type(mut self, compute_type: DataType) -> Self {
395        self.compute_type = compute_type;
396        self
397    }
398
399    /// Returns the cuSOLVER fill mode.
400    pub const fn fill_mode(&self) -> FillMode {
401        self.fill_mode
402    }
403
404    /// Returns the square matrix dimension.
405    pub const fn n(&self) -> usize {
406        self.n
407    }
408
409    /// Returns the cuSOLVER compute type.
410    pub const fn compute_type(&self) -> DataType {
411        self.compute_type
412    }
413
414    /// Returns the required device and host workspace sizes.
415    ///
416    /// # Errors
417    ///
418    /// Returns an error if the matrix shape is invalid or cuSOLVER cannot
419    /// report the workspace sizes.
420    pub fn workspace_size(
421        &self,
422        ctx: &Context,
423        params: &Params,
424        a: MatrixRef<'_, T>,
425    ) -> Result<WorkspaceSizes> {
426        xpotrf_buffer_size(ctx, params, self.fill_mode, self.n, a, self.compute_type)
427    }
428
429    /// Computes the Cholesky factorization in place.
430    ///
431    /// # Errors
432    ///
433    /// Returns an error if inputs or workspaces are invalid, or if cuSOLVER
434    /// reports a failure.
435    pub fn run(&self, ctx: &Context, params: &Params, args: PotrfArgs<'_, T>) -> Result<()> {
436        xpotrf(
437            ctx,
438            params,
439            self.fill_mode,
440            self.n,
441            args.a,
442            self.compute_type,
443            args.workspace,
444            args.dev_info,
445        )
446    }
447}
448
449impl<T> Potrs<T>
450where
451    T: DataTypeLike,
452{
453    /// Creates a typed POTRS operation.
454    pub const fn new(fill_mode: FillMode, n: usize, right_hand_sides: usize) -> Self {
455        Self {
456            fill_mode,
457            n,
458            right_hand_sides,
459            _ty: PhantomData,
460        }
461    }
462
463    /// Returns the cuSOLVER fill mode.
464    pub const fn fill_mode(&self) -> FillMode {
465        self.fill_mode
466    }
467
468    /// Returns the square matrix dimension.
469    pub const fn n(&self) -> usize {
470        self.n
471    }
472
473    /// Returns the number of right-hand sides.
474    pub const fn right_hand_sides(&self) -> usize {
475        self.right_hand_sides
476    }
477
478    /// Solves the linear system in place.
479    ///
480    /// # Errors
481    ///
482    /// Returns an error if inputs are invalid or if cuSOLVER reports a failure.
483    pub fn run(&self, ctx: &Context, params: &Params, args: PotrsArgs<'_, T>) -> Result<()> {
484        xpotrs(
485            ctx,
486            params,
487            self.fill_mode,
488            self.n,
489            self.right_hand_sides,
490            args.factor,
491            args.rhs,
492            args.dev_info,
493        )
494    }
495}
496
497impl<T> Potri<T>
498where
499    T: PotriScalar,
500{
501    /// Creates a typed POTRI operation.
502    pub const fn new(fill_mode: FillMode, n: usize) -> Self {
503        Self {
504            fill_mode,
505            n,
506            _ty: PhantomData,
507        }
508    }
509
510    /// Returns the cuSOLVER fill mode.
511    pub const fn fill_mode(&self) -> FillMode {
512        self.fill_mode
513    }
514
515    /// Returns the square matrix dimension.
516    pub const fn n(&self) -> usize {
517        self.n
518    }
519
520    /// Returns the required legacy workspace length in elements.
521    ///
522    /// # Errors
523    ///
524    /// Returns an error if the matrix shape is invalid or cuSOLVER cannot
525    /// report the workspace size.
526    pub fn workspace_len(&self, ctx: &Context, factor: MatrixMut<'_, T>) -> Result<usize> {
527        T::potri_buffer_size(ctx, self.fill_mode, self.n, factor)
528    }
529
530    /// Computes the inverse in place from a Cholesky factorization.
531    ///
532    /// # Errors
533    ///
534    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
535    /// reports a failure.
536    pub fn run(&self, ctx: &Context, args: PotriArgs<'_, T>) -> Result<()> {
537        T::potri(
538            ctx,
539            self.fill_mode,
540            self.n,
541            args.factor,
542            args.workspace,
543            args.dev_info,
544        )
545    }
546}
547
548impl<T> BatchedPotrf<T>
549where
550    T: PotrfBatchedScalar,
551{
552    /// Creates a typed batched POTRF operation.
553    pub const fn new(fill_mode: FillMode, n: usize) -> Self {
554        Self {
555            fill_mode,
556            n,
557            _ty: PhantomData,
558        }
559    }
560
561    /// Returns the cuSOLVER fill mode.
562    pub const fn fill_mode(&self) -> FillMode {
563        self.fill_mode
564    }
565
566    /// Returns the square matrix dimension.
567    pub const fn n(&self) -> usize {
568        self.n
569    }
570
571    /// Computes batched Cholesky factorizations in place.
572    ///
573    /// # Errors
574    ///
575    /// Returns an error if inputs are invalid or if cuSOLVER reports a failure.
576    pub fn run(&self, ctx: &Context, args: BatchedPotrfArgs<'_, T>) -> Result<()> {
577        T::potrf_batched(ctx, self.fill_mode, self.n, args.a, args.info)
578    }
579}
580
581impl<T> BatchedPotrs<T>
582where
583    T: PotrsBatchedScalar,
584{
585    /// Creates a typed batched POTRS operation.
586    ///
587    /// The cuSOLVER batched POTRS API supports one right-hand side per matrix.
588    pub const fn new(fill_mode: FillMode, n: usize) -> Self {
589        Self {
590            fill_mode,
591            n,
592            _ty: PhantomData,
593        }
594    }
595
596    /// Returns the cuSOLVER fill mode.
597    pub const fn fill_mode(&self) -> FillMode {
598        self.fill_mode
599    }
600
601    /// Returns the square matrix dimension.
602    pub const fn n(&self) -> usize {
603        self.n
604    }
605
606    /// Solves batched linear systems in place.
607    ///
608    /// # Errors
609    ///
610    /// Returns an error if inputs are invalid or if cuSOLVER reports a failure.
611    pub fn run(&self, ctx: &Context, args: BatchedPotrsArgs<'_, T>) -> Result<()> {
612        T::potrs_batched(
613            ctx,
614            self.fill_mode,
615            self.n,
616            args.factors,
617            args.rhs,
618            args.info,
619        )
620    }
621}
622
623impl<T> Getrf<T>
624where
625    T: DataTypeLike,
626{
627    /// Creates a typed GETRF operation using the matrix data type as compute type.
628    pub fn new(rows: usize, cols: usize) -> Self {
629        Self {
630            rows,
631            cols,
632            compute_type: T::data_type(),
633            _ty: PhantomData,
634        }
635    }
636
637    /// Sets the compute type passed to the generic cuSOLVER X API.
638    pub const fn with_compute_type(mut self, compute_type: DataType) -> Self {
639        self.compute_type = compute_type;
640        self
641    }
642
643    /// Returns the matrix row count.
644    pub const fn rows(&self) -> usize {
645        self.rows
646    }
647
648    /// Returns the matrix column count.
649    pub const fn cols(&self) -> usize {
650        self.cols
651    }
652
653    /// Returns the cuSOLVER compute type.
654    pub const fn compute_type(&self) -> DataType {
655        self.compute_type
656    }
657
658    /// Returns the required device and host workspace sizes.
659    ///
660    /// # Errors
661    ///
662    /// Returns an error if the matrix shape is invalid or cuSOLVER cannot
663    /// report the workspace sizes.
664    pub fn workspace_size(
665        &self,
666        ctx: &Context,
667        params: &Params,
668        a: MatrixRef<'_, T>,
669    ) -> Result<WorkspaceSizes> {
670        xgetrf_buffer_size(ctx, params, self.rows, self.cols, a, self.compute_type)
671    }
672
673    /// Computes the LU factorization in place.
674    ///
675    /// # Errors
676    ///
677    /// Returns an error if inputs or workspaces are invalid, or if cuSOLVER
678    /// reports a failure.
679    pub fn run(&self, ctx: &Context, params: &Params, args: GetrfArgs<'_, T>) -> Result<()> {
680        xgetrf(
681            ctx,
682            params,
683            self.rows,
684            self.cols,
685            args.a,
686            args.pivots,
687            self.compute_type,
688            args.workspace,
689            args.dev_info,
690        )
691    }
692}
693
694impl<TA, TB> Getrs<TA, TB>
695where
696    TA: DataTypeLike,
697    TB: DataTypeLike,
698{
699    /// Creates a typed GETRS operation.
700    pub const fn new(operation: Operation, n: usize, right_hand_sides: usize) -> Self {
701        Self {
702            operation,
703            n,
704            right_hand_sides,
705            _ty: PhantomData,
706        }
707    }
708
709    /// Returns the operation applied to the factorized matrix.
710    pub const fn operation(&self) -> Operation {
711        self.operation
712    }
713
714    /// Returns the square factor dimension.
715    pub const fn n(&self) -> usize {
716        self.n
717    }
718
719    /// Returns the number of right-hand sides.
720    pub const fn right_hand_sides(&self) -> usize {
721        self.right_hand_sides
722    }
723
724    /// Solves the linear system in place.
725    ///
726    /// # Errors
727    ///
728    /// Returns an error if inputs are invalid or if cuSOLVER reports a failure.
729    pub fn run(&self, ctx: &Context, params: &Params, args: GetrsArgs<'_, TA, TB>) -> Result<()> {
730        xgetrs(
731            ctx,
732            params,
733            self.operation,
734            self.n,
735            self.right_hand_sides,
736            args.factor,
737            args.pivots,
738            args.rhs,
739            args.dev_info,
740        )
741    }
742}
743
744impl<T> Trtri<T>
745where
746    T: DataTypeLike,
747{
748    /// Creates a typed TRTRI operation.
749    pub const fn new(fill_mode: FillMode, diagonal_type: DiagonalType, n: usize) -> Self {
750        Self {
751            fill_mode,
752            diagonal_type,
753            n,
754            _ty: PhantomData,
755        }
756    }
757
758    /// Returns the cuSOLVER fill mode.
759    pub const fn fill_mode(&self) -> FillMode {
760        self.fill_mode
761    }
762
763    /// Returns the diagonal type.
764    pub const fn diagonal_type(&self) -> DiagonalType {
765        self.diagonal_type
766    }
767
768    /// Returns the square matrix dimension.
769    pub const fn n(&self) -> usize {
770        self.n
771    }
772
773    /// Returns the required device and host workspace sizes.
774    ///
775    /// # Errors
776    ///
777    /// Returns an error if the matrix shape is invalid or cuSOLVER cannot
778    /// report the workspace sizes.
779    pub fn workspace_size(&self, ctx: &Context, a: MatrixRef<'_, T>) -> Result<WorkspaceSizes> {
780        xtrtri_buffer_size(ctx, self.fill_mode, self.diagonal_type, self.n, a)
781    }
782
783    /// Computes the triangular inverse in place.
784    ///
785    /// # Errors
786    ///
787    /// Returns an error if inputs or workspaces are invalid, or if cuSOLVER
788    /// reports a failure.
789    pub fn run(&self, ctx: &Context, args: TrtriArgs<'_, T>) -> Result<()> {
790        xtrtri(
791            ctx,
792            self.fill_mode,
793            self.diagonal_type,
794            self.n,
795            args.a,
796            args.workspace,
797            args.dev_info,
798        )
799    }
800}
801
802impl<TA, TB> Sytrs<TA, TB>
803where
804    TA: DataTypeLike,
805    TB: DataTypeLike,
806{
807    /// Creates a typed SYTRS operation.
808    pub const fn new(fill_mode: FillMode, n: usize, right_hand_sides: usize) -> Self {
809        Self {
810            fill_mode,
811            n,
812            right_hand_sides,
813            _ty: PhantomData,
814        }
815    }
816
817    /// Returns the cuSOLVER fill mode.
818    pub const fn fill_mode(&self) -> FillMode {
819        self.fill_mode
820    }
821
822    /// Returns the square factor dimension.
823    pub const fn n(&self) -> usize {
824        self.n
825    }
826
827    /// Returns the number of right-hand sides.
828    pub const fn right_hand_sides(&self) -> usize {
829        self.right_hand_sides
830    }
831
832    /// Returns the required device and host workspace sizes.
833    ///
834    /// # Errors
835    ///
836    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
837    /// workspace sizes.
838    pub fn workspace_size(
839        &self,
840        ctx: &Context,
841        factor: MatrixRef<'_, TA>,
842        pivots: Option<&DeviceMemory<i64>>,
843        rhs: MatrixRef<'_, TB>,
844    ) -> Result<WorkspaceSizes> {
845        xsytrs_buffer_size(
846            ctx,
847            self.fill_mode,
848            self.n,
849            self.right_hand_sides,
850            factor,
851            pivots,
852            rhs,
853        )
854    }
855
856    /// Solves the symmetric or Hermitian system in place.
857    ///
858    /// # Errors
859    ///
860    /// Returns an error if inputs or workspaces are invalid, or if cuSOLVER
861    /// reports a failure.
862    pub fn run(&self, ctx: &Context, args: SytrsArgs<'_, TA, TB>) -> Result<()> {
863        xsytrs(
864            ctx,
865            self.fill_mode,
866            self.n,
867            self.right_hand_sides,
868            args.factor,
869            args.pivots,
870            args.rhs,
871            args.workspace,
872            args.dev_info,
873        )
874    }
875}
876
877impl<T> Sytrf<T>
878where
879    T: SytrfScalar,
880{
881    /// Creates a typed SYTRF operation.
882    pub const fn new(fill_mode: FillMode, n: usize) -> Self {
883        Self {
884            fill_mode,
885            n,
886            _ty: PhantomData,
887        }
888    }
889
890    /// Returns the cuSOLVER fill mode.
891    pub const fn fill_mode(&self) -> FillMode {
892        self.fill_mode
893    }
894
895    /// Returns the square matrix dimension.
896    pub const fn n(&self) -> usize {
897        self.n
898    }
899
900    /// Returns the required legacy workspace length in elements.
901    ///
902    /// # Errors
903    ///
904    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
905    /// workspace length.
906    pub fn workspace_len(&self, ctx: &Context, a: MatrixMut<'_, T>) -> Result<usize> {
907        T::sytrf_buffer_size(ctx, self.n, a)
908    }
909
910    /// Computes the indefinite factorization in place.
911    ///
912    /// # Errors
913    ///
914    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
915    /// reports a failure.
916    pub fn run(&self, ctx: &Context, args: SytrfArgs<'_, T>) -> Result<()> {
917        T::sytrf(
918            ctx,
919            self.fill_mode,
920            self.n,
921            args.a,
922            args.pivots,
923            args.workspace,
924            args.dev_info,
925        )
926    }
927}
928
929impl<T> Sytrd<T>
930where
931    T: SytrdScalar,
932{
933    /// Creates a typed SYTRD/HETRD operation.
934    pub const fn new(fill_mode: FillMode, n: usize) -> Self {
935        Self {
936            fill_mode,
937            n,
938            _ty: PhantomData,
939        }
940    }
941
942    /// Returns the cuSOLVER fill mode.
943    pub const fn fill_mode(&self) -> FillMode {
944        self.fill_mode
945    }
946
947    /// Returns the square matrix dimension.
948    pub const fn n(&self) -> usize {
949        self.n
950    }
951
952    /// Returns the required legacy workspace length in elements.
953    ///
954    /// # Errors
955    ///
956    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
957    /// workspace length.
958    pub fn workspace_len(
959        &self,
960        ctx: &Context,
961        a: MatrixRef<'_, T>,
962        diagonal: VectorRef<'_, T::Real>,
963        off_diagonal: VectorRef<'_, T::Real>,
964        tau: VectorRef<'_, T>,
965    ) -> Result<usize> {
966        T::sytrd_buffer_size(ctx, self.fill_mode, self.n, a, diagonal, off_diagonal, tau)
967    }
968
969    /// Reduces the matrix to symmetric or Hermitian tridiagonal form in place.
970    ///
971    /// # Errors
972    ///
973    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
974    /// reports a failure.
975    pub fn run(&self, ctx: &Context, args: SytrdArgs<'_, T>) -> Result<()> {
976        T::sytrd(
977            ctx,
978            self.fill_mode,
979            self.n,
980            args.a,
981            args.diagonal,
982            args.off_diagonal,
983            args.tau,
984            args.workspace,
985            args.dev_info,
986        )
987    }
988}
989
990impl<T> Orgtr<T>
991where
992    T: OrgtrScalar,
993{
994    /// Creates a typed ORGTR/UNGTR operation.
995    pub const fn new(fill_mode: FillMode, n: usize) -> Self {
996        Self {
997            fill_mode,
998            n,
999            _ty: PhantomData,
1000        }
1001    }
1002
1003    /// Returns the cuSOLVER fill mode.
1004    pub const fn fill_mode(&self) -> FillMode {
1005        self.fill_mode
1006    }
1007
1008    /// Returns the square matrix dimension.
1009    pub const fn n(&self) -> usize {
1010        self.n
1011    }
1012
1013    /// Returns the required legacy workspace length in elements.
1014    ///
1015    /// # Errors
1016    ///
1017    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
1018    /// workspace length.
1019    pub fn workspace_len(
1020        &self,
1021        ctx: &Context,
1022        a: MatrixRef<'_, T>,
1023        tau: VectorRef<'_, T>,
1024    ) -> Result<usize> {
1025        T::orgtr_buffer_size(ctx, self.fill_mode, self.n, a, tau)
1026    }
1027
1028    /// Forms the explicit tridiagonalization factor matrix in place.
1029    ///
1030    /// # Errors
1031    ///
1032    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
1033    /// reports a failure.
1034    pub fn run(&self, ctx: &Context, args: OrgtrArgs<'_, T>) -> Result<()> {
1035        T::orgtr(
1036            ctx,
1037            self.fill_mode,
1038            self.n,
1039            args.a,
1040            args.tau,
1041            args.workspace,
1042            args.dev_info,
1043        )
1044    }
1045}
1046
1047impl<T> Ormtr<T>
1048where
1049    T: OrmtrScalar,
1050{
1051    /// Creates a typed ORMTR/UNMTR operation.
1052    pub const fn new(
1053        side: SideMode,
1054        fill_mode: FillMode,
1055        operation: Operation,
1056        rows: usize,
1057        cols: usize,
1058    ) -> Self {
1059        Self {
1060            side,
1061            fill_mode,
1062            operation,
1063            rows,
1064            cols,
1065            _ty: PhantomData,
1066        }
1067    }
1068
1069    /// Returns which side receives the tridiagonalization factor product.
1070    pub const fn side(&self) -> SideMode {
1071        self.side
1072    }
1073
1074    /// Returns the cuSOLVER fill mode.
1075    pub const fn fill_mode(&self) -> FillMode {
1076        self.fill_mode
1077    }
1078
1079    /// Returns the operation applied to the factor product.
1080    pub const fn operation(&self) -> Operation {
1081        self.operation
1082    }
1083
1084    /// Returns the target matrix row count.
1085    pub const fn rows(&self) -> usize {
1086        self.rows
1087    }
1088
1089    /// Returns the target matrix column count.
1090    pub const fn cols(&self) -> usize {
1091        self.cols
1092    }
1093
1094    /// Returns the required legacy workspace length in elements.
1095    ///
1096    /// # Errors
1097    ///
1098    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
1099    /// workspace length.
1100    pub fn workspace_len(
1101        &self,
1102        ctx: &Context,
1103        reflectors: MatrixRef<'_, T>,
1104        tau: VectorRef<'_, T>,
1105        matrix: MatrixRef<'_, T>,
1106    ) -> Result<usize> {
1107        T::ormtr_buffer_size(
1108            ctx,
1109            self.side,
1110            self.fill_mode,
1111            self.operation,
1112            self.rows,
1113            self.cols,
1114            reflectors,
1115            tau,
1116            matrix,
1117        )
1118    }
1119
1120    /// Applies the tridiagonalization factor product in place.
1121    ///
1122    /// # Errors
1123    ///
1124    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
1125    /// reports a failure.
1126    pub fn run(&self, ctx: &Context, args: OrmtrArgs<'_, T>) -> Result<()> {
1127        T::ormtr(
1128            ctx,
1129            self.side,
1130            self.fill_mode,
1131            self.operation,
1132            self.rows,
1133            self.cols,
1134            args.reflectors,
1135            args.tau,
1136            args.matrix,
1137            args.workspace,
1138            args.dev_info,
1139        )
1140    }
1141}
1142
1143impl<TV, TTau, TT> Larft<TV, TTau, TT>
1144where
1145    TV: DataTypeLike,
1146    TTau: DataTypeLike,
1147    TT: DataTypeLike,
1148{
1149    /// Creates a typed LARFT operation using `T`'s data type as compute type.
1150    pub fn new(direct: DirectMode, storev: StorevMode, n: usize, k: usize) -> Self {
1151        Self {
1152            direct,
1153            storev,
1154            n,
1155            k,
1156            compute_type: TT::data_type(),
1157            _ty: PhantomData,
1158        }
1159    }
1160
1161    /// Sets the compute type passed to the generic cuSOLVER X API.
1162    pub const fn with_compute_type(mut self, compute_type: DataType) -> Self {
1163        self.compute_type = compute_type;
1164        self
1165    }
1166
1167    /// Returns the reflector product direction.
1168    pub const fn direct(&self) -> DirectMode {
1169        self.direct
1170    }
1171
1172    /// Returns the reflector storage mode.
1173    pub const fn storev(&self) -> StorevMode {
1174        self.storev
1175    }
1176
1177    /// Returns the reflector order.
1178    pub const fn n(&self) -> usize {
1179        self.n
1180    }
1181
1182    /// Returns the number of elementary reflectors.
1183    pub const fn k(&self) -> usize {
1184        self.k
1185    }
1186
1187    /// Returns the cuSOLVER compute type.
1188    pub const fn compute_type(&self) -> DataType {
1189        self.compute_type
1190    }
1191
1192    /// Returns the required device and host workspace sizes.
1193    ///
1194    /// # Errors
1195    ///
1196    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
1197    /// workspace sizes.
1198    pub fn workspace_size(
1199        &self,
1200        ctx: &Context,
1201        params: &Params,
1202        v: MatrixRef<'_, TV>,
1203        tau: VectorRef<'_, TTau>,
1204        t: MatrixRef<'_, TT>,
1205    ) -> Result<WorkspaceSizes> {
1206        xlarft_buffer_size(
1207            ctx,
1208            params,
1209            self.direct,
1210            self.storev,
1211            self.n,
1212            self.k,
1213            v,
1214            tau,
1215            t,
1216            self.compute_type,
1217        )
1218    }
1219
1220    /// Forms the triangular factor in place.
1221    ///
1222    /// # Errors
1223    ///
1224    /// Returns an error if inputs or workspaces are invalid, or if cuSOLVER
1225    /// reports a failure.
1226    pub fn run(
1227        &self,
1228        ctx: &Context,
1229        params: &Params,
1230        args: LarftArgs<'_, TV, TTau, TT>,
1231    ) -> Result<()> {
1232        xlarft(
1233            ctx,
1234            params,
1235            self.direct,
1236            self.storev,
1237            self.n,
1238            self.k,
1239            args.v,
1240            args.tau,
1241            args.t,
1242            self.compute_type,
1243            args.workspace,
1244        )
1245    }
1246}
1247
1248impl<TA, TTau> Geqrf<TA, TTau>
1249where
1250    TA: DataTypeLike,
1251    TTau: DataTypeLike,
1252{
1253    /// Creates a typed GEQRF operation using the matrix data type as compute type.
1254    pub fn new(rows: usize, cols: usize) -> Self {
1255        Self {
1256            rows,
1257            cols,
1258            compute_type: TA::data_type(),
1259            _ty: PhantomData,
1260        }
1261    }
1262
1263    /// Sets the compute type passed to the generic cuSOLVER X API.
1264    pub const fn with_compute_type(mut self, compute_type: DataType) -> Self {
1265        self.compute_type = compute_type;
1266        self
1267    }
1268
1269    /// Returns the matrix row count.
1270    pub const fn rows(&self) -> usize {
1271        self.rows
1272    }
1273
1274    /// Returns the matrix column count.
1275    pub const fn cols(&self) -> usize {
1276        self.cols
1277    }
1278
1279    /// Returns the cuSOLVER compute type.
1280    pub const fn compute_type(&self) -> DataType {
1281        self.compute_type
1282    }
1283
1284    /// Returns the required device and host workspace sizes.
1285    ///
1286    /// # Errors
1287    ///
1288    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
1289    /// workspace sizes.
1290    pub fn workspace_size(
1291        &self,
1292        ctx: &Context,
1293        params: &Params,
1294        a: MatrixRef<'_, TA>,
1295        tau: VectorRef<'_, TTau>,
1296    ) -> Result<WorkspaceSizes> {
1297        xgeqrf_buffer_size(ctx, params, self.rows, self.cols, a, tau, self.compute_type)
1298    }
1299
1300    /// Computes the QR factorization in place.
1301    ///
1302    /// # Errors
1303    ///
1304    /// Returns an error if inputs or workspaces are invalid, or if cuSOLVER
1305    /// reports a failure.
1306    pub fn run(&self, ctx: &Context, params: &Params, args: GeqrfArgs<'_, TA, TTau>) -> Result<()> {
1307        xgeqrf(
1308            ctx,
1309            params,
1310            self.rows,
1311            self.cols,
1312            args.a,
1313            args.tau,
1314            self.compute_type,
1315            args.workspace,
1316            args.dev_info,
1317        )
1318    }
1319}
1320
1321impl<T> Ormqr<T>
1322where
1323    T: OrmqrScalar,
1324{
1325    /// Creates a typed ORMQR/UNMQR operation.
1326    pub const fn new(
1327        side: SideMode,
1328        operation: Operation,
1329        rows: usize,
1330        cols: usize,
1331        reflectors: usize,
1332    ) -> Self {
1333        Self {
1334            side,
1335            operation,
1336            rows,
1337            cols,
1338            reflectors,
1339            _ty: PhantomData,
1340        }
1341    }
1342
1343    /// Returns which side receives the reflector product.
1344    pub const fn side(&self) -> SideMode {
1345        self.side
1346    }
1347
1348    /// Returns the operation applied to the reflector product.
1349    pub const fn operation(&self) -> Operation {
1350        self.operation
1351    }
1352
1353    /// Returns the output matrix row count.
1354    pub const fn rows(&self) -> usize {
1355        self.rows
1356    }
1357
1358    /// Returns the output matrix column count.
1359    pub const fn cols(&self) -> usize {
1360        self.cols
1361    }
1362
1363    /// Returns the number of elementary reflectors.
1364    pub const fn reflectors(&self) -> usize {
1365        self.reflectors
1366    }
1367
1368    /// Returns the required legacy workspace length in elements.
1369    ///
1370    /// # Errors
1371    ///
1372    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
1373    /// workspace length.
1374    pub fn workspace_len(
1375        &self,
1376        ctx: &Context,
1377        reflectors: MatrixRef<'_, T>,
1378        tau: VectorRef<'_, T>,
1379        matrix: MatrixRef<'_, T>,
1380    ) -> Result<usize> {
1381        T::ormqr_buffer_size(
1382            ctx,
1383            self.side,
1384            self.operation,
1385            self.rows,
1386            self.cols,
1387            self.reflectors,
1388            reflectors,
1389            tau,
1390            matrix,
1391        )
1392    }
1393
1394    /// Applies the QR reflector product in place.
1395    ///
1396    /// # Errors
1397    ///
1398    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
1399    /// reports a failure.
1400    pub fn run(&self, ctx: &Context, args: OrmqrArgs<'_, T>) -> Result<()> {
1401        T::ormqr(
1402            ctx,
1403            self.side,
1404            self.operation,
1405            self.rows,
1406            self.cols,
1407            self.reflectors,
1408            args.reflectors,
1409            args.tau,
1410            args.matrix,
1411            args.workspace,
1412            args.dev_info,
1413        )
1414    }
1415}
1416
1417impl<T> Orgqr<T>
1418where
1419    T: OrgqrScalar,
1420{
1421    /// Creates a typed ORGQR/UNGQR operation.
1422    pub const fn new(rows: usize, cols: usize, reflectors: usize) -> Self {
1423        Self {
1424            rows,
1425            cols,
1426            reflectors,
1427            _ty: PhantomData,
1428        }
1429    }
1430
1431    /// Returns the output matrix row count.
1432    pub const fn rows(&self) -> usize {
1433        self.rows
1434    }
1435
1436    /// Returns the output matrix column count.
1437    pub const fn cols(&self) -> usize {
1438        self.cols
1439    }
1440
1441    /// Returns the number of elementary reflectors.
1442    pub const fn reflectors(&self) -> usize {
1443        self.reflectors
1444    }
1445
1446    /// Returns the required legacy workspace length in elements.
1447    ///
1448    /// # Errors
1449    ///
1450    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
1451    /// workspace length.
1452    pub fn workspace_len(
1453        &self,
1454        ctx: &Context,
1455        a: MatrixRef<'_, T>,
1456        tau: VectorRef<'_, T>,
1457    ) -> Result<usize> {
1458        T::orgqr_buffer_size(ctx, self.rows, self.cols, self.reflectors, a, tau)
1459    }
1460
1461    /// Forms the explicit QR factor matrix in place.
1462    ///
1463    /// # Errors
1464    ///
1465    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
1466    /// reports a failure.
1467    pub fn run(&self, ctx: &Context, args: OrgqrArgs<'_, T>) -> Result<()> {
1468        T::orgqr(
1469            ctx,
1470            self.rows,
1471            self.cols,
1472            self.reflectors,
1473            args.a,
1474            args.tau,
1475            args.workspace,
1476            args.dev_info,
1477        )
1478    }
1479}
1480
1481impl<T> Gebrd<T>
1482where
1483    T: GebrdScalar,
1484{
1485    /// Creates a typed GEBRD operation.
1486    pub const fn new(rows: usize, cols: usize) -> Self {
1487        Self {
1488            rows,
1489            cols,
1490            _ty: PhantomData,
1491        }
1492    }
1493
1494    /// Returns the matrix row count.
1495    pub const fn rows(&self) -> usize {
1496        self.rows
1497    }
1498
1499    /// Returns the matrix column count.
1500    pub const fn cols(&self) -> usize {
1501        self.cols
1502    }
1503
1504    /// Returns the required legacy workspace length in elements.
1505    ///
1506    /// # Errors
1507    ///
1508    /// Returns an error if dimensions are invalid or if cuSOLVER cannot report
1509    /// the workspace length.
1510    pub fn workspace_len(&self, ctx: &Context) -> Result<usize> {
1511        T::gebrd_buffer_size(ctx, self.rows, self.cols)
1512    }
1513
1514    /// Reduces the matrix to bidiagonal form in place.
1515    ///
1516    /// # Errors
1517    ///
1518    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
1519    /// reports a failure.
1520    pub fn run(&self, ctx: &Context, args: GebrdArgs<'_, T>) -> Result<()> {
1521        T::gebrd(
1522            ctx,
1523            self.rows,
1524            self.cols,
1525            args.a,
1526            args.diagonal,
1527            args.off_diagonal,
1528            args.tau_q,
1529            args.tau_p,
1530            args.workspace,
1531            args.dev_info,
1532        )
1533    }
1534}
1535
1536impl<T> Orgbr<T>
1537where
1538    T: OrgbrScalar,
1539{
1540    /// Creates a typed ORGBR/UNGBR operation.
1541    pub const fn new(side: SideMode, rows: usize, cols: usize, reflectors: usize) -> Self {
1542        Self {
1543            side,
1544            rows,
1545            cols,
1546            reflectors,
1547            _ty: PhantomData,
1548        }
1549    }
1550
1551    /// Returns whether to form `Q` or `P`.
1552    pub const fn side(&self) -> SideMode {
1553        self.side
1554    }
1555
1556    /// Returns the output matrix row count.
1557    pub const fn rows(&self) -> usize {
1558        self.rows
1559    }
1560
1561    /// Returns the output matrix column count.
1562    pub const fn cols(&self) -> usize {
1563        self.cols
1564    }
1565
1566    /// Returns the number of elementary reflectors.
1567    pub const fn reflectors(&self) -> usize {
1568        self.reflectors
1569    }
1570
1571    /// Returns the required legacy workspace length in elements.
1572    ///
1573    /// # Errors
1574    ///
1575    /// Returns an error if inputs are invalid or if cuSOLVER cannot report the
1576    /// workspace length.
1577    pub fn workspace_len(
1578        &self,
1579        ctx: &Context,
1580        a: MatrixRef<'_, T>,
1581        tau: VectorRef<'_, T>,
1582    ) -> Result<usize> {
1583        T::orgbr_buffer_size(
1584            ctx,
1585            self.side,
1586            self.rows,
1587            self.cols,
1588            self.reflectors,
1589            a,
1590            tau,
1591        )
1592    }
1593
1594    /// Forms the explicit bidiagonalization factor matrix in place.
1595    ///
1596    /// # Errors
1597    ///
1598    /// Returns an error if inputs or workspace are invalid, or if cuSOLVER
1599    /// reports a failure.
1600    pub fn run(&self, ctx: &Context, args: OrgbrArgs<'_, T>) -> Result<()> {
1601        T::orgbr(
1602            ctx,
1603            self.side,
1604            self.rows,
1605            self.cols,
1606            self.reflectors,
1607            args.a,
1608            args.tau,
1609            args.workspace,
1610            args.dev_info,
1611        )
1612    }
1613}
1614
1615impl<'a, T> PotrfArgs<'a, T> {
1616    /// Groups the matrix, workspace, and info buffer needed by [`Potrf::run`].
1617    pub const fn new(
1618        a: MatrixMut<'a, T>,
1619        workspace: ByteWorkspaceMut<'a>,
1620        dev_info: &'a mut DeviceMemory<i32>,
1621    ) -> Self {
1622        Self {
1623            a,
1624            workspace,
1625            dev_info,
1626        }
1627    }
1628}
1629
1630impl<'a, T> GetrfArgs<'a, T> {
1631    /// Groups the matrix, optional pivot buffer, workspace, and info buffer.
1632    pub const fn new(
1633        a: MatrixMut<'a, T>,
1634        pivots: Option<&'a mut DeviceMemory<i64>>,
1635        workspace: ByteWorkspaceMut<'a>,
1636        dev_info: &'a mut DeviceMemory<i32>,
1637    ) -> Self {
1638        Self {
1639            a,
1640            pivots,
1641            workspace,
1642            dev_info,
1643        }
1644    }
1645}
1646
1647impl<'a, TA, TB> GetrsArgs<'a, TA, TB> {
1648    /// Groups the factorized matrix, pivots, right-hand sides, and info buffer.
1649    pub const fn new(
1650        factor: MatrixRef<'a, TA>,
1651        pivots: &'a DeviceMemory<i64>,
1652        rhs: MatrixMut<'a, TB>,
1653        dev_info: &'a mut DeviceMemory<i32>,
1654    ) -> Self {
1655        Self {
1656            factor,
1657            pivots,
1658            rhs,
1659            dev_info,
1660        }
1661    }
1662}
1663
1664impl<'a, T> TrtriArgs<'a, T> {
1665    /// Groups the triangular matrix, workspace, and info buffer.
1666    pub const fn new(
1667        a: MatrixMut<'a, T>,
1668        workspace: ByteWorkspaceMut<'a>,
1669        dev_info: &'a mut DeviceMemory<i32>,
1670    ) -> Self {
1671        Self {
1672            a,
1673            workspace,
1674            dev_info,
1675        }
1676    }
1677}
1678
1679impl<'a, TA, TB> SytrsArgs<'a, TA, TB> {
1680    /// Groups the factorized matrix, optional pivots, right-hand sides,
1681    /// workspace, and info buffer.
1682    pub const fn new(
1683        factor: MatrixRef<'a, TA>,
1684        pivots: Option<&'a DeviceMemory<i64>>,
1685        rhs: MatrixMut<'a, TB>,
1686        workspace: ByteWorkspaceMut<'a>,
1687        dev_info: &'a mut DeviceMemory<i32>,
1688    ) -> Self {
1689        Self {
1690            factor,
1691            pivots,
1692            rhs,
1693            workspace,
1694            dev_info,
1695        }
1696    }
1697}
1698
1699impl<'a, T> SytrfArgs<'a, T> {
1700    /// Groups the factor matrix, optional pivot buffer, workspace, and info
1701    /// buffer.
1702    pub const fn new(
1703        a: MatrixMut<'a, T>,
1704        pivots: Option<&'a mut DeviceMemory<i32>>,
1705        workspace: &'a mut DeviceMemory<T>,
1706        dev_info: &'a mut DeviceMemory<i32>,
1707    ) -> Self {
1708        Self {
1709            a,
1710            pivots,
1711            workspace,
1712            dev_info,
1713        }
1714    }
1715}
1716
1717impl<'a, T> SytrdArgs<'a, T>
1718where
1719    T: SytrdScalar,
1720{
1721    /// Groups the matrix, tridiagonal outputs, reflectors, workspace, and info
1722    /// buffer.
1723    pub const fn new(
1724        a: MatrixMut<'a, T>,
1725        diagonal: VectorMut<'a, T::Real>,
1726        off_diagonal: VectorMut<'a, T::Real>,
1727        tau: VectorMut<'a, T>,
1728        workspace: &'a mut DeviceMemory<T>,
1729        dev_info: &'a mut DeviceMemory<i32>,
1730    ) -> Self {
1731        Self {
1732            a,
1733            diagonal,
1734            off_diagonal,
1735            tau,
1736            workspace,
1737            dev_info,
1738        }
1739    }
1740}
1741
1742impl<'a, T> OrgtrArgs<'a, T> {
1743    /// Groups the matrix, tau vector, workspace, and info buffer.
1744    pub const fn new(
1745        a: MatrixMut<'a, T>,
1746        tau: VectorRef<'a, T>,
1747        workspace: &'a mut DeviceMemory<T>,
1748        dev_info: &'a mut DeviceMemory<i32>,
1749    ) -> Self {
1750        Self {
1751            a,
1752            tau,
1753            workspace,
1754            dev_info,
1755        }
1756    }
1757}
1758
1759impl<'a, T> OrmtrArgs<'a, T> {
1760    /// Groups the reflector matrix, tau vector, target matrix, workspace, and
1761    /// info buffer.
1762    pub const fn new(
1763        reflectors: MatrixMut<'a, T>,
1764        tau: VectorMut<'a, T>,
1765        matrix: MatrixMut<'a, T>,
1766        workspace: &'a mut DeviceMemory<T>,
1767        dev_info: &'a mut DeviceMemory<i32>,
1768    ) -> Self {
1769        Self {
1770            reflectors,
1771            tau,
1772            matrix,
1773            workspace,
1774            dev_info,
1775        }
1776    }
1777}
1778
1779impl<'a, TV, TTau, TT> LarftArgs<'a, TV, TTau, TT> {
1780    /// Groups the reflector matrix, tau vector, output factor, and workspace.
1781    pub const fn new(
1782        v: MatrixRef<'a, TV>,
1783        tau: VectorRef<'a, TTau>,
1784        t: MatrixMut<'a, TT>,
1785        workspace: ByteWorkspaceMut<'a>,
1786    ) -> Self {
1787        Self {
1788            v,
1789            tau,
1790            t,
1791            workspace,
1792        }
1793    }
1794}
1795
1796impl<'a, TA, TTau> GeqrfArgs<'a, TA, TTau> {
1797    /// Groups the matrix, tau vector, workspace, and info buffer.
1798    pub const fn new(
1799        a: MatrixMut<'a, TA>,
1800        tau: VectorMut<'a, TTau>,
1801        workspace: ByteWorkspaceMut<'a>,
1802        dev_info: &'a mut DeviceMemory<i32>,
1803    ) -> Self {
1804        Self {
1805            a,
1806            tau,
1807            workspace,
1808            dev_info,
1809        }
1810    }
1811}
1812
1813impl<'a, T> OrmqrArgs<'a, T> {
1814    /// Groups the reflector matrix, tau vector, target matrix, workspace, and
1815    /// info buffer.
1816    pub const fn new(
1817        reflectors: MatrixRef<'a, T>,
1818        tau: VectorRef<'a, T>,
1819        matrix: MatrixMut<'a, T>,
1820        workspace: &'a mut DeviceMemory<T>,
1821        dev_info: &'a mut DeviceMemory<i32>,
1822    ) -> Self {
1823        Self {
1824            reflectors,
1825            tau,
1826            matrix,
1827            workspace,
1828            dev_info,
1829        }
1830    }
1831}
1832
1833impl<'a, T> OrgqrArgs<'a, T> {
1834    /// Groups the matrix, tau vector, workspace, and info buffer.
1835    pub const fn new(
1836        a: MatrixMut<'a, T>,
1837        tau: VectorRef<'a, T>,
1838        workspace: &'a mut DeviceMemory<T>,
1839        dev_info: &'a mut DeviceMemory<i32>,
1840    ) -> Self {
1841        Self {
1842            a,
1843            tau,
1844            workspace,
1845            dev_info,
1846        }
1847    }
1848}
1849
1850impl<'a, T> GebrdArgs<'a, T>
1851where
1852    T: GebrdScalar,
1853{
1854    /// Groups the matrix, bidiagonal outputs, reflectors, workspace, and info
1855    /// buffer.
1856    pub const fn new(
1857        a: MatrixMut<'a, T>,
1858        diagonal: VectorMut<'a, T::Real>,
1859        off_diagonal: VectorMut<'a, T::Real>,
1860        tau_q: VectorMut<'a, T>,
1861        tau_p: VectorMut<'a, T>,
1862        workspace: &'a mut DeviceMemory<T>,
1863        dev_info: &'a mut DeviceMemory<i32>,
1864    ) -> Self {
1865        Self {
1866            a,
1867            diagonal,
1868            off_diagonal,
1869            tau_q,
1870            tau_p,
1871            workspace,
1872            dev_info,
1873        }
1874    }
1875}
1876
1877impl<'a, T> OrgbrArgs<'a, T> {
1878    /// Groups the matrix, tau vector, workspace, and info buffer.
1879    pub const fn new(
1880        a: MatrixMut<'a, T>,
1881        tau: VectorRef<'a, T>,
1882        workspace: &'a mut DeviceMemory<T>,
1883        dev_info: &'a mut DeviceMemory<i32>,
1884    ) -> Self {
1885        Self {
1886            a,
1887            tau,
1888            workspace,
1889            dev_info,
1890        }
1891    }
1892}
1893
1894impl<'a, T> PotrsArgs<'a, T> {
1895    /// Groups the factorized matrix, right-hand sides, and info buffer needed by [`Potrs::run`].
1896    pub const fn new(
1897        factor: MatrixRef<'a, T>,
1898        rhs: MatrixMut<'a, T>,
1899        dev_info: &'a mut DeviceMemory<i32>,
1900    ) -> Self {
1901        Self {
1902            factor,
1903            rhs,
1904            dev_info,
1905        }
1906    }
1907}
1908
1909impl<'a, T> PotriArgs<'a, T> {
1910    /// Groups the factorized matrix, workspace, and info buffer needed by [`Potri::run`].
1911    pub const fn new(
1912        factor: MatrixMut<'a, T>,
1913        workspace: &'a mut DeviceMemory<T>,
1914        dev_info: &'a mut DeviceMemory<i32>,
1915    ) -> Self {
1916        Self {
1917            factor,
1918            workspace,
1919            dev_info,
1920        }
1921    }
1922}
1923
1924impl<'a, T> BatchedPotrfArgs<'a, T> {
1925    /// Groups the matrix pointer array and info buffer needed by [`BatchedPotrf::run`].
1926    pub const fn new(a: BatchedMatrixRef<'a, T>, info: &'a mut DeviceMemory<i32>) -> Self {
1927        Self { a, info }
1928    }
1929}
1930
1931impl<'a, T> BatchedPotrsArgs<'a, T> {
1932    /// Groups the factor pointer array, right-hand-side pointer array, and info buffer.
1933    pub const fn new(
1934        factors: BatchedMatrixRef<'a, T>,
1935        rhs: BatchedVectorRef<'a, T>,
1936        info: &'a mut DeviceMemory<i32>,
1937    ) -> Self {
1938        Self { factors, rhs, info }
1939    }
1940}