Skip to content

Commit 507a2b6

Browse files
committed
[Code] Change coo to csr in seq backend
1 parent 7f65092 commit 507a2b6

File tree

11 files changed

+151
-106
lines changed

11 files changed

+151
-106
lines changed

cubool/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ if (CUBOOL_WITH_SEQUENTIAL)
8686
sources/sequential/sq_backend.hpp
8787
sources/sequential/sq_matrix.cpp
8888
sources/sequential/sq_matrix.hpp
89-
sources/sequential/sq_coo_data.hpp
89+
sources/sequential/sq_csr_data.hpp
9090
sources/sequential/sq_transpose.cpp
9191
sources/sequential/sq_transpose.hpp
9292
sources/sequential/sq_kronecker.cpp
@@ -99,6 +99,7 @@ if (CUBOOL_WITH_SEQUENTIAL)
9999
sources/sequential/sq_reduce.hpp
100100
sources/sequential/sq_submatrix.cpp
101101
sources/sequential/sq_submatrix.hpp
102+
sources/sequential/sq_exclusive_scan.hpp
102103
)
103104
endif()
104105

cubool/sources/sequential/sq_coo_data.hpp renamed to cubool/sources/sequential/sq_csr_data.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@
2222
/* SOFTWARE. */
2323
/**********************************************************************************/
2424

25-
#ifndef CUBOOL_SQ_COO_DATA_HPP
26-
#define CUBOOL_SQ_COO_DATA_HPP
25+
#ifndef CUBOOL_SQ_CSR_DATA_HPP
26+
#define CUBOOL_SQ_CSR_DATA_HPP
2727

2828
#include <core/config.hpp>
2929
#include <vector>
3030

3131
namespace cubool {
3232

33-
class CooData {
33+
class CsrData {
3434
public:
35-
std::vector<index> mRowIndices;
36-
std::vector<index> mColIndices;
37-
index mNrows = 0;
38-
index mNcols = 0;
39-
index mNvals = 0;
35+
std::vector<index> rowOffsets;
36+
std::vector<index> colIndices;
37+
index nrows = 0;
38+
index ncols = 0;
39+
index nvals = 0;
4040
};
4141

4242
}
4343

44-
#endif //CUBOOL_SQ_COO_DATA_HPP
44+
#endif //CUBOOL_SQ_CSR_DATA_HPP
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**********************************************************************************/
2+
/* MIT License */
3+
/* */
4+
/* Copyright (c) 2020, 2021 JetBrains-Research */
5+
/* */
6+
/* Permission is hereby granted, free of charge, to any person obtaining a copy */
7+
/* of this software and associated documentation files (the "Software"), to deal */
8+
/* in the Software without restriction, including without limitation the rights */
9+
/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
10+
/* copies of the Software, and to permit persons to whom the Software is */
11+
/* furnished to do so, subject to the following conditions: */
12+
/* */
13+
/* The above copyright notice and this permission notice shall be included in all */
14+
/* copies or substantial portions of the Software. */
15+
/* */
16+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
17+
/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
18+
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
19+
/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
20+
/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
21+
/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
22+
/* SOFTWARE. */
23+
/**********************************************************************************/
24+
25+
#ifndef CUBOOL_SQ_EXCLUSIVE_SCAN_HPP
26+
#define CUBOOL_SQ_EXCLUSIVE_SCAN_HPP
27+
28+
namespace cubool {
29+
30+
template <typename FirstT, typename LastT, typename T>
31+
void sq_exclusive_scan(FirstT firstT, LastT lastT, T initial) {
32+
T sum = initial;
33+
while (firstT != lastT) {
34+
T next = sum + *firstT;
35+
*firstT = sum;
36+
sum = next;
37+
38+
firstT++;
39+
}
40+
}
41+
42+
}
43+
44+
#endif //CUBOOL_SQ_EXCLUSIVE_SCAN_HPP

cubool/sources/sequential/sq_kronecker.cpp

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
/**********************************************************************************/
2424

2525
#include <sequential/sq_kronecker.hpp>
26+
#include <sequential/sq_exclusive_scan.hpp>
2627

2728
namespace cubool {
2829

@@ -35,46 +36,34 @@ namespace cubool {
3536
}
3637
}
3738

38-
void sq_kronecker(const CooData& a, const CooData& b, CooData& out) {
39-
size_t nvals = a.mNvals * b.mNvals;
39+
void sq_kronecker(const CsrData& a, const CsrData& b, CsrData& out) {
40+
size_t nvals = a.nvals * b.nvals;
4041

41-
out.mNvals = nvals;
42-
out.mRowIndices.resize(nvals);
43-
out.mColIndices.resize(nvals);
44-
45-
std::vector<index> aoffsets(a.mNrows + 1, 0);
46-
std::vector<index> boffsets(b.mNrows + 1, 0);
47-
48-
for (index k = 0; k < a.mNvals; k++) {
49-
aoffsets[a.mRowIndices[k]]++;
50-
}
51-
52-
for (index k = 0; k < b.mNvals; k++) {
53-
boffsets[b.mRowIndices[k]]++;
54-
}
55-
56-
scan(aoffsets);
57-
scan(boffsets);
42+
out.nvals = nvals;
43+
out.rowOffsets.resize(a.nrows * b.nrows + 1, 0);
44+
out.colIndices.resize(nvals);
5845

5946
size_t id = 0;
6047

61-
for (index ai = 0; ai < a.mNrows; ai++) {
62-
for (index bi = 0; bi < b.mNrows; bi++) {
63-
index rowId = ai * b.mNrows + bi;
48+
for (index ai = 0; ai < a.nrows; ai++) {
49+
for (index bi = 0; bi < b.nrows; bi++) {
50+
index rowId = ai * b.nrows + bi;
6451

65-
for (index k = aoffsets[ai]; k < aoffsets[ai + 1]; k++) {
66-
index colIdBase = a.mColIndices[k] * b.mNcols;
52+
for (index k = a.rowOffsets[ai]; k < a.rowOffsets[ai + 1]; k++) {
53+
index colIdBase = a.colIndices[k] * b.ncols;
6754

68-
for (index l = boffsets[bi]; l < boffsets[bi + 1]; l++) {
69-
index colId = colIdBase + b.mColIndices[l];
55+
for (index l = b.rowOffsets[bi]; l < b.rowOffsets[bi + 1]; l++) {
56+
index colId = colIdBase + b.colIndices[l];
7057

71-
out.mRowIndices[id] = rowId;
72-
out.mColIndices[id] = colId;
58+
out.rowOffsets[rowId]++;
59+
out.colIndices[id] = colId;
7360
id += 1;
7461
}
7562
}
7663
}
7764
}
65+
66+
sq_exclusive_scan(out.rowOffsets.begin(), out.rowOffsets.end(), 0);
7867
}
7968

8069
}

cubool/sources/sequential/sq_kronecker.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#ifndef CUBOOL_SP_KRONECKER_HPP
2626
#define CUBOOL_SP_KRONECKER_HPP
2727

28-
#include <sequential/sq_coo_data.hpp>
28+
#include <sequential/sq_csr_data.hpp>
2929

3030
namespace cubool {
3131

@@ -35,7 +35,7 @@ namespace cubool {
3535
* @param b Input matrix
3636
* @param[out] out Result matrix
3737
*/
38-
void sq_kronecker(const CooData& a, const CooData& b, CooData& out);
38+
void sq_kronecker(const CsrData& a, const CsrData& b, CsrData& out);
3939

4040
}
4141

cubool/sources/sequential/sq_matrix.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <sequential/sq_transpose.hpp>
2727
#include <sequential/sq_submatrix.hpp>
2828
#include <sequential/sq_kronecker.hpp>
29+
#include <sequential/sq_exclusive_scan.hpp>
2930
#include <core/error.hpp>
3031
#include <algorithm>
3132
#include <cassert>
@@ -36,8 +37,8 @@ namespace cubool {
3637
assert(nrows > 0);
3738
assert(ncols > 0);
3839

39-
mData.mNrows = nrows;
40-
mData.mNcols = ncols;
40+
mData.nrows = nrows;
41+
mData.ncols = ncols;
4142
}
4243

4344
void SqMatrix::build(const index *rows, const index *cols, size_t nvals, bool isSorted) {
@@ -47,13 +48,12 @@ namespace cubool {
4748
assert(rows);
4849
assert(cols);
4950

50-
auto nrows = mData.mNrows;
51-
auto ncols = mData.mNcols;
51+
auto nrows = mData.nrows;
52+
auto ncols = mData.ncols;
5253

53-
mData.mRowIndices.clear();
54-
mData.mColIndices.clear();
55-
mData.mRowIndices.reserve(nvals);
56-
mData.mColIndices.reserve(nvals);
54+
mData.rowOffsets.resize(nrows + 1, 0);
55+
mData.colIndices.clear();
56+
mData.colIndices.reserve(nvals);
5757

5858
if (isSorted) {
5959
for (size_t k = 0; k < nvals; k++) {
@@ -63,8 +63,8 @@ namespace cubool {
6363
CHECK_RAISE_ERROR(i < nrows, InvalidArgument, "Index out of matrix bound");
6464
CHECK_RAISE_ERROR(j < ncols, InvalidArgument, "Index out of matrix bound");
6565

66-
mData.mRowIndices.push_back(i);
67-
mData.mColIndices.push_back(j);
66+
mData.rowOffsets[i]++;
67+
mData.colIndices.push_back(j);
6868
}
6969
}
7070
else {
@@ -86,12 +86,13 @@ namespace cubool {
8686
});
8787

8888
for (const auto& p: values) {
89-
mData.mRowIndices.push_back(p.i);
90-
mData.mColIndices.push_back(p.j);
89+
mData.rowOffsets[p.i]++;
90+
mData.colIndices.push_back(p.j);
9191
}
9292
}
9393

94-
mData.mNvals = nvals;
94+
sq_exclusive_scan(mData.rowOffsets.begin(), mData.rowOffsets.end(), 0);
95+
mData.nvals = nvals;
9596
}
9697

9798
void SqMatrix::extract(index *rows, index *cols, size_t &nvals) {
@@ -103,9 +104,13 @@ namespace cubool {
103104
assert(rows);
104105
assert(cols);
105106

106-
for (size_t k = 0; k < getNvals(); k++) {
107-
rows[k] = mData.mRowIndices[k];
108-
cols[k] = mData.mColIndices[k];
107+
size_t id = 0;
108+
for (index i = 0; i < getNrows(); i++) {
109+
for (index k = mData.rowOffsets[i]; k < mData.rowOffsets[i + 1]; k++) {
110+
rows[id] = i;
111+
cols[id] = mData.colIndices[k];
112+
id += 1;
113+
}
109114
}
110115
}
111116
}
@@ -188,14 +193,14 @@ namespace cubool {
188193
}
189194

190195
index SqMatrix::getNrows() const {
191-
return mData.mNrows;
196+
return mData.nrows;
192197
}
193198

194199
index SqMatrix::getNcols() const {
195-
return mData.mNcols;
200+
return mData.ncols;
196201
}
197202

198203
index SqMatrix::getNvals() const {
199-
return mData.mNvals;
204+
return mData.nvals;
200205
}
201206
}

cubool/sources/sequential/sq_matrix.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
#define CUBOOL_SQ_MATRIX_HPP
2727

2828
#include <backend/matrix_base.hpp>
29-
#include <sequential/sq_coo_data.hpp>
29+
#include <sequential/sq_csr_data.hpp>
3030

3131
namespace cubool {
3232

3333
/**
34-
* Coo matrix for Cpu side operations in sequential backend.
34+
* Csr matrix for Cpu side operations in sequential backend.
3535
*/
3636
class SqMatrix final: public MatrixBase {
3737
public:
@@ -55,7 +55,7 @@ namespace cubool {
5555
index getNvals() const override;
5656

5757
private:
58-
CooData mData;
58+
CsrData mData;
5959
};
6060

6161
}

cubool/sources/sequential/sq_submatrix.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,40 +23,47 @@
2323
/**********************************************************************************/
2424

2525
#include <sequential/sq_submatrix.hpp>
26+
#include <sequential/sq_exclusive_scan.hpp>
2627

2728
namespace cubool {
2829

29-
void sq_submatrix(const CooData& a, CooData& sub, index i, index j, index nrows, index ncols) {
30-
index first = a.mNvals;
31-
index last = 0;
30+
void sq_submatrix(const CsrData& a, CsrData& sub, index i, index j, index nrows, index ncols) {
31+
index first = i;
32+
index last = i + nrows;
3233
size_t nvals = 0;
3334

34-
for (index k = 0; k < a.mNvals; k++) {
35-
auto ai = a.mRowIndices[k];
36-
auto aj = a.mColIndices[k];
35+
for (index ai = first; ai < last; ai++) {
36+
for (index k = a.rowOffsets[ai]; k < a.rowOffsets[ai + 1]; k++) {
37+
index aj = a.colIndices[k];
3738

38-
if (i <= ai && ai < i + nrows && j <= aj && aj < j + ncols) {
39-
first = std::min(first, k);
40-
last = std::max(last, k);
41-
nvals += 1;
39+
if (i <= ai && ai < i + nrows && j <= aj && aj < j + ncols) {
40+
nvals += 1;
41+
}
4242
}
4343
}
4444

45-
sub.mNvals = nvals;
46-
sub.mRowIndices.resize(nvals);
47-
sub.mColIndices.resize(nvals);
45+
sub.nvals = nvals;
46+
sub.rowOffsets.resize(nrows + 1);
47+
sub.colIndices.resize(nvals);
4848

4949
size_t idx = 0;
50-
for (index k = first; k <= last; k++) {
51-
auto ai = a.mRowIndices[k];
52-
auto aj = a.mColIndices[k];
53-
54-
if (i <= ai && ai < i + nrows && j <= aj && aj < j + ncols) {
55-
sub.mRowIndices[idx] = ai - i;
56-
sub.mColIndices[idx] = aj - j;
57-
idx += 1;
50+
for (index ai = first; ai < last; ai++) {
51+
for (index k = a.rowOffsets[ai]; k < a.rowOffsets[ai + 1]; k++) {
52+
index aj = a.colIndices[k];
53+
54+
if (i <= ai && ai < i + nrows && j <= aj && aj < j + ncols) {
55+
index ri = ai - i;
56+
index rj = aj - j;
57+
58+
sub.rowOffsets[ri] += 1;
59+
sub.colIndices[idx] = rj;
60+
61+
idx += 1;
62+
}
5863
}
5964
}
65+
66+
sq_exclusive_scan(sub.rowOffsets.begin(), sub.rowOffsets.end(), 0);
6067
}
6168

6269
}

cubool/sources/sequential/sq_submatrix.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#ifndef CUBOOL_SQ_SUBMATRIX_HPP
2626
#define CUBOOL_SQ_SUBMATRIX_HPP
2727

28-
#include <sequential/sq_coo_data.hpp>
28+
#include <sequential/sq_csr_data.hpp>
2929

3030
namespace cubool {
3131

@@ -39,7 +39,7 @@ namespace cubool {
3939
* @param nrows Sub-matrix size
4040
* @param ncols Sub-matrix size
4141
*/
42-
void sq_submatrix(const CooData& a, CooData& sub, index i, index j, index nrows, index ncols);
42+
void sq_submatrix(const CsrData& a, CsrData& sub, index i, index j, index nrows, index ncols);
4343

4444
}
4545

0 commit comments

Comments
 (0)