Skip to content

Commit ac7434d

Browse files
authoredJul 21, 2022
Merge pull request #9 from neoblizz/dev
Cleaning up the container interface.
2 parents 0e9864a + 87ff0ab commit ac7434d

File tree

4 files changed

+68
-105
lines changed

4 files changed

+68
-105
lines changed
 

‎include/loops/container/coo.hxx

+31-11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
#include <loops/container/vector.hxx>
44
#include <loops/memory.hxx>
55

6+
#include <thrust/execution_policy.h>
7+
#include <thrust/iterator/zip_iterator.h>
8+
#include <thrust/sort.h>
9+
#include <thrust/tuple.h>
10+
611
namespace loops {
712

813
using namespace memory;
@@ -21,9 +26,9 @@ struct coo_t {
2126
std::size_t cols;
2227
std::size_t nnzs;
2328

24-
vector_t<index_t, space> row_indices; // I
25-
vector_t<index_t, space> col_indices; // J
26-
vector_t<value_t, space> values; // V
29+
vector_t<index_t, space> row_indices; /// I
30+
vector_t<index_t, space> col_indices; /// J
31+
vector_t<value_t, space> values; /// V
2732

2833
coo_t() : rows(0), cols(0), nnzs(0), row_indices(), col_indices(), values() {}
2934

@@ -35,21 +40,36 @@ struct coo_t {
3540
col_indices(nnz),
3641
values(nnz) {}
3742

38-
coo_t(const coo_t<index_t, value_t, memory_space_t::device>& rhs)
43+
template <auto rhs_space>
44+
coo_t(const coo_t<index_t, value_t, rhs_space>& rhs)
3945
: rows(rhs.rows),
4046
cols(rhs.cols),
4147
nnzs(rhs.nnzs),
4248
row_indices(rhs.row_indices),
4349
col_indices(rhs.col_indices),
4450
values(rhs.values) {}
4551

46-
coo_t(const coo_t<index_t, value_t, memory_space_t::host>& rhs)
47-
: rows(rhs.rows),
48-
cols(rhs.cols),
49-
nnzs(rhs.nnzs),
50-
row_indices(rhs.row_indices),
51-
col_indices(rhs.col_indices),
52-
values(rhs.values) {}
52+
void sort_by_row() {
53+
auto begin = thrust::make_zip_iterator(
54+
thrust::make_tuple(row_indices.begin(), col_indices.begin()));
55+
auto end = thrust::make_zip_iterator(
56+
thrust::make_tuple(row_indices.end(), col_indices.end()));
57+
sort(begin, end);
58+
}
59+
60+
void sort_by_column() {
61+
auto begin = thrust::make_zip_iterator(
62+
thrust::make_tuple(col_indices.begin(), row_indices.begin()));
63+
auto end = thrust::make_zip_iterator(
64+
thrust::make_tuple(col_indices.end(), row_indices.end()));
65+
sort(begin, end);
66+
}
67+
68+
private:
69+
template <typename begin_it_t, typename end_it_t>
70+
void sort(begin_it_t& begin, end_it_t& end) {
71+
thrust::sort_by_key(begin, end, values.begin());
72+
}
5373
}; // struct coo_t
5474

5575
} // namespace loops

‎include/loops/container/csr.hxx

+8-40
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,13 @@ struct csr_t {
5252
indices(nnz),
5353
values(nnz) {}
5454

55-
/**
56-
* @brief Construct a new csr from another csr object on device.
57-
*
58-
* @param rhs csr_t<index_t, offset_t, value_t, memory_space_t::device>
59-
*/
60-
csr_t(const csr_t<index_t, offset_t, value_t, memory_space_t::device>& rhs)
61-
: rows(rhs.rows),
62-
cols(rhs.cols),
63-
nnzs(rhs.nnzs),
64-
offsets(rhs.offsets),
65-
indices(rhs.indices),
66-
values(rhs.values) {}
67-
6855
/**
6956
* @brief Construct a new csr from another csr object on host.
7057
*
71-
* @param rhs csr_t<index_t, offset_t, value_t, memory_space_t::host>
58+
* @param rhs csr_t<index_t, offset_t, value_t, rhs_space>
7259
*/
73-
csr_t(const csr_t<index_t, offset_t, value_t, memory_space_t::host>& rhs)
60+
template <auto rhs_space>
61+
csr_t(const csr_t<index_t, offset_t, value_t, rhs_space>& rhs)
7462
: rows(rhs.rows),
7563
cols(rhs.cols),
7664
nnzs(rhs.nnzs),
@@ -81,39 +69,19 @@ struct csr_t {
8169
/**
8270
* @brief Construct a new csr object from coordinate format (COO).
8371
*
84-
* @param coo coo_t<index_t, value_t, memory_space_t::host>
85-
*/
86-
csr_t(const coo_t<index_t, value_t, memory_space_t::host>& coo)
87-
: rows(coo.rows),
88-
cols(coo.cols),
89-
nnzs(coo.nnzs),
90-
indices(coo.col_indices),
91-
values(coo.values) {
92-
offsets.resize(coo.rows + 1);
93-
/// TODO: Do not need this copy for all cases.
94-
vector_t<index_t, space> _row_indices = coo.row_indices;
95-
detail::indices_to_offsets<space>(_row_indices.data().get(),
96-
_row_indices.size(), offsets.data().get(),
97-
offsets.size());
98-
}
99-
100-
/**
101-
* @brief Construct a new csr object from coordinate format (COO).
102-
*
103-
* @param coo coo_t<index_t, value_t, memory_space_t::device>
72+
* @param coo coo_t<index_t, value_t, auto>
10473
*/
105-
csr_t(const coo_t<index_t, value_t, memory_space_t::device>& coo)
74+
template <auto rhs_space>
75+
csr_t(const coo_t<index_t, value_t, rhs_space>& coo)
10676
: rows(coo.rows),
10777
cols(coo.cols),
10878
nnzs(coo.nnzs),
79+
offsets(coo.rows + 1),
10980
indices(coo.col_indices),
11081
values(coo.values) {
111-
offsets.resize(coo.rows + 1);
11282
/// TODO: Do not need this copy for all cases.
11383
vector_t<index_t, space> _row_indices = coo.row_indices;
114-
detail::indices_to_offsets<space>(_row_indices.data().get(),
115-
_row_indices.size(), offsets.data().get(),
116-
offsets.size());
84+
detail::indices_to_offsets(_row_indices, offsets);
11785
}
11886
}; // struct csr_t
11987

‎include/loops/container/detail/convert.hxx

+25-50
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#include <thrust/fill.h>
1717
#include <thrust/scatter.h>
1818
#include <thrust/execution_policy.h>
19+
#include <thrust/iterator/counting_iterator.h>
20+
#include <thrust/iterator/zip_iterator.h>
21+
#include <thrust/tuple.h>
1922
#include <loops/memory.hxx>
2023

2124
namespace loops {
@@ -25,81 +28,53 @@ using namespace memory;
2528
/**
2629
* @brief Convert offsets to indices.
2730
*
28-
* @tparam space The memory space of offsets.
29-
* @tparam index_t The type of indices.
30-
* @tparam offset_t The type of offsets.
31+
* @tparam index_v_t The type of vector indices.
32+
* @tparam offset_v_t The type of vector offsets.
3133
* @param offsets The offsets.
32-
* @param size_of_offsets The size of offsets.
3334
* @param indices The indices.
34-
* @param size_of_indices The size of indices.
35-
* @param stream The stream.
3635
*/
37-
template <memory_space_t space, typename index_t, typename offset_t>
38-
void offsets_to_indices(const offset_t* offsets,
39-
const std::size_t size_of_offsets,
40-
index_t* indices,
41-
const std::size_t size_of_indices,
42-
cudaStream_t stream = 0) {
43-
// Execution policy (determines where to run the kernel).
44-
using execution_policy_t =
45-
std::conditional_t<(space == memory_space_t::device),
46-
decltype(thrust::cuda::par.on(stream)),
47-
decltype(thrust::host)>;
48-
49-
execution_policy_t exec;
36+
template <typename index_v_t, typename offset_v_t>
37+
void offsets_to_indices(const offset_v_t& offsets, index_v_t& indices) {
38+
using offset_t = typename offset_v_t::value_type;
39+
using index_t = typename index_v_t::value_type;
5040

5141
// Convert compressed offsets into uncompressed indices.
52-
thrust::fill(exec, indices + 0, indices + size_of_indices, offset_t(0));
42+
thrust::fill(indices.begin(), indices.end(), offset_t(0));
5343

5444
thrust::scatter_if(
55-
exec, // execution policy
5645
thrust::counting_iterator<offset_t>(0), // begin iterator
57-
thrust::counting_iterator<offset_t>(size_of_offsets - 1), // end iterator
58-
offsets + 0, // where to scatter
46+
thrust::counting_iterator<offset_t>(offsets.size() - 1), // end iterator
47+
offsets.begin(), // where to scatter
5948
thrust::make_transform_iterator(
6049
thrust::make_zip_iterator(
61-
thrust::make_tuple(offsets + 0, offsets + 1)),
50+
thrust::make_tuple(offsets.begin(), offsets.begin() + 1)),
6251
[=] __host__ __device__(const thrust::tuple<offset_t, offset_t>& t) {
6352
thrust::not_equal_to<offset_t> comp;
6453
return comp(thrust::get<0>(t), thrust::get<1>(t));
6554
}),
66-
indices + 0);
55+
indices.begin());
6756

68-
thrust::inclusive_scan(exec, indices + 0, indices + size_of_indices,
69-
indices + 0, thrust::maximum<offset_t>());
57+
thrust::inclusive_scan(indices.begin(), indices.end(), indices.begin(),
58+
thrust::maximum<offset_t>());
7059
}
7160

7261
/**
7362
* @brief Converts "indices"-based array to "offsets"-based array.
7463
*
75-
* @tparam space The memory space of indices.
76-
* @tparam index_t The type of indices.
77-
* @tparam offset_t The type of offsets.
64+
* @tparam index_v_t The type of vector indices.
65+
* @tparam offset_v_t The type of vector offsets.
7866
* @param indices The indices.
79-
* @param size_of_indices The size of indices.
8067
* @param offsets The offsets.
81-
* @param size_of_offsets The size of offsets.
82-
* @param stream CUDA stream.
8368
*/
84-
template <memory_space_t space, typename index_t, typename offset_t>
85-
void indices_to_offsets(index_t* indices,
86-
std::size_t size_of_indices,
87-
offset_t* offsets,
88-
std::size_t size_of_offsets,
89-
cudaStream_t stream = 0) {
90-
// Execution policy (determines where to run the kernel).
91-
using execution_policy_t =
92-
std::conditional_t<(space == memory_space_t::device),
93-
decltype(thrust::cuda::par.on(stream)),
94-
decltype(thrust::host)>;
95-
96-
execution_policy_t exec;
69+
template <typename index_v_t, typename offset_v_t>
70+
void indices_to_offsets(const index_v_t& indices, offset_v_t& offsets) {
71+
using offset_t = typename offset_v_t::value_type;
72+
using index_t = typename index_v_t::value_type;
9773

9874
// Convert uncompressed indices into compressed offsets.
99-
thrust::lower_bound(exec, indices, indices + size_of_indices,
100-
thrust::counting_iterator<offset_t>(0),
101-
thrust::counting_iterator<offset_t>(size_of_offsets),
102-
offsets + 0);
75+
thrust::lower_bound(
76+
indices.begin(), indices.end(), thrust::counting_iterator<offset_t>(0),
77+
thrust::counting_iterator<offset_t>(offsets.size()), offsets.begin());
10378
}
10479

10580
} // namespace detail

‎include/loops/util/generate.hxx

+4-4
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ void csr(std::size_t rows,
110110
uniform_distribution(coo.values.begin(), coo.values.end(), value_t(0.0),
111111
value_t(1.0));
112112

113-
// Construct row/col iterators to traverse.
113+
// Sort COO matrix.
114+
coo.sort_by_row();
115+
116+
// Zip Iterators.
114117
auto begin = thrust::make_zip_iterator(
115118
thrust::make_tuple(coo.row_indices.begin(), coo.col_indices.begin()));
116119
auto end = thrust::make_zip_iterator(
117120
thrust::make_tuple(coo.row_indices.end(), coo.col_indices.end()));
118121

119-
// Sort the COO matrix.
120-
thrust::sort_by_key(begin, end, coo.values.begin());
121-
122122
// Remove duplicates.
123123
auto new_it = thrust::unique_by_key(begin, end, coo.values.begin());
124124
auto first_it = thrust::get<1>(new_it);

0 commit comments

Comments
 (0)
Please sign in to comment.