1#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
8#![warn(missing_debug_implementations)]
9
10use core::ffi::{c_int, c_void};
11use std::sync::OnceLock;
12
13use baracuda_core::{Library, LoaderError, platform};
14use baracuda_cuda_sys::runtime::cudaStream_t;
15use baracuda_types::CudaStatus;
16
17pub type cusparseHandle_t = *mut c_void;
21pub type cusparseSpMatDescr_t = *mut c_void;
23pub type cusparseDnMatDescr_t = *mut c_void;
25pub type cusparseDnVecDescr_t = *mut c_void;
27pub type cusparseSpGEMMDescr_t = *mut c_void;
29pub type cusparseSpSVDescr_t = *mut c_void;
31pub type cusparseSpSMDescr_t = *mut c_void;
33pub type cusparseMatDescr_t = *mut c_void;
35
36#[repr(i32)]
40#[derive(Copy, Clone, Debug, Eq, PartialEq)]
41pub enum cusparseOperation_t {
42 N = 0,
44 T = 1,
46 C = 2,
48}
49
50#[repr(i32)]
52#[derive(Copy, Clone, Debug, Eq, PartialEq)]
53pub enum cusparseIndexType_t {
54 I16U = 1,
56 I32I = 2,
58 I64I = 3,
60}
61
62#[repr(i32)]
64#[derive(Copy, Clone, Debug, Eq, PartialEq)]
65pub enum cusparseIndexBase_t {
66 Zero = 0,
68 One = 1,
70}
71
72#[repr(i32)]
74#[derive(Copy, Clone, Debug, Eq, PartialEq)]
75pub enum cusparseOrder_t {
76 Row = 1,
78 Col = 2,
80}
81
82#[repr(i32)]
84#[derive(Copy, Clone, Debug, Eq, PartialEq)]
85pub enum cusparseSpMVAlg_t {
86 Default = 0,
88 CsrAlg1 = 2,
90 CsrAlg2 = 3,
92 CooAlg1 = 1,
94 CooAlg2 = 4,
96}
97
98#[repr(i32)]
100#[derive(Copy, Clone, Debug, Eq, PartialEq)]
101pub enum cusparseSpMMAlg_t {
102 Default = 0,
104 CooAlg1 = 1,
106 CsrAlg1 = 2,
108 CooAlg2 = 3,
110 CooAlg3 = 4,
112 CsrAlg2 = 5,
114 CsrAlg3 = 6,
116 Bsr = 7,
118 CsrAlg4 = 8,
120}
121
122#[repr(i32)]
124#[derive(Copy, Clone, Debug, Eq, PartialEq)]
125pub enum cusparseSpGEMMAlg_t {
126 Default = 0,
128 Alg1 = 1,
130 Alg2 = 2,
132 Alg3 = 3,
134 CsrMemoryDefault = 4,
136}
137
138#[repr(i32)]
140#[derive(Copy, Clone, Debug, Eq, PartialEq)]
141pub enum cusparseSpSVAlg_t {
142 Default = 0,
144}
145
146#[repr(i32)]
148#[derive(Copy, Clone, Debug, Eq, PartialEq)]
149pub enum cusparseSpSMAlg_t {
150 Default = 0,
152}
153
154#[repr(i32)]
156#[derive(Copy, Clone, Debug, Eq, PartialEq)]
157pub enum cusparseSDDMMAlg_t {
158 Default = 0,
160}
161
162#[repr(i32)]
164#[derive(Copy, Clone, Debug, Eq, PartialEq)]
165pub enum cusparseCsr2CscAlg_t {
166 Alg1 = 1,
168 Alg2 = 2,
170}
171
172impl cusparseCsr2CscAlg_t {
173 pub const DEFAULT: Self = Self::Alg1;
175}
176
177#[repr(i32)]
179#[derive(Copy, Clone, Debug, Eq, PartialEq)]
180pub enum cusparseFillMode_t {
181 Lower = 0,
183 Upper = 1,
185}
186
187#[repr(i32)]
189#[derive(Copy, Clone, Debug, Eq, PartialEq)]
190pub enum cusparseDiagType_t {
191 NonUnit = 0,
193 Unit = 1,
195}
196
197#[repr(i32)]
199#[derive(Copy, Clone, Debug, Eq, PartialEq)]
200pub enum cusparseSpMatAttribute_t {
201 FillMode = 0,
203 DiagType = 1,
205}
206
207#[repr(i32)]
210#[derive(Copy, Clone, Debug, Eq, PartialEq)]
211pub enum cudaDataType {
212 R_32F = 0,
214 R_64F = 1,
216 R_16F = 2,
218 C_32F = 4,
220 C_64F = 5,
222 R_16BF = 14,
224}
225
226#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
230#[repr(transparent)]
231pub struct cusparseStatus_t(pub i32);
232
233impl cusparseStatus_t {
234 pub const SUCCESS: Self = Self(0);
236 pub const NOT_INITIALIZED: Self = Self(1);
238 pub const ALLOC_FAILED: Self = Self(2);
240 pub const INVALID_VALUE: Self = Self(3);
242 pub const ARCH_MISMATCH: Self = Self(4);
244 pub const MAPPING_ERROR: Self = Self(5);
246 pub const EXECUTION_FAILED: Self = Self(6);
248 pub const INTERNAL_ERROR: Self = Self(7);
250 pub const MATRIX_TYPE_NOT_SUPPORTED: Self = Self(8);
252 pub const ZERO_PIVOT: Self = Self(9);
254 pub const NOT_SUPPORTED: Self = Self(10);
256 pub const INSUFFICIENT_RESOURCES: Self = Self(11);
258
259 pub const fn is_success(self) -> bool {
261 self.0 == 0
262 }
263}
264
265impl CudaStatus for cusparseStatus_t {
266 fn code(self) -> i32 {
267 self.0
268 }
269 fn name(self) -> &'static str {
270 match self.0 {
271 0 => "CUSPARSE_STATUS_SUCCESS",
272 1 => "CUSPARSE_STATUS_NOT_INITIALIZED",
273 2 => "CUSPARSE_STATUS_ALLOC_FAILED",
274 3 => "CUSPARSE_STATUS_INVALID_VALUE",
275 4 => "CUSPARSE_STATUS_ARCH_MISMATCH",
276 6 => "CUSPARSE_STATUS_EXECUTION_FAILED",
277 7 => "CUSPARSE_STATUS_INTERNAL_ERROR",
278 10 => "CUSPARSE_STATUS_NOT_SUPPORTED",
279 _ => "CUSPARSE_STATUS_UNRECOGNIZED",
280 }
281 }
282 fn description(self) -> &'static str {
283 match self.0 {
284 0 => "success",
285 1 => "cuSPARSE handle not initialized",
286 2 => "allocation failed",
287 3 => "invalid argument",
288 6 => "GPU execution failed",
289 10 => "operation not supported",
290 _ => "unrecognized cuSPARSE status code",
291 }
292 }
293 fn is_success(self) -> bool {
294 cusparseStatus_t::is_success(self)
295 }
296 fn library(self) -> &'static str {
297 "cusparse"
298 }
299}
300
301pub type PFN_cusparseCreate =
305 unsafe extern "C" fn(handle: *mut cusparseHandle_t) -> cusparseStatus_t;
306pub type PFN_cusparseDestroy = unsafe extern "C" fn(handle: cusparseHandle_t) -> cusparseStatus_t;
308pub type PFN_cusparseSetStream =
310 unsafe extern "C" fn(handle: cusparseHandle_t, stream: cudaStream_t) -> cusparseStatus_t;
311pub type PFN_cusparseGetVersion =
313 unsafe extern "C" fn(handle: cusparseHandle_t, version: *mut c_int) -> cusparseStatus_t;
314
315pub type PFN_cusparseCreateCsr = unsafe extern "C" fn(
317 sp_mat: *mut cusparseSpMatDescr_t,
318 rows: i64,
319 cols: i64,
320 nnz: i64,
321 csr_row_offsets: *mut c_void,
322 csr_col_ind: *mut c_void,
323 csr_values: *mut c_void,
324 csr_row_offsets_type: cusparseIndexType_t,
325 csr_col_ind_type: cusparseIndexType_t,
326 idx_base: cusparseIndexBase_t,
327 value_type: cudaDataType,
328) -> cusparseStatus_t;
329pub type PFN_cusparseDestroySpMat =
331 unsafe extern "C" fn(descr: cusparseSpMatDescr_t) -> cusparseStatus_t;
332
333pub type PFN_cusparseCreateDnVec = unsafe extern "C" fn(
335 descr: *mut cusparseDnVecDescr_t,
336 size: i64,
337 values: *mut c_void,
338 value_type: cudaDataType,
339) -> cusparseStatus_t;
340pub type PFN_cusparseDestroyDnVec =
342 unsafe extern "C" fn(descr: cusparseDnVecDescr_t) -> cusparseStatus_t;
343
344pub type PFN_cusparseSpMV_bufferSize = unsafe extern "C" fn(
346 handle: cusparseHandle_t,
347 op: cusparseOperation_t,
348 alpha: *const c_void,
349 mat_a: cusparseSpMatDescr_t,
350 vec_x: cusparseDnVecDescr_t,
351 beta: *const c_void,
352 vec_y: cusparseDnVecDescr_t,
353 compute_type: cudaDataType,
354 alg: cusparseSpMVAlg_t,
355 buffer_size: *mut usize,
356) -> cusparseStatus_t;
357
358pub type PFN_cusparseSpMV = unsafe extern "C" fn(
360 handle: cusparseHandle_t,
361 op: cusparseOperation_t,
362 alpha: *const c_void,
363 mat_a: cusparseSpMatDescr_t,
364 vec_x: cusparseDnVecDescr_t,
365 beta: *const c_void,
366 vec_y: cusparseDnVecDescr_t,
367 compute_type: cudaDataType,
368 alg: cusparseSpMVAlg_t,
369 external_buffer: *mut c_void,
370) -> cusparseStatus_t;
371
372pub type PFN_cusparseCreateCsc = unsafe extern "C" fn(
376 sp_mat: *mut cusparseSpMatDescr_t,
377 rows: i64,
378 cols: i64,
379 nnz: i64,
380 csc_col_offsets: *mut c_void,
381 csc_row_ind: *mut c_void,
382 csc_values: *mut c_void,
383 csc_col_offsets_type: cusparseIndexType_t,
384 csc_row_ind_type: cusparseIndexType_t,
385 idx_base: cusparseIndexBase_t,
386 value_type: cudaDataType,
387) -> cusparseStatus_t;
388
389pub type PFN_cusparseCreateCoo = unsafe extern "C" fn(
391 sp_mat: *mut cusparseSpMatDescr_t,
392 rows: i64,
393 cols: i64,
394 nnz: i64,
395 coo_row_ind: *mut c_void,
396 coo_col_ind: *mut c_void,
397 coo_values: *mut c_void,
398 coo_idx_type: cusparseIndexType_t,
399 idx_base: cusparseIndexBase_t,
400 value_type: cudaDataType,
401) -> cusparseStatus_t;
402
403pub type PFN_cusparseCreateBsr = unsafe extern "C" fn(
405 sp_mat: *mut cusparseSpMatDescr_t,
406 brows: i64,
407 bcols: i64,
408 bnnz: i64,
409 row_block_dim: i64,
410 col_block_dim: i64,
411 bsr_row_offsets: *mut c_void,
412 bsr_col_ind: *mut c_void,
413 bsr_values: *mut c_void,
414 bsr_row_offsets_type: cusparseIndexType_t,
415 bsr_col_ind_type: cusparseIndexType_t,
416 idx_base: cusparseIndexBase_t,
417 value_type: cudaDataType,
418 order: cusparseOrder_t,
419) -> cusparseStatus_t;
420
421pub type PFN_cusparseCreateDnMat = unsafe extern "C" fn(
423 descr: *mut cusparseDnMatDescr_t,
424 rows: i64,
425 cols: i64,
426 ld: i64,
427 values: *mut c_void,
428 value_type: cudaDataType,
429 order: cusparseOrder_t,
430) -> cusparseStatus_t;
431
432pub type PFN_cusparseDestroyDnMat =
434 unsafe extern "C" fn(descr: cusparseDnMatDescr_t) -> cusparseStatus_t;
435
436pub type PFN_cusparseSpMatGetSize = unsafe extern "C" fn(
438 sp_mat: cusparseSpMatDescr_t,
439 rows: *mut i64,
440 cols: *mut i64,
441 nnz: *mut i64,
442) -> cusparseStatus_t;
443
444pub type PFN_cusparseSpMatSetAttribute = unsafe extern "C" fn(
446 sp_mat: cusparseSpMatDescr_t,
447 attribute: cusparseSpMatAttribute_t,
448 data: *const c_void,
449 data_size: usize,
450) -> cusparseStatus_t;
451
452pub type PFN_cusparseCsrSetPointers = unsafe extern "C" fn(
454 sp_mat: cusparseSpMatDescr_t,
455 csr_row_offsets: *mut c_void,
456 csr_col_ind: *mut c_void,
457 csr_values: *mut c_void,
458) -> cusparseStatus_t;
459
460pub type PFN_cusparseCscSetPointers = unsafe extern "C" fn(
462 sp_mat: cusparseSpMatDescr_t,
463 csc_col_offsets: *mut c_void,
464 csc_row_ind: *mut c_void,
465 csc_values: *mut c_void,
466) -> cusparseStatus_t;
467
468pub type PFN_cusparseCooSetPointers = unsafe extern "C" fn(
470 sp_mat: cusparseSpMatDescr_t,
471 coo_row_ind: *mut c_void,
472 coo_col_ind: *mut c_void,
473 coo_values: *mut c_void,
474) -> cusparseStatus_t;
475
476pub type PFN_cusparseSpMM_bufferSize = unsafe extern "C" fn(
480 handle: cusparseHandle_t,
481 op_a: cusparseOperation_t,
482 op_b: cusparseOperation_t,
483 alpha: *const c_void,
484 mat_a: cusparseSpMatDescr_t,
485 mat_b: cusparseDnMatDescr_t,
486 beta: *const c_void,
487 mat_c: cusparseDnMatDescr_t,
488 compute_type: cudaDataType,
489 alg: cusparseSpMMAlg_t,
490 buffer_size: *mut usize,
491) -> cusparseStatus_t;
492
493pub type PFN_cusparseSpMM_preprocess = unsafe extern "C" fn(
495 handle: cusparseHandle_t,
496 op_a: cusparseOperation_t,
497 op_b: cusparseOperation_t,
498 alpha: *const c_void,
499 mat_a: cusparseSpMatDescr_t,
500 mat_b: cusparseDnMatDescr_t,
501 beta: *const c_void,
502 mat_c: cusparseDnMatDescr_t,
503 compute_type: cudaDataType,
504 alg: cusparseSpMMAlg_t,
505 external_buffer: *mut c_void,
506) -> cusparseStatus_t;
507
508pub type PFN_cusparseSpMM = unsafe extern "C" fn(
510 handle: cusparseHandle_t,
511 op_a: cusparseOperation_t,
512 op_b: cusparseOperation_t,
513 alpha: *const c_void,
514 mat_a: cusparseSpMatDescr_t,
515 mat_b: cusparseDnMatDescr_t,
516 beta: *const c_void,
517 mat_c: cusparseDnMatDescr_t,
518 compute_type: cudaDataType,
519 alg: cusparseSpMMAlg_t,
520 external_buffer: *mut c_void,
521) -> cusparseStatus_t;
522
523pub type PFN_cusparseSpGEMM_createDescr =
527 unsafe extern "C" fn(descr: *mut cusparseSpGEMMDescr_t) -> cusparseStatus_t;
528pub type PFN_cusparseSpGEMM_destroyDescr =
530 unsafe extern "C" fn(descr: cusparseSpGEMMDescr_t) -> cusparseStatus_t;
531
532pub type PFN_cusparseSpGEMM_workEstimation = unsafe extern "C" fn(
534 handle: cusparseHandle_t,
535 op_a: cusparseOperation_t,
536 op_b: cusparseOperation_t,
537 alpha: *const c_void,
538 mat_a: cusparseSpMatDescr_t,
539 mat_b: cusparseSpMatDescr_t,
540 beta: *const c_void,
541 mat_c: cusparseSpMatDescr_t,
542 compute_type: cudaDataType,
543 alg: cusparseSpGEMMAlg_t,
544 descr: cusparseSpGEMMDescr_t,
545 buffer_size1: *mut usize,
546 external_buffer1: *mut c_void,
547) -> cusparseStatus_t;
548
549pub type PFN_cusparseSpGEMM_compute = unsafe extern "C" fn(
551 handle: cusparseHandle_t,
552 op_a: cusparseOperation_t,
553 op_b: cusparseOperation_t,
554 alpha: *const c_void,
555 mat_a: cusparseSpMatDescr_t,
556 mat_b: cusparseSpMatDescr_t,
557 beta: *const c_void,
558 mat_c: cusparseSpMatDescr_t,
559 compute_type: cudaDataType,
560 alg: cusparseSpGEMMAlg_t,
561 descr: cusparseSpGEMMDescr_t,
562 buffer_size2: *mut usize,
563 external_buffer2: *mut c_void,
564) -> cusparseStatus_t;
565
566pub type PFN_cusparseSpGEMM_copy = unsafe extern "C" fn(
568 handle: cusparseHandle_t,
569 op_a: cusparseOperation_t,
570 op_b: cusparseOperation_t,
571 alpha: *const c_void,
572 mat_a: cusparseSpMatDescr_t,
573 mat_b: cusparseSpMatDescr_t,
574 beta: *const c_void,
575 mat_c: cusparseSpMatDescr_t,
576 compute_type: cudaDataType,
577 alg: cusparseSpGEMMAlg_t,
578 descr: cusparseSpGEMMDescr_t,
579) -> cusparseStatus_t;
580
581pub type PFN_cusparseSpSV_createDescr =
585 unsafe extern "C" fn(descr: *mut cusparseSpSVDescr_t) -> cusparseStatus_t;
586pub type PFN_cusparseSpSV_destroyDescr =
588 unsafe extern "C" fn(descr: cusparseSpSVDescr_t) -> cusparseStatus_t;
589
590pub type PFN_cusparseSpSV_bufferSize = unsafe extern "C" fn(
592 handle: cusparseHandle_t,
593 op_a: cusparseOperation_t,
594 alpha: *const c_void,
595 mat_a: cusparseSpMatDescr_t,
596 vec_x: cusparseDnVecDescr_t,
597 vec_y: cusparseDnVecDescr_t,
598 compute_type: cudaDataType,
599 alg: cusparseSpSVAlg_t,
600 descr: cusparseSpSVDescr_t,
601 buffer_size: *mut usize,
602) -> cusparseStatus_t;
603
604pub type PFN_cusparseSpSV_analysis = unsafe extern "C" fn(
606 handle: cusparseHandle_t,
607 op_a: cusparseOperation_t,
608 alpha: *const c_void,
609 mat_a: cusparseSpMatDescr_t,
610 vec_x: cusparseDnVecDescr_t,
611 vec_y: cusparseDnVecDescr_t,
612 compute_type: cudaDataType,
613 alg: cusparseSpSVAlg_t,
614 descr: cusparseSpSVDescr_t,
615 external_buffer: *mut c_void,
616) -> cusparseStatus_t;
617
618pub type PFN_cusparseSpSV_solve = unsafe extern "C" fn(
620 handle: cusparseHandle_t,
621 op_a: cusparseOperation_t,
622 alpha: *const c_void,
623 mat_a: cusparseSpMatDescr_t,
624 vec_x: cusparseDnVecDescr_t,
625 vec_y: cusparseDnVecDescr_t,
626 compute_type: cudaDataType,
627 alg: cusparseSpSVAlg_t,
628 descr: cusparseSpSVDescr_t,
629) -> cusparseStatus_t;
630
631pub type PFN_cusparseSpSM_createDescr =
635 unsafe extern "C" fn(descr: *mut cusparseSpSMDescr_t) -> cusparseStatus_t;
636pub type PFN_cusparseSpSM_destroyDescr =
638 unsafe extern "C" fn(descr: cusparseSpSMDescr_t) -> cusparseStatus_t;
639
640pub type PFN_cusparseSpSM_bufferSize = unsafe extern "C" fn(
642 handle: cusparseHandle_t,
643 op_a: cusparseOperation_t,
644 op_b: cusparseOperation_t,
645 alpha: *const c_void,
646 mat_a: cusparseSpMatDescr_t,
647 mat_b: cusparseDnMatDescr_t,
648 mat_c: cusparseDnMatDescr_t,
649 compute_type: cudaDataType,
650 alg: cusparseSpSMAlg_t,
651 descr: cusparseSpSMDescr_t,
652 buffer_size: *mut usize,
653) -> cusparseStatus_t;
654
655pub type PFN_cusparseSpSM_analysis = unsafe extern "C" fn(
657 handle: cusparseHandle_t,
658 op_a: cusparseOperation_t,
659 op_b: cusparseOperation_t,
660 alpha: *const c_void,
661 mat_a: cusparseSpMatDescr_t,
662 mat_b: cusparseDnMatDescr_t,
663 mat_c: cusparseDnMatDescr_t,
664 compute_type: cudaDataType,
665 alg: cusparseSpSMAlg_t,
666 descr: cusparseSpSMDescr_t,
667 external_buffer: *mut c_void,
668) -> cusparseStatus_t;
669
670pub type PFN_cusparseSpSM_solve = unsafe extern "C" fn(
672 handle: cusparseHandle_t,
673 op_a: cusparseOperation_t,
674 op_b: cusparseOperation_t,
675 alpha: *const c_void,
676 mat_a: cusparseSpMatDescr_t,
677 mat_b: cusparseDnMatDescr_t,
678 mat_c: cusparseDnMatDescr_t,
679 compute_type: cudaDataType,
680 alg: cusparseSpSMAlg_t,
681 descr: cusparseSpSMDescr_t,
682) -> cusparseStatus_t;
683
684pub type PFN_cusparseSDDMM_bufferSize = unsafe extern "C" fn(
688 handle: cusparseHandle_t,
689 op_a: cusparseOperation_t,
690 op_b: cusparseOperation_t,
691 alpha: *const c_void,
692 mat_a: cusparseDnMatDescr_t,
693 mat_b: cusparseDnMatDescr_t,
694 beta: *const c_void,
695 mat_c: cusparseSpMatDescr_t,
696 compute_type: cudaDataType,
697 alg: cusparseSDDMMAlg_t,
698 buffer_size: *mut usize,
699) -> cusparseStatus_t;
700
701pub type PFN_cusparseSDDMM_preprocess = unsafe extern "C" fn(
703 handle: cusparseHandle_t,
704 op_a: cusparseOperation_t,
705 op_b: cusparseOperation_t,
706 alpha: *const c_void,
707 mat_a: cusparseDnMatDescr_t,
708 mat_b: cusparseDnMatDescr_t,
709 beta: *const c_void,
710 mat_c: cusparseSpMatDescr_t,
711 compute_type: cudaDataType,
712 alg: cusparseSDDMMAlg_t,
713 external_buffer: *mut c_void,
714) -> cusparseStatus_t;
715
716pub type PFN_cusparseSDDMM = unsafe extern "C" fn(
718 handle: cusparseHandle_t,
719 op_a: cusparseOperation_t,
720 op_b: cusparseOperation_t,
721 alpha: *const c_void,
722 mat_a: cusparseDnMatDescr_t,
723 mat_b: cusparseDnMatDescr_t,
724 beta: *const c_void,
725 mat_c: cusparseSpMatDescr_t,
726 compute_type: cudaDataType,
727 alg: cusparseSDDMMAlg_t,
728 external_buffer: *mut c_void,
729) -> cusparseStatus_t;
730
731pub type PFN_cusparseCsr2cscEx2_bufferSize = unsafe extern "C" fn(
735 handle: cusparseHandle_t,
736 m: c_int,
737 n: c_int,
738 nnz: c_int,
739 csr_val: *const c_void,
740 csr_row_ptr: *const c_int,
741 csr_col_ind: *const c_int,
742 csc_val: *mut c_void,
743 csc_col_ptr: *mut c_int,
744 csc_row_ind: *mut c_int,
745 value_type: cudaDataType,
746 copy_values: c_int,
747 idx_base: cusparseIndexBase_t,
748 alg: cusparseCsr2CscAlg_t,
749 buffer_size: *mut usize,
750) -> cusparseStatus_t;
751
752pub type PFN_cusparseCsr2cscEx2 = unsafe extern "C" fn(
754 handle: cusparseHandle_t,
755 m: c_int,
756 n: c_int,
757 nnz: c_int,
758 csr_val: *const c_void,
759 csr_row_ptr: *const c_int,
760 csr_col_ind: *const c_int,
761 csc_val: *mut c_void,
762 csc_col_ptr: *mut c_int,
763 csc_row_ind: *mut c_int,
764 value_type: cudaDataType,
765 copy_values: c_int,
766 idx_base: cusparseIndexBase_t,
767 alg: cusparseCsr2CscAlg_t,
768 buffer: *mut c_void,
769) -> cusparseStatus_t;
770
771pub type PFN_cusparseSparseToDense_bufferSize = unsafe extern "C" fn(
775 handle: cusparseHandle_t,
776 mat_a: cusparseSpMatDescr_t,
777 mat_b: cusparseDnMatDescr_t,
778 alg: c_int,
779 buffer_size: *mut usize,
780) -> cusparseStatus_t;
781
782pub type PFN_cusparseSparseToDense = unsafe extern "C" fn(
784 handle: cusparseHandle_t,
785 mat_a: cusparseSpMatDescr_t,
786 mat_b: cusparseDnMatDescr_t,
787 alg: c_int,
788 external_buffer: *mut c_void,
789) -> cusparseStatus_t;
790
791pub type PFN_cusparseDenseToSparse_bufferSize = unsafe extern "C" fn(
793 handle: cusparseHandle_t,
794 mat_a: cusparseDnMatDescr_t,
795 mat_b: cusparseSpMatDescr_t,
796 alg: c_int,
797 buffer_size: *mut usize,
798) -> cusparseStatus_t;
799
800pub type PFN_cusparseDenseToSparse_analysis = unsafe extern "C" fn(
802 handle: cusparseHandle_t,
803 mat_a: cusparseDnMatDescr_t,
804 mat_b: cusparseSpMatDescr_t,
805 alg: c_int,
806 external_buffer: *mut c_void,
807) -> cusparseStatus_t;
808
809pub type PFN_cusparseDenseToSparse_convert = unsafe extern "C" fn(
811 handle: cusparseHandle_t,
812 mat_a: cusparseDnMatDescr_t,
813 mat_b: cusparseSpMatDescr_t,
814 alg: c_int,
815 external_buffer: *mut c_void,
816) -> cusparseStatus_t;
817
818pub type PFN_cusparseAxpby = unsafe extern "C" fn(
822 handle: cusparseHandle_t,
823 alpha: *const c_void,
824 vec_x: cusparseDnVecDescr_t,
825 beta: *const c_void,
826 vec_y: cusparseDnVecDescr_t,
827) -> cusparseStatus_t;
828
829pub type PFN_cusparseGather = unsafe extern "C" fn(
831 handle: cusparseHandle_t,
832 vec_y: cusparseDnVecDescr_t,
833 vec_x: cusparseDnVecDescr_t,
834) -> cusparseStatus_t;
835
836pub type PFN_cusparseScatter = unsafe extern "C" fn(
838 handle: cusparseHandle_t,
839 vec_x: cusparseDnVecDescr_t,
840 vec_y: cusparseDnVecDescr_t,
841) -> cusparseStatus_t;
842
843pub type PFN_cusparseRot = unsafe extern "C" fn(
845 handle: cusparseHandle_t,
846 c: *const c_void,
847 s: *const c_void,
848 vec_x: cusparseDnVecDescr_t,
849 vec_y: cusparseDnVecDescr_t,
850) -> cusparseStatus_t;
851
852fn cusparse_candidates() -> Vec<String> {
855 platform::versioned_library_candidates("cusparse", &["13", "12", "11"])
856}
857
858macro_rules! cusparse_fns {
859 ($($(#[$m:meta])* $name:ident as $sym:literal : $pfn:ty);* $(;)?) => {
860 pub struct Cusparse {
862 lib: Library,
863 $($name: OnceLock<$pfn>,)*
864 }
865 impl core::fmt::Debug for Cusparse {
866 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
867 f.debug_struct("Cusparse").field("lib", &self.lib).finish_non_exhaustive()
868 }
869 }
870 impl Cusparse {
871 $(
872 $(#[$m])*
873 pub fn $name(&self) -> Result<$pfn, LoaderError> {
874 if let Some(&p) = self.$name.get() { return Ok(p); }
875 let raw: *mut () = unsafe { self.lib.raw_symbol($sym)? };
876 let p: $pfn = unsafe { core::mem::transmute_copy::<*mut (), $pfn>(&raw) };
877 let _ = self.$name.set(p);
878 Ok(p)
879 }
880 )*
881 fn empty(lib: Library) -> Self {
882 Self { lib, $($name: OnceLock::new(),)* }
883 }
884 }
885 };
886}
887
888cusparse_fns! {
889 cusparse_create as "cusparseCreate": PFN_cusparseCreate;
891 cusparse_destroy as "cusparseDestroy": PFN_cusparseDestroy;
893 cusparse_set_stream as "cusparseSetStream": PFN_cusparseSetStream;
895 cusparse_get_version as "cusparseGetVersion": PFN_cusparseGetVersion;
897 cusparse_create_csr as "cusparseCreateCsr": PFN_cusparseCreateCsr;
900 cusparse_create_csc as "cusparseCreateCsc": PFN_cusparseCreateCsc;
902 cusparse_create_coo as "cusparseCreateCoo": PFN_cusparseCreateCoo;
904 cusparse_create_bsr as "cusparseCreateBsr": PFN_cusparseCreateBsr;
906 cusparse_destroy_sp_mat as "cusparseDestroySpMat": PFN_cusparseDestroySpMat;
908 cusparse_sp_mat_get_size as "cusparseSpMatGetSize": PFN_cusparseSpMatGetSize;
910 cusparse_sp_mat_set_attribute as "cusparseSpMatSetAttribute": PFN_cusparseSpMatSetAttribute;
912 cusparse_csr_set_pointers as "cusparseCsrSetPointers": PFN_cusparseCsrSetPointers;
914 cusparse_csc_set_pointers as "cusparseCscSetPointers": PFN_cusparseCscSetPointers;
916 cusparse_coo_set_pointers as "cusparseCooSetPointers": PFN_cusparseCooSetPointers;
918 cusparse_create_dn_vec as "cusparseCreateDnVec": PFN_cusparseCreateDnVec;
921 cusparse_destroy_dn_vec as "cusparseDestroyDnVec": PFN_cusparseDestroyDnVec;
923 cusparse_create_dn_mat as "cusparseCreateDnMat": PFN_cusparseCreateDnMat;
925 cusparse_destroy_dn_mat as "cusparseDestroyDnMat": PFN_cusparseDestroyDnMat;
927 cusparse_spmv_buffer_size as "cusparseSpMV_bufferSize": PFN_cusparseSpMV_bufferSize;
930 cusparse_spmv as "cusparseSpMV": PFN_cusparseSpMV;
932 cusparse_spmm_buffer_size as "cusparseSpMM_bufferSize": PFN_cusparseSpMM_bufferSize;
935 cusparse_spmm_preprocess as "cusparseSpMM_preprocess": PFN_cusparseSpMM_preprocess;
937 cusparse_spmm as "cusparseSpMM": PFN_cusparseSpMM;
939 cusparse_spgemm_create_descr as "cusparseSpGEMM_createDescr": PFN_cusparseSpGEMM_createDescr;
942 cusparse_spgemm_destroy_descr as "cusparseSpGEMM_destroyDescr": PFN_cusparseSpGEMM_destroyDescr;
944 cusparse_spgemm_work_estimation as "cusparseSpGEMM_workEstimation": PFN_cusparseSpGEMM_workEstimation;
946 cusparse_spgemm_compute as "cusparseSpGEMM_compute": PFN_cusparseSpGEMM_compute;
948 cusparse_spgemm_copy as "cusparseSpGEMM_copy": PFN_cusparseSpGEMM_copy;
950 cusparse_spsv_create_descr as "cusparseSpSV_createDescr": PFN_cusparseSpSV_createDescr;
953 cusparse_spsv_destroy_descr as "cusparseSpSV_destroyDescr": PFN_cusparseSpSV_destroyDescr;
955 cusparse_spsv_buffer_size as "cusparseSpSV_bufferSize": PFN_cusparseSpSV_bufferSize;
957 cusparse_spsv_analysis as "cusparseSpSV_analysis": PFN_cusparseSpSV_analysis;
959 cusparse_spsv_solve as "cusparseSpSV_solve": PFN_cusparseSpSV_solve;
961 cusparse_spsm_create_descr as "cusparseSpSM_createDescr": PFN_cusparseSpSM_createDescr;
964 cusparse_spsm_destroy_descr as "cusparseSpSM_destroyDescr": PFN_cusparseSpSM_destroyDescr;
966 cusparse_spsm_buffer_size as "cusparseSpSM_bufferSize": PFN_cusparseSpSM_bufferSize;
968 cusparse_spsm_analysis as "cusparseSpSM_analysis": PFN_cusparseSpSM_analysis;
970 cusparse_spsm_solve as "cusparseSpSM_solve": PFN_cusparseSpSM_solve;
972 cusparse_sddmm_buffer_size as "cusparseSDDMM_bufferSize": PFN_cusparseSDDMM_bufferSize;
975 cusparse_sddmm_preprocess as "cusparseSDDMM_preprocess": PFN_cusparseSDDMM_preprocess;
977 cusparse_sddmm as "cusparseSDDMM": PFN_cusparseSDDMM;
979 cusparse_csr2csc_ex2_buffer_size as "cusparseCsr2cscEx2_bufferSize": PFN_cusparseCsr2cscEx2_bufferSize;
982 cusparse_csr2csc_ex2 as "cusparseCsr2cscEx2": PFN_cusparseCsr2cscEx2;
984 cusparse_sparse_to_dense_buffer_size as "cusparseSparseToDense_bufferSize": PFN_cusparseSparseToDense_bufferSize;
987 cusparse_sparse_to_dense as "cusparseSparseToDense": PFN_cusparseSparseToDense;
989 cusparse_dense_to_sparse_buffer_size as "cusparseDenseToSparse_bufferSize": PFN_cusparseDenseToSparse_bufferSize;
991 cusparse_dense_to_sparse_analysis as "cusparseDenseToSparse_analysis": PFN_cusparseDenseToSparse_analysis;
993 cusparse_dense_to_sparse_convert as "cusparseDenseToSparse_convert": PFN_cusparseDenseToSparse_convert;
995 cusparse_axpby as "cusparseAxpby": PFN_cusparseAxpby;
998 cusparse_gather as "cusparseGather": PFN_cusparseGather;
1000 cusparse_scatter as "cusparseScatter": PFN_cusparseScatter;
1002 cusparse_rot as "cusparseRot": PFN_cusparseRot;
1004}
1005
1006pub fn cusparse() -> Result<&'static Cusparse, LoaderError> {
1008 static CUSPARSE: OnceLock<Cusparse> = OnceLock::new();
1009 if let Some(c) = CUSPARSE.get() {
1010 return Ok(c);
1011 }
1012 let candidates: Vec<&'static str> = cusparse_candidates()
1013 .into_iter()
1014 .map(|s| Box::leak(s.into_boxed_str()) as &'static str)
1015 .collect();
1016 let candidates_leaked: &'static [&'static str] = Box::leak(candidates.into_boxed_slice());
1017 let lib = Library::open("cusparse", candidates_leaked)?;
1018 let c = Cusparse::empty(lib);
1019 let _ = CUSPARSE.set(c);
1020 Ok(CUSPARSE.get().expect("OnceLock set or lost race"))
1021}