FlashGraph-ng
A new frontier in large-scale graph analysis and data mining
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
local_matrix_store.h
1 #ifndef __LOCAL_MATRIX_STORE_H__
2 #define __LOCAL_MATRIX_STORE_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 <memory>
24 #include <boost/format.hpp>
25 
26 #include "comm_exception.h"
27 #include "log.h"
28 
29 #include "local_vec_store.h"
30 #include "matrix_store.h"
31 #include "raw_data_array.h"
32 
33 namespace fm
34 {
35 
36 class bulk_operate;
37 class bulk_uoperate;
38 class arr_apply_operate;
39 
40 namespace detail
41 {
42 
43 /*
44  * This is a base class that represents part of a matrix.
45  * The original matrix can be an SMP matrix, a NUMA matrix,
46  * an external-memory matrix or a distributed-memory matrix.
47  * It is guaranteed that this matrix stores the portion of the original
48  * matrix in the local memory.
49  * This class has very similar interface as mem_matrix_store, but it's
50  * used for different purpose.
51  */
52 class local_matrix_store: public matrix_store
53 {
54  // These information is created when the local matrix store is created.
55  // But we can resize the matrix store, so it exposes part of the original
56  // local matrix store.
57  off_t global_start_row;
58  off_t global_start_col;
59  size_t num_rows;
60  size_t num_cols;
61 
62  // The start row and column exposed to users. They are relative to
63  // the original local matrix store.
64  off_t local_start_row;
65  off_t local_start_col;
66  // Which node the matrix data is stored.
67  int node_id;
68 protected:
69  size_t get_orig_num_rows() const {
70  return num_rows;
71  }
72  size_t get_orig_num_cols() const {
73  return num_cols;
74  }
75 
76  struct matrix_info {
77  off_t start_row;
78  off_t start_col;
79  size_t num_rows;
80  size_t num_cols;
81  };
82 
83  struct matrix_info get_global_transpose_info() const {
84  matrix_info info;
85  info.start_row = global_start_col;
86  info.start_col = global_start_row;
87  info.num_rows = num_cols;
88  info.num_cols = num_rows;
89  return info;
90  }
91  struct matrix_info get_local_transpose_info() const {
92  matrix_info info;
93  info.start_row = local_start_col;
94  info.start_col = local_start_row;
95  info.num_rows = get_num_cols();
96  info.num_cols = get_num_rows();
97  return info;
98  }
99  void resize_transpose(local_matrix_store &store) const;
100 
101  template<class RES_TYPE, class THIS_TYPE>
102  local_matrix_store::ptr create_transpose(const THIS_TYPE &this_store) const {
103  struct matrix_info t_info = get_global_transpose_info();
104  local_matrix_store *store
105  = new RES_TYPE(this_store.get_data(),
106  t_info.start_row, t_info.start_col, t_info.num_rows,
107  t_info.num_cols, get_type(), get_node_id());
108  resize_transpose(*store);
109  return matrix_store::ptr(store);
110  }
111 
112  template<class RES_TYPE, class THIS_TYPE>
113  local_matrix_store::ptr create_transpose(THIS_TYPE &this_store) {
114  struct matrix_info t_info = get_global_transpose_info();
115  local_matrix_store *store
116  = new RES_TYPE(this_store.get_data(),
117  t_info.start_row, t_info.start_col, t_info.num_rows,
118  t_info.num_cols, get_type(), get_node_id());
119  resize_transpose(*store);
120  return matrix_store::ptr(store);
121  }
122 public:
123  typedef std::shared_ptr<local_matrix_store> ptr;
124  typedef std::shared_ptr<const local_matrix_store> const_ptr;
125 
126  static ptr cast(matrix_store::ptr store) {
127  // TODO do I need to check the store object.
128  return std::static_pointer_cast<local_matrix_store>(store);
129  }
130 
131  static const_ptr cast(matrix_store::const_ptr store) {
132  // TODO do I need to check the store object.
133  return std::static_pointer_cast<const local_matrix_store>(store);
134  }
135 
136  local_matrix_store(off_t global_start_row, off_t global_start_col,
137  size_t nrow, size_t ncol, const scalar_type &type,
138  int node_id): matrix_store(nrow, ncol, true, type) {
139  this->global_start_row = global_start_row;
140  this->global_start_col = global_start_col;
141  this->num_rows = nrow;
142  this->num_cols = ncol;
143  this->local_start_row = 0;
144  this->local_start_col = 0;
145  this->node_id = node_id;
146  }
147 
148  /*
149  * Test if the matrix store exposes its entire data.
150  */
151  bool is_whole() const {
152  return local_start_row == 0 && local_start_col == 0
153  && num_rows == get_num_rows() && num_cols == get_num_cols();
154  }
155 
156  int get_node_id() const {
157  return node_id;
158  }
159 
160  off_t get_local_start_row() const {
161  return local_start_row;
162  }
163  off_t get_local_start_col() const {
164  return local_start_col;
165  }
166 
167  off_t get_global_start_row() const {
168  return global_start_row + get_local_start_row();
169  }
170  off_t get_global_start_col() const {
171  return global_start_col + get_local_start_col();
172  }
173 
174  virtual std::string get_name() const {
175  return (boost::format("local_mat(%1%,%2%)") % get_num_rows()
176  % get_num_cols()).str();
177  }
178  virtual std::unordered_map<size_t, size_t> get_underlying_mats() const {
179  return std::unordered_map<size_t, size_t>();
180  }
181 
182  virtual bool resize(off_t local_start_row, off_t local_start_col,
183  size_t local_num_rows, size_t local_num_cols);
184  virtual void reset_size() {
185  local_start_row = 0;
186  local_start_col = 0;
187  matrix_store::resize(num_rows, num_cols);
188  }
189  virtual local_matrix_store::ptr conv2(matrix_layout_t layout) const;
190 
191  virtual bool read_only() const = 0;
192  virtual const char *get_raw_arr() const = 0;
193  virtual char *get_raw_arr() = 0;
194  virtual const char *get(size_t row, size_t col) const = 0;
195  virtual char *get(size_t row, size_t col) = 0;
196 
197  virtual bool copy_from(const local_matrix_store &store) = 0;
198 
199  virtual matrix_store::const_ptr transpose() const = 0;
200  virtual matrix_store::ptr transpose() = 0;
201 
203 
204  virtual std::pair<size_t, size_t> get_portion_size() const {
205  assert(0);
206  return std::pair<size_t, size_t>(0, 0);
207  }
208  virtual async_cres_t get_portion_async(
209  size_t start_row, size_t start_col, size_t num_rows,
210  size_t num_cols, std::shared_ptr<portion_compute> compute) const {
211  assert(0);
212  return async_cres_t();
213  }
214  virtual async_res_t get_portion_async(
215  size_t start_row, size_t start_col, size_t num_rows,
216  size_t num_cols, std::shared_ptr<portion_compute> compute) {
217  assert(0);
218  return async_res_t();
219  }
220  virtual void write_portion_async(
221  std::shared_ptr<const local_matrix_store> portion,
222  off_t start_row, off_t start_col) {
223  assert(0);
224  }
225 
226  template<class Type>
227  Type get(size_t row, size_t col) const {
228  return *(const Type *) get(row, col);
229  }
230 
231  template<class Type>
232  void set(size_t row, size_t col, Type val) {
233  *(Type *) get(row, col) = val;
234  }
235 };
236 
237 class local_col_matrix_store: public local_matrix_store
238 {
239  // This is to hold the pointer to the original data so it won't be free'd.
240  raw_data_array orig_data_ref;
241 
242 protected:
243  void set_orig_data(const raw_data_array &data_ref) {
244  this->orig_data_ref = data_ref;
245  }
246 public:
247  typedef std::shared_ptr<local_col_matrix_store> ptr;
248  typedef std::shared_ptr<const local_col_matrix_store> const_ptr;
249 
250  static ptr cast(local_matrix_store::ptr store) {
251  if (store->store_layout() != matrix_layout_t::L_COL) {
252  BOOST_LOG_TRIVIAL(error) << "the local matrix store isn't col major";
253  return ptr();
254  }
255  return std::static_pointer_cast<local_col_matrix_store>(store);
256  }
257  static const_ptr cast(local_matrix_store::const_ptr store) {
258  if (store->store_layout() != matrix_layout_t::L_COL) {
259  BOOST_LOG_TRIVIAL(error) << "the local matrix store isn't col major";
260  return const_ptr();
261  }
262  return std::static_pointer_cast<const local_col_matrix_store>(store);
263  }
264 
265  local_col_matrix_store(off_t global_start_row, off_t global_start_col,
266  size_t nrow, size_t ncol, const scalar_type &type,
267  int node_id): local_matrix_store(global_start_row, global_start_col,
268  nrow, ncol, type, node_id) {
269  }
270  local_col_matrix_store(const raw_data_array &data_ref, off_t global_start_row,
271  off_t global_start_col, size_t nrow, size_t ncol,
272  const scalar_type &type, int node_id): local_matrix_store(
273  global_start_row, global_start_col, nrow, ncol, type, node_id) {
274  this->orig_data_ref = data_ref;
275  }
276 
277  bool hold_orig_data() const {
278  return orig_data_ref.get_raw_data() != NULL;
279  }
280 
281  // Get the offset of the entry in the original local matrix store.
282  off_t get_orig_offset(off_t row, off_t col) const {
283  return (col + get_local_start_col()) * get_orig_num_rows()
284  + row + get_local_start_row();
285  }
286 
287  virtual void reset_data();
288  virtual void set_data(const set_operate &op);
289  virtual bool copy_from(const local_matrix_store &store);
290 
291  virtual const char *get_col(size_t col) const = 0;
292  virtual char *get_col(size_t col) = 0;
293 
294  virtual const char *get(size_t row, size_t col) const {
295  return get_col(col) + row * get_entry_size();
296  }
297 
298  virtual char *get(size_t row, size_t col) {
299  return get_col(col) + row * get_entry_size();
300  }
301 
302  virtual matrix_layout_t store_layout() const {
303  return matrix_layout_t::L_COL;
304  }
305 
306  virtual local_matrix_store::const_ptr get_portion(
307  size_t local_start_row, size_t local_start_col, size_t num_rows,
308  size_t num_cols) const;
309  virtual local_matrix_store::ptr get_portion(
310  size_t local_start_row, size_t local_start_col, size_t num_rows,
311  size_t num_cols);
312 };
313 
314 class local_row_matrix_store: public local_matrix_store
315 {
316  // This is to hold the pointer to the original data so it won't be free'd.
317  raw_data_array orig_data_ref;
318 
319 protected:
320  void set_orig_data(const raw_data_array &data_ref) {
321  this->orig_data_ref = data_ref;
322  }
323 public:
324  typedef std::shared_ptr<local_row_matrix_store> ptr;
325  typedef std::shared_ptr<const local_row_matrix_store> const_ptr;
326 
327  static ptr cast(local_matrix_store::ptr store) {
328  if (store->store_layout() != matrix_layout_t::L_ROW) {
329  BOOST_LOG_TRIVIAL(error) << "the local matrix store isn't row major";
330  return ptr();
331  }
332  return std::static_pointer_cast<local_row_matrix_store>(store);
333  }
334  static const_ptr cast(local_matrix_store::const_ptr store) {
335  if (store->store_layout() != matrix_layout_t::L_ROW) {
336  BOOST_LOG_TRIVIAL(error) << "the local matrix store isn't row major";
337  return const_ptr();
338  }
339  return std::static_pointer_cast<const local_row_matrix_store>(store);
340  }
341 
342  local_row_matrix_store(off_t global_start_row, off_t global_start_col,
343  size_t nrow, size_t ncol, const scalar_type &type,
344  int node_id): local_matrix_store(global_start_row, global_start_col,
345  nrow, ncol, type, node_id) {
346  }
347  local_row_matrix_store(const raw_data_array &data_ref, off_t global_start_row,
348  off_t global_start_col, size_t nrow, size_t ncol,
349  const scalar_type &type, int node_id): local_matrix_store(
350  global_start_row, global_start_col, nrow, ncol, type, node_id) {
351  this->orig_data_ref = data_ref;
352  }
353 
354  bool hold_orig_data() const {
355  return orig_data_ref.get_raw_data() != NULL;
356  }
357 
358  // Get the offset of the entry in the original local matrix store.
359  off_t get_orig_offset(off_t row, off_t col) const {
360  return (row + get_local_start_row()) * get_orig_num_cols()
361  + col + get_local_start_col();
362  }
363 
364  virtual void reset_data();
365  virtual void set_data(const set_operate &op);
366  virtual bool copy_from(const local_matrix_store &store);
367 
368  virtual const char *get_row(size_t row) const = 0;
369  virtual char *get_row(size_t row) = 0;
370  virtual const char *get_rows(size_t row_start, size_t row_end) const = 0;
371  virtual char *get_rows(size_t row_start, size_t row_end) = 0;
372 
373  virtual matrix_layout_t store_layout() const {
374  return matrix_layout_t::L_ROW;
375  }
376 
377  virtual const char *get(size_t row, size_t col) const {
378  return get_row(row) + col * get_entry_size();
379  }
380  virtual char *get(size_t row, size_t col) {
381  return get_row(row) + col * get_entry_size();
382  }
383 
384  virtual local_matrix_store::const_ptr get_portion(
385  size_t local_start_row, size_t local_start_col, size_t num_rows,
386  size_t num_cols) const;
387  virtual local_matrix_store::ptr get_portion(
388  size_t local_start_row, size_t local_start_col, size_t num_rows,
389  size_t num_cols);
390 };
391 
392 /*
393  * A matrix owns data to store portion of data in a column-major matrix.
394  */
395 class local_buf_col_matrix_store: public local_col_matrix_store
396 {
397  raw_data_array data;
398 public:
399  local_buf_col_matrix_store(off_t global_start_row, off_t global_start_col,
400  size_t nrow, size_t ncol, const scalar_type &type,
401  int node_id): local_col_matrix_store(global_start_row, global_start_col,
402  nrow, ncol, type, node_id) {
403  if (nrow * ncol > 0) {
404  data = raw_data_array(nrow * ncol * type.get_size());
405  set_orig_data(data);
406  }
407  }
408 
409  local_buf_col_matrix_store(const raw_data_array &data,
410  off_t global_start_row, off_t global_start_col, size_t nrow,
411  size_t ncol, const scalar_type &type,
412  int node_id): local_col_matrix_store(data, global_start_row,
413  global_start_col, nrow, ncol, type, node_id) {
414  this->data = data;
415  }
416 
417  const raw_data_array &get_data() const {
418  return data;
419  }
420 
421  virtual bool read_only() const {
422  return false;
423  }
424 
425  virtual const char *get_raw_arr() const {
426  if (get_local_start_row() > 0 || get_num_rows() < get_orig_num_rows())
427  return NULL;
428  else
429  return data.get_raw() + get_orig_offset(0, 0) * get_entry_size();
430  }
431 
432  virtual char *get_raw_arr() {
433  if (get_local_start_row() > 0 || get_num_rows() < get_orig_num_rows())
434  return NULL;
435  else
436  return data.get_raw() + get_orig_offset(0, 0) * get_entry_size();
437  }
438 
439  virtual const char *get_col(size_t col) const {
440  return data.get_raw() + get_orig_offset(0, col) * get_entry_size();
441  }
442  virtual char *get_col(size_t col) {
443  return data.get_raw() + get_orig_offset(0, col) * get_entry_size();
444  }
445 
446  virtual matrix_store::const_ptr transpose() const;
447  virtual matrix_store::ptr transpose();
448 };
449 
450 /*
451  * A matrix owns data to store portion of data in a row-major matrix.
452  */
453 class local_buf_row_matrix_store: public local_row_matrix_store
454 {
455  raw_data_array data;
456 public:
457  local_buf_row_matrix_store(off_t global_start_row, off_t global_start_col,
458  size_t nrow, size_t ncol, const scalar_type &type,
459  int node_id): local_row_matrix_store(global_start_row, global_start_col,
460  nrow, ncol, type, node_id) {
461  if (nrow * ncol > 0) {
462  data = raw_data_array(nrow * ncol * type.get_size());
463  set_orig_data(data);
464  }
465  }
466 
467  local_buf_row_matrix_store(const raw_data_array &data, off_t global_start_row,
468  off_t global_start_col, size_t nrow, size_t ncol,
469  const scalar_type &type, int node_id): local_row_matrix_store(data,
470  global_start_row, global_start_col, nrow, ncol, type, node_id) {
471  this->data = data;
472  }
473 
474  const raw_data_array &get_data() const {
475  return data;
476  }
477 
478  virtual bool read_only() const {
479  return false;
480  }
481 
482  virtual const char *get_raw_arr() const {
483  if (get_local_start_col() > 0 || get_num_cols() < get_orig_num_cols())
484  return NULL;
485  else
486  return data.get_raw() + get_orig_offset(0, 0) * get_entry_size();
487  }
488 
489  virtual char *get_raw_arr() {
490  if (get_local_start_col() > 0 || get_num_cols() < get_orig_num_cols())
491  return NULL;
492  else
493  return data.get_raw() + get_orig_offset(0, 0) * get_entry_size();
494  }
495 
496  virtual const char *get_row(size_t row) const {
497  return data.get_raw() + get_orig_offset(row, 0) * get_entry_size();
498  }
499 
500  virtual char *get_row(size_t row) {
501  return data.get_raw() + get_orig_offset(row, 0) * get_entry_size();
502  }
503 
504  virtual const char *get_rows(size_t row_start, size_t row_end) const {
505  if (row_end > get_num_rows() || get_local_start_col() > 0)
506  return NULL;
507  else
508  return get_row(row_start);
509  }
510  virtual char *get_rows(size_t row_start, size_t row_end) {
511  if (row_end > get_num_rows() || get_local_start_col() > 0)
512  return NULL;
513  else
514  return get_row(row_start);
515  }
516 
517  virtual matrix_store::const_ptr transpose() const;
518  virtual matrix_store::ptr transpose();
519 };
520 
521 /*
522  * A matrix that references portion of data in another column-major matrix.
523  * The referenced data is stored contiguously.
524  */
525 class local_ref_contig_col_matrix_store: public local_col_matrix_store
526 {
527  char *data;
528 public:
529  local_ref_contig_col_matrix_store(char *data, off_t global_start_row,
530  off_t global_start_col, size_t nrow, size_t ncol,
531  const scalar_type &type, int node_id): local_col_matrix_store(
532  global_start_row, global_start_col, nrow, ncol, type, node_id) {
533  this->data = data;
534  }
535 
536  local_ref_contig_col_matrix_store(const raw_data_array &data_ref, char *data,
537  off_t global_start_row, off_t global_start_col, size_t nrow, size_t ncol,
538  const scalar_type &type, int node_id): local_col_matrix_store(data_ref,
539  global_start_row, global_start_col, nrow, ncol, type, node_id) {
540  this->data = data;
541  }
542 
543  char *get_data() {
544  return data;
545  }
546 
547  const char *get_data() const {
548  return data;
549  }
550 
551  virtual bool read_only() const {
552  return false;
553  }
554 
555  virtual const char *get_raw_arr() const {
556  if (get_local_start_row() > 0 || get_num_rows() < get_orig_num_rows())
557  return NULL;
558  else
559  return data + get_orig_offset(0, 0) * get_entry_size();
560  }
561 
562  virtual char *get_raw_arr() {
563  if (get_local_start_row() > 0 || get_num_rows() < get_orig_num_rows())
564  return NULL;
565  else
566  return data + get_orig_offset(0, 0) * get_entry_size();
567  }
568 
569  virtual const char *get_col(size_t col) const {
570  return data + get_orig_offset(0, col) * get_entry_size();
571  }
572  virtual char *get_col(size_t col) {
573  return data + get_orig_offset(0, col) * get_entry_size();
574  }
575 
576  virtual matrix_store::const_ptr transpose() const;
577  virtual matrix_store::ptr transpose();
578 };
579 
580 /*
581  * A matrix that references portion of data in another row-major matrix.
582  * The referenced data is stored contiguously.
583  */
584 class local_ref_contig_row_matrix_store: public local_row_matrix_store
585 {
586  char *data;
587 public:
588  local_ref_contig_row_matrix_store(char *data, off_t global_start_row,
589  off_t global_start_col, size_t nrow, size_t ncol,
590  const scalar_type &type, int node_id): local_row_matrix_store(
591  global_start_row, global_start_col, nrow, ncol, type, node_id) {
592  this->data = data;
593  }
594 
595  local_ref_contig_row_matrix_store(const raw_data_array &data_ref, char *data,
596  off_t global_start_row, off_t global_start_col, size_t nrow, size_t ncol,
597  const scalar_type &type, int node_id): local_row_matrix_store(data_ref,
598  global_start_row, global_start_col, nrow, ncol, type, node_id) {
599  this->data = data;
600  }
601 
602  char *get_data() {
603  return data;
604  }
605 
606  const char *get_data() const {
607  return data;
608  }
609 
610  virtual bool read_only() const {
611  return false;
612  }
613 
614  virtual const char *get_raw_arr() const {
615  if (get_local_start_col() > 0 || get_num_cols() < get_orig_num_cols())
616  return NULL;
617  else
618  return data + get_orig_offset(0, 0) * get_entry_size();
619  }
620 
621  virtual char *get_raw_arr() {
622  if (get_local_start_col() > 0 || get_num_cols() < get_orig_num_cols())
623  return NULL;
624  else
625  return data + get_orig_offset(0, 0) * get_entry_size();
626  }
627 
628  virtual const char *get_rows(size_t row_start, size_t row_end) const {
629  if (row_end > get_num_rows() || get_local_start_col() > 0)
630  return NULL;
631  else
632  return get_row(row_start);
633  }
634  virtual char *get_rows(size_t row_start, size_t row_end) {
635  if (row_end > get_num_rows() || get_local_start_col() > 0)
636  return NULL;
637  else
638  return get_row(row_start);
639  }
640 
641  virtual const char *get_row(size_t row) const {
642  return data + get_orig_offset(row, 0) * get_entry_size();
643  }
644 
645  virtual char *get_row(size_t row) {
646  return data + get_orig_offset(row, 0) * get_entry_size();
647  }
648 
649  virtual matrix_store::const_ptr transpose() const;
650  virtual matrix_store::ptr transpose();
651 };
652 
653 /*
654  * A matrix that references portion of data in another column-major matrix.
655  * The referenced data isn't guaranteed to be stored contiguously.
656  */
657 class local_ref_col_matrix_store: public local_col_matrix_store
658 {
659  std::vector<char *> cols;
660 public:
661  local_ref_col_matrix_store(const std::vector<char *> &cols,
662  off_t global_start_row, off_t global_start_col,
663  size_t nrow, size_t ncol, const scalar_type &type,
664  int node_id): local_col_matrix_store(global_start_row,
665  global_start_col, nrow, cols.size(), type, node_id) {
666  this->cols = cols;
667  assert(cols.size() == ncol);
668  }
669 
670  local_ref_col_matrix_store(const raw_data_array &data_ref,
671  const std::vector<char *> &cols, off_t global_start_row,
672  off_t global_start_col, size_t nrow, size_t ncol,
673  const scalar_type &type, int node_id): local_col_matrix_store(
674  data_ref, global_start_row, global_start_col, nrow, cols.size(),
675  type, node_id) {
676  this->cols = cols;
677  assert(cols.size() == ncol);
678  }
679 
680  const std::vector<char *> &get_data() {
681  return cols;
682  }
683 
684  std::vector<const char *> get_data() const {
685  return std::vector<const char *>(cols.begin(), cols.end());
686  }
687 
688  virtual bool read_only() const {
689  return false;
690  }
691 
692  virtual const char *get_raw_arr() const {
693  return NULL;
694  }
695 
696  virtual char *get_raw_arr() {
697  return NULL;
698  }
699 
700  virtual const char *get_col(size_t col) const {
701  return cols[col + get_local_start_col()]
702  + get_local_start_row() * get_entry_size();
703  }
704  virtual char *get_col(size_t col) {
705  return cols[col + get_local_start_col()]
706  + get_local_start_row() * get_entry_size();
707  }
708 
709  virtual matrix_store::const_ptr transpose() const;
710  virtual matrix_store::ptr transpose();
711 };
712 
713 /*
714  * A matrix that references portion of data in another row-major matrix.
715  * The referenced data isn't guaranteed to be stored contiguously.
716  */
717 class local_ref_row_matrix_store: public local_row_matrix_store
718 {
719  std::vector<char *> rows;
720 public:
721  local_ref_row_matrix_store(const std::vector<char *> &rows,
722  off_t global_start_row, off_t global_start_col,
723  size_t nrow, size_t ncol, const scalar_type &type,
724  int node_id): local_row_matrix_store(global_start_row,
725  global_start_col, rows.size(), ncol, type, node_id) {
726  this->rows = rows;
727  assert(rows.size() == nrow);
728  }
729 
730  local_ref_row_matrix_store(const raw_data_array &data_ref,
731  const std::vector<char *> &rows, off_t global_start_row,
732  off_t global_start_col, size_t nrow, size_t ncol,
733  const scalar_type &type, int node_id): local_row_matrix_store(
734  data_ref, global_start_row, global_start_col, rows.size(), ncol,
735  type, node_id) {
736  this->rows = rows;
737  assert(rows.size() == nrow);
738  }
739 
740  const std::vector<char *> &get_data() {
741  return rows;
742  }
743 
744  std::vector<const char *> get_data() const {
745  return std::vector<const char *>(rows.begin(), rows.end());
746  }
747 
748  virtual bool read_only() const {
749  return false;
750  }
751 
752  virtual const char *get_raw_arr() const {
753  return NULL;
754  }
755 
756  virtual char *get_raw_arr() {
757  return NULL;
758  }
759 
760  virtual const char *get_rows(size_t row_start, size_t row_end) const {
761  return NULL;
762  }
763  virtual char *get_rows(size_t row_start, size_t row_end) {
764  return NULL;
765  }
766 
767  virtual const char *get_row(size_t row) const {
768  return rows[row + get_local_start_row()]
769  + get_local_start_col() * get_entry_size();
770  }
771 
772  virtual char *get_row(size_t row) {
773  return rows[row + get_local_start_row()]
774  + get_local_start_col() * get_entry_size();
775  }
776 
777  virtual matrix_store::const_ptr transpose() const;
778  virtual matrix_store::ptr transpose();
779 };
780 
781 /*
782  * A matrix that references portion of const data in another column-major matrix.
783  * The referenced data is stored contiguously.
784  */
785 class local_cref_contig_col_matrix_store: public local_col_matrix_store
786 {
787  const char *data;
788 public:
789  local_cref_contig_col_matrix_store(const char *data, off_t global_start_row,
790  off_t global_start_col, size_t nrow, size_t ncol, const scalar_type &type,
791  int node_id): local_col_matrix_store(global_start_row,
792  global_start_col, nrow, ncol, type, node_id) {
793  this->data = data;
794  }
795 
796  local_cref_contig_col_matrix_store(const raw_data_array &data_ref, const char *data,
797  off_t global_start_row, off_t global_start_col, size_t nrow, size_t ncol,
798  const scalar_type &type, int node_id): local_col_matrix_store(data_ref,
799  global_start_row, global_start_col, nrow, ncol, type, node_id) {
800  this->data = data;
801  }
802 
803  const char *get_data() const {
804  return data;
805  }
806 
807  virtual bool read_only() const {
808  return true;
809  }
810 
811  virtual const char *get_raw_arr() const {
812  if (get_local_start_row() > 0 || get_num_rows() < get_orig_num_rows())
813  return NULL;
814  else
815  return data + get_orig_offset(0, 0) * get_entry_size();
816  }
817  virtual const char *get_col(size_t col) const {
818  return data + get_orig_offset(0, col) * get_entry_size();
819  }
820 
821  virtual char *get_raw_arr() {
822  assert(0);
823  return NULL;
824  }
825  virtual char *get_col(size_t col) {
826  assert(0);
827  return NULL;
828  }
829 
830  virtual matrix_store::const_ptr transpose() const;
831  virtual matrix_store::ptr transpose();
832 };
833 
834 /*
835  * A matrix that references portion of const data in another row-major matrix.
836  * The referenced data is stored contiguously.
837  */
838 class local_cref_contig_row_matrix_store: public local_row_matrix_store
839 {
840  const char *data;
841 public:
842  local_cref_contig_row_matrix_store(const char *data, off_t global_start_row,
843  off_t global_start_col, size_t nrow, size_t ncol, const scalar_type &type,
844  int node_id): local_row_matrix_store(global_start_row,
845  global_start_col, nrow, ncol, type, node_id) {
846  this->data = data;
847  }
848 
849  local_cref_contig_row_matrix_store(const raw_data_array &data_ref, const char *data,
850  off_t global_start_row, off_t global_start_col, size_t nrow, size_t ncol,
851  const scalar_type &type, int node_id): local_row_matrix_store(data_ref,
852  global_start_row, global_start_col, nrow, ncol, type, node_id) {
853  this->data = data;
854  }
855 
856  const char *get_data() const {
857  return data;
858  }
859 
860  virtual bool read_only() const {
861  return true;
862  }
863 
864  virtual const char *get_raw_arr() const {
865  if (get_local_start_col() > 0 || get_num_cols() < get_orig_num_cols())
866  return NULL;
867  else
868  return data + get_orig_offset(0, 0) * get_entry_size();
869  }
870  virtual const char *get_row(size_t row) const {
871  return data + get_orig_offset(row, 0) * get_entry_size();
872  }
873  virtual const char *get_rows(size_t row_start, size_t row_end) const {
874  if (row_end > get_num_rows() || get_local_start_col() > 0)
875  return NULL;
876  else
877  return get_row(row_start);
878  }
879 
880  virtual char *get_raw_arr() {
881  assert(0);
882  return NULL;
883  }
884  virtual char *get_row(size_t row) {
885  assert(0);
886  return NULL;
887  }
888  virtual char *get_rows(size_t row_start, size_t row_end) {
889  assert(0);
890  return NULL;
891  }
892 
893  virtual matrix_store::const_ptr transpose() const;
894  virtual matrix_store::ptr transpose();
895 };
896 
897 /*
898  * A matrix that references portion of data in another column-major matrix.
899  * The referenced data isn't guaranteed to be stored contiguously.
900  */
901 class local_cref_col_matrix_store: public local_col_matrix_store
902 {
903  std::vector<const char *> cols;
904 public:
905  local_cref_col_matrix_store(const std::vector<const char *> &cols,
906  off_t global_start_row, off_t global_start_col,
907  size_t nrow, size_t ncol, const scalar_type &type,
908  int node_id): local_col_matrix_store(global_start_row,
909  global_start_col, nrow, cols.size(), type, node_id) {
910  this->cols = cols;
911  assert(cols.size() == ncol);
912  }
913 
914  local_cref_col_matrix_store(const raw_data_array &data_ref,
915  const std::vector<const char *> &cols, off_t global_start_row,
916  off_t global_start_col, size_t nrow, size_t ncol, const scalar_type &type,
917  int node_id): local_col_matrix_store(data_ref, global_start_row,
918  global_start_col, nrow, cols.size(), type, node_id) {
919  this->cols = cols;
920  assert(cols.size() == ncol);
921  }
922 
923  const std::vector<const char *> get_data() const {
924  return cols;
925  }
926 
927  virtual bool read_only() const {
928  return true;
929  }
930 
931  virtual const char *get_col(size_t col) const {
932  return cols[col + get_local_start_col()]
933  + get_local_start_row() * get_entry_size();
934  }
935 
936  virtual const char *get_raw_arr() const {
937  return NULL;
938  }
939  virtual char *get_raw_arr() {
940  assert(0);
941  return NULL;
942  }
943  virtual char *get_col(size_t col) {
944  assert(0);
945  return NULL;
946  }
947 
948  virtual matrix_store::const_ptr transpose() const;
949  virtual matrix_store::ptr transpose();
950 };
951 
952 /*
953  * A matrix that references portion of data in another row-major matrix.
954  * The referenced data isn't guaranteed to be stored contiguously.
955  */
956 class local_cref_row_matrix_store: public local_row_matrix_store
957 {
958  std::vector<const char *> rows;
959 public:
960  local_cref_row_matrix_store(const std::vector<const char *> &rows,
961  off_t global_start_row, off_t global_start_col,
962  size_t nrow, size_t ncol, const scalar_type &type,
963  int node_id): local_row_matrix_store(global_start_row,
964  global_start_col, rows.size(), ncol, type, node_id) {
965  this->rows = rows;
966  assert(rows.size() == nrow);
967  }
968 
969  local_cref_row_matrix_store(const raw_data_array &data_ref,
970  const std::vector<const char *> &rows, off_t global_start_row,
971  off_t global_start_col, size_t nrow, size_t ncol, const scalar_type &type,
972  int node_id): local_row_matrix_store(data_ref, global_start_row,
973  global_start_col, rows.size(), ncol, type, node_id) {
974  this->rows = rows;
975  assert(rows.size() == nrow);
976  }
977 
978  const std::vector<const char *> get_data() const {
979  return rows;
980  }
981 
982  virtual bool read_only() const {
983  return true;
984  }
985 
986  virtual const char *get_row(size_t row) const {
987  return rows[row + get_local_start_row()]
988  + get_local_start_col() * get_entry_size();
989  }
990  virtual const char *get_rows(size_t row_start, size_t row_end) const {
991  return NULL;
992  }
993 
994  virtual const char *get_raw_arr() const {
995  return NULL;
996  }
997  virtual char *get_raw_arr() {
998  assert(0);
999  return NULL;
1000  }
1001  virtual char *get_row(size_t row) {
1002  assert(0);
1003  return NULL;
1004  }
1005  virtual char *get_rows(size_t row_start, size_t row_end) {
1006  assert(0);
1007  return NULL;
1008  }
1009 
1010  virtual matrix_store::const_ptr transpose() const;
1011  virtual matrix_store::ptr transpose();
1012 };
1013 
1014 class lvirtual_col_matrix_store: public local_col_matrix_store
1015 {
1016 public:
1017  lvirtual_col_matrix_store(off_t global_start_row, off_t global_start_col,
1018  size_t nrow, size_t ncol, const scalar_type &type,
1019  int node_id): local_col_matrix_store(global_start_row,
1020  global_start_col, nrow, ncol, type, node_id) {
1021  }
1022 
1023  virtual bool read_only() const {
1024  return true;
1025  }
1026 
1027  using local_col_matrix_store::get_raw_arr;
1028  virtual char *get_raw_arr() {
1029  return NULL;
1030  }
1031 
1032  virtual char *get(size_t row, size_t col) {
1033  return NULL;
1034  }
1035 
1036  virtual bool copy_from(const local_matrix_store &store) {
1037  return false;
1038  }
1039 
1040  virtual void reset_data() {
1041  }
1042 
1043  virtual void set_data(const set_operate &op) {
1044  }
1045 
1046  using local_col_matrix_store::transpose;
1047  virtual matrix_store::ptr transpose() {
1048  return matrix_store::ptr();
1049  }
1050 
1051  using local_col_matrix_store::get_col;
1052  virtual char *get_col(size_t col) {
1053  return NULL;
1054  }
1055 
1056  virtual local_matrix_store::const_ptr get_portion(
1057  size_t local_start_row, size_t local_start_col, size_t num_rows,
1058  size_t num_cols) const {
1059  assert(0);
1060  return local_matrix_store::const_ptr();
1061  }
1062  virtual local_matrix_store::ptr get_portion(
1063  size_t local_start_row, size_t local_start_col, size_t num_rows,
1064  size_t num_cols) {
1065  assert(0);
1066  return local_matrix_store::ptr();
1067  }
1068 };
1069 
1070 class lvirtual_row_matrix_store: public local_row_matrix_store
1071 {
1072 public:
1073  lvirtual_row_matrix_store(off_t global_start_row, off_t global_start_col,
1074  size_t nrow, size_t ncol, const scalar_type &type,
1075  int node_id): local_row_matrix_store(global_start_row,
1076  global_start_col, nrow, ncol, type, node_id) {
1077  }
1078 
1079  virtual bool read_only() const {
1080  return true;
1081  }
1082 
1083  using local_row_matrix_store::get_raw_arr;
1084  virtual char *get_raw_arr() {
1085  return NULL;
1086  }
1087 
1088  virtual char *get(size_t row, size_t col) {
1089  return NULL;
1090  }
1091 
1092  virtual bool copy_from(const local_matrix_store &store) {
1093  return false;
1094  }
1095 
1096  virtual void reset_data() {
1097  }
1098 
1099  virtual void set_data(const set_operate &op) {
1100  }
1101 
1102  using local_row_matrix_store::transpose;
1103  virtual matrix_store::ptr transpose() {
1104  return matrix_store::ptr();
1105  }
1106 
1107  using local_row_matrix_store::get_row;
1108  virtual char *get_row(size_t row) {
1109  return NULL;
1110  }
1111  virtual char *get_rows(size_t row_start, size_t row_end) {
1112  return NULL;
1113  }
1114 
1115  virtual local_matrix_store::const_ptr get_portion(
1116  size_t local_start_row, size_t local_start_col, size_t num_rows,
1117  size_t num_cols) const {
1118  assert(0);
1119  return local_matrix_store::const_ptr();
1120  }
1121  virtual local_matrix_store::ptr get_portion(
1122  size_t local_start_row, size_t local_start_col, size_t num_rows,
1123  size_t num_cols) {
1124  assert(0);
1125  return local_matrix_store::ptr();
1126  }
1127 };
1128 
1129 /*
1130  * These are the general operations on the local matrix store.
1131  */
1132 void aggregate(const local_matrix_store &store, const bulk_operate &op,
1133  int margin, local_vec_store &res);
1134 void mapply2(const local_matrix_store &m1, const local_matrix_store &m2,
1135  const bulk_operate &op, local_matrix_store &res);
1136 void sapply(const local_matrix_store &store, const bulk_uoperate &op,
1137  local_matrix_store &res);
1138 void apply(int margin, const arr_apply_operate &op,
1139  const local_matrix_store &in_mat, local_matrix_store &out_mat);
1140 void inner_prod(const local_matrix_store &m1, const local_matrix_store &m2,
1141  const bulk_operate &left_op, const bulk_operate &right_op,
1142  local_matrix_store &res);
1143 void mapply_cols(const local_matrix_store &m1, const local_vec_store &vals,
1144  const bulk_operate &op, local_matrix_store &m2);
1145 void mapply_rows(const local_matrix_store &m1, const local_vec_store &vals,
1146  const bulk_operate &op, local_matrix_store &m2);
1147 
1148 }
1149 
1150 }
1151 
1152 #endif