33 #include "Triplet.hpp"
34 #include "SparseMatrix.hpp"
52 template<
typename T,
typename _i_value=ULI >
86 if( one.
i() < two.
i() )
88 if ( one.
i() > two.
i() )
90 if ( one.
j() < two.
j() )
92 if ( one.
j() > two.
j() )
104 ICRS( std::string file, T zero = 0 ) {
118 ICRS(
const ULI number_of_nonzeros,
const ULI number_of_rows,
const ULI number_of_cols, T zero ):
119 SparseMatrix< T, ULI >( number_of_nonzeros, number_of_cols, number_of_rows, zero ) {
120 ds =
new T[ this->
nnz ];
123 bytes =
sizeof( ULI ) * 2 +
sizeof( _i_value ) * 2 * this->
nnz +
sizeof( T ) * this->
nnz;
137 ds =
new T[ this->
nnz ];
138 c_ind =
new _i_value[ this->
nnz - 1 ];
139 r_ind =
new _i_value[ this->
nnz - 1 ];
140 for( ULI i=0; i<this->
nnz; i = i + 1 ) {
141 ds[ i ] = toCopy.
ds[ i ];
145 bytes =
sizeof( ULI ) * 2 +
sizeof( _i_value ) * 2 * this->nnz +
sizeof( T ) * this->nnz;
160 load( input, m, n, zero );
170 if( log2(this->
noc) >
sizeof( _i_value ) * 8 )
171 std::cerr <<
"Warning: the matrix with " << this->
noc <<
" columns cannot be represented within " << (
sizeof( _i_value )*8) <<
"-bit index values this ICRS instance uses!" << std::endl;
173 if( log2(this->
nor) >
sizeof( _i_value ) * 8 )
174 std::cerr <<
"Warning: the matrix with " << this->
nor <<
" rows cannot be represented within " << (
sizeof( _i_value )*8) <<
"-bit index values this ICRS instance uses!" << std::endl;
176 if( m==0 || n==0 || input.size() == 0 ) {
184 typename std::vector< Triplet< T > >::iterator in_it;
200 std::vector< ULI > r_ind_temp;
201 typename std::vector< Triplet< T > >::iterator it = input.begin();
202 ULI prev_row = (*it).i();
203 r_ind_temp.push_back( prev_row );
207 for( ; it!=input.end(); it++ ) {
208 assert( (*it).i() < this->
nor );
209 assert( (*it).j() < this->
noc );
210 assert( (*it).i() >= prev_row );
211 if( (*it).i() > prev_row ) {
212 assert( (*it).i() - prev_row <
m );
213 r_ind_temp.push_back( (*it).i() - prev_row );
214 prev_row = (*it).i();
217 this->
nnz = input.size();
220 const unsigned long int allocsize = this->
nnz;
221 ds =
new T[ allocsize ];
222 c_ind =
new _i_value[ allocsize ];
223 r_ind =
new _i_value[ r_ind_temp.size() ];
226 bytes =
sizeof( ULI ) * 2 +
sizeof( _i_value ) * ( allocsize + r_ind_temp.size() ) +
sizeof( T ) * allocsize;
235 for( ULI i=1; i<r_ind_temp.size(); i++ ) {
236 r_ind[i-1] = r_ind_temp[ i ];
237 if( static_cast< ULI >(
r_ind[i-1] ) != r_ind_temp[ i ] ) {
238 std::cerr <<
"Row increment too large to store in this ICRS instance!" << std::endl;
245 ULI prev_col =
c_start = input[ 0 ].j();
247 unsigned long int check_jumps = 0;
248 unsigned long int check_row = r_ind_temp[0];
249 assert( r_ind_temp[ 0 ] ==
r_start );
250 ds[ 0 ] = input[ 0 ].value;
251 for( ULI i=1; i<this->
nnz; ++i ) {
253 const ULI currow = cur.
i();
254 const ULI curcol = cur.
j();
255 if( currow == prev_row ) {
256 c_ind[i-1] = curcol - prev_col;
257 if( static_cast< ULI >(
c_ind[i-1] ) != curcol - prev_col ) {
258 std::cerr <<
"Column increment too large to store in this ICRS instance!" << std::endl;
261 assert( currow == check_row );
263 assert( currow > prev_row );
264 c_ind[i-1] = this->
noc + ( curcol - prev_col );
265 if( static_cast< ULI >(
c_ind[i-1] ) - this->
noc + prev_col != curcol ) {
266 std::cerr <<
"Overflowed column increment too large to store in this ICRS instance!" << std::endl;
269 check_row +=
r_ind[ check_jumps++ ];
270 assert( currow == check_row );
277 std::cout << currow <<
"," << curcol <<
"(" << cur.
value <<
") maps to " <<
c_ind[ i ] << std::endl;
282 for(
unsigned long int i=this->nnz; i<allocsize; ++i ) {
288 assert( check_jumps == r_ind_temp.size()-1 );
315 assert( row_start <= this->
r_start );
316 assert( column_start <= this->
c_start );
317 this->r_start = row_start;
318 this->c_start = column_start;
327 virtual void zxa(
const T*__restrict__ pDataX, T*__restrict__ pDataZ ) {
328 if( this->
nor == 0 || this->
noc == 0 || this->
nnz == 0 )
return;
329 T *__restrict__ pDataA =
ds;
330 const T *__restrict__ pDataAend =
ds + this->
nnz;
332 const T *
const pDataZend = pDataZ + this->
noc;
335 _i_value *__restrict__ pIncRow =
r_ind;
336 _i_value *__restrict__ pIncCol =
c_ind;
341 while( pDataA < pDataAend ) {
342 while( pDataZ < pDataZend ) {
343 *pDataZ += *pDataA * *pDataX;
349 pDataX += *pIncRow++;
359 virtual void zax(
const T*__restrict__ pDataX, T*__restrict__ pDataZ ) {
360 if( this->
nor == 0 || this->
noc == 0 || this->
nnz == 0 )
return;
362 T *__restrict__ pDataA =
ds;
363 const T *
const pDataAend =
ds + this->
nnz;
364 const T *
const pDataXend = pDataX + this->
noc;
366 const T *
const pDataXst = pDataX;
367 const T *
const pDataZst = pDataZ;
368 const T *
const pDataZend = pDataZ + this->
nor;
371 _i_value *__restrict__ pIncRow =
r_ind;
372 _i_value *__restrict__ pIncCol =
c_ind;
375 assert( r_start < this->nor );
376 assert( c_start < this->noc );
377 assert( this->nnz > 0 );
380 while( pDataA < pDataAend ) {
381 while( pDataX < pDataXend ) {
382 assert( pDataA < pDataAend );
383 assert( pDataX >= pDataXst );
384 assert( pDataX < pDataXend );
385 assert( pDataZ >= pDataZst );
386 assert( pDataZ < pDataZend );
387 assert( pDataX + this->noc >= pDataXend );
388 assert( pDataA + this->nnz >= pDataAend );
389 assert( pDataZ + this->nor >= pDataZend );
391 *pDataZ += *pDataA++ * *pDataX;
392 pDataX += *pIncCol++;
396 pDataZ += *pIncRow++;
402 void ZaX(
const T*__restrict__
const *__restrict__
const X, T *__restrict__
const *__restrict__
const Z ) {
408 T *__restrict__ pDataA =
ds;
413 _i_value *__restrict__ pIncRow =
r_ind;
414 _i_value *__restrict__ pIncCol =
c_ind;
417 const T *__restrict__ pDataX[ k ];
418 T *__restrict__ pDataZ[ k ];
421 for(
size_t s = 0; s < k; ++s ) {
427 while( pDataA < pDataAend ) {
429 while( pDataX[0] < pDataXend ) {
431 for(
size_t s = 0; s < k; ++s ) {
432 *(pDataZ[s]) += *pDataA * *(pDataX[s]);
433 pDataX[s] += *pIncCol;
440 for(
size_t s = 0; s < k; ++s ) {
442 pDataX[s] -= SparseMatrix< T, ULI >::noc;
444 pDataZ[s] += *pIncRow;
453 void ZXa(
const T *__restrict__
const *__restrict__
const X, T *__restrict__
const *__restrict__
const Z ) {
454 if( this->
nor == 0 || this->
noc == 0 || this->
nnz == 0 )
return;
455 T *__restrict__ pDataA =
ds;
456 const T *__restrict__ pDataAend =
ds + this->
nnz;
457 const T *__restrict__
const pDataZend = Z[0] + this->
noc;
461 _i_value *__restrict__ pIncRow =
r_ind;
462 _i_value *__restrict__ pIncCol =
c_ind;
464 const T *__restrict__ pDataX[ k ];
465 T *__restrict__ pDataZ[ k ];
467 for(
size_t s = 0; s < k; ++s ) {
472 while( pDataA < pDataAend ) {
473 while( pDataZ[0] < pDataZend ) {
474 for(
size_t s = 0; s < k; ++s ) {
475 *(pDataZ[s]) += *pDataA * *(pDataX[s]);
476 pDataZ[s] += *pIncCol;
481 for(
size_t s = 0; s < k; ++s ) {
482 pDataZ[s] -= this->
noc;
483 pDataX[s] += *pIncRow;
491 if(
ds != NULL )
delete []
ds;
ULI nnz
Number of non-zeros.
Definition: SparseMatrix.hpp:58
ULI r_start
Start position, row.
Definition: ICRS.hpp:63
ICRS(std::string file, T zero=0)
Base constructor.
Definition: ICRS.hpp:104
The incremental compressed row storage sparse matrix data structure.
Definition: ICRS.hpp:53
void ZaX(const T *__restrict__ const *__restrict__ const X, T *__restrict__ const *__restrict__ const Z)
Definition: ICRS.hpp:402
virtual size_t bytesUsed()
Function to query the amount of storage required by this sparse matrix.
Definition: ICRS.hpp:496
virtual void getFirstIndexPair(ULI &row, ULI &col)
Returns the first nonzero index, per reference.
Definition: ICRS.hpp:295
ULI i() const
Definition: Triplet.hpp:70
virtual void zxa(const T *__restrict__ pDataX, T *__restrict__ pDataZ)
In-place z=xA function.
Definition: ICRS.hpp:327
ICRS(ICRS< T > &toCopy)
Copy constructor.
Definition: ICRS.hpp:130
_i_value * r_ind
Array containing the row jumps.
Definition: ICRS.hpp:72
virtual unsigned long int m()
Queries the number of rows this matrix contains.
Definition: SparseMatrix.hpp:107
static int compareTriplets(const void *left, const void *right)
Comparison function used for sorting input data.
Definition: ICRS.hpp:83
void ZXa(const T *__restrict__ const *__restrict__ const X, T *__restrict__ const *__restrict__ const Z)
Definition: ICRS.hpp:453
void loadFromFile(const std::string file, const T zero=0)
Function which loads a matrix from a matrix market file.
Definition: SparseMatrix.hpp:89
Interface common to all sparse matrix storage schemes.
Definition: SparseMatrix.hpp:46
_i_value * c_ind
Array containing the column jumps.
Definition: ICRS.hpp:69
ULI noc
Number of columns.
Definition: SparseMatrix.hpp:55
ICRS(std::vector< Triplet< T > > &input, const ULI m, const ULI n, const T zero=0)
Constructor which transforms a collection of input triplets to CRS format.
Definition: ICRS.hpp:159
size_t bytes
Remembers the number of bytes allocated.
Definition: ICRS.hpp:75
ICRS(const ULI number_of_nonzeros, const ULI number_of_rows, const ULI number_of_cols, T zero)
Base constructor which only initialises the internal arrays.
Definition: ICRS.hpp:118
T value
Value stored at this triplet.
Definition: Triplet.hpp:95
~ICRS()
Base deconstructor.
Definition: ICRS.hpp:490
static const size_t fillIn
Fill-in field for interoperability with vecBICRS.
Definition: ICRS.hpp:80
ULI nor
Number of rows.
Definition: SparseMatrix.hpp:52
virtual void zax(const T *__restrict__ pDataX, T *__restrict__ pDataZ)
In-place z=Ax function.
Definition: ICRS.hpp:359
T zero_element
The element considered to be zero.
Definition: SparseMatrix.hpp:63
ULI j() const
Definition: Triplet.hpp:73
ICRS()
Base constructor.
Definition: ICRS.hpp:98
virtual unsigned long int n()
Queries the number of columns this matrix contains.
Definition: SparseMatrix.hpp:115
ULI c_start
Start position, column.
Definition: ICRS.hpp:66
T * ds
Array containing the actual nnz non-zeros.
Definition: ICRS.hpp:60
A single triplet value.
Definition: Triplet.hpp:52
void setStartingPos(const ULI row_start, const ULI column_start)
Sets starting position of matrix multiplication.
Definition: ICRS.hpp:314
void getStartingPos(ULI &row_start, ULI &column_start)
Gets starting position (first nonzero location)
Definition: ICRS.hpp:301
virtual void load(std::vector< Triplet< T > > &input, const ULI m, const ULI n, const T zero)
Definition: ICRS.hpp:164