planc
Parallel Lowrank Approximation with Non-negativity Constraints
ddt.hpp
Go to the documentation of this file.
1 /* Copyright Koby Hayashi 2018 */
2 
3 #ifndef DIMTREE_DDT_HPP_
4 #define DIMTREE_DDT_HPP_
5 
6 #include "common/ncpfactors.hpp"
7 #include "common/tensor.hpp"
8 #include "dimtree/ddttensor.hpp"
9 #include "dimtree/dimtrees.hpp"
10 
12  ktensor *m_local_Y;
13  tensor *m_local_T;
14  tensor *projection_Tensor;
15  tensor *buffer_Tensor;
16  ktensor *projection_Ktensor;
17  double *col_MTTKRP;
18  long int num_threads;
19  long int s;
20  long int ldp;
21  long int rdp;
22 
23  public:
24  DenseDimensionTree(const planc::Tensor &i_input_tensor,
25  const planc::NCPFactors &i_ncp_factors,
26  long int split_mode) {
27  m_local_T = reinterpret_cast<tensor *>(malloc(sizeof *m_local_T));
28  m_local_Y = reinterpret_cast<ktensor *>(malloc(sizeof *m_local_Y));
29  projection_Tensor =
30  reinterpret_cast<tensor *>(malloc(sizeof *projection_Tensor));
31  buffer_Tensor = reinterpret_cast<tensor *>(malloc(sizeof *buffer_Tensor));
32  projection_Ktensor =
33  reinterpret_cast<ktensor *>(malloc(sizeof *projection_Ktensor));
34  m_local_T->data = const_cast<double *>(&i_input_tensor.m_data[0]);
35  m_local_T->nmodes = i_input_tensor.modes();
36  m_local_T->dims_product = i_input_tensor.numel();
37  m_local_Y->factors = reinterpret_cast<double **>(
38  malloc(sizeof(double *) * m_local_T->nmodes));
39  m_local_Y->dims = (long int *)malloc(sizeof(long int) * m_local_T->nmodes);
40  m_local_T->dims = (long int *)malloc(sizeof(long int) * m_local_T->nmodes);
41  m_local_Y->nmodes = i_ncp_factors.modes();
42  m_local_Y->rank = i_ncp_factors.rank();
43  VEC temp_vec = i_ncp_factors.lambda();
44  m_local_Y->lambdas = temp_vec.memptr();
45  m_local_Y->dims_product = arma::prod(i_ncp_factors.dimensions());
46 
47  for (long int i = 0; i < m_local_T->nmodes; i++) {
48  m_local_T->dims[i] = i_input_tensor.dimensions()[i];
49  m_local_Y->dims[i] = i_input_tensor.dimensions()[i];
50  m_local_Y->factors[i] = reinterpret_cast<double *>(
51  malloc(sizeof(double) * i_ncp_factors.rank() * m_local_T->dims[i]));
52  }
53  num_threads = 16;
54  s = split_mode;
55  // Allocate memory for the larger of two partial MTTKRP
57  if (ldp <= rdp) {
58  projection_Tensor->data = reinterpret_cast<double *>(
59  malloc(sizeof(double) * rdp * m_local_Y->rank));
60  buffer_Tensor->data = reinterpret_cast<double *>(
61  malloc(sizeof(double) * m_local_Y->rank * rdp));
62  } else {
63  projection_Tensor->data = reinterpret_cast<double *>(
64  malloc(sizeof(double) * ldp * m_local_Y->rank));
65  buffer_Tensor->data = reinterpret_cast<double *>(
66  malloc(sizeof(double) * m_local_Y->rank * ldp));
67  }
68 
69  projection_Tensor->nmodes = m_local_T->nmodes;
70  buffer_Tensor->nmodes = m_local_T->nmodes;
71 
72  projection_Tensor->dims =
73  (long int *)malloc(sizeof(long int) * m_local_T->nmodes);
74  buffer_Tensor->dims =
75  (long int *)malloc(sizeof(long int) * m_local_T->nmodes);
76  for (long int i = 0; i < m_local_T->nmodes; i++) {
77  projection_Tensor->dims[i] = m_local_T->dims[i];
78  buffer_Tensor->dims[i] = m_local_T->dims[i];
79  }
80 
81  projection_Tensor->dims_product = m_local_T->dims_product;
82  buffer_Tensor->dims_product = m_local_T->dims_product;
83  ktensor_copy_constructor(m_local_Y, projection_Ktensor);
84  for (long int i = 0; i < i_ncp_factors.modes(); i++) {
85  MAT temp = i_ncp_factors.factor(i).t();
86  std::memcpy(m_local_Y->factors[i], temp.memptr(),
87  sizeof(double) * temp.n_rows * temp.n_cols);
88  }
89  // col_MTTKRP = (double*)malloc(sizeof(double) * m_local_Y->rank *
90  // max_mode);
91  }
92 
93  void set_factor(const double *arma_factor_ptr, const long int mode) {
94  // TransposeM(arma_factor_ptr, m_local_Y->factors[mode],
95  // m_local_Y->dims[mode], m_local_Y->rank);
96  std::memcpy(m_local_Y->factors[mode], arma_factor_ptr,
97  sizeof(double) * m_local_Y->dims[mode] * m_local_Y->rank);
98  }
99 
101  for (long int i = 0; i < m_local_T->nmodes; i++) {
102  free(m_local_Y->factors[i]);
103  }
104  free(m_local_Y->factors);
105  free(m_local_Y->dims);
106  free(m_local_T->dims);
107  destruct_Tensor(projection_Tensor);
108  destruct_Tensor(buffer_Tensor);
109  destruct_Ktensor(projection_Ktensor, 0);
110  free(m_local_Y);
111  free(m_local_T);
112  free(projection_Ktensor);
113  free(buffer_Tensor);
114  free(projection_Tensor);
115  // free(col_MTTKRP);
116  }
117 
118  void set_left_right_product(const long int i_split_mode) {
119  ldp = 1;
120  rdp = 1;
121  for (long int i = 0; i < m_local_T->nmodes; i++) {
122  if (i <= i_split_mode) {
123  ldp *= m_local_T->dims[i];
124  } else {
125  rdp *= m_local_T->dims[i];
126  }
127  }
128  }
129 
130  /*
131  * Return the col major ordered mttkrp
132  */
133 
134  void in_order_reuse_MTTKRP(long int n, double *out, bool colmajor,
135  double &multittv_time, double &mttkrp_time) {
136  // ktensor *Y = m_local_Y;
137  direction D;
138  multittv_time = 0;
139  mttkrp_time = 0;
140 
141  if (n == 0) {
145  D = ::direction::right; // Contracting over the right modes
147  m_local_Y, projection_Ktensor, s + 1,
148  opposite_direction(D)); // s+1 because s is included in the left
149 
150  if (projection_Ktensor->nmodes == 1) { // factor matrix output PM
158  tic();
159  partial_MTTKRP_with_KRP_output_FM(D, m_local_Y, m_local_T, num_threads);
160  mttkrp_time += toc();
161 
162  } else { // tensor output PM
172  tic();
173  partial_MTTKRP_with_KRP_output_T(s, D, m_local_Y, m_local_T,
174  projection_Tensor, num_threads);
175  mttkrp_time += toc();
176  tic();
177  multi_TTV_with_KRP_output_FM(D, projection_Tensor, projection_Ktensor,
178  num_threads);
179  multittv_time += toc();
180  }
181  } else if (n == s + 1) {
185  D = ::direction::left; // Contracting over the left modes
187  m_local_Y, projection_Ktensor, s,
188  opposite_direction(D)); // s because s is not included on the right
189  if (projection_Ktensor->nmodes == 1) { // factor matrix output PM
190  tic();
191  partial_MTTKRP_with_KRP_output_FM(D, m_local_Y, m_local_T, num_threads);
192  mttkrp_time += toc();
193  } else {
194  tic();
195  partial_MTTKRP_with_KRP_output_T(s, D, m_local_Y, m_local_T,
196  projection_Tensor, num_threads);
197  mttkrp_time += toc();
198 
199  // op(D) because multi ttvs in this tree structure are always right
200  tic();
201  multi_TTV_with_KRP_output_FM(opposite_direction(D), projection_Tensor,
202  projection_Ktensor, num_threads);
203  multittv_time += toc();
204  }
205  } else {
206  D = ::direction::left;
207  if (projection_Ktensor->nmodes == 2) {
208  // A single left contraction to output a factor martix
209  tic();
210  multi_TTV_with_KRP_output_FM(D, projection_Tensor, projection_Ktensor,
211  num_threads);
212  multittv_time += toc();
213  } else {
218  tic();
219  multi_TTV_with_KRP_output_T(0, D, projection_Tensor, projection_Ktensor,
220  buffer_Tensor, num_threads);
221  multittv_time += toc();
222 
223  LR_tensor_Reduction(buffer_Tensor, projection_Tensor,
224  buffer_Tensor->nmodes, D);
225  tensor_data_swap(projection_Tensor, buffer_Tensor);
226 
227  remove_mode_Ktensor(projection_Ktensor,
228  0); // remove the 0th factor matrix and mode from
229  // the projection_Ktensor
230  tic();
231  multi_TTV_with_KRP_output_FM(::direction::right, projection_Tensor,
232  projection_Ktensor, num_threads);
233  multittv_time += toc();
234  }
235  }
236  if (colmajor) {
237  TransposeM(m_local_Y->factors[n], out, m_local_Y->rank,
238  m_local_Y->dims[n]);
239  } else {
240  std::memcpy(out, m_local_Y->factors[n],
241  sizeof(double) * m_local_Y->rank * m_local_Y->dims[n]);
242  }
243  }
244 };
245 
246 #endif // DIMTREE_DDT_HPP_
UVEC dimensions() const
dimensions of every mode
Definition: ncpfactors.hpp:98
Data is stored such that the unfolding is column major.
Definition: tensor.hpp:32
void ktensor_copy_constructor(ktensor *Y, ktensor *nY)
Definition: ddttensor.hpp:1413
void multi_TTV_with_KRP_output_FM(direction D, tensor *input_tensor, ktensor *input_ktensor, long int num_threads)
multi_TTV_with_KRP_output_FM(); Wrapper function for performing a multi_TTV with a KRP and outputin...
Definition: dimtrees.hpp:464
void tic()
start the timer. easy to call as tic(); some code; double t=toc();
Definition: utils.hpp:42
void tensor_data_swap(tensor *t1, tensor *t2)
Definition: ddttensor.hpp:1378
void LR_tensor_Reduction(tensor *T, tensor *nT, long int n, direction D)
Definition: ddttensor.hpp:1388
void set_factor(const double *arma_factor_ptr, const long int mode)
Definition: ddt.hpp:93
std::vector< double > m_data
Definition: tensor.hpp:73
void multi_TTV_with_KRP_output_T(long int s, direction D, tensor *input_tensor, ktensor *input_ktensor, tensor *output_tensor, long int num_threads)
Definition: dimtrees.hpp:481
void destruct_Ktensor(ktensor *Y, long int clear_factors)
Definition: ddttensor.hpp:1348
void set_left_right_product(const long int i_split_mode)
Definition: ddt.hpp:118
double toc()
Definition: utils.hpp:48
VEC lambda() const
returns the lambda vector
Definition: ncpfactors.hpp:104
void LR_Ktensor_Reordering_existingY(ktensor *Y, ktensor *nY, long int n, direction D)
Definition: ddttensor.hpp:1297
DenseDimensionTree(const planc::Tensor &i_input_tensor, const planc::NCPFactors &i_ncp_factors, long int split_mode)
Definition: ddt.hpp:24
void in_order_reuse_MTTKRP(long int n, double *out, bool colmajor, double &multittv_time, double &mttkrp_time)
Definition: ddt.hpp:134
direction opposite_direction(direction D)
Definition: ddttensor.hpp:1434
void partial_MTTKRP_with_KRP_output_FM(direction D, ktensor *Y, tensor *T, long int num_threads)
partial_MTTKRP_with_KRP_output_FM(); Wrapper function for computing a partial_MTTKRP with KRP and o...
Definition: dimtrees.hpp:250
int modes() const
Return the number of modes. It is a scalar value.
Definition: tensor.hpp:159
void destruct_Tensor(tensor *T)
Definition: ddttensor.hpp:1370
int rank() const
returns low rank
Definition: ncpfactors.hpp:96
#define MAT
Definition: utils.h:52
int modes() const
returns number of modes
Definition: ncpfactors.hpp:102
void partial_MTTKRP_with_KRP_output_T(long int s, direction D, ktensor *input_ktensor, tensor *input_tensor, tensor *output_tensor, long int num_threads)
partial_MTTKRP_with_KRP_output_T() Wrapper function for computing partial_MTTKRP with KRP and outpu...
Definition: dimtrees.hpp:281
void TransposeM(double *A, double *A_T, long int rowsA, long int colsA)
Definition: ddttensor.hpp:668
UVEC dimensions() const
Returns a vector of dimensions on every mode.
Definition: tensor.hpp:161
UWORD numel() const
Returns total number of elements.
Definition: tensor.hpp:172
void remove_mode_Ktensor(ktensor *Y, long int n)
Definition: ddttensor.hpp:1323
#define VEC
Definition: utils.h:61
MAT & factor(const int i_n) const
factor matrix of a mode i_n
Definition: ncpfactors.hpp:100