matrix_concatenation_without_communication.cc File Reference
#include "generic.h"

Functions

template<typename myType >
void construct_vector (myType given_array[], unsigned given_arraysize, Vector< myType > &result_vector)
 
template<typename myType >
void output_vector (Vector< myType > &given_vector)
 
void fill_in_mat_info (unsigned const nblock_row, unsigned const nblock_col, unsigned dimarray[], Vector< Vector< Vector< unsigned > > > &mat_info_vec)
 
void create_matrix_ascend_col_row (unsigned const nrow, unsigned const ncol, const OomphCommunicator *const comm_pt, bool const distributed, CRDoubleMatrix &block)
 
void fill_in_sub_matrices (const OomphCommunicator *const comm_pt, const bool distributed, Vector< Vector< Vector< unsigned > > > &mat_info, DenseMatrix< CRDoubleMatrix * > &mat_pt)
 
void create_matrices_to_cat (unsigned dimarray[], const OomphCommunicator *const comm_pt, DenseMatrix< CRDoubleMatrix * > &mat_pt)
 
int main (int argc, char *argv[])
 

Function Documentation

◆ construct_vector()

template<typename myType >
void construct_vector ( myType  given_array[],
unsigned  given_arraysize,
Vector< myType > &  result_vector 
)
36 {
37  // Clear and reserve the required memory.
38  result_vector.clear();
39  result_vector.reserve(given_arraysize);
40 
41  for (unsigned i = 0; i < given_arraysize; i++)
42  {
43  result_vector.push_back(given_array[i]);
44  }
45 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9

References i.

Referenced by fill_in_mat_info().

◆ create_matrices_to_cat()

void create_matrices_to_cat ( unsigned  dimarray[],
const OomphCommunicator *const  comm_pt,
DenseMatrix< CRDoubleMatrix * > &  mat_pt 
)
194 {
195 
196  const unsigned nblock_row = mat_pt.nrow();
197  const unsigned nblock_col = mat_pt.ncol();
198 
199  // We store the above array in a data structure such that
200  // mat_info[0][0][0] gives us the number of rows in the block (0,0)
201  // mat_info[0][0][1] gives us the number of columns in the block (0,0)
202  Vector<Vector<Vector<unsigned> > > mat_info_vec;
203 
204  // Helper function to fill in mat_info given
205  // nblock_row, nblock_col and dim_array.
206  fill_in_mat_info(nblock_row,nblock_col,dimarray,mat_info_vec);
207 
208  // Fill in each sub matrix using create_matrix_ascend_col_row(..)
209  bool distributed = true;
210  fill_in_sub_matrices(comm_pt,distributed,mat_info_vec,mat_pt);
211 }
unsigned long nrow() const
Return the number of rows of the matrix.
Definition: matrices.h:485
unsigned long ncol() const
Return the number of columns of the matrix.
Definition: matrices.h:491
Definition: oomph-lib/src/generic/Vector.h:58
void fill_in_sub_matrices(const OomphCommunicator *const comm_pt, const bool distributed, Vector< Vector< Vector< unsigned > > > &mat_info, DenseMatrix< CRDoubleMatrix * > &mat_pt)
Definition: matrix_concatenation_without_communication.cc:165
void fill_in_mat_info(unsigned const nblock_row, unsigned const nblock_col, unsigned dimarray[], Vector< Vector< Vector< unsigned > > > &mat_info_vec)
Definition: matrix_concatenation_without_communication.cc:65

References fill_in_mat_info(), fill_in_sub_matrices(), oomph::DenseMatrix< T >::ncol(), and oomph::DenseMatrix< T >::nrow().

Referenced by main().

◆ create_matrix_ascend_col_row()

void create_matrix_ascend_col_row ( unsigned const  nrow,
unsigned const  ncol,
const OomphCommunicator *const  comm_pt,
bool const  distributed,
CRDoubleMatrix block 
)
116 {
117  // Clear the block
118  block.clear();
119 
120  // Create the distribution.
121  LinearAlgebraDistribution distri(comm_pt,nrow,distributed);
122 
123  // The number of rows this processor is responsible for.
124  unsigned nrow_local = distri.nrow_local();
125 
126  // The number of values this processor will have to insert.
127  unsigned nval = nrow_local*ncol;
128 
129  // The first_row will be used as an offset for the values to insert.
130  unsigned first_row = distri.first_row();
131 
132  // Fill in values...
133  Vector<double> values(nval,0);
134  for (unsigned val_i = 0; val_i < nval; val_i++)
135  {
136  values[val_i] = (val_i+1) + (first_row)*ncol;
137  }
138 
139  // Vectors for the column index and row_start.
140  Vector<int> column_indicies(nval,0);
141  Vector<int> row_start(nrow_local+1,0);
142 
143  unsigned column_indicies_i = 0;
144  for (unsigned row_i = 0; row_i < nrow_local; row_i++)
145  {
146  for (unsigned col_i = 0; col_i < ncol; col_i++)
147  {
148  column_indicies[column_indicies_i] = col_i;
149  column_indicies_i++;
150  }
151  row_start[row_i] = ncol*row_i;
152  }
153 
154  // Fill in the last row_start.
155  row_start[nrow_local] = nval;
156 
157  block.build(&distri,ncol,values,column_indicies,row_start);
158 }
m m block(1, 0, 2, 2)<< 4
Definition: linear_algebra_distribution.h:64

References block(), oomph::LinearAlgebraDistribution::first_row(), and oomph::LinearAlgebraDistribution::nrow_local().

Referenced by fill_in_sub_matrices().

◆ fill_in_mat_info()

void fill_in_mat_info ( unsigned const  nblock_row,
unsigned const  nblock_col,
unsigned  dimarray[],
Vector< Vector< Vector< unsigned > > > &  mat_info_vec 
)
68 {
69  // The total number of dimensions is two times the number of blocks
70  // Since matrices are squares. This should be the same number of elements in
71  // dimarray.
72  unsigned ndims = 2*nblock_row*nblock_col;
73 
74  // Put dimarray into dimvec_all, since Vectors are nicer to work with.
75  Vector<unsigned> dimvec_all;
76  construct_vector(dimarray,ndims,dimvec_all);
77 
78  // index for the dimvec_all array.
79  unsigned dimvec_all_i = 0;
80  for (unsigned block_row_i = 0; block_row_i < nblock_row; block_row_i++)
81  {
82  // create the Vector for the columns for the current row.
83  Vector<Vector<unsigned> > current_block_col_vec;
84 
85  // loop through the block columns
86  for (unsigned block_col_i = 0; block_col_i < nblock_col; block_col_i++)
87  {
88  // loop through the dimensions for this block.
89  Vector<unsigned> current_dim_vec;
90 
91  for (unsigned dim_i = 0; dim_i < 2; dim_i++)
92  {
93  current_dim_vec.push_back(dimvec_all[dimvec_all_i]);
94  dimvec_all_i++;
95  } // for the individual block dimensions.
96 
97  // push current_dim_vec into the current entry...
98  current_block_col_vec.push_back(current_dim_vec);
99  } // for the columns in this block row.
100 
101  // push the current block column vec onto the current row vec.
102  mat_info_vec.push_back(current_block_col_vec);
103  }// for the number of block rows.
104 }
void construct_vector(myType given_array[], unsigned given_arraysize, Vector< myType > &result_vector)
Definition: matrix_concatenation_without_communication.cc:34

References construct_vector().

Referenced by create_matrices_to_cat().

◆ fill_in_sub_matrices()

void fill_in_sub_matrices ( const OomphCommunicator *const  comm_pt,
const bool  distributed,
Vector< Vector< Vector< unsigned > > > &  mat_info,
DenseMatrix< CRDoubleMatrix * > &  mat_pt 
)
169 {
170  unsigned nblock_row = mat_pt.nrow();
171  unsigned nblock_col = mat_pt.ncol();
172 
173  for (unsigned block_row_i = 0; block_row_i < nblock_row; block_row_i++)
174  {
175  for (unsigned block_col_i = 0; block_col_i < nblock_col; block_col_i++)
176  {
177  unsigned nrow = mat_info[block_row_i][block_col_i][0];
178  unsigned ncol = mat_info[block_row_i][block_col_i][1];
179 
180  mat_pt(block_row_i,block_col_i)=new CRDoubleMatrix;
181 
182  create_matrix_ascend_col_row(nrow,ncol,comm_pt,distributed,
183  *mat_pt(block_row_i,block_col_i));
184  }
185  }
186 }
Definition: matrices.h:888
void create_matrix_ascend_col_row(unsigned const nrow, unsigned const ncol, const OomphCommunicator *const comm_pt, bool const distributed, CRDoubleMatrix &block)
Definition: matrix_concatenation_without_communication.cc:112

References create_matrix_ascend_col_row(), oomph::DenseMatrix< T >::ncol(), and oomph::DenseMatrix< T >::nrow().

Referenced by create_matrices_to_cat().

◆ main()

int main ( int argc  ,
char argv[] 
)

Driver code: Testing CRDoubleMatrixHelpers::concatenate_without_communication(...) We concatenate uniformly distributed matrices.

Let (x,y) be a matrix with x rows and y columns, with entries increasing along the columns, then along the rows. For example, (3,3) is [1 2 3 4 5 6 7 8 9].

We concatenate the following matrices: (7,7)(7,5)(7,3) (5,7)(5,5)(5,3) (3,7)(3,5)(3,3)

(7,7)(7,5) (5,7)(5,5) (3,7)(3,5)

(7,7)(7,5)(7,3) (5,7)(5,5)(5,3)

Communication between processors is NOT required, but the block structure of the sub blocks are NOT preserved in the result matrix. Please see self_test/mpi/vector_concatenation_without_communication/ for more detail.

The script validate.sh should run this self test on 1, 2, 3 and 4 cores.

244 {
245 #ifdef OOMPH_HAS_MPI
246  // Initialise MPI
247  MPI_Helpers::init(argc,argv);
248 #endif
249 
250  // Get the global oomph-lib communicator
251  const OomphCommunicator* const comm_pt = MPI_Helpers::communicator_pt();
252 
253  unsigned nblock_row = 3;
254  unsigned nblock_col = 3;
255 
256  // Supply the dimensions of the matrices to concatenate.
257  // The matrices must be in the order: first row, then along the columns,
258  // then second row, et cetera...
259  // The number of elements in this must be 2*nblock_row*nblock_col.
260  // In this test, we concatenate blocks with the following dimension and
261  // arrangements:
262  //
263  // (7,7) (7,5) (7,3)
264  // (5,7) (5,5) (5,3)
265  // (3,7) (3,5) (3,3)
266  unsigned dimarray[] = {7,7,7,5,7,3,5,7,5,5,5,3,3,7,3,5,3,3};
267 
268  // The data structure to store the pointers to matrices.
269  DenseMatrix<CRDoubleMatrix*> mat0_pt(nblock_row,nblock_col,0);
270 
271  // Create the matrice to concatenate.
272  create_matrices_to_cat(dimarray,comm_pt,mat0_pt);
273 
275 
276  // stuff for the output
277  unsigned my_rank = comm_pt->my_rank();
278  unsigned nproc = comm_pt->nproc();
279 
280  // Test #0, we concaenate
281  // (7,7) (7,5) (7,3)
282  // (5,7) (5,5) (5,3)
283  // (3,7) (3,5) (3,3)
284 
285  // We require the LinearAlgebraDistribution of the block rows.
286  // We use the first column.
287  Vector<LinearAlgebraDistribution*> row_distribution0_pt;
288  for (unsigned block_row_i = 0; block_row_i < nblock_row; block_row_i++)
289  {
290  row_distribution0_pt.push_back(mat0_pt(block_row_i,0)
291  ->distribution_pt());
292  }
293 
294  // Perform the concatenation.
295  // Note: Because this is a square block matrix, we only need to pass one
296  // Vector of distributions. This will be used for both row_distribution_pt
297  // and col_distribution_pt in the concatenate_without_communication(...)
298  // function.
299  CRDoubleMatrix result_matrix0;
301  row_distribution0_pt,mat0_pt,result_matrix0);
302 
303  std::ostringstream result_mat0_stream;
304  result_mat0_stream << "out0_NP" << nproc << "R" << my_rank;
305  result_matrix0.sparse_indexed_output(result_mat0_stream.str().c_str());
306 
307  // Clear the result matrix.
308  result_matrix0.clear();
309 
311  // Test #1, we concaenate
312  // (7,7) (7,5)
313  // (5,7) (5,5)
314  // (3,7) (3,5)
315 
316  nblock_row = 3;
317  nblock_col = 2;
318  DenseMatrix<CRDoubleMatrix*> mat1_pt(nblock_row,nblock_col,0);
319 
320  // Get the blocks.
321  for (unsigned block_row_i = 0; block_row_i < nblock_row; block_row_i++)
322  {
323  for (unsigned block_col_i = 0; block_col_i < nblock_col; block_col_i++)
324  {
325  mat1_pt(block_row_i,block_col_i) = mat0_pt(block_row_i,block_col_i);
326  }
327  }
328 
329  // We require the LinearAlgebraDistribution of the block rows.
330  // We use the first column.
331  Vector<LinearAlgebraDistribution*> row_distribution1_pt;
332  for (unsigned block_row_i = 0; block_row_i < nblock_row; block_row_i++)
333  {
334  row_distribution1_pt.push_back(row_distribution0_pt[block_row_i]);
335  }
336 
337  // We require the LinearAlgebraDistribution of the block "columns".
338  // We use the first column.
339  Vector<LinearAlgebraDistribution*> col_distribution1_pt;
340  for (unsigned block_col_i = 0; block_col_i < nblock_col; block_col_i++)
341  {
342  col_distribution1_pt.push_back(row_distribution0_pt[block_col_i]);
343  }
344 
345  // The result matrix.
346  CRDoubleMatrix result_matrix1;
347 
348  // Call the concatenate function.
350  row_distribution1_pt,col_distribution1_pt,mat1_pt,result_matrix1);
351 
352  std::ostringstream result_mat1_stream;
353  result_mat1_stream << "out1_NP" << nproc << "R" << my_rank;
354  result_matrix1.sparse_indexed_output(result_mat1_stream.str().c_str());
355 
356  // Clear the result matrix.
357  result_matrix1.clear();
358 
360  // Test #2, we concaenate
361  // (7,7) (7,5) (7,3)
362  // (5,7) (5,5) (5,3)
363  nblock_row = 2;
364  nblock_col = 3;
365  DenseMatrix<CRDoubleMatrix*> mat2_pt(nblock_row,nblock_col,0);
366 
367  // Get the blocks.
368  for (unsigned block_row_i = 0; block_row_i < nblock_row; block_row_i++)
369  {
370  for (unsigned block_col_i = 0; block_col_i < nblock_col; block_col_i++)
371  {
372  mat2_pt(block_row_i,block_col_i) = mat0_pt(block_row_i,block_col_i);
373  }
374  }
375 
376  // We require the LinearAlgebraDistribution of the block rows.
377  // We use the first column.
378  Vector<LinearAlgebraDistribution*> row_distribution2_pt;
379  for (unsigned block_row_i = 0; block_row_i < nblock_row; block_row_i++)
380  {
381  row_distribution2_pt.push_back(row_distribution0_pt[block_row_i]);
382  }
383 
384  // We require the LinearAlgebraDistribution of the block "columns".
385  // We use the first column.
386  Vector<LinearAlgebraDistribution*> col_distribution2_pt;
387  for (unsigned block_col_i = 0; block_col_i < nblock_col; block_col_i++)
388  {
389  col_distribution2_pt.push_back(row_distribution0_pt[block_col_i]);
390  }
391 
392  // The result matrix.
393  CRDoubleMatrix result_matrix2;
394 
395  // Call the concatenate function.
397  row_distribution2_pt,col_distribution2_pt,mat2_pt,result_matrix2);
398 
399  std::ostringstream result_mat2_stream;
400  result_mat2_stream << "out2_NP" << nproc << "R" << my_rank;
401  result_matrix2.sparse_indexed_output(result_mat2_stream.str().c_str());
402 
403  // Clear the result matrix.
404  result_matrix2.clear();
405 
406  // There are 3 by 3 block matrices to delete.
407  nblock_row = 3;
408  nblock_col = 3;
409  // Delete the matrices.
410  for (unsigned row_i = 0; row_i < nblock_row; row_i++)
411  {
412  for (unsigned col_i = 0; col_i < nblock_col; col_i++)
413  {
414  delete mat0_pt(row_i,col_i);
415  } // for col_i
416  } // for row_i
417 
418 #ifdef OOMPH_HAS_MPI
419  // finalize MPI
420  MPI_Helpers::finalize();
421 #endif
422  return(EXIT_SUCCESS);
423 } // end_of_main
void clear()
clear
Definition: matrices.cc:1657
Definition: matrices.h:386
void sparse_indexed_output(std::ostream &outfile, const unsigned &precision=0, const bool &output_bottom_right_zero=false) const
Definition: matrices.h:182
Definition: communicator.h:54
int my_rank() const
my rank
Definition: communicator.h:176
int nproc() const
number of processors
Definition: communicator.h:157
void create_matrices_to_cat(unsigned dimarray[], const OomphCommunicator *const comm_pt, DenseMatrix< CRDoubleMatrix * > &mat_pt)
Definition: matrix_concatenation_without_communication.cc:192
void concatenate_without_communication(const Vector< DoubleVector * > &in_vector_pt, DoubleVector &out_vector)
Definition: double_vector.cc:1856

References oomph::CRDoubleMatrix::clear(), oomph::MPI_Helpers::communicator_pt(), oomph::CRDoubleMatrixHelpers::concatenate_without_communication(), create_matrices_to_cat(), oomph::MPI_Helpers::finalize(), oomph::MPI_Helpers::init(), oomph::OomphCommunicator::my_rank(), oomph::OomphCommunicator::nproc(), and oomph::Matrix< T, MATRIX_TYPE >::sparse_indexed_output().

◆ output_vector()

template<typename myType >
void output_vector ( Vector< myType > &  given_vector)
50 {
51  typename Vector<myType>::iterator it;
52 
53  for(it = given_vector.begin(); it != given_vector.end(); ++it)
54  {
55  oomph_info << *it << std::endl;
56  }
57 }
OomphInfo oomph_info
Definition: oomph_definitions.cc:319

References oomph::oomph_info.