CUDA中cuSolver的稀疏矩阵格式CSR格式和普通dense矩阵的格式互转。

3 篇文章 0 订阅
3 篇文章 0 订阅

 

CSR格式表示的矩阵,如图:

 

 

稀疏矩阵被3个向量来表示:

1. csrRowPtr:    可以理解为每一行前累计的非零元素的个数(最后一个元素就是非零元素的总个数)。

2.csrColInd:    每一个非零元素所在的列index。

3.csrVal:     每一个非零的元素本身的值。

 

下面实现了列主元格式和CSR格式的互转。

用列主元表示上图中的矩阵,用一个一维数组,则其中的值分别是

【 1,0,2,0,3,4,5,0,0,6,7,0,0,0,8,9 】

代码如下:

先是生成了一个稀疏的矩阵,然后存储为列主元的格式。

然后转换为稀疏矩阵CSR的格式,即三个向量表示。

然后用这三个向量再恢复出用列主元表示的矩阵。

#include<stdlib.h>
#include<assert.h>
#include<iostream>
using namespace std;





void fill_random(float*data, int m, int n) {
	for (int i = 0; i < m*n; i++) {
		data[i] = rand() % 100;
		if (data[i] < 80) //made sparse 
			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);
}

void csr2dense(int*&rowPtr, int*&colInd, float*&val, float*&data, int m, int n) {
	data = (float*)calloc(m*n,sizeof(float));

	int nnv = rowPtr[m];
	int* help = (int*)malloc(sizeof(int)*nnv); //indicates row index of element
	for (int i = 0, l = 1; i < nnv; i++) {
		while (i >= rowPtr[l])
			l++;
		help[i] = l-1;
	}

	for (int i = 0; i < nnv; i++) {
		int datal = help[i] + colInd[i] * m;
		data[datal] = val[i];
	}

	free(help);
}

bool same_matrix(float*A, float*B, int m, int n) {
	for (int i = 0; i < m*n; i++) {
		if (A[i] != B[i])
			return false;
	}
	return true;
}


int main() {
	int m = 4;
	int n = 4;
	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]);



	float*newA;
	csr2dense(csrRowPtr, csrColInd, csrVal, newA, m, n);
	print_matrix(newA, m, n);

	assert(same_matrix(A, newA, m, n)); //debug mode
}

运行结果

cslayee@163#com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值