27 |
#include "mmio.h" |
#include "mmio.h" |
28 |
#include "SystemMatrix.h" |
#include "SystemMatrix.h" |
29 |
|
|
30 |
|
#include "limits.h" |
31 |
|
|
32 |
#define FSCANF_CHECK(scan_ret, reason) { if (scan_ret == EOF) perror(reason); return NULL; } |
#define FSCANF_CHECK(scan_ret, reason) { if (scan_ret == EOF) perror(reason); return NULL; } |
33 |
|
|
34 |
static void swap( index_t*, index_t*, double*, int, int ); |
static void swap( index_t*, index_t*, double*, int, int ); |
73 |
void q_sort( index_t *row, index_t *col, double *val, int begin, int end ) |
void q_sort( index_t *row, index_t *col, double *val, int begin, int end ) |
74 |
{ |
{ |
75 |
int l, r; |
int l, r; |
76 |
index_t pivot, lval; |
unsigned long pivot, lval; |
77 |
|
|
78 |
|
|
79 |
if( end > begin ) |
if( end > begin ) |
80 |
{ |
{ |
81 |
pivot = N * row[begin] + col[begin]; |
pivot = ((unsigned long)N) * row[begin]+col[begin] ; |
82 |
l = begin + 1; |
l = begin + 1; |
83 |
r = end; |
r = end; |
84 |
|
|
85 |
while( l < r ) |
while( l < r ) |
86 |
{ |
{ |
87 |
lval = N * row[l] + col[l]; |
lval = ((unsigned long)N) * row[l]+col[l]; |
88 |
if( lval < pivot ) |
if( lval < pivot ) |
89 |
l++; |
l++; |
90 |
else |
else |
151 |
/* get matrix size */ |
/* get matrix size */ |
152 |
if( mm_read_mtx_crd_size(fileHandle_p, &M, &N, &nz) != 0 ) |
if( mm_read_mtx_crd_size(fileHandle_p, &M, &N, &nz) != 0 ) |
153 |
{ |
{ |
154 |
Paso_setError(IO_ERROR, "Paso_SystemMatrix_loadMM_toCSR: Could not read sparse matrix size"); |
Paso_setError(IO_ERROR, "Paso_SystemMatrix_loadMM_toCSR: Could not read sparse matrix size."); |
155 |
|
Paso_MPIInfo_free(mpi_info); |
156 |
|
fclose( fileHandle_p ); |
157 |
|
return NULL; |
158 |
|
} |
159 |
|
|
160 |
|
/* Check whether we can handle current matrix size. |
161 |
|
In the q_sort algorithm we use N*M+N expression which should be in the limits of "unsigned long".*/ |
162 |
|
if( M>=(ULONG_MAX-N)/N ) |
163 |
|
{ |
164 |
|
Paso_setError(IO_ERROR, "Paso_SystemMatrix_loadMM_toCSR: Matrix size is too big."); |
165 |
Paso_MPIInfo_free(mpi_info); |
Paso_MPIInfo_free(mpi_info); |
166 |
fclose( fileHandle_p ); |
fclose( fileHandle_p ); |
167 |
return NULL; |
return NULL; |
201 |
col_ind[i]--; |
col_ind[i]--; |
202 |
} |
} |
203 |
fclose( fileHandle_p ); |
fclose( fileHandle_p ); |
|
|
|
204 |
/* sort the entries */ |
/* sort the entries */ |
205 |
q_sort( row_ind, col_ind, val, 0, nz ); |
q_sort( row_ind, col_ind, val, 0, nz ); |
206 |
|
|
207 |
/* setup row_ptr */ |
/* setup row_ptr */ |
208 |
curr_row = 0; |
curr_row = 0; |
209 |
for( i=0; (i<nz && curr_row<M); curr_row++ ) |
for( i=0; (i<nz && curr_row<M); curr_row++ ) |
210 |
{ |
{ |
211 |
while( row_ind[i] != curr_row ) |
while( row_ind[i] != curr_row ){ |
212 |
i++; |
i++; |
213 |
|
} |
214 |
row_ptr[curr_row] = i; |
row_ptr[curr_row] = i; |
215 |
} |
} |
216 |
row_ptr[M] = nz; |
row_ptr[M] = nz; |
306 |
return NULL; |
return NULL; |
307 |
} |
} |
308 |
|
|
309 |
|
/* Check whether we can handle current matrix size. |
310 |
|
In the q_sort algorithm we use N*M+N expression which should be in the limits of "unsigned long".*/ |
311 |
|
if( M>=(ULONG_MAX-N)/N ) |
312 |
|
{ |
313 |
|
Paso_setError(IO_ERROR, "Paso_SystemMatrix_loadMM_toCSC: Matrix size is too big."); |
314 |
|
Paso_MPIInfo_free(mpi_info); |
315 |
|
fclose( fileHandle_p ); |
316 |
|
return NULL; |
317 |
|
} |
318 |
|
|
319 |
/* prepare storage */ |
/* prepare storage */ |
320 |
col_ind = MEMALLOC( nz, index_t ); |
col_ind = MEMALLOC( nz, index_t ); |
321 |
row_ind = MEMALLOC( nz, index_t ); |
row_ind = MEMALLOC( nz, index_t ); |