26#define TAG_SPM_SYMM 3483
70 if ( miss_nbr[ owner ] >= miss_sze[ owner ] ) {
71 miss_sze[ owner ] *= 2;
72 miss_buf[ owner ] = (
spm_int_t*)realloc( miss_buf[ owner ],
73 miss_sze[ owner ] * 2 *
sizeof(
spm_int_t) );
75 newelem = miss_buf[ owner ] + 2 * miss_nbr[ owner ];
126 for ( k=frow; k < lrow; k++ )
190 for (jl=0; jl<spm->
n; jl++, coltmp++, loc2glob++)
192 jg = spm->
replicated ? jl : *loc2glob - baseval;
194 for ( k=coltmp[0]; k<coltmp[1]; k++, rowtmp++ )
196 ig = *rowtmp - baseval;
203 il = (glob2loc == NULL) ? ig : glob2loc[ig];
205#if defined(SPM_WITH_MPI)
211 int owner = (int)(- il - 1);
230#if defined(SPM_WITH_MPI)
280 assert( glob2loc != NULL );
282 for ( k=0; k<nbrecv; k++, buffer+=2 )
289 assert( (jl >= 0) && (jl < spm->n) );
339 MPI_Request *requests = malloc( clustnbr *
sizeof(MPI_Request) );
350 for ( c=0; c<clustnbr; c++ )
352 requests[c] = MPI_REQUEST_NULL;
353 if ( c == clustnum ) {
358 maxrecv =
spm_imax( maxrecv, recvcnts[c] );
361 if ( miss_nbr[c] > 0 ) {
362 maxsend =
spm_imax( maxsend, miss_nbr[c] );
364 MPI_Isend( miss_buf[c], 2 * miss_nbr[c],
SPM_MPI_INT,
370 if ( (maxrecv == 0) && (maxsend == 0) ) {
377 buffer = malloc( 2 * maxrecv *
sizeof(
spm_int_t) );
385 for ( c=0; c<clustnbr; c++ )
387 if ( (c == clustnum) || (recvcnts[c] == 0) ) {
390 rc = MPI_Recv( buffer, 2 * recvcnts[c],
SPM_MPI_INT,
392 if ( rc != MPI_SUCCESS ) {
393 char errmsg[MPI_MAX_ERROR_STRING];
396 MPI_Error_string( status.MPI_ERROR, errmsg, &len );
397 fprintf( stderr,
"Recv: %s\n", errmsg );
399 assert( rc == MPI_SUCCESS );
405 spm_symm_check_remote( spm, miss_sze, miss_buf, miss_nbr,
406 recvcnts[c], buffer );
412 for ( c=0; c<clustnbr; c++ )
414 if ( requests[c] != MPI_REQUEST_NULL )
416 assert( miss_nbr[c] > 0 );
417 rc = MPI_Wait( requests + c, &status );
418 if ( rc != MPI_SUCCESS ) {
419 char errmsg[MPI_MAX_ERROR_STRING];
422 MPI_Error_string( status.MPI_ERROR, errmsg, &len );
423 fprintf( stderr,
"Wait(send): %s\n", errmsg );
425 assert( rc == MPI_SUCCESS );
428 if ( c != clustnum ) {
475 return newsize + (miss_nbr * spm->
dof * spm->
dof);
479 for ( k=0; k<miss_nbr; k++, miss_buf+=2 )
483 ig = spm->
replicated ? il : loc2glob[ il ] - baseval;
485 newsize += (dofs[ig+1] - dofs[ig]) * (dofs[jg+1] - dofs[jg]);
551 dofj = (spm->
dof > 0) ? spm->
dof : dofs[jg+1] - dofs[jg];
556 for ( k=0; k<nbelt; k++ )
558 ig = (*oldrow)[k] - baseval;
559 dofi = (spm->
dof > 0) ? spm->
dof : dofs[ig+1] - dofs[ig];
565 memcpy( *newval, *oldval, nbval );
571 memcpy( *newrow, *oldrow, nbelt *
sizeof(
spm_int_t) );
638 const char **oldvalptr,
645 const char *oldval = *oldvalptr;
646 char *newval = *newvalptr;
657 dofj = (spm->
dof > 0) ? spm->
dof : dofs[jg+1] - dofs[jg];
661 for ( k=frow; k<lrow; k++, oldrow++, newrow++ )
663 ig = *oldrow - baseval;
666 while( ((*miss_nbr) > 0) &&
667 ((*miss_buf)[0] == jl) &&
668 ((*miss_buf)[1] < ig) )
673 newrow[0] = miss_ig + baseval;
678 dofi = (spm->
dof > 0) ? spm->
dof : dofs[miss_ig+1] - dofs[miss_ig];
679 nbval = dofi * dofj * eltsize;
680 memset( newval, 0x00, nbval );
694 dofi = (spm->
dof > 0) ? spm->
dof : dofs[ig+1] - dofs[ig];
695 nbval = dofi * dofj * eltsize;
696 memcpy( newval, oldval, nbval );
705 while( ((*miss_nbr) > 0) &&
706 ((*miss_buf)[0] == jl) )
711 newrow[0] = miss_ig + baseval;
716 dofi = (spm->
dof > 0) ? spm->
dof : dofs[miss_ig+1] - dofs[miss_ig];
717 nbval = dofi * dofj * eltsize;
718 memset( newval, 0x00, nbval );
765 const char *oldval = spm->
values;
779 spmIntSort2Asc1( miss_buf, miss_nbr );
782 nnz = spm->
nnz + miss_nbr;
783 newrow = malloc( nnz *
sizeof(
spm_int_t) );
788 newval = malloc( nnzexp * eltsize );
799 for ( jl=0; jl<spm->
n; jl++, colptr++, loc2glob++ )
801 assert( (l+baseval) >= colptr[0] );
804 jg = spm->
replicated ? jl : *loc2glob - baseval;
806 if ( (miss_nbr == 0) || (miss_buf[0] > jl) )
813 spm, eltsize, jg, colptr,
814 &oldrow, &rowtmp, &oldval, &valtmp );
818 spm, eltsize, jl, jg, colptr,
819 &oldrow, &rowtmp, &oldval, &valtmp,
820 &miss_nbr, &miss_buf );
823 colptr[0] = l + baseval;
826 colptr[0] = l + baseval;
828 assert( miss_nbr == 0 );
829 assert( (colptr[0] - baseval) == nnz );
830 assert( (rowtmp - newrow) == nnz );
832 (((valtmp - newval)/eltsize) == ((
size_t)nnzexp)) );
897 miss_sze = malloc( clustnbr *
sizeof(
spm_int_t) );
898 miss_buf = malloc( clustnbr *
sizeof(
spm_int_t*) );
899 miss_nbr = malloc( clustnbr *
sizeof(
spm_int_t) );
901 for ( i=0; i<clustnbr; i++ )
903 miss_sze[i] = buffsize;
904 miss_buf[i] = malloc( 2 * buffsize *
sizeof(
spm_int_t) );
912#if defined(SPM_WITH_MPI)
915 spm_symm_remote_exchange( spm, miss_sze, miss_buf, miss_nbr );
920 nb = miss_nbr[ clustnum ];
923 miss_nbr[ clustnum ],
924 miss_buf[ clustnum ] );
927#if defined(SPM_WITH_MPI)
947 for ( i=0; i < clustnbr; i++)
949 free( miss_buf[ i ] );
static size_t spm_size_of(spm_coeftype_t type)
Double datatype that is not converted through precision generator functions.
static spm_int_t spm_imax(spm_int_t a, spm_int_t b)
Internal function to compute max(a,b)
spm_int_t spmSymmetrize(spmatrix_t *spm)
Symmetrize the pattern of the spm.
#define SPM_MPI_INT
The MPI type associated to spm_int_t.
int spm_int_t
The main integer datatype used in spm arrays.
The sparse matrix data structure.
spm_int_t * spm_getandset_glob2loc(spmatrix_t *spm)
Computes the glob2loc array if needed, and returns it.
#define TAG_SPM_SYMM
Arbitrary tag for the symmetry exchange communications.
static spm_int_t spm_symm_local_copy_column(const spmatrix_t *spm, size_t eltsize, spm_int_t jg, const spm_int_t *colptr, const spm_int_t **oldrow, spm_int_t **newrow, const char **oldval, char **newval)
Copy the former column into the new one.
static int spm_symm_local_search(const spm_int_t *colptr, const spm_int_t *rowptr, spm_int_t jl, spm_int_t ig, spm_int_t baseval)
Search locally if an element exists.
static void spm_symm_check_local_pattern(spmatrix_t *spm, spm_int_t *miss_sze, spm_int_t **miss_buf, spm_int_t *miss_nbr)
Check the local symmetry of the pattern.
static void spm_symm_local_add(spmatrix_t *spm, spm_int_t miss_nbr, spm_int_t *miss_buf)
Add the missing entries to the local spm.
static spm_int_t spm_symm_values_newsize(const spmatrix_t *spm, spm_int_t miss_nbr, const spm_int_t *miss_buf)
Compute the new size of the values array.
static spm_int_t spm_symm_local_extend_column(spmatrix_t *spm, size_t eltsize, spm_int_t jl, spm_int_t jg, const spm_int_t *colptr, const spm_int_t **oldrowptr, spm_int_t **newrowptr, const char **oldvalptr, char **newvalptr, spm_int_t *miss_nbr, spm_int_t **miss_buf)
Add the missing entries to the local spm.
static void spm_symm_add_missing_elt(spm_int_t *miss_sze, spm_int_t **miss_buf, spm_int_t *miss_nbr, spm_int_t jg, spm_int_t ig, int owner)
Add a couple (ig, jg) in the list of missing entries of the owner.