Morpheus 1.0.0
Dynamic matrix type and algorithms for sparse matrices
Loading...
Searching...
No Matches
Csr/Serial/Morpheus_Convert_Impl.hpp
1
24#ifndef MORPHEUS_CSR_SERIAL_CONVERT_IMPL_HPP
25#define MORPHEUS_CSR_SERIAL_CONVERT_IMPL_HPP
26
27#include <Morpheus_Macros.hpp>
28#if defined(MORPHEUS_ENABLE_SERIAL)
29
30#include <Morpheus_SpaceTraits.hpp>
31#include <Morpheus_FormatTraits.hpp>
32#include <Morpheus_FormatTags.hpp>
33#include <Morpheus_Spaces.hpp>
34
35namespace Morpheus {
36namespace Impl {
37
38template <typename ExecSpace, typename SourceType, typename DestinationType>
39void convert(
40 const SourceType& src, DestinationType& dst,
41 typename std::enable_if<
42 Morpheus::is_csr_matrix_format_container_v<SourceType> &&
43 Morpheus::is_csr_matrix_format_container_v<DestinationType> &&
44 Morpheus::has_custom_backend_v<ExecSpace> &&
45 Morpheus::has_serial_execution_space_v<ExecSpace> &&
46 Morpheus::has_access_v<ExecSpace, SourceType, DestinationType>>::type* =
47 nullptr) {
48 using size_type = typename SourceType::size_type;
49
50 dst.resize(src.nrows(), src.ncols(), src.nnnz());
51
52 // element-wise copy of indices and values
53 for (size_type n = 0; n < src.nrows() + 1; n++) {
54 dst.row_offsets(n) = src.crow_offsets(n);
55 }
56
57 for (size_type n = 0; n < src.nnnz(); n++) {
58 dst.column_indices(n) = src.ccolumn_indices(n);
59 }
60
61 for (size_type n = 0; n < src.nnnz(); n++) {
62 dst.values(n) = src.cvalues(n);
63 }
64}
65
66template <typename ExecSpace, typename SourceType, typename DestinationType>
67void convert(
68 const SourceType& src, DestinationType& dst,
69 typename std::enable_if<
70 Morpheus::is_csr_matrix_format_container_v<SourceType> &&
71 Morpheus::is_coo_matrix_format_container_v<DestinationType> &&
72 Morpheus::has_custom_backend_v<ExecSpace> &&
73 Morpheus::has_serial_execution_space_v<ExecSpace> &&
74 Morpheus::has_access_v<ExecSpace, SourceType, DestinationType>>::type* =
75 nullptr) {
76 // Complexity: Linear. Specifically O(nnz(csr) + max(n_row,n_col))
77 using size_type = typename SourceType::size_type;
78 using index_type = typename SourceType::index_type;
79
80 dst.resize(src.nrows(), src.ncols(), src.nnnz());
81
82 // expand compressed indices
83 for (size_type i = 0; i < src.nrows(); i++) {
84 for (index_type jj = src.crow_offsets(i); jj < src.crow_offsets(i + 1);
85 jj++) {
86 dst.row_indices(jj) = i;
87 }
88 }
89
90 for (size_type n = 0; n < src.nnnz(); n++) {
91 dst.column_indices(n) = src.ccolumn_indices(n);
92 }
93
94 for (size_type n = 0; n < src.nnnz(); n++) {
95 dst.values(n) = src.cvalues(n);
96 }
97}
98
99template <typename ExecSpace, typename SourceType, typename DestinationType>
100void convert(
101 const SourceType& src, DestinationType& dst,
102 typename std::enable_if<
103 Morpheus::is_coo_matrix_format_container_v<SourceType> &&
104 Morpheus::is_csr_matrix_format_container_v<DestinationType> &&
105 Morpheus::has_custom_backend_v<ExecSpace> &&
106 Morpheus::has_serial_execution_space_v<ExecSpace> &&
107 Morpheus::has_access_v<ExecSpace, SourceType, DestinationType>>::type* =
108 nullptr) {
109 // Complexity: Linear. Specifically O(nnz(coo) + max(n_row,n_col))
110 using size_type = typename SourceType::size_type;
111 using index_type = typename SourceType::index_type;
112
113 dst.resize(src.nrows(), src.ncols(), src.nnnz());
114 // Make sure we zero offsets for correct cumsum
115 dst.row_offsets().assign(src.nrows() + 1, 0);
116
117 // compute number of non-zero entries per row of coo src
118 for (size_type n = 0; n < src.nnnz(); n++) {
119 dst.row_offsets(src.crow_indices(n))++;
120 }
121
122 // cumsum the nnz per row to get csr row_offsets
123 index_type cumsum = 0;
124 for (size_type i = 0; i < src.nrows(); i++) {
125 index_type temp = dst.row_offsets(i);
126 dst.row_offsets(i) = cumsum;
127 cumsum += temp;
128 }
129
130 dst.row_offsets(src.nrows()) = src.nnnz();
131
132 // write coo column indices and values into csr
133 for (size_type n = 0; n < src.nnnz(); n++) {
134 size_type row = src.crow_indices(n);
135 size_type dest = dst.row_offsets(row);
136
137 dst.column_indices(dest) = src.ccolumn_indices(n);
138 dst.values(dest) = src.cvalues(n);
139
140 dst.row_offsets(row)++;
141 }
142
143 index_type last = 0;
144 for (size_type i = 0; i <= src.nrows(); i++) {
145 index_type temp = dst.row_offsets(i);
146 dst.row_offsets(i) = last;
147 last = temp;
148 }
149
150 // TODO: remove duplicates, if any?
151}
152
153} // namespace Impl
154} // namespace Morpheus
155
156#endif // MORPHEUS_ENABLE_SERIAL
157#endif // MORPHEUS_CSR_SERIAL_CONVERT_IMPL_HPP
Generic Morpheus interfaces.
Definition: dummy.cpp:24