Discontinuous Galerkin Library
#include "dg/algorithm.h"
sparseblockmat.h
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <thrust/host_vector.h>
5#include <cusp/coo_matrix.h>
7#include "config.h"
8#include "exceptions.h"
9#include "tensor_traits.h"
10#include "tensor_traits.h"
11
12namespace dg
13{
14
44template<class value_type>
46{
48 EllSparseBlockMat() = default;
64 EllSparseBlockMat( int num_block_rows, int num_block_cols,
65 int num_blocks_per_line, int num_different_blocks, int n):
66 data(num_different_blocks*n*n),
67 cols_idx( num_block_rows*num_blocks_per_line),
68 data_idx(cols_idx.size()), right_range(2),
69 num_rows(num_block_rows),
70 num_cols(num_block_cols),
71 blocks_per_line(num_blocks_per_line),
72 n(n), left_size(1), right_size(1)
73 {
74 right_range[0]=0;
75 right_range[1]=1;
76 }
78 int total_num_rows()const{
80 }
82 int total_num_cols()const{
84 }
85
91 cusp::coo_matrix<int, value_type, cusp::host_memory> asCuspMatrix() const;
92
102 void symv(SharedVectorTag, SerialTag, value_type alpha, const value_type* RESTRICT x, value_type beta, value_type* RESTRICT y) const;
103
106 right_range[0]=0;
108 }
110 void set_right_size( int new_right_size ){
111 right_size = new_right_size;
113 }
115 void set_left_size( int new_left_size ){
116 left_size = new_left_size;
117 }
124 void display( std::ostream& os = std::cout, bool show_data = false) const;
125
126 thrust::host_vector<value_type> data;
127 thrust::host_vector<int> cols_idx;
128 thrust::host_vector<int> data_idx;
129 thrust::host_vector<int> right_range;
133 int n;
136
137};
138
139
140//four classes/files play together in mpi distributed EllSparseBlockMat
141//CooSparseBlockMat and kernels, NearestNeighborComm, RowColDistMat
142//and the creation functions in mpi_derivatives.h
177template<class value_type>
179{
181 CooSparseBlockMat() = default;
191 CooSparseBlockMat( int num_block_rows, int num_block_cols, int n, int left_size, int right_size):
192 num_rows(num_block_rows), num_cols(num_block_cols), num_entries(0),
194
203 void add_value( int row, int col, const thrust::host_vector<value_type>& element)
204 {
205 assert( (int)element.size() == n*n);
206 int index = data.size()/n/n;
207 data.insert( data.end(), element.begin(), element.end());
208 rows_idx.push_back(row);
209 cols_idx.push_back(col);
210 data_idx.push_back( index );
211
212 num_entries++;
213 }
214
216 int total_num_rows()const{
218 }
220 int total_num_cols()const{
222 }
223
224
225
235 void symv(SharedVectorTag, SerialTag, value_type alpha, const value_type** x, value_type beta, value_type* RESTRICT y) const;
242 void display(std::ostream& os = std::cout, bool show_data = false) const;
243
244 thrust::host_vector<value_type> data;
245 thrust::host_vector<int> cols_idx;
246 thrust::host_vector<int> rows_idx;
247 thrust::host_vector<int> data_idx;
251 int n;
254};
256
257template<class value_type>
258void EllSparseBlockMat<value_type>::symv(SharedVectorTag, SerialTag, value_type alpha, const value_type* RESTRICT x, value_type beta, value_type* RESTRICT y) const
259{
260 //simplest implementation (all optimization must respect the order of operations)
261 for( int s=0; s<left_size; s++)
262 for( int i=0; i<num_rows; i++)
263 for( int k=0; k<n; k++)
264 for( int j=right_range[0]; j<right_range[1]; j++)
265 {
266 int I = ((s*num_rows + i)*n+k)*right_size+j;
267 // if y[I] isnan then even beta = 0 does not make it 0
268 y[I] = beta == 0 ? (value_type)0 : y[I]*beta;
269 for( int d=0; d<blocks_per_line; d++)
270 {
271 value_type temp = 0;
272 for( int q=0; q<n; q++) //multiplication-loop
273 temp = DG_FMA( data[ (data_idx[i*blocks_per_line+d]*n + k)*n+q],
274 x[((s*num_cols + cols_idx[i*blocks_per_line+d])*n+q)*right_size+j],
275 temp);
276 y[I] = DG_FMA( alpha,temp, y[I]);
277 }
278 }
279}
280template<class value_type>
281cusp::coo_matrix<int, value_type, cusp::host_memory> EllSparseBlockMat<value_type>::asCuspMatrix() const
282{
283 cusp::array1d<value_type, cusp::host_memory> values;
284 cusp::array1d<int, cusp::host_memory> row_indices;
285 cusp::array1d<int, cusp::host_memory> column_indices;
286 for( int s=0; s<left_size; s++)
287 for( int i=0; i<num_rows; i++)
288 for( int k=0; k<n; k++)
289 for( int j=right_range[0]; j<right_range[1]; j++)
290 {
291 int I = ((s*num_rows + i)*n+k)*right_size+j;
292 for( int d=0; d<blocks_per_line; d++)
293 for( int q=0; q<n; q++) //multiplication-loop
294 {
295 row_indices.push_back(I);
296 column_indices.push_back(
297 ((s*num_cols + cols_idx[i*blocks_per_line+d])*n+q)*right_size+j);
298 values.push_back(data[ (data_idx[i*blocks_per_line+d]*n + k)*n+q]);
299 }
300 }
301 cusp::coo_matrix<int, value_type, cusp::host_memory> A(
302 total_num_rows(), total_num_cols(), values.size());
303 A.row_indices = row_indices;
304 A.column_indices = column_indices;
305 A.values = values;
306 return A;
307}
308
309template<class value_type>
310void CooSparseBlockMat<value_type>::symv( SharedVectorTag, SerialTag, value_type alpha, const value_type** x, value_type beta, value_type* RESTRICT y) const
311{
312 if( num_entries==0)
313 return;
314 if( beta!= 1 )
315 std::cerr << "Beta != 1 yields wrong results in CooSparseBlockMat!! Beta = "<<beta<<"\n";
316 assert( beta == 1 && "Beta != 1 yields wrong results in CooSparseBlockMat!!");
317 // In fact, Beta is ignored in the following code
318
319 //simplest implementation (sums block by block)
320 for( int s=0; s<left_size; s++)
321 for( int k=0; k<n; k++)
322 for( int j=0; j<right_size; j++)
323 for( int i=0; i<num_entries; i++)
324 {
325 value_type temp = 0;
326 for( int q=0; q<n; q++) //multiplication-loop
327 temp = DG_FMA( data[ (data_idx[i]*n + k)*n+q],
328 //x[((s*num_cols + cols_idx[i])*n+q)*right_size+j],
329 x[cols_idx[i]][(q*left_size +s )*right_size+j],
330 temp);
331 int I = ((s*num_rows + rows_idx[i])*n+k)*right_size+j;
332 y[I] = DG_FMA( alpha,temp, y[I]);
333 }
334}
335
336template<class T>
337void EllSparseBlockMat<T>::display( std::ostream& os, bool show_data ) const
338{
339 os << "Data array has "<<data.size()/n/n<<" blocks of size "<<n<<"x"<<n<<"\n";
340 os << "num_rows "<<num_rows<<"\n";
341 os << "num_cols "<<num_cols<<"\n";
342 os << "blocks_per_line "<<blocks_per_line<<"\n";
343 os << "n "<<n<<"\n";
344 os << "left_size "<<left_size<<"\n";
345 os << "right_size "<<right_size<<"\n";
346 os << "right_range_0 "<<right_range[0]<<"\n";
347 os << "right_range_1 "<<right_range[1]<<"\n";
348 os << "Column indices: \n";
349 for( int i=0; i<num_rows; i++)
350 {
351 for( int d=0; d<blocks_per_line; d++)
352 os << cols_idx[i*blocks_per_line + d] <<" ";
353 os << "\n";
354 }
355 os << "\n Data indices: \n";
356 for( int i=0; i<num_rows; i++)
357 {
358 for( int d=0; d<blocks_per_line; d++)
359 os << data_idx[i*blocks_per_line + d] <<" ";
360 os << "\n";
361 }
362 if(show_data)
363 {
364 os << "\n Data: \n";
365 for( unsigned i=0; i<data.size()/n/n; i++)
366 for(unsigned k=0; k<n*n; k++)
367 {
369 res.d = data[i*n*n+k];
370 os << "idx "<<i<<" "<<res.d <<"\t"<<res.i<<"\n";
371 }
372 }
373 os << std::endl;
374}
375
376template<class value_type>
377void CooSparseBlockMat<value_type>::display( std::ostream& os, bool show_data) const
378{
379 os << "Data array has "<<data.size()/n/n<<" blocks of size "<<n<<"x"<<n<<"\n";
380 os << "num_rows "<<num_rows<<"\n";
381 os << "num_cols "<<num_cols<<"\n";
382 os << "num_entries "<<num_entries<<"\n";
383 os << "n "<<n<<"\n";
384 os << "left_size "<<left_size<<"\n";
385 os << "right_size "<<right_size<<"\n";
386 os << "row\tcolumn\tdata:\n";
387 for( int i=0; i<num_entries; i++)
388 os << rows_idx[i]<<"\t"<<cols_idx[i] <<"\t"<<data_idx[i]<<"\n";
389 if(show_data)
390 {
391 os << "\n Data: \n";
392 for( unsigned i=0; i<data.size()/n/n; i++)
393 for(unsigned k=0; k<n*n; k++)
394 {
396 res.d = data[i*n*n+k];
397 os << "idx "<<i<<" "<<res.d <<"\t"<<res.i<<"\n";
398 }
399 }
400 os << std::endl;
401
402}
403
407template <class T>
409{
410 using value_type = T;
412};
413template <class T>
415{
416 using value_type = T;
418};
420
421} //namespace dg
Error classes or the dg library.
@ y
y direction
@ x
x direction
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Coo Sparse Block Matrix format.
Definition: sparseblockmat.h:179
int num_rows
number of rows
Definition: sparseblockmat.h:248
int total_num_cols() const
total number of columns is num_cols*n*left_size*right_size
Definition: sparseblockmat.h:220
thrust::host_vector< int > data_idx
is of size num_entries and contains indices into the data array
Definition: sparseblockmat.h:247
thrust::host_vector< value_type > data
The data array is of size n*n*num_different_blocks and contains the blocks.
Definition: sparseblockmat.h:244
void display(std::ostream &os=std::cout, bool show_data=false) const
Display internal data to a stream.
thrust::host_vector< int > rows_idx
is of size num_entries and contains the row indices
Definition: sparseblockmat.h:246
int left_size
size of the left Kronecker delta
Definition: sparseblockmat.h:252
int n
each block has size n*n
Definition: sparseblockmat.h:251
void symv(SharedVectorTag, SerialTag, value_type alpha, const value_type **x, value_type beta, value_type *RESTRICT y) const
Apply the matrix to a vector.
void add_value(int row, int col, const thrust::host_vector< value_type > &element)
Convenience function to assemble the matrix.
Definition: sparseblockmat.h:203
int total_num_rows() const
total number of rows is num_rows*n*left_size*right_size
Definition: sparseblockmat.h:216
int num_cols
number of columns
Definition: sparseblockmat.h:249
CooSparseBlockMat(int num_block_rows, int num_block_cols, int n, int left_size, int right_size)
Allocate storage.
Definition: sparseblockmat.h:191
CooSparseBlockMat()=default
default constructor does nothing
thrust::host_vector< int > cols_idx
is of size num_entries and contains the column indices
Definition: sparseblockmat.h:245
int right_size
size of the right Kronecker delta (is e.g 1 for a x - derivative)
Definition: sparseblockmat.h:253
int num_entries
number of entries in the matrix
Definition: sparseblockmat.h:250
Ell Sparse Block Matrix format.
Definition: sparseblockmat.h:46
void display(std::ostream &os=std::cout, bool show_data=false) const
Display internal data to a stream.
int total_num_cols() const
total number of columns is num_cols*n*left_size*right_size
Definition: sparseblockmat.h:82
EllSparseBlockMat()=default
default constructor does nothing
thrust::host_vector< int > data_idx
has the same size as cols_idx and contains indices into the data array, i.e. the block number
Definition: sparseblockmat.h:128
void set_default_range()
Set right_range[0] = 0, right_range[1] = right_size
Definition: sparseblockmat.h:105
int blocks_per_line
number of blocks in each line
Definition: sparseblockmat.h:132
int num_rows
number of block rows, each row contains blocks
Definition: sparseblockmat.h:130
void set_right_size(int new_right_size)
Set right_size = new_right_size; set_default_range();
Definition: sparseblockmat.h:110
thrust::host_vector< value_type > data
The data array is of size n*n*num_different_blocks and contains the blocks. The first block is contai...
Definition: sparseblockmat.h:126
EllSparseBlockMat(int num_block_rows, int num_block_cols, int num_blocks_per_line, int num_different_blocks, int n)
Allocate storage.
Definition: sparseblockmat.h:64
int total_num_rows() const
total number of rows is num_rows*n*left_size*right_size
Definition: sparseblockmat.h:78
void set_left_size(int new_left_size)
Set left_size = new_left_size;
Definition: sparseblockmat.h:115
int left_size
size of the left Kronecker delta
Definition: sparseblockmat.h:134
cusp::coo_matrix< int, value_type, cusp::host_memory > asCuspMatrix() const
Convert to a cusp coordinate sparse matrix.
void symv(SharedVectorTag, SerialTag, value_type alpha, const value_type *RESTRICT x, value_type beta, value_type *RESTRICT y) const
Apply the matrix to a vector.
int num_cols
number of block columns
Definition: sparseblockmat.h:131
thrust::host_vector< int > cols_idx
is of size num_rows*num_blocks_per_line and contains the column indices % n into the vector
Definition: sparseblockmat.h:127
int n
each block has size n*n
Definition: sparseblockmat.h:133
thrust::host_vector< int > right_range
range (can be used to apply the matrix to only part of the right rows
Definition: sparseblockmat.h:129
int right_size
size of the right Kronecker delta (is e.g 1 for a x - derivative)
Definition: sparseblockmat.h:135
Indicate sequential execution.
Definition: execution_policy.h:26
Indicate a contiguous chunk of shared memory.
Definition: vector_categories.h:41
indicate our sparse block matrix format
Definition: matrix_categories.h:33
T value_type
Definition: sparseblockmat.h:416
T value_type
Definition: sparseblockmat.h:410
The vector traits.
Definition: tensor_traits.h:31