【cuda学习日记】8.1 GPU加速库 --cuSPARSE

news/2025/3/18 18:07:22/

8.1.1 cuSPARSE概念

cuSPARSE是一个线性代数库,内含很多通用的稀疏线性代数函数。

稠密存储方式(dense)

把矩阵中的每个元素都存储起来,不管它是否为零。
在这里插入图片描述

坐标稀疏矩阵格式(COO)

坐标稀疏矩阵格式(COO)存储了稀疏矩阵中每个非零元素的行坐标、列坐标及其元素值。因此当通过给定的行列坐标对存储在COO格式中的稀疏矩阵进行检索的时候,如果没有匹配值,那么这个位置的值为零. 只有当矩阵中的非零元素不到1/3时,才会节约存储空间。
在这里插入图片描述

压缩稀疏行方式(CSR)和压缩稀疏列方式(CSC)compressed sparse row/col

参考 : https://blog.csdn.net/m0_57102661/article/details/140112320

#include <iostream>
#include <cuda_runtime.h>
#include <cusparse.h>int main() {// 初始化稠密矩阵 (4x4)const int m = 4; // 行数const int n = 4; // 列数const int nnz = 9; // 非零元素个数double h_A[m * n] = {1, 0, 0, 2,0, 3, 4, 0,5, 0, 6, 0,0, 7, 0, 8};// 打印稠密矩阵std::cout << "Dense Matrix:" << std::endl;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {std::cout << h_A[i * n + j] << " ";}std::cout << std::endl;}// 初始化 cuSPARSEcusparseHandle_t handle;CHECK_CUSPARSE(cusparseCreate(&handle));// 分配设备内存并拷贝稠密矩阵到设备double *d_A;CHECK_CUDA(cudaMalloc((void**)&d_A, m * n * sizeof(double)));CHECK_CUDA(cudaMemcpy(d_A, h_A, m * n * sizeof(double), cudaMemcpyHostToDevice));// 创建稠密矩阵描述符cusparseDnMatDescr_t matA;CHECK_CUSPARSE(cusparseCreateDnMat(&matA, m, n, n, d_A, CUDA_R_64F, CUSPARSE_ORDER_ROW));// 创建稀疏矩阵描述符 (CSR 格式)cusparseSpMatDescr_t matB;int *d_csrRowPtr, *d_csrColInd;double *d_csrVal;CHECK_CUDA(cudaMalloc((void**)&d_csrRowPtr, (m + 1) * sizeof(int)));CHECK_CUDA(cudaMalloc((void**)&d_csrColInd, nnz * sizeof(int)));CHECK_CUDA(cudaMalloc((void**)&d_csrVal, nnz * sizeof(double)));CHECK_CUSPARSE(cusparseCreateCsr(&matB, m, n, nnz, d_csrRowPtr, d_csrColInd, d_csrVal,CUSPARSE_INDEX_32I, CUSPARSE_INDEX_32I, CUSPARSE_INDEX_BASE_ZERO, CUDA_R_64F));// 分配缓冲区size_t bufferSize = 0;CHECK_CUSPARSE(cusparseDenseToSparse_bufferSize(handle, matA, matB, CUSPARSE_DENSETOSPARSE_ALG_DEFAULT, &bufferSize));void *d_buffer;CHECK_CUDA(cudaMalloc(&d_buffer, bufferSize));// 执行稠密矩阵转稀疏矩阵CHECK_CUSPARSE(cusparseDenseToSparse_analysis(handle, matA, matB, CUSPARSE_DENSETOSPARSE_ALG_DEFAULT, d_buffer));CHECK_CUSPARSE(cusparseDenseToSparse_convert(handle, matA, matB, CUSPARSE_DENSETOSPARSE_ALG_DEFAULT, d_buffer));// 将结果拷贝回主机int h_csrRowPtr[m + 1];int h_csrColInd[nnz];double h_csrVal[nnz];CHECK_CUDA(cudaMemcpy(h_csrRowPtr, d_csrRowPtr, (m + 1) * sizeof(int), cudaMemcpyDeviceToHost));CHECK_CUDA(cudaMemcpy(h_csrColInd, d_csrColInd, nnz * sizeof(int), cudaMemcpyDeviceToHost));CHECK_CUDA(cudaMemcpy(h_csrVal, d_csrVal, nnz * sizeof(double), cudaMemcpyDeviceToHost));// 打印 CSR 格式的结果std::cout << "\nCSR RowPtr:" << std::endl;for (int i = 0; i <= m; i++) {std::cout << h_csrRowPtr[i] << " ";}std::cout << std::endl;std::cout << "CSR ColInd:" << std::endl;for (int i = 0; i < nnz; i++) {std::cout << h_csrColInd[i] << " ";}std::cout << std::endl;std::cout << "CSR Val:" << std::endl;for (int i = 0; i < nnz; i++) {std::cout << h_csrVal[i] << " ";}std::cout << std::endl;// 释放设备内存CHECK_CUDA(cudaFree(d_A));CHECK_CUDA(cudaFree(d_csrRowPtr));CHECK_CUDA(cudaFree(d_csrColInd));CHECK_CUDA(cudaFree(d_csrVal));CHECK_CUDA(cudaFree(d_buffer));// 销毁描述符和句柄CHECK_CUSPARSE(cusparseDestroyDnMat(matA));CHECK_CUSPARSE(cusparseDestroySpMat(matB));CHECK_CUSPARSE(cusparseDestroy(handle));return 0;
}在common.h里添加```c
// 检查 CUDA 错误
#define CHECK_CUDA(func)                                                       \
{                                                                              \cudaError_t status = (func);                                               \if (status != cudaSuccess) {                                               \std::cerr << "CUDA Error: " << cudaGetErrorString(status) << std::endl; \exit(EXIT_FAILURE);                                                    \}                                                                          \
}// 检查 cuSPARSE 错误
#define CHECK_CUSPARSE(func)                                                   \
{                                                                              \cusparseStatus_t status = (func);                                          \if (status != CUSPARSE_STATUS_SUCCESS) {                                   \std::cerr << "cuSPARSE Error: " << status << std::endl;                \exit(EXIT_FAILURE);                                                    \}                                                                          \
}
编译: nvcc -o dense2csr cusparse.cu -lcusparse
输出:```c
Dense Matrix:
1 0 0 2 
0 3 4 0 
5 0 6 0 
0 7 0 8 CSR RowPtr:
0 2 4 6 8 
CSR ColInd:
0 3 1 2 0 2 1 3 0 
CSR Val:
1 2 3 4 5 6 7 8 0

http://www.ppmy.cn/news/1580121.html

相关文章

Redis,从数据结构到集群的知识总结

Redis基础部分 2. 数据结构 redis底层使用C语言实现&#xff0c;这里主要分析底层数据结构 2.1 动态字符串(SDS) 由于C底层的字符串数组一旦遇到’\0’就会认为这个字符串数组已经结束&#xff0c;意味着无法存储二进制数据&#xff08;如图片、音频等&#xff09;&#xff…

Java0317初尝试与报错

支付模块&#xff1a;27min讲了打开神秘开关 在前面讲了Data&#xff0c;NoArgsConstructor&#xff0c;AllArgsConstructor lombok技术 报错1 package com.itheima.demo; public class GoldCard extends Card { Override public void cost(double money){ //消费八折 setM…

高效手机检测:视觉分析技术的优势

在当今社会&#xff0c;手机已成为人们日常生活和工作中不可或缺的工具。然而&#xff0c;在某些特定场合&#xff0c;如考场、工作场所等&#xff0c;手机的使用却可能带来负面影响。因此&#xff0c;如何有效监测和防止在这些场合偷用手机的行为&#xff0c;成为了一个亟待解…

Python游戏开发自学指南:从入门到实践(第四天)

Python不仅适用于数据分析、Web开发和自动化脚本&#xff0c;还可以用于游戏开发&#xff01;虽然Python不是传统意义上的游戏开发语言&#xff0c;但其简洁的语法和丰富的库使其成为初学者学习游戏开发的绝佳选择。本文将为你提供一份全面的Python游戏开发自学指南&#xff0c…

海鲜水产行业wordpress外贸主题

模板采用清新的海洋风格设计&#xff0c;完美契合水产和海鲜行业的特点&#xff0c;让您的网站在众多竞争者中脱颖而出。 高质量的图片展示区域&#xff0c;让您可以展示新鲜捕捞的海鲜产品&#xff0c;吸引客户的注意力。 多功能性&#xff0c;满足业务需求&#xff1a; 模…

【2025】基于python+django的慢性病健康管理系统(源码、万字文档、图文修改、调试答疑)

系统功能结构图如下 慢性病健康管理系统 课题背景 随着全球人口老龄化的加剧以及生活方式的改变&#xff0c;慢性病的发病率呈上升趋势&#xff0c;给个人健康和社会医疗资源带来了巨大压力。传统的慢性病管理模式存在信息不畅、患者参与度低、医疗资源分配不均等问题&#xf…

Java 分布式高并发重试方案及实现

文章目录 Java 分布式高并发重试方案及实现一、重试机制的背景和意义二、基于 Spring Boot 的重试方案实现1. 使用 Spring Retry 实现重试机制添加依赖开启重试功能定义重试逻辑使用重试服务 2. 使用 Fast-Retry 实现高性能重试引入依赖编程式重试注解式重试 三、重试机制的注意…

C# 一文读懂委托与事件

什么是委托 delegate 诞生&#xff1a;技术点出来的原因就是 有一些需要将方法作为入参 处理的情况 比如 业务处理完需要回调函数 那就需要传函数入参 委托是C#中的一种类型安全函数指针&#xff0c;允许将方法作为参数传递或存储。它本质上是面向对象的&#xff0c;对方法签名…