1mod info;
2mod raw;
3mod validation;
4
5use singe_cuda::{
6 data_type::DataTypeLike,
7 memory::DeviceMemory,
8 types::{Complex32, Complex64},
9};
10
11use crate::{
12 context::Context,
13 error::Result,
14 layout::{ByteWorkspaceMut, MatrixMut, MatrixRef, SelectionWorkspaceSizes, WorkspaceSizes},
15 params::Params,
16 types::{EigenMode, EigenType, FillMode},
17};
18
19use raw::*;
20
21pub use info::SyevjInfo;
22
23#[derive(Debug, Clone, Copy, PartialEq)]
24#[non_exhaustive]
25pub enum EigenSelection<T> {
26 All,
27 ByValue { lower: T, upper: T },
28 ByIndex { start: usize, end: usize },
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub struct Syevd {
33 pub mode: EigenMode,
34 pub fill_mode: FillMode,
35 pub n: usize,
36 pub leading_dimension: usize,
37}
38
39impl Syevd {
40 pub fn new(mode: EigenMode, fill_mode: FillMode, n: usize, leading_dimension: usize) -> Self {
41 Self {
42 mode,
43 fill_mode,
44 n,
45 leading_dimension,
46 }
47 }
48
49 pub fn workspace_size<TA: DataTypeLike, TW: DataTypeLike>(
50 self,
51 ctx: &Context,
52 params: &Params,
53 input: SyevdInput<'_, TA, TW>,
54 ) -> Result<WorkspaceSizes> {
55 xsyevd_buffer_size(
56 ctx,
57 params,
58 self.mode,
59 self.fill_mode,
60 self.n,
61 input.a,
62 self.leading_dimension,
63 input.eigenvalues,
64 )
65 }
66
67 pub fn execute<TA: DataTypeLike, TW: DataTypeLike>(
68 self,
69 ctx: &Context,
70 params: &Params,
71 bindings: SyevdBindings<'_, TA, TW>,
72 ) -> Result<()> {
73 xsyevd(
74 ctx,
75 params,
76 self.mode,
77 self.fill_mode,
78 self.n,
79 bindings.a,
80 self.leading_dimension,
81 bindings.eigenvalues,
82 bindings.workspace,
83 bindings.dev_info,
84 )
85 }
86}
87
88#[derive(Debug, Clone, Copy)]
89pub struct SyevdInput<'a, TA, TW> {
90 pub a: &'a DeviceMemory<TA>,
91 pub eigenvalues: &'a DeviceMemory<TW>,
92}
93
94#[derive(Debug)]
95pub struct SyevdBindings<'a, TA, TW> {
96 pub a: &'a mut DeviceMemory<TA>,
97 pub eigenvalues: &'a mut DeviceMemory<TW>,
98 pub workspace: ByteWorkspaceMut<'a>,
99 pub dev_info: &'a mut DeviceMemory<i32>,
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103pub struct Geev {
104 pub n: usize,
105 pub leading_dimension: usize,
106}
107
108impl Geev {
109 pub fn new(n: usize, leading_dimension: usize) -> Self {
110 Self {
111 n,
112 leading_dimension,
113 }
114 }
115
116 pub fn workspace_size<TA: DataTypeLike, TW: DataTypeLike, TV: DataTypeLike>(
117 self,
118 ctx: &Context,
119 params: &Params,
120 input: GeevInput<'_, TA, TW, TV>,
121 ) -> Result<WorkspaceSizes> {
122 xgeev_buffer_size(
123 ctx,
124 params,
125 self.n,
126 MatrixRef::new(input.a, self.leading_dimension),
127 input.eigenvalues,
128 input.right_vectors,
129 )
130 }
131
132 pub fn execute<TA: DataTypeLike, TW: DataTypeLike, TV: DataTypeLike>(
133 self,
134 ctx: &Context,
135 params: &Params,
136 bindings: GeevBindings<'_, TA, TW, TV>,
137 ) -> Result<()> {
138 xgeev(
139 ctx,
140 params,
141 self.n,
142 MatrixMut::new(bindings.a, self.leading_dimension),
143 bindings.eigenvalues,
144 bindings.right_vectors,
145 bindings.workspace,
146 bindings.dev_info,
147 )
148 }
149}
150
151#[derive(Debug, Clone, Copy)]
152pub struct GeevInput<'a, TA, TW, TV> {
153 pub a: &'a DeviceMemory<TA>,
154 pub eigenvalues: &'a DeviceMemory<TW>,
155 pub right_vectors: Option<MatrixRef<'a, TV>>,
156}
157
158#[derive(Debug)]
159pub struct GeevBindings<'a, TA, TW, TV> {
160 pub a: &'a mut DeviceMemory<TA>,
161 pub eigenvalues: &'a mut DeviceMemory<TW>,
162 pub right_vectors: Option<MatrixMut<'a, TV>>,
163 pub workspace: ByteWorkspaceMut<'a>,
164 pub dev_info: &'a mut DeviceMemory<i32>,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq)]
168pub struct SyevBatched {
169 pub mode: EigenMode,
170 pub fill_mode: FillMode,
171 pub n: usize,
172 pub leading_dimension: usize,
173 pub batch_count: usize,
174}
175
176impl SyevBatched {
177 pub fn new(
178 mode: EigenMode,
179 fill_mode: FillMode,
180 n: usize,
181 leading_dimension: usize,
182 batch_count: usize,
183 ) -> Self {
184 Self {
185 mode,
186 fill_mode,
187 n,
188 leading_dimension,
189 batch_count,
190 }
191 }
192
193 pub fn workspace_size<TA: DataTypeLike, TW: DataTypeLike>(
194 self,
195 ctx: &Context,
196 params: &Params,
197 input: SyevdInput<'_, TA, TW>,
198 ) -> Result<WorkspaceSizes> {
199 xsyev_batched_buffer_size(
200 ctx,
201 params,
202 self.mode,
203 self.fill_mode,
204 self.n,
205 MatrixRef::new(input.a, self.leading_dimension),
206 input.eigenvalues,
207 self.batch_count,
208 )
209 }
210
211 pub fn execute<TA: DataTypeLike, TW: DataTypeLike>(
212 self,
213 ctx: &Context,
214 params: &Params,
215 bindings: SyevdBindings<'_, TA, TW>,
216 ) -> Result<()> {
217 xsyev_batched(
218 ctx,
219 params,
220 self.mode,
221 self.fill_mode,
222 self.n,
223 MatrixMut::new(bindings.a, self.leading_dimension),
224 bindings.eigenvalues,
225 self.batch_count,
226 bindings.workspace,
227 bindings.dev_info,
228 )
229 }
230}
231
232#[derive(Debug, Clone, Copy, PartialEq)]
233pub struct Syevdx<T> {
234 pub mode: EigenMode,
235 pub fill_mode: FillMode,
236 pub selection: EigenSelection<T>,
237 pub n: usize,
238 pub leading_dimension: usize,
239}
240
241impl<T> Syevdx<T> {
242 pub fn new(
243 mode: EigenMode,
244 fill_mode: FillMode,
245 selection: EigenSelection<T>,
246 n: usize,
247 leading_dimension: usize,
248 ) -> Self {
249 Self {
250 mode,
251 fill_mode,
252 selection,
253 n,
254 leading_dimension,
255 }
256 }
257}
258
259impl<T: Copy + Default> Syevdx<T> {
260 pub fn workspace_size<TA: DataTypeLike, TW: DataTypeLike>(
261 self,
262 ctx: &Context,
263 params: &Params,
264 input: SyevdInput<'_, TA, TW>,
265 ) -> Result<SelectionWorkspaceSizes> {
266 xsyevdx_buffer_size(
267 ctx,
268 params,
269 self.mode,
270 self.fill_mode,
271 self.selection,
272 self.n,
273 input.a,
274 self.leading_dimension,
275 input.eigenvalues,
276 )
277 }
278
279 pub fn execute<TA: DataTypeLike, TW: DataTypeLike>(
280 self,
281 ctx: &Context,
282 params: &Params,
283 bindings: SyevdBindings<'_, TA, TW>,
284 ) -> Result<usize> {
285 xsyevdx(
286 ctx,
287 params,
288 self.mode,
289 self.fill_mode,
290 self.selection,
291 self.n,
292 bindings.a,
293 self.leading_dimension,
294 bindings.eigenvalues,
295 bindings.workspace,
296 bindings.dev_info,
297 )
298 }
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq)]
302pub struct Syevj {
303 pub mode: EigenMode,
304 pub fill_mode: FillMode,
305 pub n: usize,
306 pub leading_dimension: usize,
307}
308
309impl Syevj {
310 pub fn new(mode: EigenMode, fill_mode: FillMode, n: usize, leading_dimension: usize) -> Self {
311 Self {
312 mode,
313 fill_mode,
314 n,
315 leading_dimension,
316 }
317 }
318
319 pub fn workspace_size_f32(
320 self,
321 ctx: &Context,
322 input: SyevjInput<'_, f32, f32>,
323 params: &SyevjInfo,
324 ) -> Result<usize> {
325 ssyevj_buffer_size(
326 ctx,
327 self.mode,
328 self.fill_mode,
329 self.n,
330 input.a,
331 self.leading_dimension,
332 input.eigenvalues,
333 params,
334 )
335 }
336
337 pub fn execute_f32(
338 self,
339 ctx: &Context,
340 bindings: SyevjBindings<'_, f32, f32>,
341 params: &SyevjInfo,
342 ) -> Result<()> {
343 ssyevj(
344 ctx,
345 self.mode,
346 self.fill_mode,
347 self.n,
348 bindings.a,
349 self.leading_dimension,
350 bindings.eigenvalues,
351 bindings.workspace,
352 bindings.dev_info,
353 params,
354 )
355 }
356
357 pub fn workspace_size_f64(
358 self,
359 ctx: &Context,
360 input: SyevjInput<'_, f64, f64>,
361 params: &SyevjInfo,
362 ) -> Result<usize> {
363 dsyevj_buffer_size(
364 ctx,
365 self.mode,
366 self.fill_mode,
367 self.n,
368 input.a,
369 self.leading_dimension,
370 input.eigenvalues,
371 params,
372 )
373 }
374
375 pub fn execute_f64(
376 self,
377 ctx: &Context,
378 bindings: SyevjBindings<'_, f64, f64>,
379 params: &SyevjInfo,
380 ) -> Result<()> {
381 dsyevj(
382 ctx,
383 self.mode,
384 self.fill_mode,
385 self.n,
386 bindings.a,
387 self.leading_dimension,
388 bindings.eigenvalues,
389 bindings.workspace,
390 bindings.dev_info,
391 params,
392 )
393 }
394
395 pub fn workspace_size_complex_f32(
396 self,
397 ctx: &Context,
398 input: SyevjInput<'_, Complex32, f32>,
399 params: &SyevjInfo,
400 ) -> Result<usize> {
401 cheevj_buffer_size(
402 ctx,
403 self.mode,
404 self.fill_mode,
405 self.n,
406 input.a,
407 self.leading_dimension,
408 input.eigenvalues,
409 params,
410 )
411 }
412
413 pub fn execute_complex_f32(
414 self,
415 ctx: &Context,
416 bindings: SyevjBindings<'_, Complex32, f32>,
417 params: &SyevjInfo,
418 ) -> Result<()> {
419 cheevj(
420 ctx,
421 self.mode,
422 self.fill_mode,
423 self.n,
424 bindings.a,
425 self.leading_dimension,
426 bindings.eigenvalues,
427 bindings.workspace,
428 bindings.dev_info,
429 params,
430 )
431 }
432
433 pub fn workspace_size_complex_f64(
434 self,
435 ctx: &Context,
436 input: SyevjInput<'_, Complex64, f64>,
437 params: &SyevjInfo,
438 ) -> Result<usize> {
439 zheevj_buffer_size(
440 ctx,
441 self.mode,
442 self.fill_mode,
443 self.n,
444 input.a,
445 self.leading_dimension,
446 input.eigenvalues,
447 params,
448 )
449 }
450
451 pub fn execute_complex_f64(
452 self,
453 ctx: &Context,
454 bindings: SyevjBindings<'_, Complex64, f64>,
455 params: &SyevjInfo,
456 ) -> Result<()> {
457 zheevj(
458 ctx,
459 self.mode,
460 self.fill_mode,
461 self.n,
462 bindings.a,
463 self.leading_dimension,
464 bindings.eigenvalues,
465 bindings.workspace,
466 bindings.dev_info,
467 params,
468 )
469 }
470}
471
472#[derive(Debug, Clone, Copy, PartialEq, Eq)]
473pub struct SyevjBatched {
474 pub mode: EigenMode,
475 pub fill_mode: FillMode,
476 pub n: usize,
477 pub leading_dimension: usize,
478 pub batch_count: usize,
479}
480
481impl SyevjBatched {
482 pub fn new(
483 mode: EigenMode,
484 fill_mode: FillMode,
485 n: usize,
486 leading_dimension: usize,
487 batch_count: usize,
488 ) -> Self {
489 Self {
490 mode,
491 fill_mode,
492 n,
493 leading_dimension,
494 batch_count,
495 }
496 }
497
498 pub fn workspace_size_f32(
499 self,
500 ctx: &Context,
501 input: SyevjInput<'_, f32, f32>,
502 params: &SyevjInfo,
503 ) -> Result<usize> {
504 ssyevj_batched_buffer_size(
505 ctx,
506 self.mode,
507 self.fill_mode,
508 self.n,
509 input.a,
510 self.leading_dimension,
511 input.eigenvalues,
512 params,
513 self.batch_count,
514 )
515 }
516
517 pub fn execute_f32(
518 self,
519 ctx: &Context,
520 bindings: SyevjBindings<'_, f32, f32>,
521 params: &SyevjInfo,
522 ) -> Result<()> {
523 ssyevj_batched(
524 ctx,
525 self.mode,
526 self.fill_mode,
527 self.n,
528 bindings.a,
529 self.leading_dimension,
530 bindings.eigenvalues,
531 bindings.workspace,
532 bindings.dev_info,
533 params,
534 self.batch_count,
535 )
536 }
537
538 pub fn workspace_size_f64(
539 self,
540 ctx: &Context,
541 input: SyevjInput<'_, f64, f64>,
542 params: &SyevjInfo,
543 ) -> Result<usize> {
544 dsyevj_batched_buffer_size(
545 ctx,
546 self.mode,
547 self.fill_mode,
548 self.n,
549 input.a,
550 self.leading_dimension,
551 input.eigenvalues,
552 params,
553 self.batch_count,
554 )
555 }
556
557 pub fn execute_f64(
558 self,
559 ctx: &Context,
560 bindings: SyevjBindings<'_, f64, f64>,
561 params: &SyevjInfo,
562 ) -> Result<()> {
563 dsyevj_batched(
564 ctx,
565 self.mode,
566 self.fill_mode,
567 self.n,
568 bindings.a,
569 self.leading_dimension,
570 bindings.eigenvalues,
571 bindings.workspace,
572 bindings.dev_info,
573 params,
574 self.batch_count,
575 )
576 }
577
578 pub fn workspace_size_complex_f32(
579 self,
580 ctx: &Context,
581 input: SyevjInput<'_, Complex32, f32>,
582 params: &SyevjInfo,
583 ) -> Result<usize> {
584 cheevj_batched_buffer_size(
585 ctx,
586 self.mode,
587 self.fill_mode,
588 self.n,
589 input.a,
590 self.leading_dimension,
591 input.eigenvalues,
592 params,
593 self.batch_count,
594 )
595 }
596
597 pub fn execute_complex_f32(
598 self,
599 ctx: &Context,
600 bindings: SyevjBindings<'_, Complex32, f32>,
601 params: &SyevjInfo,
602 ) -> Result<()> {
603 cheevj_batched(
604 ctx,
605 self.mode,
606 self.fill_mode,
607 self.n,
608 bindings.a,
609 self.leading_dimension,
610 bindings.eigenvalues,
611 bindings.workspace,
612 bindings.dev_info,
613 params,
614 self.batch_count,
615 )
616 }
617
618 pub fn workspace_size_complex_f64(
619 self,
620 ctx: &Context,
621 input: SyevjInput<'_, Complex64, f64>,
622 params: &SyevjInfo,
623 ) -> Result<usize> {
624 zheevj_batched_buffer_size(
625 ctx,
626 self.mode,
627 self.fill_mode,
628 self.n,
629 input.a,
630 self.leading_dimension,
631 input.eigenvalues,
632 params,
633 self.batch_count,
634 )
635 }
636
637 pub fn execute_complex_f64(
638 self,
639 ctx: &Context,
640 bindings: SyevjBindings<'_, Complex64, f64>,
641 params: &SyevjInfo,
642 ) -> Result<()> {
643 zheevj_batched(
644 ctx,
645 self.mode,
646 self.fill_mode,
647 self.n,
648 bindings.a,
649 self.leading_dimension,
650 bindings.eigenvalues,
651 bindings.workspace,
652 bindings.dev_info,
653 params,
654 self.batch_count,
655 )
656 }
657}
658
659#[derive(Debug, Clone, Copy)]
660pub struct SyevjInput<'a, TA, TW> {
661 pub a: &'a DeviceMemory<TA>,
662 pub eigenvalues: &'a DeviceMemory<TW>,
663}
664
665#[derive(Debug)]
666pub struct SyevjBindings<'a, TA, TW> {
667 pub a: &'a mut DeviceMemory<TA>,
668 pub eigenvalues: &'a mut DeviceMemory<TW>,
669 pub workspace: &'a mut DeviceMemory<TA>,
670 pub dev_info: &'a mut DeviceMemory<i32>,
671}
672
673#[derive(Debug, Clone, Copy, PartialEq, Eq)]
674pub struct Sygvj {
675 pub eig_type: EigenType,
676 pub mode: EigenMode,
677 pub fill_mode: FillMode,
678 pub n: usize,
679 pub leading_dimension_a: usize,
680 pub leading_dimension_b: usize,
681}
682
683impl Sygvj {
684 pub fn new(
685 eig_type: EigenType,
686 mode: EigenMode,
687 fill_mode: FillMode,
688 n: usize,
689 leading_dimension_a: usize,
690 leading_dimension_b: usize,
691 ) -> Self {
692 Self {
693 eig_type,
694 mode,
695 fill_mode,
696 n,
697 leading_dimension_a,
698 leading_dimension_b,
699 }
700 }
701
702 pub fn workspace_size_f32(
703 self,
704 ctx: &Context,
705 input: SygvInput<'_, f32, f32>,
706 params: &SyevjInfo,
707 ) -> Result<usize> {
708 ssygvj_buffer_size(
709 ctx,
710 self.eig_type,
711 self.mode,
712 self.fill_mode,
713 self.n,
714 input.a,
715 self.leading_dimension_a,
716 input.b,
717 self.leading_dimension_b,
718 input.eigenvalues,
719 params,
720 )
721 }
722
723 pub fn execute_f32(
724 self,
725 ctx: &Context,
726 bindings: SygvBindings<'_, f32, f32>,
727 params: &SyevjInfo,
728 ) -> Result<()> {
729 ssygvj(
730 ctx,
731 self.eig_type,
732 self.mode,
733 self.fill_mode,
734 self.n,
735 bindings.a,
736 self.leading_dimension_a,
737 bindings.b,
738 self.leading_dimension_b,
739 bindings.eigenvalues,
740 bindings.workspace,
741 bindings.dev_info,
742 params,
743 )
744 }
745
746 pub fn workspace_size_f64(
747 self,
748 ctx: &Context,
749 input: SygvInput<'_, f64, f64>,
750 params: &SyevjInfo,
751 ) -> Result<usize> {
752 dsygvj_buffer_size(
753 ctx,
754 self.eig_type,
755 self.mode,
756 self.fill_mode,
757 self.n,
758 input.a,
759 self.leading_dimension_a,
760 input.b,
761 self.leading_dimension_b,
762 input.eigenvalues,
763 params,
764 )
765 }
766
767 pub fn execute_f64(
768 self,
769 ctx: &Context,
770 bindings: SygvBindings<'_, f64, f64>,
771 params: &SyevjInfo,
772 ) -> Result<()> {
773 dsygvj(
774 ctx,
775 self.eig_type,
776 self.mode,
777 self.fill_mode,
778 self.n,
779 bindings.a,
780 self.leading_dimension_a,
781 bindings.b,
782 self.leading_dimension_b,
783 bindings.eigenvalues,
784 bindings.workspace,
785 bindings.dev_info,
786 params,
787 )
788 }
789
790 pub fn workspace_size_complex_f32(
791 self,
792 ctx: &Context,
793 input: SygvInput<'_, Complex32, f32>,
794 params: &SyevjInfo,
795 ) -> Result<usize> {
796 chegvj_buffer_size(
797 ctx,
798 self.eig_type,
799 self.mode,
800 self.fill_mode,
801 self.n,
802 input.a,
803 self.leading_dimension_a,
804 input.b,
805 self.leading_dimension_b,
806 input.eigenvalues,
807 params,
808 )
809 }
810
811 pub fn execute_complex_f32(
812 self,
813 ctx: &Context,
814 bindings: SygvBindings<'_, Complex32, f32>,
815 params: &SyevjInfo,
816 ) -> Result<()> {
817 chegvj(
818 ctx,
819 self.eig_type,
820 self.mode,
821 self.fill_mode,
822 self.n,
823 bindings.a,
824 self.leading_dimension_a,
825 bindings.b,
826 self.leading_dimension_b,
827 bindings.eigenvalues,
828 bindings.workspace,
829 bindings.dev_info,
830 params,
831 )
832 }
833
834 pub fn workspace_size_complex_f64(
835 self,
836 ctx: &Context,
837 input: SygvInput<'_, Complex64, f64>,
838 params: &SyevjInfo,
839 ) -> Result<usize> {
840 zhegvj_buffer_size(
841 ctx,
842 self.eig_type,
843 self.mode,
844 self.fill_mode,
845 self.n,
846 input.a,
847 self.leading_dimension_a,
848 input.b,
849 self.leading_dimension_b,
850 input.eigenvalues,
851 params,
852 )
853 }
854
855 pub fn execute_complex_f64(
856 self,
857 ctx: &Context,
858 bindings: SygvBindings<'_, Complex64, f64>,
859 params: &SyevjInfo,
860 ) -> Result<()> {
861 zhegvj(
862 ctx,
863 self.eig_type,
864 self.mode,
865 self.fill_mode,
866 self.n,
867 bindings.a,
868 self.leading_dimension_a,
869 bindings.b,
870 self.leading_dimension_b,
871 bindings.eigenvalues,
872 bindings.workspace,
873 bindings.dev_info,
874 params,
875 )
876 }
877}
878
879#[derive(Debug, Clone, Copy, PartialEq, Eq)]
880pub struct Sygvd {
881 pub eig_type: EigenType,
882 pub mode: EigenMode,
883 pub fill_mode: FillMode,
884 pub n: usize,
885 pub leading_dimension_a: usize,
886 pub leading_dimension_b: usize,
887}
888
889impl Sygvd {
890 pub fn new(
891 eig_type: EigenType,
892 mode: EigenMode,
893 fill_mode: FillMode,
894 n: usize,
895 leading_dimension_a: usize,
896 leading_dimension_b: usize,
897 ) -> Self {
898 Self {
899 eig_type,
900 mode,
901 fill_mode,
902 n,
903 leading_dimension_a,
904 leading_dimension_b,
905 }
906 }
907
908 pub fn workspace_size_f32(
909 self,
910 ctx: &Context,
911 input: SygvInput<'_, f32, f32>,
912 ) -> Result<usize> {
913 ssygvd_buffer_size(
914 ctx,
915 self.eig_type,
916 self.mode,
917 self.fill_mode,
918 self.n,
919 input.a,
920 self.leading_dimension_a,
921 input.b,
922 self.leading_dimension_b,
923 input.eigenvalues,
924 )
925 }
926
927 pub fn execute_f32(self, ctx: &Context, bindings: SygvBindings<'_, f32, f32>) -> Result<()> {
928 ssygvd(
929 ctx,
930 self.eig_type,
931 self.mode,
932 self.fill_mode,
933 self.n,
934 bindings.a,
935 self.leading_dimension_a,
936 bindings.b,
937 self.leading_dimension_b,
938 bindings.eigenvalues,
939 bindings.workspace,
940 bindings.dev_info,
941 )
942 }
943
944 pub fn workspace_size_f64(
945 self,
946 ctx: &Context,
947 input: SygvInput<'_, f64, f64>,
948 ) -> Result<usize> {
949 dsygvd_buffer_size(
950 ctx,
951 self.eig_type,
952 self.mode,
953 self.fill_mode,
954 self.n,
955 input.a,
956 self.leading_dimension_a,
957 input.b,
958 self.leading_dimension_b,
959 input.eigenvalues,
960 )
961 }
962
963 pub fn execute_f64(self, ctx: &Context, bindings: SygvBindings<'_, f64, f64>) -> Result<()> {
964 dsygvd(
965 ctx,
966 self.eig_type,
967 self.mode,
968 self.fill_mode,
969 self.n,
970 bindings.a,
971 self.leading_dimension_a,
972 bindings.b,
973 self.leading_dimension_b,
974 bindings.eigenvalues,
975 bindings.workspace,
976 bindings.dev_info,
977 )
978 }
979
980 pub fn workspace_size_complex_f32(
981 self,
982 ctx: &Context,
983 input: SygvInput<'_, Complex32, f32>,
984 ) -> Result<usize> {
985 chegvd_buffer_size(
986 ctx,
987 self.eig_type,
988 self.mode,
989 self.fill_mode,
990 self.n,
991 input.a,
992 self.leading_dimension_a,
993 input.b,
994 self.leading_dimension_b,
995 input.eigenvalues,
996 )
997 }
998
999 pub fn execute_complex_f32(
1000 self,
1001 ctx: &Context,
1002 bindings: SygvBindings<'_, Complex32, f32>,
1003 ) -> Result<()> {
1004 chegvd(
1005 ctx,
1006 self.eig_type,
1007 self.mode,
1008 self.fill_mode,
1009 self.n,
1010 bindings.a,
1011 self.leading_dimension_a,
1012 bindings.b,
1013 self.leading_dimension_b,
1014 bindings.eigenvalues,
1015 bindings.workspace,
1016 bindings.dev_info,
1017 )
1018 }
1019
1020 pub fn workspace_size_complex_f64(
1021 self,
1022 ctx: &Context,
1023 input: SygvInput<'_, Complex64, f64>,
1024 ) -> Result<usize> {
1025 zhegvd_buffer_size(
1026 ctx,
1027 self.eig_type,
1028 self.mode,
1029 self.fill_mode,
1030 self.n,
1031 input.a,
1032 self.leading_dimension_a,
1033 input.b,
1034 self.leading_dimension_b,
1035 input.eigenvalues,
1036 )
1037 }
1038
1039 pub fn execute_complex_f64(
1040 self,
1041 ctx: &Context,
1042 bindings: SygvBindings<'_, Complex64, f64>,
1043 ) -> Result<()> {
1044 zhegvd(
1045 ctx,
1046 self.eig_type,
1047 self.mode,
1048 self.fill_mode,
1049 self.n,
1050 bindings.a,
1051 self.leading_dimension_a,
1052 bindings.b,
1053 self.leading_dimension_b,
1054 bindings.eigenvalues,
1055 bindings.workspace,
1056 bindings.dev_info,
1057 )
1058 }
1059}
1060
1061#[derive(Debug, Clone, Copy, PartialEq)]
1062pub struct Sygvdx<T> {
1063 pub eig_type: EigenType,
1064 pub mode: EigenMode,
1065 pub fill_mode: FillMode,
1066 pub selection: EigenSelection<T>,
1067 pub n: usize,
1068 pub leading_dimension_a: usize,
1069 pub leading_dimension_b: usize,
1070}
1071
1072impl<T> Sygvdx<T> {
1073 pub fn new(
1074 eig_type: EigenType,
1075 mode: EigenMode,
1076 fill_mode: FillMode,
1077 selection: EigenSelection<T>,
1078 n: usize,
1079 leading_dimension_a: usize,
1080 leading_dimension_b: usize,
1081 ) -> Self {
1082 Self {
1083 eig_type,
1084 mode,
1085 fill_mode,
1086 selection,
1087 n,
1088 leading_dimension_a,
1089 leading_dimension_b,
1090 }
1091 }
1092}
1093
1094impl Sygvdx<f32> {
1095 pub fn workspace_size_f32(
1096 self,
1097 ctx: &Context,
1098 input: SygvInput<'_, f32, f32>,
1099 ) -> Result<(usize, usize)> {
1100 ssygvdx_selected_buffer_size(
1101 ctx,
1102 self.eig_type,
1103 self.mode,
1104 self.fill_mode,
1105 self.selection,
1106 self.n,
1107 input.a,
1108 self.leading_dimension_a,
1109 input.b,
1110 self.leading_dimension_b,
1111 input.eigenvalues,
1112 )
1113 }
1114
1115 pub fn execute_f32(self, ctx: &Context, bindings: SygvBindings<'_, f32, f32>) -> Result<usize> {
1116 ssygvdx_selected(
1117 ctx,
1118 self.eig_type,
1119 self.mode,
1120 self.fill_mode,
1121 self.selection,
1122 self.n,
1123 bindings.a,
1124 self.leading_dimension_a,
1125 bindings.b,
1126 self.leading_dimension_b,
1127 bindings.eigenvalues,
1128 bindings.workspace,
1129 bindings.dev_info,
1130 )
1131 }
1132
1133 pub fn workspace_size_complex_f32(
1134 self,
1135 ctx: &Context,
1136 input: SygvInput<'_, Complex32, f32>,
1137 ) -> Result<(usize, usize)> {
1138 chegvdx_selected_buffer_size(
1139 ctx,
1140 self.eig_type,
1141 self.mode,
1142 self.fill_mode,
1143 self.selection,
1144 self.n,
1145 input.a,
1146 self.leading_dimension_a,
1147 input.b,
1148 self.leading_dimension_b,
1149 input.eigenvalues,
1150 )
1151 }
1152
1153 pub fn execute_complex_f32(
1154 self,
1155 ctx: &Context,
1156 bindings: SygvBindings<'_, Complex32, f32>,
1157 ) -> Result<usize> {
1158 chegvdx_selected(
1159 ctx,
1160 self.eig_type,
1161 self.mode,
1162 self.fill_mode,
1163 self.selection,
1164 self.n,
1165 bindings.a,
1166 self.leading_dimension_a,
1167 bindings.b,
1168 self.leading_dimension_b,
1169 bindings.eigenvalues,
1170 bindings.workspace,
1171 bindings.dev_info,
1172 )
1173 }
1174}
1175
1176impl Sygvdx<f64> {
1177 pub fn workspace_size_f64(
1178 self,
1179 ctx: &Context,
1180 input: SygvInput<'_, f64, f64>,
1181 ) -> Result<(usize, usize)> {
1182 dsygvdx_selected_buffer_size(
1183 ctx,
1184 self.eig_type,
1185 self.mode,
1186 self.fill_mode,
1187 self.selection,
1188 self.n,
1189 input.a,
1190 self.leading_dimension_a,
1191 input.b,
1192 self.leading_dimension_b,
1193 input.eigenvalues,
1194 )
1195 }
1196
1197 pub fn execute_f64(self, ctx: &Context, bindings: SygvBindings<'_, f64, f64>) -> Result<usize> {
1198 dsygvdx_selected(
1199 ctx,
1200 self.eig_type,
1201 self.mode,
1202 self.fill_mode,
1203 self.selection,
1204 self.n,
1205 bindings.a,
1206 self.leading_dimension_a,
1207 bindings.b,
1208 self.leading_dimension_b,
1209 bindings.eigenvalues,
1210 bindings.workspace,
1211 bindings.dev_info,
1212 )
1213 }
1214
1215 pub fn workspace_size_complex_f64(
1216 self,
1217 ctx: &Context,
1218 input: SygvInput<'_, Complex64, f64>,
1219 ) -> Result<(usize, usize)> {
1220 zhegvdx_selected_buffer_size(
1221 ctx,
1222 self.eig_type,
1223 self.mode,
1224 self.fill_mode,
1225 self.selection,
1226 self.n,
1227 input.a,
1228 self.leading_dimension_a,
1229 input.b,
1230 self.leading_dimension_b,
1231 input.eigenvalues,
1232 )
1233 }
1234
1235 pub fn execute_complex_f64(
1236 self,
1237 ctx: &Context,
1238 bindings: SygvBindings<'_, Complex64, f64>,
1239 ) -> Result<usize> {
1240 zhegvdx_selected(
1241 ctx,
1242 self.eig_type,
1243 self.mode,
1244 self.fill_mode,
1245 self.selection,
1246 self.n,
1247 bindings.a,
1248 self.leading_dimension_a,
1249 bindings.b,
1250 self.leading_dimension_b,
1251 bindings.eigenvalues,
1252 bindings.workspace,
1253 bindings.dev_info,
1254 )
1255 }
1256}
1257
1258#[derive(Debug, Clone, Copy)]
1259pub struct SygvInput<'a, TA, TW> {
1260 pub a: &'a DeviceMemory<TA>,
1261 pub b: &'a DeviceMemory<TA>,
1262 pub eigenvalues: &'a DeviceMemory<TW>,
1263}
1264
1265#[derive(Debug)]
1266pub struct SygvBindings<'a, TA, TW> {
1267 pub a: &'a mut DeviceMemory<TA>,
1268 pub b: &'a mut DeviceMemory<TA>,
1269 pub eigenvalues: &'a mut DeviceMemory<TW>,
1270 pub workspace: &'a mut DeviceMemory<TA>,
1271 pub dev_info: &'a mut DeviceMemory<i32>,
1272}
1273
1274#[cfg(test)]
1275mod tests {
1276 use super::{EigenSelection, Geev, SyevBatched};
1277 use crate::{
1278 eigen::validation::selection_parts,
1279 types::{EigenMode, EigenRange, FillMode},
1280 };
1281
1282 #[test]
1283 fn eigen_selection_all_maps_cleanly() {
1284 let (range, values, indices) = selection_parts::<f32>(EigenSelection::All);
1285 assert_eq!(range, EigenRange::All);
1286 assert_eq!(values, None);
1287 assert_eq!(indices, None);
1288 }
1289
1290 #[test]
1291 fn eigen_selection_index_maps_cleanly() {
1292 let (range, values, indices) =
1293 selection_parts::<f64>(EigenSelection::ByIndex { start: 2, end: 5 });
1294 assert_eq!(range, EigenRange::Index);
1295 assert_eq!(values, None);
1296 assert_eq!(indices, Some((2, 5)));
1297 }
1298
1299 #[test]
1300 fn syev_batched_descriptor_preserves_operation_shape() {
1301 let op = SyevBatched::new(EigenMode::Vector, FillMode::Lower, 16, 20, 7);
1302
1303 assert_eq!(op.mode, EigenMode::Vector);
1304 assert_eq!(op.fill_mode, FillMode::Lower);
1305 assert_eq!(op.n, 16);
1306 assert_eq!(op.leading_dimension, 20);
1307 assert_eq!(op.batch_count, 7);
1308 }
1309
1310 #[test]
1311 fn geev_descriptor_preserves_operation_shape() {
1312 let op = Geev::new(12, 16);
1313
1314 assert_eq!(op.n, 12);
1315 assert_eq!(op.leading_dimension, 16);
1316 }
1317}