1#![allow(
8 non_camel_case_types,
9 non_snake_case,
10 non_upper_case_globals,
11 reason = "names mirror the vendor C API (FFI bindings)"
12)]
13#![warn(missing_debug_implementations)]
14
15use core::ffi::{c_int, c_void};
16use std::sync::OnceLock;
17
18use baracuda_core::{Library, LoaderError, platform};
19use baracuda_cuda_sys::runtime::cudaStream_t;
20use baracuda_types::CudaStatus;
21
22pub type cusparseHandle_t = *mut c_void;
26pub type cusparseSpMatDescr_t = *mut c_void;
28pub type cusparseDnMatDescr_t = *mut c_void;
30pub type cusparseDnVecDescr_t = *mut c_void;
32pub type cusparseSpGEMMDescr_t = *mut c_void;
34pub type cusparseSpSVDescr_t = *mut c_void;
36pub type cusparseSpSMDescr_t = *mut c_void;
38pub type cusparseMatDescr_t = *mut c_void;
40
41#[repr(i32)]
45#[derive(Copy, Clone, Debug, Eq, PartialEq)]
46pub enum cusparseOperation_t {
47 N = 0,
49 T = 1,
51 C = 2,
53}
54
55#[repr(i32)]
57#[derive(Copy, Clone, Debug, Eq, PartialEq)]
58pub enum cusparseIndexType_t {
59 I16U = 1,
61 I32I = 2,
63 I64I = 3,
65}
66
67#[repr(i32)]
69#[derive(Copy, Clone, Debug, Eq, PartialEq)]
70pub enum cusparseIndexBase_t {
71 Zero = 0,
73 One = 1,
75}
76
77#[repr(i32)]
79#[derive(Copy, Clone, Debug, Eq, PartialEq)]
80pub enum cusparseOrder_t {
81 Row = 1,
83 Col = 2,
85}
86
87#[repr(i32)]
89#[derive(Copy, Clone, Debug, Eq, PartialEq)]
90pub enum cusparseSpMVAlg_t {
91 Default = 0,
93 CsrAlg1 = 2,
95 CsrAlg2 = 3,
97 CooAlg1 = 1,
99 CooAlg2 = 4,
101}
102
103#[repr(i32)]
105#[derive(Copy, Clone, Debug, Eq, PartialEq)]
106pub enum cusparseSpMMAlg_t {
107 Default = 0,
109 CooAlg1 = 1,
111 CsrAlg1 = 2,
113 CooAlg2 = 3,
115 CooAlg3 = 4,
117 CsrAlg2 = 5,
119 CsrAlg3 = 6,
121 Bsr = 7,
123 CsrAlg4 = 8,
125}
126
127#[repr(i32)]
129#[derive(Copy, Clone, Debug, Eq, PartialEq)]
130pub enum cusparseSpGEMMAlg_t {
131 Default = 0,
133 Alg1 = 1,
135 Alg2 = 2,
137 Alg3 = 3,
139 CsrMemoryDefault = 4,
141}
142
143#[repr(i32)]
145#[derive(Copy, Clone, Debug, Eq, PartialEq)]
146pub enum cusparseSpSVAlg_t {
147 Default = 0,
149}
150
151#[repr(i32)]
153#[derive(Copy, Clone, Debug, Eq, PartialEq)]
154pub enum cusparseSpSMAlg_t {
155 Default = 0,
157}
158
159#[repr(i32)]
161#[derive(Copy, Clone, Debug, Eq, PartialEq)]
162pub enum cusparseSDDMMAlg_t {
163 Default = 0,
165}
166
167#[repr(i32)]
169#[derive(Copy, Clone, Debug, Eq, PartialEq)]
170pub enum cusparseCsr2CscAlg_t {
171 Alg1 = 1,
173 Alg2 = 2,
175}
176
177impl cusparseCsr2CscAlg_t {
178 pub const DEFAULT: Self = Self::Alg1;
180}
181
182#[repr(i32)]
184#[derive(Copy, Clone, Debug, Eq, PartialEq)]
185pub enum cusparseFillMode_t {
186 Lower = 0,
188 Upper = 1,
190}
191
192#[repr(i32)]
194#[derive(Copy, Clone, Debug, Eq, PartialEq)]
195pub enum cusparseDiagType_t {
196 NonUnit = 0,
198 Unit = 1,
200}
201
202#[repr(i32)]
204#[derive(Copy, Clone, Debug, Eq, PartialEq)]
205pub enum cusparseSpMatAttribute_t {
206 FillMode = 0,
208 DiagType = 1,
210}
211
212#[repr(i32)]
215#[derive(Copy, Clone, Debug, Eq, PartialEq)]
216pub enum cudaDataType {
217 R_32F = 0,
219 R_64F = 1,
221 R_16F = 2,
223 C_32F = 4,
225 C_64F = 5,
227 R_16BF = 14,
229}
230
231#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
235#[repr(transparent)]
236pub struct cusparseStatus_t(pub i32);
237
238impl cusparseStatus_t {
239 pub const SUCCESS: Self = Self(0);
241 pub const NOT_INITIALIZED: Self = Self(1);
243 pub const ALLOC_FAILED: Self = Self(2);
245 pub const INVALID_VALUE: Self = Self(3);
247 pub const ARCH_MISMATCH: Self = Self(4);
249 pub const MAPPING_ERROR: Self = Self(5);
251 pub const EXECUTION_FAILED: Self = Self(6);
253 pub const INTERNAL_ERROR: Self = Self(7);
255 pub const MATRIX_TYPE_NOT_SUPPORTED: Self = Self(8);
257 pub const ZERO_PIVOT: Self = Self(9);
259 pub const NOT_SUPPORTED: Self = Self(10);
261 pub const INSUFFICIENT_RESOURCES: Self = Self(11);
263
264 pub const fn is_success(self) -> bool {
266 self.0 == 0
267 }
268}
269
270impl CudaStatus for cusparseStatus_t {
271 fn code(self) -> i32 {
272 self.0
273 }
274 fn name(self) -> &'static str {
275 match self.0 {
276 0 => "CUSPARSE_STATUS_SUCCESS",
277 1 => "CUSPARSE_STATUS_NOT_INITIALIZED",
278 2 => "CUSPARSE_STATUS_ALLOC_FAILED",
279 3 => "CUSPARSE_STATUS_INVALID_VALUE",
280 4 => "CUSPARSE_STATUS_ARCH_MISMATCH",
281 6 => "CUSPARSE_STATUS_EXECUTION_FAILED",
282 7 => "CUSPARSE_STATUS_INTERNAL_ERROR",
283 10 => "CUSPARSE_STATUS_NOT_SUPPORTED",
284 _ => "CUSPARSE_STATUS_UNRECOGNIZED",
285 }
286 }
287 fn description(self) -> &'static str {
288 match self.0 {
289 0 => "success",
290 1 => "cuSPARSE handle not initialized",
291 2 => "allocation failed",
292 3 => "invalid argument",
293 6 => "GPU execution failed",
294 10 => "operation not supported",
295 _ => "unrecognized cuSPARSE status code",
296 }
297 }
298 fn is_success(self) -> bool {
299 cusparseStatus_t::is_success(self)
300 }
301 fn library(self) -> &'static str {
302 "cusparse"
303 }
304}
305
306pub type PFN_cusparseCreate =
310 unsafe extern "C" fn(handle: *mut cusparseHandle_t) -> cusparseStatus_t;
311pub type PFN_cusparseDestroy = unsafe extern "C" fn(handle: cusparseHandle_t) -> cusparseStatus_t;
313pub type PFN_cusparseSetStream =
315 unsafe extern "C" fn(handle: cusparseHandle_t, stream: cudaStream_t) -> cusparseStatus_t;
316pub type PFN_cusparseGetVersion =
318 unsafe extern "C" fn(handle: cusparseHandle_t, version: *mut c_int) -> cusparseStatus_t;
319
320pub type PFN_cusparseCreateCsr = unsafe extern "C" fn(
322 sp_mat: *mut cusparseSpMatDescr_t,
323 rows: i64,
324 cols: i64,
325 nnz: i64,
326 csr_row_offsets: *mut c_void,
327 csr_col_ind: *mut c_void,
328 csr_values: *mut c_void,
329 csr_row_offsets_type: cusparseIndexType_t,
330 csr_col_ind_type: cusparseIndexType_t,
331 idx_base: cusparseIndexBase_t,
332 value_type: cudaDataType,
333) -> cusparseStatus_t;
334pub type PFN_cusparseDestroySpMat =
336 unsafe extern "C" fn(descr: cusparseSpMatDescr_t) -> cusparseStatus_t;
337
338pub type PFN_cusparseCreateDnVec = unsafe extern "C" fn(
340 descr: *mut cusparseDnVecDescr_t,
341 size: i64,
342 values: *mut c_void,
343 value_type: cudaDataType,
344) -> cusparseStatus_t;
345pub type PFN_cusparseDestroyDnVec =
347 unsafe extern "C" fn(descr: cusparseDnVecDescr_t) -> cusparseStatus_t;
348
349pub type PFN_cusparseSpMV_bufferSize = unsafe extern "C" fn(
351 handle: cusparseHandle_t,
352 op: cusparseOperation_t,
353 alpha: *const c_void,
354 mat_a: cusparseSpMatDescr_t,
355 vec_x: cusparseDnVecDescr_t,
356 beta: *const c_void,
357 vec_y: cusparseDnVecDescr_t,
358 compute_type: cudaDataType,
359 alg: cusparseSpMVAlg_t,
360 buffer_size: *mut usize,
361) -> cusparseStatus_t;
362
363pub type PFN_cusparseSpMV = unsafe extern "C" fn(
365 handle: cusparseHandle_t,
366 op: cusparseOperation_t,
367 alpha: *const c_void,
368 mat_a: cusparseSpMatDescr_t,
369 vec_x: cusparseDnVecDescr_t,
370 beta: *const c_void,
371 vec_y: cusparseDnVecDescr_t,
372 compute_type: cudaDataType,
373 alg: cusparseSpMVAlg_t,
374 external_buffer: *mut c_void,
375) -> cusparseStatus_t;
376
377pub type PFN_cusparseCreateCsc = unsafe extern "C" fn(
381 sp_mat: *mut cusparseSpMatDescr_t,
382 rows: i64,
383 cols: i64,
384 nnz: i64,
385 csc_col_offsets: *mut c_void,
386 csc_row_ind: *mut c_void,
387 csc_values: *mut c_void,
388 csc_col_offsets_type: cusparseIndexType_t,
389 csc_row_ind_type: cusparseIndexType_t,
390 idx_base: cusparseIndexBase_t,
391 value_type: cudaDataType,
392) -> cusparseStatus_t;
393
394pub type PFN_cusparseCreateCoo = unsafe extern "C" fn(
396 sp_mat: *mut cusparseSpMatDescr_t,
397 rows: i64,
398 cols: i64,
399 nnz: i64,
400 coo_row_ind: *mut c_void,
401 coo_col_ind: *mut c_void,
402 coo_values: *mut c_void,
403 coo_idx_type: cusparseIndexType_t,
404 idx_base: cusparseIndexBase_t,
405 value_type: cudaDataType,
406) -> cusparseStatus_t;
407
408pub type PFN_cusparseCreateBsr = unsafe extern "C" fn(
410 sp_mat: *mut cusparseSpMatDescr_t,
411 brows: i64,
412 bcols: i64,
413 bnnz: i64,
414 row_block_dim: i64,
415 col_block_dim: i64,
416 bsr_row_offsets: *mut c_void,
417 bsr_col_ind: *mut c_void,
418 bsr_values: *mut c_void,
419 bsr_row_offsets_type: cusparseIndexType_t,
420 bsr_col_ind_type: cusparseIndexType_t,
421 idx_base: cusparseIndexBase_t,
422 value_type: cudaDataType,
423 order: cusparseOrder_t,
424) -> cusparseStatus_t;
425
426pub type PFN_cusparseCreateDnMat = unsafe extern "C" fn(
428 descr: *mut cusparseDnMatDescr_t,
429 rows: i64,
430 cols: i64,
431 ld: i64,
432 values: *mut c_void,
433 value_type: cudaDataType,
434 order: cusparseOrder_t,
435) -> cusparseStatus_t;
436
437pub type PFN_cusparseDestroyDnMat =
439 unsafe extern "C" fn(descr: cusparseDnMatDescr_t) -> cusparseStatus_t;
440
441pub type PFN_cusparseSpMatGetSize = unsafe extern "C" fn(
443 sp_mat: cusparseSpMatDescr_t,
444 rows: *mut i64,
445 cols: *mut i64,
446 nnz: *mut i64,
447) -> cusparseStatus_t;
448
449pub type PFN_cusparseSpMatSetAttribute = unsafe extern "C" fn(
451 sp_mat: cusparseSpMatDescr_t,
452 attribute: cusparseSpMatAttribute_t,
453 data: *const c_void,
454 data_size: usize,
455) -> cusparseStatus_t;
456
457pub type PFN_cusparseCsrSetPointers = unsafe extern "C" fn(
459 sp_mat: cusparseSpMatDescr_t,
460 csr_row_offsets: *mut c_void,
461 csr_col_ind: *mut c_void,
462 csr_values: *mut c_void,
463) -> cusparseStatus_t;
464
465pub type PFN_cusparseCscSetPointers = unsafe extern "C" fn(
467 sp_mat: cusparseSpMatDescr_t,
468 csc_col_offsets: *mut c_void,
469 csc_row_ind: *mut c_void,
470 csc_values: *mut c_void,
471) -> cusparseStatus_t;
472
473pub type PFN_cusparseCooSetPointers = unsafe extern "C" fn(
475 sp_mat: cusparseSpMatDescr_t,
476 coo_row_ind: *mut c_void,
477 coo_col_ind: *mut c_void,
478 coo_values: *mut c_void,
479) -> cusparseStatus_t;
480
481pub type PFN_cusparseSpMM_bufferSize = unsafe extern "C" fn(
485 handle: cusparseHandle_t,
486 op_a: cusparseOperation_t,
487 op_b: cusparseOperation_t,
488 alpha: *const c_void,
489 mat_a: cusparseSpMatDescr_t,
490 mat_b: cusparseDnMatDescr_t,
491 beta: *const c_void,
492 mat_c: cusparseDnMatDescr_t,
493 compute_type: cudaDataType,
494 alg: cusparseSpMMAlg_t,
495 buffer_size: *mut usize,
496) -> cusparseStatus_t;
497
498pub type PFN_cusparseSpMM_preprocess = unsafe extern "C" fn(
500 handle: cusparseHandle_t,
501 op_a: cusparseOperation_t,
502 op_b: cusparseOperation_t,
503 alpha: *const c_void,
504 mat_a: cusparseSpMatDescr_t,
505 mat_b: cusparseDnMatDescr_t,
506 beta: *const c_void,
507 mat_c: cusparseDnMatDescr_t,
508 compute_type: cudaDataType,
509 alg: cusparseSpMMAlg_t,
510 external_buffer: *mut c_void,
511) -> cusparseStatus_t;
512
513pub type PFN_cusparseSpMM = unsafe extern "C" fn(
515 handle: cusparseHandle_t,
516 op_a: cusparseOperation_t,
517 op_b: cusparseOperation_t,
518 alpha: *const c_void,
519 mat_a: cusparseSpMatDescr_t,
520 mat_b: cusparseDnMatDescr_t,
521 beta: *const c_void,
522 mat_c: cusparseDnMatDescr_t,
523 compute_type: cudaDataType,
524 alg: cusparseSpMMAlg_t,
525 external_buffer: *mut c_void,
526) -> cusparseStatus_t;
527
528pub type PFN_cusparseSpGEMM_createDescr =
532 unsafe extern "C" fn(descr: *mut cusparseSpGEMMDescr_t) -> cusparseStatus_t;
533pub type PFN_cusparseSpGEMM_destroyDescr =
535 unsafe extern "C" fn(descr: cusparseSpGEMMDescr_t) -> cusparseStatus_t;
536
537pub type PFN_cusparseSpGEMM_workEstimation = unsafe extern "C" fn(
539 handle: cusparseHandle_t,
540 op_a: cusparseOperation_t,
541 op_b: cusparseOperation_t,
542 alpha: *const c_void,
543 mat_a: cusparseSpMatDescr_t,
544 mat_b: cusparseSpMatDescr_t,
545 beta: *const c_void,
546 mat_c: cusparseSpMatDescr_t,
547 compute_type: cudaDataType,
548 alg: cusparseSpGEMMAlg_t,
549 descr: cusparseSpGEMMDescr_t,
550 buffer_size1: *mut usize,
551 external_buffer1: *mut c_void,
552) -> cusparseStatus_t;
553
554pub type PFN_cusparseSpGEMM_compute = unsafe extern "C" fn(
556 handle: cusparseHandle_t,
557 op_a: cusparseOperation_t,
558 op_b: cusparseOperation_t,
559 alpha: *const c_void,
560 mat_a: cusparseSpMatDescr_t,
561 mat_b: cusparseSpMatDescr_t,
562 beta: *const c_void,
563 mat_c: cusparseSpMatDescr_t,
564 compute_type: cudaDataType,
565 alg: cusparseSpGEMMAlg_t,
566 descr: cusparseSpGEMMDescr_t,
567 buffer_size2: *mut usize,
568 external_buffer2: *mut c_void,
569) -> cusparseStatus_t;
570
571pub type PFN_cusparseSpGEMM_copy = unsafe extern "C" fn(
573 handle: cusparseHandle_t,
574 op_a: cusparseOperation_t,
575 op_b: cusparseOperation_t,
576 alpha: *const c_void,
577 mat_a: cusparseSpMatDescr_t,
578 mat_b: cusparseSpMatDescr_t,
579 beta: *const c_void,
580 mat_c: cusparseSpMatDescr_t,
581 compute_type: cudaDataType,
582 alg: cusparseSpGEMMAlg_t,
583 descr: cusparseSpGEMMDescr_t,
584) -> cusparseStatus_t;
585
586pub type PFN_cusparseSpSV_createDescr =
590 unsafe extern "C" fn(descr: *mut cusparseSpSVDescr_t) -> cusparseStatus_t;
591pub type PFN_cusparseSpSV_destroyDescr =
593 unsafe extern "C" fn(descr: cusparseSpSVDescr_t) -> cusparseStatus_t;
594
595pub type PFN_cusparseSpSV_bufferSize = unsafe extern "C" fn(
597 handle: cusparseHandle_t,
598 op_a: cusparseOperation_t,
599 alpha: *const c_void,
600 mat_a: cusparseSpMatDescr_t,
601 vec_x: cusparseDnVecDescr_t,
602 vec_y: cusparseDnVecDescr_t,
603 compute_type: cudaDataType,
604 alg: cusparseSpSVAlg_t,
605 descr: cusparseSpSVDescr_t,
606 buffer_size: *mut usize,
607) -> cusparseStatus_t;
608
609pub type PFN_cusparseSpSV_analysis = unsafe extern "C" fn(
611 handle: cusparseHandle_t,
612 op_a: cusparseOperation_t,
613 alpha: *const c_void,
614 mat_a: cusparseSpMatDescr_t,
615 vec_x: cusparseDnVecDescr_t,
616 vec_y: cusparseDnVecDescr_t,
617 compute_type: cudaDataType,
618 alg: cusparseSpSVAlg_t,
619 descr: cusparseSpSVDescr_t,
620 external_buffer: *mut c_void,
621) -> cusparseStatus_t;
622
623pub type PFN_cusparseSpSV_solve = unsafe extern "C" fn(
625 handle: cusparseHandle_t,
626 op_a: cusparseOperation_t,
627 alpha: *const c_void,
628 mat_a: cusparseSpMatDescr_t,
629 vec_x: cusparseDnVecDescr_t,
630 vec_y: cusparseDnVecDescr_t,
631 compute_type: cudaDataType,
632 alg: cusparseSpSVAlg_t,
633 descr: cusparseSpSVDescr_t,
634) -> cusparseStatus_t;
635
636pub type PFN_cusparseSpSM_createDescr =
640 unsafe extern "C" fn(descr: *mut cusparseSpSMDescr_t) -> cusparseStatus_t;
641pub type PFN_cusparseSpSM_destroyDescr =
643 unsafe extern "C" fn(descr: cusparseSpSMDescr_t) -> cusparseStatus_t;
644
645pub type PFN_cusparseSpSM_bufferSize = unsafe extern "C" fn(
647 handle: cusparseHandle_t,
648 op_a: cusparseOperation_t,
649 op_b: cusparseOperation_t,
650 alpha: *const c_void,
651 mat_a: cusparseSpMatDescr_t,
652 mat_b: cusparseDnMatDescr_t,
653 mat_c: cusparseDnMatDescr_t,
654 compute_type: cudaDataType,
655 alg: cusparseSpSMAlg_t,
656 descr: cusparseSpSMDescr_t,
657 buffer_size: *mut usize,
658) -> cusparseStatus_t;
659
660pub type PFN_cusparseSpSM_analysis = unsafe extern "C" fn(
662 handle: cusparseHandle_t,
663 op_a: cusparseOperation_t,
664 op_b: cusparseOperation_t,
665 alpha: *const c_void,
666 mat_a: cusparseSpMatDescr_t,
667 mat_b: cusparseDnMatDescr_t,
668 mat_c: cusparseDnMatDescr_t,
669 compute_type: cudaDataType,
670 alg: cusparseSpSMAlg_t,
671 descr: cusparseSpSMDescr_t,
672 external_buffer: *mut c_void,
673) -> cusparseStatus_t;
674
675pub type PFN_cusparseSpSM_solve = unsafe extern "C" fn(
677 handle: cusparseHandle_t,
678 op_a: cusparseOperation_t,
679 op_b: cusparseOperation_t,
680 alpha: *const c_void,
681 mat_a: cusparseSpMatDescr_t,
682 mat_b: cusparseDnMatDescr_t,
683 mat_c: cusparseDnMatDescr_t,
684 compute_type: cudaDataType,
685 alg: cusparseSpSMAlg_t,
686 descr: cusparseSpSMDescr_t,
687) -> cusparseStatus_t;
688
689pub type PFN_cusparseSDDMM_bufferSize = unsafe extern "C" fn(
693 handle: cusparseHandle_t,
694 op_a: cusparseOperation_t,
695 op_b: cusparseOperation_t,
696 alpha: *const c_void,
697 mat_a: cusparseDnMatDescr_t,
698 mat_b: cusparseDnMatDescr_t,
699 beta: *const c_void,
700 mat_c: cusparseSpMatDescr_t,
701 compute_type: cudaDataType,
702 alg: cusparseSDDMMAlg_t,
703 buffer_size: *mut usize,
704) -> cusparseStatus_t;
705
706pub type PFN_cusparseSDDMM_preprocess = unsafe extern "C" fn(
708 handle: cusparseHandle_t,
709 op_a: cusparseOperation_t,
710 op_b: cusparseOperation_t,
711 alpha: *const c_void,
712 mat_a: cusparseDnMatDescr_t,
713 mat_b: cusparseDnMatDescr_t,
714 beta: *const c_void,
715 mat_c: cusparseSpMatDescr_t,
716 compute_type: cudaDataType,
717 alg: cusparseSDDMMAlg_t,
718 external_buffer: *mut c_void,
719) -> cusparseStatus_t;
720
721pub type PFN_cusparseSDDMM = unsafe extern "C" fn(
723 handle: cusparseHandle_t,
724 op_a: cusparseOperation_t,
725 op_b: cusparseOperation_t,
726 alpha: *const c_void,
727 mat_a: cusparseDnMatDescr_t,
728 mat_b: cusparseDnMatDescr_t,
729 beta: *const c_void,
730 mat_c: cusparseSpMatDescr_t,
731 compute_type: cudaDataType,
732 alg: cusparseSDDMMAlg_t,
733 external_buffer: *mut c_void,
734) -> cusparseStatus_t;
735
736pub type PFN_cusparseCsr2cscEx2_bufferSize = unsafe extern "C" fn(
740 handle: cusparseHandle_t,
741 m: c_int,
742 n: c_int,
743 nnz: c_int,
744 csr_val: *const c_void,
745 csr_row_ptr: *const c_int,
746 csr_col_ind: *const c_int,
747 csc_val: *mut c_void,
748 csc_col_ptr: *mut c_int,
749 csc_row_ind: *mut c_int,
750 value_type: cudaDataType,
751 copy_values: c_int,
752 idx_base: cusparseIndexBase_t,
753 alg: cusparseCsr2CscAlg_t,
754 buffer_size: *mut usize,
755) -> cusparseStatus_t;
756
757pub type PFN_cusparseCsr2cscEx2 = unsafe extern "C" fn(
759 handle: cusparseHandle_t,
760 m: c_int,
761 n: c_int,
762 nnz: c_int,
763 csr_val: *const c_void,
764 csr_row_ptr: *const c_int,
765 csr_col_ind: *const c_int,
766 csc_val: *mut c_void,
767 csc_col_ptr: *mut c_int,
768 csc_row_ind: *mut c_int,
769 value_type: cudaDataType,
770 copy_values: c_int,
771 idx_base: cusparseIndexBase_t,
772 alg: cusparseCsr2CscAlg_t,
773 buffer: *mut c_void,
774) -> cusparseStatus_t;
775
776pub type PFN_cusparseSparseToDense_bufferSize = unsafe extern "C" fn(
780 handle: cusparseHandle_t,
781 mat_a: cusparseSpMatDescr_t,
782 mat_b: cusparseDnMatDescr_t,
783 alg: c_int,
784 buffer_size: *mut usize,
785) -> cusparseStatus_t;
786
787pub type PFN_cusparseSparseToDense = unsafe extern "C" fn(
789 handle: cusparseHandle_t,
790 mat_a: cusparseSpMatDescr_t,
791 mat_b: cusparseDnMatDescr_t,
792 alg: c_int,
793 external_buffer: *mut c_void,
794) -> cusparseStatus_t;
795
796pub type PFN_cusparseDenseToSparse_bufferSize = unsafe extern "C" fn(
798 handle: cusparseHandle_t,
799 mat_a: cusparseDnMatDescr_t,
800 mat_b: cusparseSpMatDescr_t,
801 alg: c_int,
802 buffer_size: *mut usize,
803) -> cusparseStatus_t;
804
805pub type PFN_cusparseDenseToSparse_analysis = unsafe extern "C" fn(
807 handle: cusparseHandle_t,
808 mat_a: cusparseDnMatDescr_t,
809 mat_b: cusparseSpMatDescr_t,
810 alg: c_int,
811 external_buffer: *mut c_void,
812) -> cusparseStatus_t;
813
814pub type PFN_cusparseDenseToSparse_convert = unsafe extern "C" fn(
816 handle: cusparseHandle_t,
817 mat_a: cusparseDnMatDescr_t,
818 mat_b: cusparseSpMatDescr_t,
819 alg: c_int,
820 external_buffer: *mut c_void,
821) -> cusparseStatus_t;
822
823pub type PFN_cusparseAxpby = unsafe extern "C" fn(
827 handle: cusparseHandle_t,
828 alpha: *const c_void,
829 vec_x: cusparseDnVecDescr_t,
830 beta: *const c_void,
831 vec_y: cusparseDnVecDescr_t,
832) -> cusparseStatus_t;
833
834pub type PFN_cusparseGather = unsafe extern "C" fn(
836 handle: cusparseHandle_t,
837 vec_y: cusparseDnVecDescr_t,
838 vec_x: cusparseDnVecDescr_t,
839) -> cusparseStatus_t;
840
841pub type PFN_cusparseScatter = unsafe extern "C" fn(
843 handle: cusparseHandle_t,
844 vec_x: cusparseDnVecDescr_t,
845 vec_y: cusparseDnVecDescr_t,
846) -> cusparseStatus_t;
847
848pub type PFN_cusparseRot = unsafe extern "C" fn(
850 handle: cusparseHandle_t,
851 c: *const c_void,
852 s: *const c_void,
853 vec_x: cusparseDnVecDescr_t,
854 vec_y: cusparseDnVecDescr_t,
855) -> cusparseStatus_t;
856
857fn cusparse_candidates() -> Vec<String> {
860 platform::versioned_library_candidates("cusparse", &["13", "12", "11"])
861}
862
863macro_rules! cusparse_fns {
864 ($($(#[$m:meta])* $name:ident as $sym:literal : $pfn:ty);* $(;)?) => {
865 pub struct Cusparse {
867 lib: Library,
868 $($name: OnceLock<$pfn>,)*
869 }
870 impl core::fmt::Debug for Cusparse {
871 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
872 f.debug_struct("Cusparse").field("lib", &self.lib).finish_non_exhaustive()
873 }
874 }
875 impl Cusparse {
876 $(
877 $(#[$m])*
878 pub fn $name(&self) -> Result<$pfn, LoaderError> {
879 if let Some(&p) = self.$name.get() { return Ok(p); }
880 let raw: *mut () = unsafe { self.lib.raw_symbol($sym)? };
881 let p: $pfn = unsafe { core::mem::transmute_copy::<*mut (), $pfn>(&raw) };
882 let _ = self.$name.set(p);
883 Ok(p)
884 }
885 )*
886 fn empty(lib: Library) -> Self {
887 Self { lib, $($name: OnceLock::new(),)* }
888 }
889 }
890 };
891}
892
893cusparse_fns! {
894 cusparse_create as "cusparseCreate": PFN_cusparseCreate;
896 cusparse_destroy as "cusparseDestroy": PFN_cusparseDestroy;
898 cusparse_set_stream as "cusparseSetStream": PFN_cusparseSetStream;
900 cusparse_get_version as "cusparseGetVersion": PFN_cusparseGetVersion;
902 cusparse_create_csr as "cusparseCreateCsr": PFN_cusparseCreateCsr;
905 cusparse_create_csc as "cusparseCreateCsc": PFN_cusparseCreateCsc;
907 cusparse_create_coo as "cusparseCreateCoo": PFN_cusparseCreateCoo;
909 cusparse_create_bsr as "cusparseCreateBsr": PFN_cusparseCreateBsr;
911 cusparse_destroy_sp_mat as "cusparseDestroySpMat": PFN_cusparseDestroySpMat;
913 cusparse_sp_mat_get_size as "cusparseSpMatGetSize": PFN_cusparseSpMatGetSize;
915 cusparse_sp_mat_set_attribute as "cusparseSpMatSetAttribute": PFN_cusparseSpMatSetAttribute;
917 cusparse_csr_set_pointers as "cusparseCsrSetPointers": PFN_cusparseCsrSetPointers;
919 cusparse_csc_set_pointers as "cusparseCscSetPointers": PFN_cusparseCscSetPointers;
921 cusparse_coo_set_pointers as "cusparseCooSetPointers": PFN_cusparseCooSetPointers;
923 cusparse_create_dn_vec as "cusparseCreateDnVec": PFN_cusparseCreateDnVec;
926 cusparse_destroy_dn_vec as "cusparseDestroyDnVec": PFN_cusparseDestroyDnVec;
928 cusparse_create_dn_mat as "cusparseCreateDnMat": PFN_cusparseCreateDnMat;
930 cusparse_destroy_dn_mat as "cusparseDestroyDnMat": PFN_cusparseDestroyDnMat;
932 cusparse_spmv_buffer_size as "cusparseSpMV_bufferSize": PFN_cusparseSpMV_bufferSize;
935 cusparse_spmv as "cusparseSpMV": PFN_cusparseSpMV;
937 cusparse_spmm_buffer_size as "cusparseSpMM_bufferSize": PFN_cusparseSpMM_bufferSize;
940 cusparse_spmm_preprocess as "cusparseSpMM_preprocess": PFN_cusparseSpMM_preprocess;
942 cusparse_spmm as "cusparseSpMM": PFN_cusparseSpMM;
944 cusparse_spgemm_create_descr as "cusparseSpGEMM_createDescr": PFN_cusparseSpGEMM_createDescr;
947 cusparse_spgemm_destroy_descr as "cusparseSpGEMM_destroyDescr": PFN_cusparseSpGEMM_destroyDescr;
949 cusparse_spgemm_work_estimation as "cusparseSpGEMM_workEstimation": PFN_cusparseSpGEMM_workEstimation;
951 cusparse_spgemm_compute as "cusparseSpGEMM_compute": PFN_cusparseSpGEMM_compute;
953 cusparse_spgemm_copy as "cusparseSpGEMM_copy": PFN_cusparseSpGEMM_copy;
955 cusparse_spsv_create_descr as "cusparseSpSV_createDescr": PFN_cusparseSpSV_createDescr;
958 cusparse_spsv_destroy_descr as "cusparseSpSV_destroyDescr": PFN_cusparseSpSV_destroyDescr;
960 cusparse_spsv_buffer_size as "cusparseSpSV_bufferSize": PFN_cusparseSpSV_bufferSize;
962 cusparse_spsv_analysis as "cusparseSpSV_analysis": PFN_cusparseSpSV_analysis;
964 cusparse_spsv_solve as "cusparseSpSV_solve": PFN_cusparseSpSV_solve;
966 cusparse_spsm_create_descr as "cusparseSpSM_createDescr": PFN_cusparseSpSM_createDescr;
969 cusparse_spsm_destroy_descr as "cusparseSpSM_destroyDescr": PFN_cusparseSpSM_destroyDescr;
971 cusparse_spsm_buffer_size as "cusparseSpSM_bufferSize": PFN_cusparseSpSM_bufferSize;
973 cusparse_spsm_analysis as "cusparseSpSM_analysis": PFN_cusparseSpSM_analysis;
975 cusparse_spsm_solve as "cusparseSpSM_solve": PFN_cusparseSpSM_solve;
977 cusparse_sddmm_buffer_size as "cusparseSDDMM_bufferSize": PFN_cusparseSDDMM_bufferSize;
980 cusparse_sddmm_preprocess as "cusparseSDDMM_preprocess": PFN_cusparseSDDMM_preprocess;
982 cusparse_sddmm as "cusparseSDDMM": PFN_cusparseSDDMM;
984 cusparse_csr2csc_ex2_buffer_size as "cusparseCsr2cscEx2_bufferSize": PFN_cusparseCsr2cscEx2_bufferSize;
987 cusparse_csr2csc_ex2 as "cusparseCsr2cscEx2": PFN_cusparseCsr2cscEx2;
989 cusparse_sparse_to_dense_buffer_size as "cusparseSparseToDense_bufferSize": PFN_cusparseSparseToDense_bufferSize;
992 cusparse_sparse_to_dense as "cusparseSparseToDense": PFN_cusparseSparseToDense;
994 cusparse_dense_to_sparse_buffer_size as "cusparseDenseToSparse_bufferSize": PFN_cusparseDenseToSparse_bufferSize;
996 cusparse_dense_to_sparse_analysis as "cusparseDenseToSparse_analysis": PFN_cusparseDenseToSparse_analysis;
998 cusparse_dense_to_sparse_convert as "cusparseDenseToSparse_convert": PFN_cusparseDenseToSparse_convert;
1000 cusparse_axpby as "cusparseAxpby": PFN_cusparseAxpby;
1003 cusparse_gather as "cusparseGather": PFN_cusparseGather;
1005 cusparse_scatter as "cusparseScatter": PFN_cusparseScatter;
1007 cusparse_rot as "cusparseRot": PFN_cusparseRot;
1009}
1010
1011pub fn cusparse() -> Result<&'static Cusparse, LoaderError> {
1013 static CUSPARSE: OnceLock<Cusparse> = OnceLock::new();
1014 if let Some(c) = CUSPARSE.get() {
1015 return Ok(c);
1016 }
1017 let candidates: Vec<&'static str> = cusparse_candidates()
1018 .into_iter()
1019 .map(|s| Box::leak(s.into_boxed_str()) as &'static str)
1020 .collect();
1021 let candidates_leaked: &'static [&'static str] = Box::leak(candidates.into_boxed_slice());
1022 let lib = Library::open("cusparse", candidates_leaked)?;
1023 let c = Cusparse::empty(lib);
1024 let _ = CUSPARSE.set(c);
1025 Ok(CUSPARSE.get().expect("OnceLock set or lost race"))
1026}