1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#ifndef _MATRIX_H_
#define _MATRIX_H_
#include <assert.h>
#include <stdio.h>
#include "common.h"
#include "utils.h"
struct COOMatrix {
uint32_t numRows;
uint32_t numCols;
uint32_t numNonzeros;
uint32_t *rowIdxs;
struct Nonzero *nonzeros;
};
struct CSRMatrix {
uint32_t numRows;
uint32_t numCols;
uint32_t numNonzeros;
uint32_t *rowPtrs;
struct Nonzero *nonzeros;
};
static struct COOMatrix readCOOMatrix(const char *fileName)
{
struct COOMatrix cooMatrix;
// Initialize fields
FILE *fp = fopen(fileName, "r");
assert(fscanf(fp, "%u", &cooMatrix.numRows));
if (cooMatrix.numRows % 2 == 1) {
PRINT_WARNING
("Reading matrix %s: number of rows must be even. Padding with an extra row.",
fileName);
cooMatrix.numRows++;
}
assert(fscanf(fp, "%u", &cooMatrix.numCols));
assert(fscanf(fp, "%u", &cooMatrix.numNonzeros));
cooMatrix.rowIdxs =
(uint32_t *)
malloc(ROUND_UP_TO_MULTIPLE_OF_8
(cooMatrix.numNonzeros * sizeof(uint32_t)));
cooMatrix.nonzeros =
(struct Nonzero *)
malloc(ROUND_UP_TO_MULTIPLE_OF_8
(cooMatrix.numNonzeros * sizeof(struct Nonzero)));
// Read the nonzeros
for (uint32_t i = 0; i < cooMatrix.numNonzeros; ++i) {
uint32_t rowIdx;
assert(fscanf(fp, "%u", &rowIdx));
cooMatrix.rowIdxs[i] = rowIdx - 1; // File format indexes begin at 1
uint32_t colIdx;
assert(fscanf(fp, "%u", &colIdx));
cooMatrix.nonzeros[i].col = colIdx - 1; // File format indexes begin at 1
cooMatrix.nonzeros[i].value = 1.0f;
}
return cooMatrix;
}
static void freeCOOMatrix(struct COOMatrix cooMatrix)
{
free(cooMatrix.rowIdxs);
free(cooMatrix.nonzeros);
}
static struct CSRMatrix coo2csr(struct COOMatrix cooMatrix)
{
struct CSRMatrix csrMatrix;
// Initialize fields
csrMatrix.numRows = cooMatrix.numRows;
csrMatrix.numCols = cooMatrix.numCols;
csrMatrix.numNonzeros = cooMatrix.numNonzeros;
csrMatrix.rowPtrs =
(uint32_t *)
malloc(ROUND_UP_TO_MULTIPLE_OF_8
((csrMatrix.numRows + 1) * sizeof(uint32_t)));
csrMatrix.nonzeros =
(struct Nonzero *)
malloc(ROUND_UP_TO_MULTIPLE_OF_8
(csrMatrix.numNonzeros * sizeof(struct Nonzero)));
// Histogram rowIdxs
memset(csrMatrix.rowPtrs, 0,
(csrMatrix.numRows + 1) * sizeof(uint32_t));
for (uint32_t i = 0; i < cooMatrix.numNonzeros; ++i) {
uint32_t rowIdx = cooMatrix.rowIdxs[i];
csrMatrix.rowPtrs[rowIdx]++;
}
// Prefix sum rowPtrs
uint32_t sumBeforeNextRow = 0;
for (uint32_t rowIdx = 0; rowIdx < csrMatrix.numRows; ++rowIdx) {
uint32_t sumBeforeRow = sumBeforeNextRow;
sumBeforeNextRow += csrMatrix.rowPtrs[rowIdx];
csrMatrix.rowPtrs[rowIdx] = sumBeforeRow;
}
csrMatrix.rowPtrs[csrMatrix.numRows] = sumBeforeNextRow;
// Bin the nonzeros
for (uint32_t i = 0; i < cooMatrix.numNonzeros; ++i) {
uint32_t rowIdx = cooMatrix.rowIdxs[i];
uint32_t nnzIdx = csrMatrix.rowPtrs[rowIdx]++;
csrMatrix.nonzeros[nnzIdx] = cooMatrix.nonzeros[i];
}
// Restore rowPtrs
for (uint32_t rowIdx = csrMatrix.numRows - 1; rowIdx > 0; --rowIdx) {
csrMatrix.rowPtrs[rowIdx] = csrMatrix.rowPtrs[rowIdx - 1];
}
csrMatrix.rowPtrs[0] = 0;
return csrMatrix;
}
static void freeCSRMatrix(struct CSRMatrix csrMatrix)
{
free(csrMatrix.rowPtrs);
free(csrMatrix.nonzeros);
}
static void initVector(float *vec, uint32_t size)
{
for (uint32_t i = 0; i < size; ++i) {
vec[i] = 1.0f;
}
}
#endif
|