FlashGraph-ng
A new frontier in large-scale graph analysis and data mining
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
block_dense_matrix.h
1 #ifndef __BLOCK_DENSE_MATRIX_H__
2 #define __BLOCK_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 "dense_matrix.h"
24 #include "generic_type.h"
25 #include "vector.h"
26 #include "sparse_matrix.h"
27 
28 #include "eigensolver.h"
29 
30 namespace fm
31 {
32 
33 namespace eigen
34 {
35 
36 extern size_t num_col_writes;
37 extern size_t num_col_writes_concept;
38 extern size_t num_col_reads_concept;
39 extern size_t num_multiply_concept;
40 extern std::deque<dense_matrix::ptr> cached_mats;
41 
42 void set_num_cached_mats(size_t num);
43 
44 class block_multi_vector
45 {
46  size_t MAX_MUL_BLOCKS;
47 
48  // Indicate whether this MV stores the subspace.
49  bool is_subspace;
50  bool in_mem;
51  size_t block_size;
52  size_t num_rows;
53  size_t num_cols;
54  const fm::scalar_type &type;
55 protected:
56  std::vector<fm::dense_matrix::ptr> mats;
57 
58  block_multi_vector(size_t nrow, size_t ncol, size_t block_size,
59  const fm::scalar_type &_type, bool in_mem, bool is_subspace);
60  block_multi_vector(const std::vector<fm::dense_matrix::ptr> &mats,
61  bool in_mem);
62 public:
63  typedef std::shared_ptr<block_multi_vector> ptr;
64 
65  static void sparse_matrix_multiply(const spm_function &multiply,
66  // in_mem indicates where Y is stored.
67  const block_multi_vector &X, block_multi_vector &Y,
68  bool out_mat_in_mem);
69 
70  static ptr create(size_t nrow, size_t ncol, size_t block_size,
71  const fm::scalar_type &type, bool in_mem, bool is_subspace) {
72  assert(ncol % block_size == 0);
73  return ptr(new block_multi_vector(nrow, ncol, block_size,
74  type, in_mem, is_subspace));
75  }
76 
77  bool is_in_mem() const {
78  return in_mem;
79  }
80 
81  void set_multiply_blocks(size_t num) {
82  MAX_MUL_BLOCKS = num;
83  }
84 
85  size_t get_num_rows() const {
86  return num_rows;
87  }
88 
89  size_t get_num_cols() const {
90  return num_cols;
91  }
92 
93  size_t get_num_blocks() const {
94  return num_cols / block_size;
95  }
96 
97  size_t get_entry_size() const {
98  return type.get_size();
99  }
100 
101  size_t get_block_size() const {
102  return block_size;
103  }
104 
105  int get_num_nodes() const {
106  return fm::matrix_conf.get_num_nodes();
107  }
108 
109  const fm::scalar_type &get_type() const {
110  return type;
111  }
112 
113  fm::dense_matrix::ptr get_block(off_t block_idx) const {
114  return mats[block_idx];
115  }
116 
117  virtual void set_block(off_t block_idx, fm::dense_matrix::const_ptr mat) {
118  if (mat) {
119  assert(mat->get_num_cols() == block_size);
120  mats[block_idx] = mat->clone();
121  }
122  else
123  mats[block_idx] = fm::dense_matrix::ptr();
124  }
125 
126  void set_block(const block_multi_vector &mv, const std::vector<int>& index);
127 
128  fm::dense_matrix::const_ptr get_col(off_t col_idx) const;
129 
130  fm::dense_matrix::ptr get_col_mat(const std::vector<off_t> &index) const;
131 
132  block_multi_vector::ptr get_cols(const std::vector<int> &index);
133  /*
134  * The difference between get_cols and get_cols_mirror is that any change
135  * to the multi_vector returned by get_cols() doesn't affect the original
136  * multi_vector, but any changes to the multi_vector returned by
137  * get_cols_mirror() affect the original multi_vector.
138  */
139  block_multi_vector::ptr get_cols_mirror(const std::vector<int> &index);
140 
141  block_multi_vector::ptr clone() const;
142 
143  block_multi_vector::ptr gemm(const block_multi_vector &A,
144  fm::detail::mem_col_matrix_store::const_ptr B,
145  const fm::scalar_variable &alpha,
146  const fm::scalar_variable &beta) const;
147 
148  void assign(const block_multi_vector &vecs);
149 
150  block_multi_vector::ptr add(const block_multi_vector &vecs) const;
151  fm::dense_matrix::ptr MvTransMv(const block_multi_vector &mv) const;
152  std::vector<double> MvDot(const block_multi_vector &mv) const;
153 
154  fm::dense_matrix::ptr conv2matrix() const;
155 
156  template<class Type>
157  void init_rand(Type min, Type max) {
158  size_t num_blocks = get_num_blocks();
159  num_col_writes += this->get_num_cols();
160  for (size_t i = 0; i < num_blocks; i++)
161  set_block(i, fm::dense_matrix::create_randu<Type>(min, max,
162  get_num_rows(), block_size, fm::matrix_layout_t::L_COL,
163  get_num_nodes(), in_mem));
164  }
165 
166  template<class Type>
167  block_multi_vector::ptr multiply_scalar(Type val) const {
168  size_t num_blocks = get_num_blocks();
169  assert(!is_subspace);
170  block_multi_vector::ptr ret_vecs = block_multi_vector::create(
171  get_num_rows(), get_num_cols(), block_size, type, in_mem, false);
172  for (size_t i = 0; i < num_blocks; i++)
173  ret_vecs->set_block(i, get_block(i)->multiply_scalar(val));
174  return ret_vecs;
175  }
176 
177  template<class Type>
178  block_multi_vector::ptr scale_cols(const std::vector<Type> &vec) const {
179  size_t num_blocks = get_num_blocks();
180  assert(!is_subspace);
181  block_multi_vector::ptr ret_vecs = block_multi_vector::create(
182  get_num_rows(), get_num_cols(), block_size, type, in_mem, false);
183  for (size_t i = 0; i < num_blocks; i++) {
184  fm::detail::smp_vec_store::ptr sub_vec
185  = fm::detail::smp_vec_store::create(block_size,
186  fm::get_scalar_type<Type>());
187  for (size_t k = 0; k < block_size; k++)
188  sub_vec->set<Type>(k, vec[i * block_size + k]);
189  fm::vector::ptr sub_vec1 = fm::vector::create(sub_vec);
190  ret_vecs->set_block(i, get_block(i)->scale_cols(sub_vec1));
191  }
192  return ret_vecs;
193  }
194 };
195 
196 }
197 
198 }
199 
200 #endif
Definition: generic_type.h:235
Definition: generic_type.h:138