Motr  M0
matvec.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
22 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_SNS
23 #include "lib/trace.h"
24 
25 #include "lib/errno.h"
26 #include "lib/memory.h"
27 #include "lib/misc.h" /* memcpy */
28 #include "lib/assert.h"
29 #include "lib/types.h"
30 #include "sns/matvec.h"
31 
32 /* ============================================================================
33  GLOBAL @TODO: ALLOCATE AND FREE DATA WITH CORRESPONDING ALIGNMENT!!!
34  =========================================================================== */
35 
36 M0_INTERNAL int m0_matvec_init(struct m0_matvec *v, uint32_t sz)
37 {
38  v->mv_size = sz;
39  M0_ALLOC_ARR(v->mv_vector, sz);
40  return v->mv_vector == NULL ? -ENOMEM : 0;
41 }
42 
43 M0_INTERNAL void m0_matvec_fini(struct m0_matvec *v)
44 {
45  m0_free0(&v->mv_vector);
46  v->mv_size = 0;
47 }
48 
49 M0_INTERNAL int m0_matrix_init(struct m0_matrix *m, uint32_t w, uint32_t h)
50 {
51  uint32_t i;
52  m->m_height = h;
53  m->m_width = w;
54 
55  M0_ALLOC_ARR(m->m_matrix, h);
56  if (m->m_matrix == NULL)
57  return M0_ERR(-ENOMEM);
58 
59  for (i = 0; i < h; ++i) {
60  M0_ALLOC_ARR(m->m_matrix[i], w);
61  if (m->m_matrix[i] == NULL) {
63  return M0_ERR(-ENOMEM);
64  }
65  }
66 
67  return 0;
68 }
69 
70 M0_INTERNAL void m0_matrix_fini(struct m0_matrix *m)
71 {
72  uint32_t i;
73 
74  for (i = 0; i < m->m_height; ++i)
75  m0_free0(&m->m_matrix[i]);
76  m0_free0(&m->m_matrix);
77  m->m_height = m->m_width = 0;
78 }
79 
80 m0_parity_elem_t* m0_matvec_elem_get(const struct m0_matvec *v, uint32_t x)
81 {
82  M0_PRE(x < v->mv_size);
83  return &v->mv_vector[x];
84 }
85 
86 m0_parity_elem_t* m0_matrix_elem_get(const struct m0_matrix *m, uint32_t x, uint32_t y)
87 {
88  M0_PRE(x < m->m_width);
89  M0_PRE(y < m->m_height);
90  return &m->m_matrix[y][x];
91 }
92 
93 M0_INTERNAL void m0_matrix_print(const struct m0_matrix *mat)
94 {
95  uint32_t x, y;
96  M0_PRE(mat);
97 
98  M0_LOG(M0_DEBUG, "-----> mat %p\n", mat);
99 
100  for (y = 0; y < mat->m_height; ++y) {
101  for (x = 0; x < mat->m_width; ++x)
102  M0_LOG(M0_DEBUG, "%6d ", *m0_matrix_elem_get(mat, x, y));
103  M0_LOG(M0_DEBUG, "\n");
104  }
105 
106  M0_LOG(M0_DEBUG, "\n");
107 }
108 
109 M0_INTERNAL void m0_matvec_print(const struct m0_matvec *vec)
110 {
111  uint32_t x;
112  M0_PRE(vec);
113 
114  M0_LOG(M0_DEBUG, "-----> vec %p\n", vec);
115  for (x = 0; x < vec->mv_size; ++x)
116  M0_LOG(M0_DEBUG, "%6d\n", *m0_matvec_elem_get(vec, x));
117  M0_LOG(M0_DEBUG, "\n");
118 }
119 
120 M0_INTERNAL void m0_matrix_swap_row(struct m0_matrix *m, uint32_t r0,
121  uint32_t r1)
122 {
123  m0_parity_elem_t *temp;
124  M0_PRE(r0 < m->m_height && r1 < m->m_height);
125 
126  temp = m->m_matrix[r0];
127  m->m_matrix[r0] = m->m_matrix[r1];
128  m->m_matrix[r1] = temp;
129 }
130 
131 M0_INTERNAL void m0_matvec_swap_row(struct m0_matvec *v, uint32_t r0,
132  uint32_t r1)
133 {
134  m0_parity_elem_t temp;
135  M0_PRE(r0 < v->mv_size && r1 < v->mv_size);
136 
137  temp = v->mv_vector[r0];
138  v->mv_vector[r0] = v->mv_vector[r1];
139  v->mv_vector[r1] = temp;
140 }
141 
142 M0_INTERNAL void m0_matrix_row_operate(struct m0_matrix *m, uint32_t row,
145 {
146  uint32_t x;
147  M0_PRE(m);
148 
149  for (x = 0; x < m->m_width; ++x) {
151  *e = f(*e, c);
152  }
153 }
154 
155 M0_INTERNAL void m0_matvec_row_operate(struct m0_matvec *v, uint32_t row,
158 {
160  M0_PRE(v);
161 
162  *e = f(*e, c);
163 }
164 
165 M0_INTERNAL void m0_matrix_rows_operate(struct m0_matrix *m, uint32_t row0,
166  uint32_t row1,
168  m0_parity_elem_t c0,
170  m0_parity_elem_t c1,
172 {
173  uint32_t x;
174  M0_PRE(m);
175 
176  for (x = 0; x < m->m_width; ++x) {
177  m0_parity_elem_t *e0 = m0_matrix_elem_get(m, x, row0);
178  m0_parity_elem_t *e1 = m0_matrix_elem_get(m, x, row1);
179  *e0 = f(f0(*e0, c0), f1(*e1, c1));
180  }
181 }
182 
183 M0_INTERNAL void m0_matrix_rows_operate2(struct m0_matrix *m, uint32_t row0,
184  uint32_t row1,
186  m0_parity_elem_t c0,
188 {
189  uint32_t x;
190  M0_PRE(m);
191 
192  for (x = 0; x < m->m_width; ++x) {
193  m0_parity_elem_t *e0 = m0_matrix_elem_get(m, x, row0);
194  m0_parity_elem_t *e1 = m0_matrix_elem_get(m, x, row1);
195  *e0 = f(f0(*e0, c0), *e1);
196  }
197 }
198 
199 M0_INTERNAL void m0_matrix_rows_operate1(struct m0_matrix *m, uint32_t row0,
200  uint32_t row1,
202  m0_parity_elem_t c1,
204 {
205  uint32_t x;
206  M0_PRE(m);
207 
208  for (x = 0; x < m->m_width; ++x) {
209  m0_parity_elem_t *e0 = m0_matrix_elem_get(m, x, row0);
210  m0_parity_elem_t *e1 = m0_matrix_elem_get(m, x, row1);
211  *e0 = f(*e0, f1(*e1, c1));
212  }
213 }
214 
215 M0_INTERNAL void m0_matrix_cols_operate(struct m0_matrix *m, uint32_t col0,
216  uint32_t col1,
218  m0_parity_elem_t c0,
220  m0_parity_elem_t c1,
222 {
223  uint32_t y;
224 
225  M0_PRE(m);
226 
227  for (y = 0; y < m->m_height; ++y) {
228  m0_parity_elem_t *e0 = m0_matrix_elem_get(m, col0, y);
229  m0_parity_elem_t *e1 = m0_matrix_elem_get(m, col1, y);
230  *e0 = f(f0(*e0, c0), f1(*e1, c1));
231  }
232 }
233 
234 M0_INTERNAL void m0_matrix_col_operate(struct m0_matrix *m, uint32_t col,
237 {
238  uint32_t y;
239  M0_PRE(m);
240 
241  for (y = 0; y < m->m_height; ++y) {
242  m0_parity_elem_t *e = m0_matrix_elem_get(m, col, y);
243  *e = f(*e, c);
244  }
245 }
246 
247 M0_INTERNAL void m0_matvec_rows_operate(struct m0_matvec *v, uint32_t row0,
248  uint32_t row1,
250  m0_parity_elem_t c0,
252  m0_parity_elem_t c1,
254 {
255  m0_parity_elem_t *e0;
256  m0_parity_elem_t *e1;
257 
258  M0_PRE(v);
259 
260  e0 = m0_matvec_elem_get(v, row0);
261  e1 = m0_matvec_elem_get(v, row1);
262  *e0 = f(f0(*e0, c0), f1(*e1, c1));
263 }
264 
265 M0_INTERNAL void m0_matvec_rows_operate1(struct m0_matvec *v, uint32_t row0,
266  uint32_t row1,
268  m0_parity_elem_t c1,
270 {
271  m0_parity_elem_t *e0;
272  m0_parity_elem_t *e1;
273 
274  M0_PRE(v);
275 
276  e0 = m0_matvec_elem_get(v, row0);
277  e1 = m0_matvec_elem_get(v, row1);
278  *e0 = f(*e0, f1(*e1, c1));
279 }
280 
281 M0_INTERNAL void m0_matvec_rows_operate2(struct m0_matvec *v, uint32_t row0,
282  uint32_t row1,
284  m0_parity_elem_t c0,
286 {
287  m0_parity_elem_t *e0;
288  m0_parity_elem_t *e1;
289 
290  M0_PRE(v);
291 
292  e0 = m0_matvec_elem_get(v, row0);
293  e1 = m0_matvec_elem_get(v, row1);
294  *e0 = f(f0(*e0, c0), *e1);
295 }
296 
297 
298 M0_INTERNAL void m0_matrix_vec_multiply(const struct m0_matrix *m,
299  const struct m0_matvec *v,
300  struct m0_matvec *r,
303 {
304  uint32_t y;
305  uint32_t x;
306 
307  M0_PRE(v != NULL && m != NULL && r != NULL);
308  M0_PRE(m->m_width == v->mv_size && m->m_height == r->mv_size);
309 
310  for (y = 0; y < m->m_height; ++y) {
312  *er = M0_PARITY_ZERO;
313 
314  for (x = 0; x < m->m_width; ++x) {
317  if (ev == M0_PARITY_ZERO || em == M0_PARITY_ZERO)
318  continue;
319  *er = add(*er, mul(ev, em));
320  }
321  }
322 }
323 
324 M0_INTERNAL void m0_matrix_submatrix_get(const struct m0_matrix *mat,
325  struct m0_matrix *submat,
326  uint32_t x_off, uint32_t y_off)
327 {
328  uint32_t x;
329  uint32_t y;
330 
331  M0_PRE(mat->m_width >= (submat->m_width + x_off)
332  && mat->m_height >= (submat->m_height + y_off));
333 
334  for (y = 0; y < submat->m_height; ++y) {
335  for (x = 0; x < submat->m_width; ++x) {
336  *m0_matrix_elem_get(submat, x, y) =
337  *m0_matrix_elem_get(mat, x + x_off, y + y_off);
338  }
339  }
340 }
341 
342 M0_INTERNAL void m0_matrix_multiply(const struct m0_matrix *ma,
343  const struct m0_matrix *mb,
344  struct m0_matrix *mc)
345 {
346  uint32_t i;
347  uint32_t j;
348  uint32_t k;
350  static m0_parity_elem_t* (*e)(const struct m0_matrix *m, uint32_t x,
351  uint32_t y) = m0_matrix_elem_get;
352 
353  M0_PRE(ma != NULL);
354  M0_PRE(mb != NULL);
355  M0_PRE(mc != NULL);
356  M0_PRE(mc->m_height == ma->m_height);
357  M0_PRE(mc->m_width == mb->m_width);
359 
360  for (i = 0; i < ma->m_height; ++i) {
361  for (j = 0; j < ma->m_width; ++j) {
362  for (k = 0; k < mb->m_height; ++k) {
363  res = m0_parity_mul(*e(ma, i, j), *e(mb, j, k));
364  *e(mc, i, k) = m0_parity_add(*e(mc, i, k), res);
365  }
366  }
367 
368  }
369 }
370 
371 M0_INTERNAL void m0_identity_matrix_fill(struct m0_matrix *identity_mat)
372 {
373  uint32_t i;
374  uint32_t j;
375  bool rc;
376 
377  rc = m0_matrix_is_square(identity_mat);
378  M0_PRE(rc);
379 
380  for (i = 0; i < identity_mat->m_width; ++i) {
381  for (j = 0; j < identity_mat->m_height; ++j) {
382  *m0_matrix_elem_get(identity_mat, i, j) = !!(i == j);
383  }
384  }
385 }
386 
387 M0_INTERNAL bool m0_matrix_is_init(const struct m0_matrix *mat)
388 {
389  return mat != NULL && mat->m_matrix != NULL && mat->m_width > 0 &&
390  mat->m_height > 0;
391 }
392 
393 M0_INTERNAL bool m0_matrix_is_null(const struct m0_matrix *mat)
394 {
395  return m0_forall(i, mat->m_height,
396  m0_forall(j, mat->m_width,
397  *m0_matrix_elem_get(mat, i, j) == 0));
398 }
399 
400 M0_INTERNAL void m0_matrix_row_copy(struct m0_matrix *des,
401  const struct m0_matrix *src,
402  uint32_t des_row, uint32_t src_row)
403 {
405  M0_PRE(des->m_width == src->m_width);
406  M0_PRE(des_row < des->m_height && src_row < src->m_height);
407 
408  memcpy(m0_matrix_elem_get(des, 0, des_row),
409  m0_matrix_elem_get(src, 0, src_row),
410  src->m_width* sizeof (m0_parity_elem_t));
411 }
412 
413 M0_INTERNAL bool m0_matrix_is_square(const struct m0_matrix *mat)
414 {
415  return mat != NULL && mat->m_width != 0 &&
416  mat->m_width == mat->m_height;
417 }
418 
419 #undef M0_TRACE_SUBSYSTEM
420 
421 /*
422  * Local variables:
423  * c-indentation-style: "K&R"
424  * c-basic-offset: 8
425  * tab-width: 8
426  * fill-column: 80
427  * scroll-step: 1
428  * End:
429  */
M0_INTERNAL void m0_matvec_rows_operate(struct m0_matvec *v, uint32_t row0, uint32_t row1, m0_matvec_matrix_binary_operator_t f0, m0_parity_elem_t c0, m0_matvec_matrix_binary_operator_t f1, m0_parity_elem_t c1, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:247
M0_INTERNAL void m0_matvec_print(const struct m0_matvec *vec)
Definition: matvec.c:109
static m0_parity_elem_t m0_parity_add(m0_parity_elem_t x, m0_parity_elem_t y)
Definition: parity_ops.h:41
M0_INTERNAL bool m0_matrix_is_null(const struct m0_matrix *mat)
Definition: matvec.c:393
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
#define NULL
Definition: misc.h:38
static struct m0_addb2_mach * m
Definition: consumer.c:38
M0_INTERNAL void m0_matrix_row_copy(struct m0_matrix *des, const struct m0_matrix *src, uint32_t des_row, uint32_t src_row)
Definition: matvec.c:400
static bool x
Definition: sm.c:168
static FILE * f
Definition: adieu.c:79
#define M0_LOG(level,...)
Definition: trace.h:167
uint32_t m_height
Definition: matvec.h:57
Definition: sock.c:772
M0_INTERNAL bool m0_matrix_is_square(const struct m0_matrix *mat)
Definition: matvec.c:413
M0_INTERNAL void m0_matrix_cols_operate(struct m0_matrix *m, uint32_t col0, uint32_t col1, m0_matvec_matrix_binary_operator_t f0, m0_parity_elem_t c0, m0_matvec_matrix_binary_operator_t f1, m0_parity_elem_t c1, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:215
M0_INTERNAL bool m0_matrix_is_init(const struct m0_matrix *mat)
Definition: matvec.c:387
M0_INTERNAL void m0_matrix_row_operate(struct m0_matrix *m, uint32_t row, m0_parity_elem_t c, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:142
int i
Definition: dir.c:1033
M0_INTERNAL void m0_matvec_row_operate(struct m0_matvec *v, uint32_t row, m0_parity_elem_t c, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:155
return M0_ERR(-EOPNOTSUPP)
m0_parity_elem_t * mv_vector
Definition: matvec.h:36
M0_INTERNAL void m0_matrix_col_operate(struct m0_matrix *m, uint32_t col, m0_parity_elem_t c, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:234
M0_INTERNAL void m0_matvec_rows_operate1(struct m0_matvec *v, uint32_t row0, uint32_t row1, m0_matvec_matrix_binary_operator_t f1, m0_parity_elem_t c1, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:265
struct mock_balloc mb
Definition: ad.c:173
#define m0_free0(pptr)
Definition: memory.h:77
static void * vec
Definition: xcode.c:168
uint32_t mv_size
Definition: matvec.h:35
M0_INTERNAL void m0_matrix_rows_operate(struct m0_matrix *m, uint32_t row0, uint32_t row1, m0_matvec_matrix_binary_operator_t f0, m0_parity_elem_t c0, m0_matvec_matrix_binary_operator_t f1, m0_parity_elem_t c1, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:165
#define M0_PARITY_ZERO
Definition: parity_ops.h:33
static struct m0_addb2_callback c
Definition: consumer.c:41
M0_INTERNAL void m0_matvec_swap_row(struct m0_matvec *v, uint32_t r0, uint32_t r1)
Definition: matvec.c:131
M0_INTERNAL void m0_matrix_rows_operate1(struct m0_matrix *m, uint32_t row0, uint32_t row1, m0_matvec_matrix_binary_operator_t f1, m0_parity_elem_t c1, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:199
M0_INTERNAL void m0_matrix_multiply(const struct m0_matrix *ma, const struct m0_matrix *mb, struct m0_matrix *mc)
Definition: matvec.c:342
M0_INTERNAL void m0_matvec_rows_operate2(struct m0_matvec *v, uint32_t row0, uint32_t row1, m0_matvec_matrix_binary_operator_t f0, m0_parity_elem_t c0, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:281
m0_parity_elem_t * m0_matrix_elem_get(const struct m0_matrix *m, uint32_t x, uint32_t y)
Definition: matvec.c:86
m0_parity_elem_t * m0_matvec_elem_get(const struct m0_matvec *v, uint32_t x)
Definition: matvec.c:80
M0_INTERNAL void m0_matrix_submatrix_get(const struct m0_matrix *mat, struct m0_matrix *submat, uint32_t x_off, uint32_t y_off)
Definition: matvec.c:324
m0_parity_elem_t(* m0_matvec_matrix_binary_operator_t)(m0_parity_elem_t, m0_parity_elem_t)
Definition: matvec.h:76
#define m0_forall(var, nr,...)
Definition: misc.h:112
M0_INTERNAL void m0_matrix_fini(struct m0_matrix *m)
Definition: matvec.c:70
M0_INTERNAL void m0_identity_matrix_fill(struct m0_matrix *identity_mat)
Definition: matvec.c:371
M0_INTERNAL int m0_matrix_init(struct m0_matrix *m, uint32_t w, uint32_t h)
Definition: matvec.c:49
M0_INTERNAL void m0_matrix_vec_multiply(const struct m0_matrix *m, const struct m0_matvec *v, struct m0_matvec *r, m0_matvec_matrix_binary_operator_t mul, m0_matvec_matrix_binary_operator_t add)
Definition: matvec.c:298
static int r[NR]
Definition: thread.c:46
int m0_parity_elem_t
Definition: parity_ops.h:36
m0_parity_elem_t ** m_matrix
Definition: matvec.h:58
M0_INTERNAL void m0_matrix_rows_operate2(struct m0_matrix *m, uint32_t row0, uint32_t row1, m0_matvec_matrix_binary_operator_t f0, m0_parity_elem_t c0, m0_matvec_matrix_binary_operator_t f)
Definition: matvec.c:183
M0_INTERNAL int m0_matvec_init(struct m0_matvec *v, uint32_t sz)
Definition: matvec.c:36
static m0_parity_elem_t m0_parity_mul(m0_parity_elem_t x, m0_parity_elem_t y)
Definition: parity_ops.h:51
M0_INTERNAL void m0_matvec_fini(struct m0_matvec *v)
Definition: matvec.c:43
uint32_t m_width
Definition: matvec.h:56
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL void m0_matrix_print(const struct m0_matrix *mat)
Definition: matvec.c:93
static void add(struct m0_addb2_mach *mach, uint64_t id, int n, const uint64_t *value)
Definition: addb2.c:934
M0_INTERNAL void m0_matrix_swap_row(struct m0_matrix *m, uint32_t r0, uint32_t r1)
Definition: matvec.c:120