Skip to content

Commit 85dca8a

Browse files
authored
Merge pull request #10 from neoblizz/dev
Format improvements for CSR, CSC, COO.
2 parents ac7434d + c17ddf6 commit 85dca8a

File tree

5 files changed

+170
-39
lines changed

5 files changed

+170
-39
lines changed

benchmarks/spmv/work_oriented.cu

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,5 @@ void work_oriented_bench(nvbench::state& state, nvbench::type_list<value_t>) {
5858
}
5959

6060
// Define a type_list to use for the type axis:
61-
using value_types = nvbench::type_list<int, float>;
61+
using value_types = nvbench::type_list<int, float, double>;
6262
NVBENCH_BENCH_TYPES(work_oriented_bench, NVBENCH_TYPE_AXES(value_types));

include/loops/container/coo.hxx

+95-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
1+
/**
2+
* @file coo.hxx
3+
* @author Muhammad Osama (mosama@ucdavis.edu)
4+
* @brief Interface for Coordinate format.
5+
* @version 0.1
6+
* @date 2022-07-21
7+
*
8+
* @copyright Copyright (c) 2022
9+
*
10+
*/
11+
112
#pragma once
213

14+
#include <loops/container/formats.hxx>
15+
#include <loops/container/detail/convert.hxx>
316
#include <loops/container/vector.hxx>
417
#include <loops/memory.hxx>
518

6-
#include <thrust/execution_policy.h>
7-
#include <thrust/iterator/zip_iterator.h>
819
#include <thrust/sort.h>
920
#include <thrust/tuple.h>
21+
#include <thrust/unique.h>
22+
#include <thrust/execution_policy.h>
23+
#include <thrust/iterator/zip_iterator.h>
1024

1125
namespace loops {
1226

@@ -30,8 +44,19 @@ struct coo_t {
3044
vector_t<index_t, space> col_indices; /// J
3145
vector_t<value_t, space> values; /// V
3246

47+
/**
48+
* @brief Construct a new coo object with everything initialized to zero.
49+
*
50+
*/
3351
coo_t() : rows(0), cols(0), nnzs(0), row_indices(), col_indices(), values() {}
3452

53+
/**
54+
* @brief Construct a new coo object with the given dimensions.
55+
*
56+
* @param r Number of rows.
57+
* @param c Number of columns.
58+
* @param nnz Number of non-zero elements.
59+
*/
3560
coo_t(std::size_t r, std::size_t c, std::size_t nnz)
3661
: rows(r),
3762
cols(c),
@@ -40,6 +65,11 @@ struct coo_t {
4065
col_indices(nnz),
4166
values(nnz) {}
4267

68+
/**
69+
* @brief Construct a new coo from another coo object on host/device.
70+
*
71+
* @param rhs coo_t<index_t, value_t, rhs_space>
72+
*/
4373
template <auto rhs_space>
4474
coo_t(const coo_t<index_t, value_t, rhs_space>& rhs)
4575
: rows(rhs.rows),
@@ -49,6 +79,28 @@ struct coo_t {
4979
col_indices(rhs.col_indices),
5080
values(rhs.values) {}
5181

82+
/**
83+
* @brief Construct a new coo object from compressed sparse format (CSR).
84+
*
85+
* @param csr csr_t<index_t, offset_t, value_t, rhs_space>
86+
*/
87+
template <auto rhs_space, typename offset_t>
88+
coo_t(const csr_t<index_t, offset_t, value_t, rhs_space>& csr)
89+
: rows(csr.rows),
90+
cols(csr.cols),
91+
nnzs(csr.nnzs),
92+
row_indices(csr.nnzs),
93+
col_indices(csr.col_indices),
94+
values(csr.values) {
95+
/// TODO: Do not need this copy for all cases.
96+
vector_t<offset_t, space> _row_offsets = csr.offsets;
97+
detail::offsets_to_indices(_row_offsets, row_indices);
98+
}
99+
100+
/**
101+
* @brief Sorts the coordinate matrix by row indices.
102+
*
103+
*/
52104
void sort_by_row() {
53105
auto begin = thrust::make_zip_iterator(
54106
thrust::make_tuple(row_indices.begin(), col_indices.begin()));
@@ -57,6 +109,10 @@ struct coo_t {
57109
sort(begin, end);
58110
}
59111

112+
/**
113+
* @brief Sorts the coordinate matrix by column indices.
114+
*
115+
*/
60116
void sort_by_column() {
61117
auto begin = thrust::make_zip_iterator(
62118
thrust::make_tuple(col_indices.begin(), row_indices.begin()));
@@ -65,7 +121,44 @@ struct coo_t {
65121
sort(begin, end);
66122
}
67123

124+
/**
125+
* @brief Sorts, removes I,J pairs.
126+
*
127+
*/
128+
void remove_duplicates() {
129+
// Sort by row indices.
130+
this->sort_by_row();
131+
auto begin = thrust::make_zip_iterator(
132+
thrust::make_tuple(row_indices.begin(), col_indices.begin()));
133+
auto end = thrust::make_zip_iterator(
134+
thrust::make_tuple(row_indices.end(), col_indices.end()));
135+
136+
// Remove duplicates.
137+
auto new_it = thrust::unique_by_key(begin, end, values.begin());
138+
auto first_it = thrust::get<1>(new_it);
139+
nnzs = thrust::distance(values.begin(), first_it);
140+
141+
// Resize vectors to new size.
142+
row_indices.resize(nnzs);
143+
col_indices.resize(nnzs);
144+
values.resize(nnzs);
145+
}
146+
68147
private:
148+
/**
149+
* @brief Sorting helper, uses zip iterator as begin and end.
150+
*
151+
* @par Example Zip iterator:
152+
* auto begin = thrust::make_zip_iterator(
153+
* thrust::make_tuple(col_indices.begin(), row_indices.begin()));
154+
* auto end = thrust::make_zip_iterator(
155+
* thrust::make_tuple(col_indices.end(), row_indices.end()));
156+
*
157+
* @tparam begin_it_t Begin iterator type.
158+
* @tparam end_it_t End iterator type.
159+
* @param begin Begin iterator (zip iterator of row and col indices).
160+
* @param end End iterator (zip iterator of row and col indices).
161+
*/
69162
template <typename begin_it_t, typename end_it_t>
70163
void sort(begin_it_t& begin, end_it_t& end) {
71164
thrust::sort_by_key(begin, end, values.begin());

include/loops/container/csc.hxx

+52-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
/**
2+
* @file csc.hxx
3+
* @author Muhammad Osama (mosama@ucdavis.edu)
4+
* @brief Interface for Compressed Sparse-Column format.
5+
* @version 0.1
6+
* @date 2022-07-21
7+
*
8+
* @copyright Copyright (c) 2022
9+
*
10+
*/
11+
112
#pragma once
213

314
#include <loops/container/vector.hxx>
@@ -27,17 +38,56 @@ struct csc_t {
2738
vector_t<index_t, space> indices; /// Ap
2839
vector_t<value_t, space> values; /// Ax
2940

41+
/**
42+
* @brief Construct a new csc object with everything initialized to zero.
43+
*
44+
*/
3045
csc_t() : rows(0), cols(0), nnzs(0), offsets(), indices(), values() {}
3146

47+
/**
48+
* @brief Construct a new csc object with the given dimensions.
49+
*
50+
* @param r Number of rows.
51+
* @param c Number of columns.
52+
* @param nnz Number of non-zero elements.
53+
*/
3254
csc_t(std::size_t r, std::size_t c, std::size_t nnz)
3355
: rows(r),
3456
cols(c),
3557
nnzs(nnz),
36-
offsets(c + 1),
58+
offsets(r + 1),
3759
indices(nnz),
3860
values(nnz) {}
3961

40-
~csc_t() {}
62+
/**
63+
* @brief Construct a new csc from another csc object on host/device.
64+
*
65+
* @param rhs csc_t<index_t, offset_t, value_t, rhs_space>
66+
*/
67+
template <auto rhs_space>
68+
csc_t(const csc_t<index_t, offset_t, value_t, rhs_space>& rhs)
69+
: rows(rhs.rows),
70+
cols(rhs.cols),
71+
nnzs(rhs.nnzs),
72+
offsets(rhs.offsets),
73+
indices(rhs.indices),
74+
values(rhs.values) {}
75+
76+
/**
77+
* @brief Construct a new csc object from coordinate format (COO).
78+
* @note This constructor creates a copy of the input COO matrix.
79+
*
80+
* @param coo coo_t<index_t, value_t, auto>
81+
*/
82+
template <auto rhs_space>
83+
csc_t(const coo_t<index_t, value_t, rhs_space>& coo)
84+
: rows(coo.rows), cols(coo.cols), nnzs(coo.nnzs), offsets(coo.cols + 1) {
85+
coo_t<index_t, value_t, space> __(coo);
86+
__.sort_by_column();
87+
indices = std::move(__.row_indices);
88+
values = std::move(__.values);
89+
detail::indices_to_offsets(__.col_indices, offsets);
90+
}
4191

4292
}; // struct csc_t
4393

include/loops/container/csr.hxx

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
/**
2+
* @file csr.hxx
3+
* @author Muhammad Osama (mosama@ucdavis.edu)
4+
* @brief Interface for Compressed Sparse-Row format.
5+
* @version 0.1
6+
* @date 2022-07-21
7+
*
8+
* @copyright Copyright (c) 2022
9+
*
10+
*/
11+
112
#pragma once
213

314
#include <loops/container/vector.hxx>
@@ -44,7 +55,7 @@ struct csr_t {
4455
* @param c Number of columns.
4556
* @param nnz Number of non-zero elements.
4657
*/
47-
csr_t(const std::size_t& r, const std::size_t& c, const std::size_t& nnz)
58+
csr_t(std::size_t r, std::size_t c, std::size_t nnz)
4859
: rows(r),
4960
cols(c),
5061
nnzs(nnz),
@@ -53,7 +64,7 @@ struct csr_t {
5364
values(nnz) {}
5465

5566
/**
56-
* @brief Construct a new csr from another csr object on host.
67+
* @brief Construct a new csr from another csr object on host/device.
5768
*
5869
* @param rhs csr_t<index_t, offset_t, value_t, rhs_space>
5970
*/
@@ -68,20 +79,18 @@ struct csr_t {
6879

6980
/**
7081
* @brief Construct a new csr object from coordinate format (COO).
82+
* @note This constructor creates a copy of the input COO matrix.
7183
*
7284
* @param coo coo_t<index_t, value_t, auto>
7385
*/
7486
template <auto rhs_space>
7587
csr_t(const coo_t<index_t, value_t, rhs_space>& coo)
76-
: rows(coo.rows),
77-
cols(coo.cols),
78-
nnzs(coo.nnzs),
79-
offsets(coo.rows + 1),
80-
indices(coo.col_indices),
81-
values(coo.values) {
82-
/// TODO: Do not need this copy for all cases.
83-
vector_t<index_t, space> _row_indices = coo.row_indices;
84-
detail::indices_to_offsets(_row_indices, offsets);
88+
: rows(coo.rows), cols(coo.cols), nnzs(coo.nnzs), offsets(coo.rows + 1) {
89+
coo_t<index_t, value_t, space> __(coo);
90+
__.sort_by_row();
91+
indices = std::move(__.col_indices);
92+
values = std::move(__.values);
93+
detail::indices_to_offsets(__.row_indices, offsets);
8594
}
8695
}; // struct csr_t
8796

include/loops/util/generate.hxx

+2-23
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,9 @@
1313
#include <chrono>
1414
#include <thrust/random.h>
1515
#include <thrust/distance.h>
16-
#include <thrust/iterator/counting_iterator.h>
17-
#include <thrust/iterator/zip_iterator.h>
1816
#include <thrust/transform.h>
1917
#include <thrust/execution_policy.h>
20-
#include <thrust/sort.h>
21-
#include <thrust/unique.h>
18+
#include <thrust/iterator/counting_iterator.h>
2219

2320
#include <loops/memory.hxx>
2421
#include <loops/container/formats.hxx>
@@ -110,26 +107,8 @@ void csr(std::size_t rows,
110107
uniform_distribution(coo.values.begin(), coo.values.end(), value_t(0.0),
111108
value_t(1.0));
112109

113-
// Sort COO matrix.
114-
coo.sort_by_row();
115-
116-
// Zip Iterators.
117-
auto begin = thrust::make_zip_iterator(
118-
thrust::make_tuple(coo.row_indices.begin(), coo.col_indices.begin()));
119-
auto end = thrust::make_zip_iterator(
120-
thrust::make_tuple(coo.row_indices.end(), coo.col_indices.end()));
121-
122110
// Remove duplicates.
123-
auto new_it = thrust::unique_by_key(begin, end, coo.values.begin());
124-
auto first_it = thrust::get<1>(new_it);
125-
auto new_distance = thrust::distance(coo.values.begin(), first_it);
126-
127-
// Resize the COO matrix.
128-
coo.row_indices.resize(new_distance);
129-
coo.col_indices.resize(new_distance);
130-
coo.values.resize(new_distance);
131-
coo.nnzs = new_distance;
132-
111+
coo.remove_duplicates();
133112
matrix = coo;
134113
}
135114

0 commit comments

Comments
 (0)