FlashGraph-ng
A new frontier in large-scale graph analysis and data mining
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
NUMA_dense_matrix.h
1 #ifndef __NUMA_DENSE_MATRIX_H__
2 #define __NUMA_DENSE_MATRIX_H__
3 
4 /*
5  * Copyright 2014 Open Connectome Project (http://openconnecto.me)
6  * Written by Da Zheng (zhengda1936@gmail.com)
7  *
8  * This file is part of FlashMatrix.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22 
23 #include "comm_exception.h"
24 
25 #include "raw_data_array.h"
26 #include "NUMA_mapper.h"
27 #include "NUMA_vector.h"
28 #include "mem_matrix_store.h"
29 
30 namespace fm
31 {
32 
33 namespace detail
34 {
35 
36 class NUMA_matrix_store: public mem_matrix_store
37 {
38  const size_t data_id;
39 protected:
40  NUMA_matrix_store(size_t nrow, size_t ncol, const scalar_type &type,
41  size_t _data_id): mem_matrix_store(nrow, ncol,
42  type), data_id(_data_id) {
43  }
44 public:
45  typedef std::shared_ptr<NUMA_matrix_store> ptr;
46  typedef std::shared_ptr<const NUMA_matrix_store> const_ptr;
47 
48  static ptr cast(matrix_store::ptr store);
49  static const_ptr cast(matrix_store::const_ptr store);
50 
51  static ptr create(size_t nrow, size_t ncol, int num_nodes,
52  matrix_layout_t layout, const scalar_type &type);
53 
54  size_t get_data_id() const {
55  return data_id;
56  }
57  virtual std::unordered_map<size_t, size_t> get_underlying_mats() const {
58  std::unordered_map<size_t, size_t> ret;
59  ret.insert(std::pair<size_t, size_t>(data_id,
60  get_num_rows() * get_num_cols()));
61  return ret;
62  }
63 
64  virtual matrix_store::const_ptr get_rows(
65  const std::vector<off_t> &idxs) const {
66  assert(0);
67  return matrix_store::const_ptr();
68  }
69  virtual bool write2file(const std::string &file_name) const {
70  assert(0);
71  return false;
72  }
73 };
74 
75 class NUMA_row_matrix_store: public NUMA_matrix_store
76 {
77 protected:
78  NUMA_row_matrix_store(size_t nrow, size_t ncol, const scalar_type &type,
79  size_t data_id): NUMA_matrix_store(nrow, ncol, type, data_id) {
80  }
81 public:
82  typedef std::shared_ptr<NUMA_row_matrix_store> ptr;
83 
84  static ptr cast(matrix_store::ptr store) {
85  // TODO check store type.
86  return std::static_pointer_cast<NUMA_row_matrix_store>(store);
87  }
88 
89  virtual matrix_layout_t store_layout() const {
90  return matrix_layout_t::L_ROW;
91  }
92 };
93 
94 class NUMA_col_matrix_store: public NUMA_matrix_store
95 {
96 protected:
97  NUMA_col_matrix_store(size_t nrow, size_t ncol, const scalar_type &type,
98  size_t data_id): NUMA_matrix_store(nrow, ncol, type, data_id) {
99  }
100 public:
101  typedef std::shared_ptr<NUMA_col_matrix_store> ptr;
102 
103  static ptr cast(matrix_store::ptr store) {
104  // TODO check store type.
105  return std::static_pointer_cast<NUMA_col_matrix_store>(store);
106  }
107 
108  virtual matrix_layout_t store_layout() const {
109  return matrix_layout_t::L_COL;
110  }
111 };
112 
113 class NUMA_col_wide_matrix_store;
114 class NUMA_row_wide_matrix_store;
115 
116 /*
117  * This class defines an in-memory dense matrix whose data is organized
118  * in row major and has many more rows than columns. The matrix is optimized
119  * for a NUMA machine. Rows in the matrix are distributed across multiple
120  * NUMA node. Multiple adjacent rows are stored in contiguous memory and
121  * a single row is guaranteed to be stored together.
122  */
123 class NUMA_row_tall_matrix_store: public NUMA_row_matrix_store
124 {
125  // This is to map rows to different NUMA nodes.
126  NUMA_mapper mapper;
127  std::vector<detail::raw_data_array> data;
128 
129  // The copy constructor performs shallow copy.
130  NUMA_row_tall_matrix_store(const NUMA_row_tall_matrix_store &mat);
131 
132  NUMA_row_tall_matrix_store(size_t nrow, size_t ncol, int num_nodes,
133  const scalar_type &type);
134  NUMA_row_tall_matrix_store(const std::vector<detail::raw_data_array> &data,
135  size_t nrow, size_t ncol, const NUMA_mapper &mapper,
136  const scalar_type &type);
137 public:
138  typedef std::shared_ptr<NUMA_row_tall_matrix_store> ptr;
139 
140  static ptr create(const std::vector<detail::raw_data_array> &data,
141  size_t nrow, size_t ncol, const NUMA_mapper &mapper,
142  const scalar_type &type) {
143  return ptr(new NUMA_row_tall_matrix_store(data, nrow, ncol,
144  mapper, type));
145  }
146 
147  static ptr create(size_t nrow, size_t ncol, int num_nodes,
148  const scalar_type &type) {
149  return ptr(new NUMA_row_tall_matrix_store(nrow, ncol, num_nodes, type));
150  }
151 
152  int get_num_nodes() const {
153  return data.size();
154  }
155 
156  const char *get_row(size_t row_idx) const;
157  char *get_row(size_t row_idx);
158  using NUMA_matrix_store::get_rows;
159  const char *get_rows(size_t row_start, size_t row_end) const;
160  char *get_rows(size_t row_start, size_t row_end);
161 
162  const char *get(size_t row_idx, size_t col_idx) const {
163  const char *row = get_row(row_idx);
164  return row + col_idx * get_entry_size();
165  }
166 
167  char *get(size_t row_idx, size_t col_idx) {
168  char *row = get_row(row_idx);
169  return row + col_idx * get_entry_size();
170  }
171 
172 
173  virtual matrix_store::const_ptr get_rows(const std::vector<off_t> &idxs) const;
174  virtual matrix_store::const_ptr get_cols(const std::vector<off_t> &idxs) const;
175  virtual std::shared_ptr<const local_matrix_store> get_portion(
176  size_t start_row, size_t start_col, size_t num_rows,
177  size_t num_cols) const;
178  virtual std::shared_ptr<local_matrix_store> get_portion(
179  size_t start_row, size_t start_col, size_t num_rows,
180  size_t num_cols);
181  virtual std::shared_ptr<const local_matrix_store> get_portion(size_t id) const;
182  virtual std::shared_ptr<local_matrix_store> get_portion(size_t id);
183 
184  virtual vec_store::const_ptr get_row_vec(off_t row) const {
185  BOOST_LOG_TRIVIAL(error)
186  << "Can't get a row from a NUMA tall row matrix";
187  return vec_store::const_ptr();
188  }
189  virtual vec_store::const_ptr get_col_vec(off_t idx) const {
190  BOOST_LOG_TRIVIAL(error)
191  << "Can't get a column from a NUMA tall row matrix";
192  return vec_store::const_ptr();
193  }
194 
195  virtual matrix_store::const_ptr transpose() const;
196  virtual bool write2file(const std::string &file_name) const;
197 
198  friend class NUMA_col_wide_matrix_store;
199 };
200 
201 /*
202  * This class defines an in-memory dense matrix whose data is organized
203  * in column major and has many more rows than columns. The matrix is optimized
204  * for a NUMA machine. Each column in the matrix are distributed across multiple
205  * NUMA nodes.
206  */
207 class NUMA_col_tall_matrix_store: public NUMA_col_matrix_store
208 {
209  std::vector<NUMA_vec_store::ptr> data;
210 
211  NUMA_col_tall_matrix_store(
212  const std::vector<NUMA_vec_store::ptr> &cols): NUMA_col_matrix_store(
213  cols.front()->get_length(), cols.size(),
214  cols.front()->get_type(), mat_counter++) {
215  this->data = cols;
216  }
217 
218  // The copy constructor performs shallow copy.
219  NUMA_col_tall_matrix_store(
220  const NUMA_col_tall_matrix_store &mat): NUMA_col_matrix_store(
221  mat.get_num_rows(), mat.get_num_cols(), mat.get_type(),
222  mat.get_data_id()) {
223  this->data = mat.data;
224  }
225 
226  NUMA_col_tall_matrix_store(size_t nrow, size_t ncol, int num_nodes,
227  const scalar_type &type);
228 public:
229  typedef std::shared_ptr<NUMA_col_tall_matrix_store> ptr;
230 
231  static ptr create(const std::vector<NUMA_vec_store::ptr> &cols) {
232  return ptr(new NUMA_col_tall_matrix_store(cols));
233  }
234 
235  static ptr create(size_t nrow, size_t ncol, int num_nodes,
236  const scalar_type &type) {
237  return ptr(new NUMA_col_tall_matrix_store(nrow, ncol, num_nodes, type));
238  }
239 
240  int get_num_nodes() const {
241  return data[0]->get_num_nodes();
242  }
243 
244  char *get(size_t row_idx, size_t col_idx) {
245  return data[col_idx]->get(row_idx);
246  }
247 
248  const char *get(size_t row_idx, size_t col_idx) const {
249  return data[col_idx]->get(row_idx);
250  }
251 
252 
253  virtual matrix_store::const_ptr get_rows(const std::vector<off_t> &idxs) const;
254  virtual matrix_store::const_ptr get_cols(const std::vector<off_t> &idxs) const;
255  virtual std::shared_ptr<const local_matrix_store> get_portion(
256  size_t start_row, size_t start_col, size_t num_rows,
257  size_t num_cols) const;
258  virtual std::shared_ptr<local_matrix_store> get_portion(
259  size_t start_row, size_t start_col, size_t num_rows,
260  size_t num_cols);
261  virtual std::shared_ptr<const local_matrix_store> get_portion(size_t id) const;
262  virtual std::shared_ptr<local_matrix_store> get_portion(size_t id);
263 
264  virtual vec_store::ptr get_col_vec(off_t col) {
265  return data[col];
266  }
267  virtual vec_store::const_ptr get_col_vec(off_t col) const {
268  return data[col];
269  }
270  virtual vec_store::const_ptr get_row_vec(off_t idx) const {
271  BOOST_LOG_TRIVIAL(error)
272  << "Can't get a row from a NUMA tall column matrix";
273  return vec_store::const_ptr();
274  }
275 
276  virtual matrix_store::const_ptr transpose() const;
277  virtual bool write2file(const std::string &file_name) const;
278 
279  friend class NUMA_row_wide_matrix_store;
280 };
281 
282 class NUMA_row_wide_matrix_store: public NUMA_row_matrix_store
283 {
284  NUMA_col_tall_matrix_store store;
285 
286  NUMA_row_wide_matrix_store(size_t nrow, size_t ncol, int num_nodes,
287  const scalar_type &type): NUMA_row_matrix_store(nrow, ncol,
288  type, mat_counter++), store(ncol, nrow, num_nodes, type) {
289  }
290 
291  /*
292  * The constructed matrix store will be the transpose of _store.
293  */
294  NUMA_row_wide_matrix_store(
295  const NUMA_col_tall_matrix_store &_store): NUMA_row_matrix_store(
296  _store.get_num_cols(), _store.get_num_rows(),
297  _store.get_type(), _store.get_data_id()), store(_store) {
298  }
299 public:
300  typedef std::shared_ptr<NUMA_row_wide_matrix_store> ptr;
301 
302  static ptr create(size_t nrow, size_t ncol, int num_nodes,
303  const scalar_type &type) {
304  return ptr(new NUMA_row_wide_matrix_store(nrow, ncol, num_nodes, type));
305  }
306 
307  static ptr create_transpose(const NUMA_col_tall_matrix_store &store) {
308  return ptr(new NUMA_row_wide_matrix_store(store));
309  }
310 
311  int get_num_nodes() const {
312  return store.get_num_nodes();
313  }
314 
315  char *get(size_t row_idx, size_t col_idx) {
316  return store.get(col_idx, row_idx);
317  }
318 
319  const char *get(size_t row_idx, size_t col_idx) const {
320  return store.get(col_idx, row_idx);
321  }
322 
323  virtual std::shared_ptr<const local_matrix_store> get_portion(
324  size_t start_row, size_t start_col, size_t num_rows,
325  size_t num_cols) const;
326  virtual std::shared_ptr<local_matrix_store> get_portion(
327  size_t start_row, size_t start_col, size_t num_rows,
328  size_t num_cols);
329  virtual std::shared_ptr<const local_matrix_store> get_portion(size_t id) const;
330  virtual std::shared_ptr<local_matrix_store> get_portion(size_t id);
331 
332  virtual vec_store::const_ptr get_row_vec(off_t row) const {
333  return store.get_col_vec(row);
334  }
335  virtual vec_store::const_ptr get_col_vec(off_t idx) const {
336  BOOST_LOG_TRIVIAL(error)
337  << "Can't get a column from a NUMA wide row matrix";
338  return vec_store::const_ptr();
339  }
340  virtual matrix_store::const_ptr get_rows(
341  const std::vector<off_t> &idxs) const {
342  return store.get_cols(idxs);
343  }
344 
345  virtual matrix_store::const_ptr transpose() const;
346 };
347 
348 class NUMA_col_wide_matrix_store: public NUMA_col_matrix_store
349 {
350  NUMA_row_tall_matrix_store store;
351 
352  NUMA_col_wide_matrix_store(size_t nrow, size_t ncol, int num_nodes,
353  const scalar_type &type): NUMA_col_matrix_store(nrow, ncol,
354  type, mat_counter++), store(ncol, nrow, num_nodes, type) {
355  }
356 
357  /*
358  * The constructed matrix store will be the transpose of _store.
359  */
360  NUMA_col_wide_matrix_store(
361  const NUMA_row_tall_matrix_store &_store): NUMA_col_matrix_store(
362  _store.get_num_cols(), _store.get_num_rows(),
363  _store.get_type(), _store.get_data_id()), store(_store) {
364  }
365 public:
366  typedef std::shared_ptr<NUMA_col_wide_matrix_store> ptr;
367 
368  static ptr create(size_t nrow, size_t ncol, int num_nodes,
369  const scalar_type &type) {
370  return ptr(new NUMA_col_wide_matrix_store(nrow, ncol, num_nodes, type));
371  }
372 
373  static ptr create_transpose(const NUMA_row_tall_matrix_store &store) {
374  return ptr(new NUMA_col_wide_matrix_store(store));
375  }
376 
377  int get_num_nodes() const {
378  return store.get_num_nodes();
379  }
380 
381  const char *get_col(size_t col_idx) const {
382  return store.get_row(col_idx);
383  }
384 
385  char *get_col(size_t col_idx) {
386  return store.get_row(col_idx);
387  }
388 
389  using NUMA_matrix_store::get_cols;
390  const char *get_cols(size_t col_start, size_t col_end) const {
391  return store.get_rows(col_start, col_end);
392  }
393 
394  char *get_cols(size_t col_start, size_t col_end) {
395  return store.get_rows(col_start, col_end);
396  }
397 
398  const char *get(size_t row_idx, size_t col_idx) const {
399  return store.get(col_idx, row_idx);
400  }
401 
402  char *get(size_t row_idx, size_t col_idx) {
403  return store.get(col_idx, row_idx);
404  }
405 
406  virtual std::shared_ptr<const local_matrix_store> get_portion(
407  size_t start_row, size_t start_col, size_t num_rows,
408  size_t num_cols) const;
409  virtual std::shared_ptr<local_matrix_store> get_portion(
410  size_t start_row, size_t start_col, size_t num_rows,
411  size_t num_cols);
412  virtual std::shared_ptr<const local_matrix_store> get_portion(size_t id) const;
413  virtual std::shared_ptr<local_matrix_store> get_portion(size_t id);
414 
415  virtual vec_store::const_ptr get_col_vec(off_t col) const {
416  BOOST_LOG_TRIVIAL(error)
417  << "Can't get a column from a NUMA wide col matrix";
418  return vec_store::const_ptr();
419  }
420  virtual vec_store::const_ptr get_row_vec(off_t row) const {
421  BOOST_LOG_TRIVIAL(error)
422  << "Can't get a row from a NUMA wide col matrix";
423  return vec_store::const_ptr();
424  }
425 
426  virtual matrix_store::const_ptr transpose() const;
427 };
428 
429 }
430 
431 }
432 
433 #endif