Main Page | Class List | File List | Class Members

CS_ICRS.hpp

00001 #include "Triplet.hpp"
00002 #include <vector>
00003 #include <algorithm>
00004 #include <assert.h>
00005 
00006 #include "CS_ELEMENT.hpp"
00007 #include "CS_ARRAY.hpp"
00008 
00009 //#define _DEBUG
00010 
00011 #ifndef _H_CS_ICRS
00012 #define _H_CS_ICRS
00013 
00014 #ifdef _DEBUG
00015 #include<iostream>
00016 #endif
00017 
00021 template< typename T >
00022 class CS_ICRS {
00023 
00024   private:
00025 
00027         typedef unsigned long int ULI;
00028 
00029   protected:
00030 
00032         CS_ELEMENT< ULI > nnz;
00033 
00035         CS_ELEMENT< ULI > nor;
00036 
00038         CS_ELEMENT< ULI > noc;
00039 
00041         CS_ARRAY< T >* nzs;
00042 
00044         CS_ARRAY< ULI >* c_ind;
00045 
00047         CS_ARRAY< ULI >* r_ind;
00048 
00050         CS_ELEMENT< T > zero_element;
00051 
00053         static int compareTriplets( const void * left, const void * right ) {
00054                 const Triplet< T > one = *( (Triplet< T > *)left );
00055                 const Triplet< T > two = *( (Triplet< T > *)right );
00056                 if( one.i() < two.i() )
00057                         return -1;
00058                 if ( one.i() > two.i() )
00059                         return 1;
00060                 if ( one.j() < two.j() )
00061                         return -1;
00062                 if ( one.j() > two.j() )
00063                         return 1;
00064                 return 0;
00065         }
00066 
00067   public:
00068 
00078         CS_ICRS( const ULI number_of_nonzeros, const ULI number_of_rows, const ULI number_of_cols, const T zero ):
00079                 nnz( number_of_nonzeros ), noc( number_of_cols ), nor( number_of_rows ), zero_element( zero ) {
00080                 nzs = new CS_ARRAY< T>( nnz.const_access(), "Nonzeros array (ICRS)" );
00081                 c_ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array storing the column index differences (ICRS)" );
00082                 r_ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array storing the row index differences (ICRS)" );
00083         }
00084 
00089         CS_ICRS( CS_ICRS< T >& toCopy ) {
00090                 zero_element = toCopy.zero_element;
00091                 nnz = toCopy.nnz;
00092                 noc = toCopy.noc;
00093                 nor = toCopy.nor;
00094                 nzs = new CS_ARRAY< T >( nnz.const_access(), "Nonzeros array( CS_ICRS, copied )" );
00095                 c_ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array storing the column indices (CS_ICRS, copied)" );
00096                 r_ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array storing the row index indices (CS_ICRS, copied)" );
00097                 for( CS_ELEMENT< ULI > i=0; i<nnz; i = i + 1 ) {
00098                         nzs->access( i.const_access() ) = toCopy.nzs->const_access( i.const_access() );
00099                         c_ind->access( i.const_access() ) = toCopy.c_ind->const_access( i.const_access() );
00100                         r_ind->access( i.const_access() ) = toCopy.r_ind->const_access( i.const_access() );
00101                 }
00102         }
00103 
00114         CS_ICRS( std::vector< Triplet< T > >& input, const ULI m, const ULI n, T& zero ) {
00115                 zero_element = zero;
00116                 //find nnz
00117                 nnz = input.size();
00118 
00119                 nor = m;
00120                 noc = n;
00121         
00122                 typename std::vector< Triplet< T > >::iterator in_it;
00123 
00124                 //WARNING: noc*nor typically overflows on 32 bits!
00125                 //         immediately start recording differences
00126                 //         instead of trying to directly calculate
00127                 //         the index as i*noc+j.
00128         
00129                 //sort( input.begin(), input.end(), compareTriplets );
00130                 qsort( &input[ 0 ], input.size(), sizeof( Triplet< T > ), &compareTriplets );
00131 
00132                 //filter out zeros and count the number of row jumps
00133                 ULI prev_row = 0;
00134                 std::vector< ULI > r_ind_temp;
00135                 typename std::vector< Triplet< T > >::iterator it = input.begin();
00136                 for( ; it!=input.end(); it++ ) {
00137                         if( (*it).i() > prev_row ) { r_ind_temp.push_back( (*it).i() - prev_row ); prev_row = (*it).i(); }
00138                 }
00139                 nnz = input.size();
00140 
00141                 //allocate arrays
00142                 nzs = new CS_ARRAY< T >( nnz.unrecorded_access(), "Array of nonzeros (CS_ICRS)" );
00143                 c_ind = new CS_ARRAY< ULI >( nnz.unrecorded_access() + 1, "Array of column index indices (CS_ICRS)" );
00144                 r_ind = new CS_ARRAY< ULI >( r_ind_temp.size() + 1, "Array of row index indices (CS_ICRS)" );
00145 
00146                 //set last entry
00147                 c_ind->unrecorded_access( nnz.unrecorded_access() ) = noc.unrecorded_access();
00148                 //r_ind does not have to be set; although the last element is read, it is actually never used.
00149 
00150                 //copy row-jump vector
00151                 for( ULI i=0; i<r_ind_temp.size(); i++ )
00152                         r_ind->unrecorded_access( i ) = r_ind_temp[ i ];
00153 
00154                 //make ICRS
00155                 ULI prev_col = 0;
00156                 prev_row = 0;
00157 
00158                 for( ULI i=0; i<nnz.unrecorded_access(); ++i ) {
00159                         const Triplet< T > cur = input[ i ];
00160                         const ULI currow = cur.i();
00161                         const ULI curcol = cur.j();
00162                         if( currow == prev_row ) {
00163                                 c_ind->unrecorded_access( i ) = curcol - prev_col;
00164                         } else {
00165                                 c_ind->unrecorded_access( i ) = noc.unrecorded_access() + ( curcol - prev_col );
00166                                 prev_row = currow;
00167                         }
00168                         nzs->unrecorded_access( i ) = cur.value;
00169                         prev_col = curcol;
00170 
00171 #ifdef _DEBUG
00172                         std::cout << currow << "," << curcol << "(" << cur.value << ") maps to " << c_ind[ i ] << std::endl;
00173 #endif
00174                 }
00175         }
00176 
00185         /*CS_ICRS( std::vector< Triplet< T > >& input, T& zero ) {
00186                 zero_element = zero;
00187                 //find nnz
00188                 nnz = input.size();
00189         
00190                 //find number of cols
00191                 noc = nor = static_cast< ULI >( 0 );
00192                 typename std::vector< Triplet< T > >::iterator in_it;
00193                 in_it = input.begin();
00194                 for( ; in_it!=input.end(); in_it++ ) {
00195                         const CS_ELEMENT< ULI > currow = ( *in_it ).i();
00196                         const CS_ELEMENT< ULI > curcol = ( *in_it ).j();
00197                         if ( currow > nor ) nor = currow;
00198                         if ( curcol > noc ) noc = curcol;
00199                 }
00200 
00201                 ++nor; ++noc;
00202 
00203 #ifdef _DEBUG
00204                 std::cout << "Max col index found: " << noc << std::endl;
00205                 std::cout << "Max row index found: " << nor << std::endl;
00206 #endif
00207         
00208                 //WARNING: noc*nor typically overflows on 32 bits!
00209                 //         immediately start recording differences
00210                 //         instead of trying to directly calculate
00211                 //         the index as i*noc+j.
00212         
00213                 sort( input.begin(), input.end(), compareTriplets );
00214 
00215                 //allocate arrays
00216                 nzs = new CS_ARRAY< T >( nnz.const_access(), "Array of nonzeros (CS_ICRS)" );
00217                 ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array of index differences (CS_ICRS)" );
00218                 ULI prev_col = 0;
00219                 ULI prev_row = 0;
00220 
00221                 //make CRS
00222                 for( CS_ELEMENT< ULI > i=0; i<nnz; ++i ) {
00223                         const Triplet< T > cur = input[ i.const_access() ];
00224                         if( cur.value == zero_element.const_access() ) { nnz.access() -= 1; continue; }
00225 
00226                         const ULI curdiff = ( cur.i() - prev_row ) * ( noc.const_access() - 1 ) + cur.j() - prev_col;
00227                         ind->access( i.const_access() ) = curdiff;
00228                         nzs->access( i.const_access() ) = cur.value;
00229                         prev_row = cur.i();
00230                         prev_col = cur.j();
00231 
00232                         //the below overflows like crazy
00233                         //nzs[ i ] = cur.value;
00234                         //ind[ i ] = cur.i() * noc + cur.j();
00235 #ifdef _DEBUG
00236                         std::cout << cur.i() << "," << cur.j() << " maps to " << ind[ i.const_access() ] << " / " << ( nor*noc ) << std::endl;
00237 #endif
00238                 }
00239         }*/
00240 
00251         /*T& random_access( const ULI& i, const ULI& j ) { TODO
00252         }*/
00253 
00262         T* zax( T* x_orig ) {
00263 
00264                 CS_ARRAY< T >* x = new CS_ARRAY< T >( noc.unrecorded_access(), "x-vector in CS_ICRS::zax" );
00265                 x->unrecordedCopyFrom( x_orig );
00266 
00267                 T* true_ret = new T[ nor.unrecorded_access() ];
00268                 CS_ARRAY< T >* ret = new CS_ARRAY< T >( nor.unrecorded_access(), "z-vector in CS_ICRS::zax" );
00269 
00270                 for( ULI i=0; i < nor.unrecorded_access(); ++i )
00271                         ret->access( i ) = zero_element.unrecorded_access();
00272 
00273                 ULI row_ind_pointer = 0; //ULI* row_ind_pointer = &(r_ind[0]) ( = r_ind, when using raw array types)
00274                 ULI index = 0;
00275                 ULI row = 0;
00276                 ULI column = c_ind->const_access( 0 ); //ULI* column = c_ind;
00277 
00278                 while( index < nnz.unrecorded_access() ) {
00279                         while( column < noc.unrecorded_access() ) {
00280                                 ret->access( row ) += nzs->const_access( index ) * x->const_access( column ); //*column++
00281                                 index += 1;
00282                                 column += c_ind->const_access( index );//colum += *c_ind_p++
00283                         }
00284                         row += r_ind->const_access( row_ind_pointer ); // row += *row_ind_pointer++; i.e., no cache effects due to indirect access
00285                         row_ind_pointer++;
00286                         column -= noc.unrecorded_access();
00287                 }
00288 
00289                 ret->unrecordedCopyTo( true_ret );
00290                 delete ret;
00291                 delete x;
00292                 return true_ret;
00293         }
00294 
00306         T* zaxtrace( T* x_orig ) {
00307 
00308                 CS_ARRAY< T >* x = new CS_ARRAY< T >( noc.unrecorded_access(), "x-vector in CS_ICRS::zax" );
00309                 x->unrecordedCopyFrom( x_orig );
00310 
00311                 T* true_ret = new T[ nor.unrecorded_access() ];
00312                 CS_ARRAY< T >* ret = new CS_ARRAY< T >( nor.unrecorded_access(), "z-vector in CS_ICRS::zax" );
00313 
00314                 for( ULI i=0; i < nor.unrecorded_access(); ++i )
00315                         ret->access( i ) = zero_element.unrecorded_access();
00316 
00317                 ULI row_ind_pointer = 0; //ULI* row_ind_pointer = &(r_ind[0]) ( = r_ind, when using raw array types)
00318                 ULI index = 0;
00319                 ULI row = 0;
00320                 ULI column = c_ind->const_access( 0 ); //ULI* column = c_ind;
00321 
00322                 while( index < nnz.unrecorded_access() ) {
00323                         while( column < noc.unrecorded_access() ) {
00324                                 std::cout << "TRACE:"<<row<<","<<column<<std::endl;
00325                                 ret->access( row ) += nzs->const_access( index ) * x->const_access( column ); //*column++
00326                                 index += 1;
00327                                 column += c_ind->const_access( index );//colum += *c_ind_p++
00328                         }
00329                         row += r_ind->const_access( row_ind_pointer ); // row += *row_ind_pointer++; i.e., no cache effects due to indirect access
00330                         row_ind_pointer++;
00331                         column -= noc.unrecorded_access();
00332                 }
00333 
00334                 ret->unrecordedCopyTo( true_ret );
00335                 delete ret;
00336                 delete x;
00337                 return true_ret;
00338         }
00339 
00341         ~CS_ICRS() {
00342                 delete nzs;
00343                 delete c_ind;
00344                 delete r_ind;
00345         }
00346 
00347 };
00348 
00349 #endif
00350 

Generated on Fri Aug 15 18:12:22 2008 for Run-timeCacheSimulator by  doxygen 1.3.9.1