虽然sepgraph有这部分代码,还是自己先试着实现一下,这样读起来也方便

行压缩格式Compressed Sparse Row (CSR)
CSR需要三种数据来表达:数值、列号、行转移。CSR不是三元组,而是整体的编码方式。

CSR

编码:
行优先遍历矩阵Matrix
values数组中保存矩阵中非零元素。
column indices数组保存values数组中对应位置非零元素的列索引。
row offsets数组的下标表示每一行第一个非零元素的行索引,元素值为values数组的下标,最后一个元素值为非零元素的个数。

解码:
遍历values数组,对其中的元素值x(下标记为index_X)去column indices数组中对应位置取出x在原矩阵中的列索引(记为col_index),然后在row offsets数组查找index_X,如果index_X在row offsets中,其在row offsets中的下标即为x在原矩阵中的行索引(记为row_index),如果index_X不在row offsets中,则使用上一个row_index值(因为编码时是逐行编码,且row offsets仅保存每行的第一个非零元素,所以当前x与上一x在同一行)。

此为前言,清楚逻辑,代码就好办了

#include<stdlib.h>
#include<time.h>
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;__global__ void csr(int* d_in_1,int* d_in_2,float* d_in_3){int i = blockIdx.x * blockDim.x + threadIdx.x; int start = d_in_1[i];int end = d_in_1[i + 1];for(int j = start;j < end ;j++){printf("(%d,%d) ",i,d_in_2[j]);}}//随机生成一个图的邻接矩阵
void fill_random(float*data, int m, int n) {srand((unsigned)(time(NULL))); //每次生成的随机数不一样for (int i = 0; i < m*n; i++) {data[i] = rand() % 100;  //生成100以内的随机数if (data[i] < 80) data[i] = 0;}
}void print_matrix(float*data, int m, int n) {for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {int l = i + j * m;cout << data[l] << " ";}cout << endl;}cout << endl;
}void print_matrix(int*data, int m, int n) {for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {int l = i + j * m;cout << data[l] << " ";}cout << endl;}cout << endl;
}void dense2csr(float*data, int*&rowPtr, int*&colInd, float*&val, int m, int n) {rowPtr = (int*)malloc(sizeof(int)*(m + 1));int* tcolInd = (int*)malloc(sizeof(int)*(m *n));float* tval = (float*)malloc(sizeof(float)*(m *n));int towtal = m * n;int nnv = 0;for (int i = 0; i < m; i++) {rowPtr[i] = nnv;//记录行偏移,其实也是前面一共已经有多少边for (int j = 0; j < n; j++) {int l = i + j * m;if (data[l] != 0) {tcolInd[nnv] = j;//记录列索引tval[nnv] = data[l];//记录边权nnv++;//找到一个边,行偏移加一}}}rowPtr[m] = nnv;colInd = (int*)malloc(sizeof(int)*(nnv));val = (float*)malloc(sizeof(float)*(nnv));memcpy(colInd, tcolInd, sizeof(float)*nnv);memcpy(val, tval, sizeof(float)*nnv);free(tcolInd);free(tval);
}int main() {int m = 5;int n = 5;float*A = (float*)malloc(sizeof(float)*m*n);fill_random(A, m, n);print_matrix(A, m, n);int*csrRowPtr;int*csrColInd;float*csrVal;dense2csr(A, csrRowPtr, csrColInd, csrVal, m, n);print_matrix(csrRowPtr, 1, m + 1);print_matrix(csrColInd, 1, csrRowPtr[m]);print_matrix(csrVal, 1, csrRowPtr[m]);const int ARRAY_SIZE = m + 1;const int ARRAY_BYTES_1 = ARRAY_SIZE * sizeof(int);const int ARRAY_BYTES_2 = csrRowPtr[ARRAY_SIZE - 1] * sizeof(int);const int ARRAY_BYTES_3 = csrRowPtr[ARRAY_SIZE - 1] * sizeof(float);// 生成cpu上的csr结构int h_in_1[m + 1];int h_in_2[csrRowPtr[m]];float h_in_3[csrRowPtr[m]];for(int i = 0;i < m + 1 ; i++){h_in_1[i] = csrRowPtr[i];}for(int i = 0;i < csrRowPtr[m]; i++){h_in_2[i] = csrColInd[i];h_in_3[i] = csrVal[i];}// 声明GPU上的CSR结构int* d_in_1;int* d_in_2;float* d_in_3;// 分配空间cudaMalloc((void**) &d_in_1,ARRAY_BYTES_1);cudaMalloc((void**) &d_in_2,ARRAY_BYTES_2);cudaMalloc((void**) &d_in_3,ARRAY_BYTES_3);// 转移全部cudaMemcpy(d_in_1,h_in_1,ARRAY_BYTES_1,cudaMemcpyHostToDevice);cudaMemcpy(d_in_2,h_in_2,ARRAY_BYTES_2,cudaMemcpyHostToDevice);cudaMemcpy(d_in_3,h_in_3,ARRAY_BYTES_3,cudaMemcpyHostToDevice);// 操作全部csr<<<1,ARRAY_SIZE>>>(d_in_1,d_in_2,d_in_3);// 释放内存cudaFree(d_in_1);cudaFree(d_in_2);cudaFree(d_in_3);return 0;
}

运行的结果如下

先输出一个随机生成的带权重有向稀疏图,在cpu中将其压缩为csr格式并输出,再传递到gpu上,并输出每一条边的起点和终点。

cuda编程与gpu并行计算(六):图稀疏矩阵转为CSR结构并传入gpu相关推荐

  1. CUDA编程学习3——并行计算初窥CUDA的软硬件架构

    目录 并行计算概述 查看GPU相关信息 软硬件架构基础 物理层(物理结构) 逻辑层(kernel组织) 物理层和逻辑层的总结 参考 并行计算概述 所谓并行计算的概念定义 同时多个计算资源一起工作(逻辑 ...

  2. pytorch 多GPU并行计算

    并行计算分为两类: https://baijiahao.baidu.com/s?id=1632494497660364845&wfr=spider&for=pc 模型并行:将模型的多个 ...

  3. CUDA 编程上手指南:CUDA C 编程及 GPU 基本知识

    作者丨科技猛兽 编辑丨极市平台 本文原创首发于极市平台,转载请获得授权并标明出处. 推荐大家关注极市平台公众号,每天都会更新最新的计算机视觉论文解读.综述盘点.调参攻略.面试经验等干货~ 目录 1 C ...

  4. CUDA编程之快速入门-----GPU加速原理和编程实现

    转载:https://www.cnblogs.com/skyfsm/p/9673960.html CUDA(Compute Unified Device Architecture)的中文全称为计算统一 ...

  5. CUDA编程——GPU架构,由sp,sm,thread,block,grid,warp说起

    目录 1.从硬件看 2.从软件看 3.对应关系 4.SIMT和SIMD 掌握部分硬件知识,有助于程序员编写更好的CUDA程序,提升CUDA程序性能,本文目的是理清sp,sm,thread,block, ...

  6. NVIDIA GPU SM和CUDA编程理解

    SM硬件架构基础 不同架构的变化可以参考: ​​​​​​从AI系统角度回顾GPU架构变迁--从Fermi到Ampere(V1.2) - 知乎 英伟达GPU架构演进近十年,从费米到安培 - 知乎 Vol ...

  7. cuda编程以及GPU基本知识

    目录 CPU与GPU的基本知识 CPU特点 GPU特点 GPU vs. CPU 什么样的问题适合GPU? GPU编程 CUDA编程并行计算的整体流程 CUDA编程术语:硬件 CUDA编程术语:内存模型 ...

  8. 一文了解GPU并行计算CUDA

    了解GPU并行计算CUDA 一.CUDA和GPU简介 二.GPU工作原理与结构 2.1.基础GPU架构 2.2.GPU编程模型 2.3.软件和硬件的对应关系 三.GPU应用领域 四.GPU+CPU异构 ...

  9. [人工智能-深度学习-40]:英伟达GPU CUDA 编程框架简介

    作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/detai ...

最新文章

  1. 图像低频高频区域分离 小波变换
  2. 用jk触发器构成二分频电路_深入了解数字电路之时序电路
  3. c语言与硬件连接案例,实际LED硬件连接
  4. 【CentOS Linux 7】实验1【Linux文件目录管理】
  5. wpf怎么让grid表格中元素显示到最顶层_一文搞定PPT中的快捷键
  6. vs code 开发企业级python_基于VS Code配置Python开发环境
  7. 实际操作之路考的这些事
  8. 嘉年华专访 | 国际上智能运维研究
  9. jquery插入第一个元素? [问题点数:20分,结帖人zsw19909001]
  10. 物联网核心安全系列——智能汽车安全防护的重要性
  11. 【计算机毕业设计】基于SpringBoot的物流管理系统
  12. IT行业发展凶猛,你的工作会被人工智能取代吗?
  13. 安装liunx出现Entering emergency mode
  14. codevs5172 装病的聚聚 (最短路spfa的延伸应用)(对三角不等式的深入理解)--by lethalboy
  15. [转]centos安装oracle
  16. 做RAID和不做RAID的区别
  17. scp 保留文件属组_scp传输文件的权限问题
  18. Mini MP3 Player模块无法正常播放
  19. 海德汉角度编码器RCN727F与替代型号RCN8390F参数对比
  20. Others10_玩转信用卡之信用卡黑话

热门文章

  1. 基于javaFX的固定资产管理系统
  2. CAD 开发实现不重启CAD软件修改代码调试
  3. 【经典】思科、华为路由器交换机模拟器大全及教程
  4. springboot配置进行https请求访问demo
  5. 产品经理 - 产品设计方法论业务落地部分_包括流程产品文档方法论需求设计方法论
  6. Python自动翻译英语论文PDF(三十九)
  7. setup界面的network configuration 进不去的原因
  8. 【软件测试】—— 基础知识总结
  9. db2 ? 22018
  10. mapX - 基本操作(1)