Distributed Ranges
Loading...
Searching...
No Matches
generate_csr.hpp
1// SPDX-FileCopyrightText: Intel Corporation
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#pragma once
6
7#include <concepts>
8#include <dr/views/csr_matrix_view.hpp>
9#include <fmt/core.h>
10#include <random>
11#include <unordered_set>
12
13namespace dr {
14
15namespace {
16
17template <typename T> struct uniform_distribution {
18 using type = std::uniform_int_distribution<T>;
19};
20
21template <std::floating_point T> struct uniform_distribution<T> {
22 using type = std::uniform_real_distribution<T>;
23};
24
25template <typename T>
26using uniform_distribution_t = typename uniform_distribution<T>::type;
27
28struct pair_hash {
29 template <std::integral I>
30 inline std::size_t operator()(const std::pair<I, I> &v) const {
31 return v.first * 31 + v.second;
32 }
33};
34
35} // namespace
36
37// it returns matrix view of randomly generated matrix
38// the memory is owned by the view, so it needs to be released using
39// destroy_csr_matrix_view
40template <typename T = float, std::integral I = std::size_t>
41auto generate_random_csr(dr::index<I> shape, double density = 0.01,
42 unsigned int seed = 0) {
43
44 assert(density >= 0.0 && density < 1.0);
45
46 std::unordered_set<std::pair<I, I>, pair_hash> tuples{};
47 std::vector<std::pair<std::pair<I, I>, T>> entries;
48 std::size_t nnz = density * shape[0] * shape[1];
49 entries.reserve(nnz);
50
51 std::mt19937 gen(seed);
52 std::uniform_int_distribution<I> row(0, shape[0] - 1);
53 std::uniform_int_distribution<I> column(0, shape[1] - 1);
54
55 uniform_distribution_t<T> value_gen(0, 1);
56
57 while (tuples.size() < nnz) {
58 auto i = row(gen);
59 auto j = column(gen);
60 if (tuples.find({i, j}) == tuples.end()) {
61 T value = value_gen(gen);
62 tuples.insert({i, j});
63 entries.push_back({{i, j}, value});
64 }
65 }
66 T *values = new T[nnz];
67 I *rowptr = new I[shape[0] + 1];
68 I *colind = new I[nnz];
69
70 rowptr[0] = 0;
71
72 std::size_t r = 0;
73 std::size_t c = 0;
74 std::sort(entries.begin(), entries.end());
75 for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
76 auto &&[index, value] = *iter;
77 auto &&[i, j] = index;
78
79 values[c] = value;
80 colind[c] = j;
81
82 while (r < i) {
83 if (r + 1 > shape[0]) {
84 // TODO: exception?
85 // throw std::runtime_error("csr_matrix_impl_: given invalid matrix");
86 }
87 rowptr[r + 1] = c;
88 r++;
89 }
90 c++;
91
92 if (c > nnz) {
93 // TODO: exception?
94 // throw std::runtime_error("csr_matrix_impl_: given invalid matrix");
95 }
96 }
97
98 for (; r < shape[0]; r++) {
99 rowptr[r + 1] = nnz;
100 }
101
102 return dr::views::csr_matrix_view(values, rowptr, colind, shape, nnz, 0);
103}
104
105// it returns matrix view of band matrix
106// the memory is owned by the view, so it needs to be released using
107// destroy_csr_matrix_view
108template <typename T = float, std::integral I = std::size_t>
109auto generate_band_csr(I size, std::size_t up_band = 3,
110 std::size_t down_band = 3) {
111 std::size_t nnz = (1 + up_band + down_band) * size -
112 (up_band * (up_band + 1) / 2) -
113 (down_band * (down_band + 1) / 2);
114
115 T *values = new T[nnz];
116 I *rowptr = new I[size + 1];
117 I *colind = new I[nnz];
118
119 rowptr[0] = 0;
120
121 std::size_t r = 0;
122 std::size_t c = 0;
123 for (auto i = 0; i < size; i++) {
124 for (auto j = std::max(static_cast<long long>(i) -
125 static_cast<long long>(down_band),
126 static_cast<long long>(0));
127 j < i; j++) {
128 values[c] = 1;
129 colind[c] = static_cast<I>(j);
130 c++;
131 }
132 values[c] = 1;
133 colind[c] = i;
134 c++;
135 for (auto j = i + 1; j <= i + up_band; j++) {
136 if (j >= size) {
137 continue;
138 }
139 values[c] = 1;
140 colind[c] = j;
141 c++;
142 }
143 rowptr[r + 1] = c;
144 r++;
145 }
146
147 for (; r < size; r++) {
148 rowptr[r + 1] = nnz;
149 }
150
151 return dr::views::csr_matrix_view<T, I>(values, rowptr, colind, {size, size},
152 nnz, 0);
153}
154
155} // namespace dr
Definition: index.hpp:34
Definition: csr_matrix_view.hpp:126