Mentions légales du service

Skip to content
Snippets Groups Projects
Commit e291cbe1 authored by Mathieu Faverge's avatar Mathieu Faverge
Browse files

Move to the attic unused files

parent 661a48a6
No related branches found
No related tags found
No related merge requests found
/**
* PaStiX CSC management routines.
*
* PaStiX is a software package provided by Inria Bordeaux - Sud-Ouest,
* LaBRI, University of Bordeaux 1 and IPB.
*
* @version 1.0.0
* @author Mathieu Faverge
* @author Pierre Ramet
* @author Xavier Lacoste
* @date 2011-11-11
* @precisions normal z -> c d s
*
**/
#include "common.h"
#include "z_csc_utils.h"
/* /\* */
/* Function: cmp_colrow */
/* Used for qsort to sort arrays of pastix_int_t following their first element. */
/* Returns the difference between the first element of *p1* and */
/* the first element of *p2* */
/* Parameters: */
/* p1 - the first array to compare */
/* p2 - the second array to compare */
/* *\/ */
/* int */
/* cmp_colrow(const void *p1, const void *p2) */
/* { */
/* return ((* (pastix_int_t * const *) p1) - (*(pastix_int_t * const *) p2)); */
/* } */
/*
Function: z_csc_symgraph
Modify the CSC to a symetric graph one.
Don't use it on a lower symetric CSC
it would give you all the CSC upper + lower.
External function.
Parameters:
n - Number of columns/vertices
ia - Starting index of each column in *ja* and *a*
ja - Row index of each element
a - Value of each element,can be NULL
newn - New number of column
newia - Starting index of each column in *ja* and *a*
newja - Row index of each element
newa - Value of each element,can be NULL
*/
int z_csc_symgraph( pastix_int_t n,
const pastix_int_t *ia,
const pastix_int_t *ja,
const pastix_complex64_t *a,
pastix_int_t *newn,
pastix_int_t **newia,
pastix_int_t **newja,
pastix_complex64_t **newa)
{
return z_csc_symgraph_int(n, ia, ja, a, newn, newia, newja, newa, API_NO);
}
/*
Function: csc_symgraph_int
Modify the CSC to a symetric graph one.
Don't use it on a lower symetric CSC
it would give you all the CSC upper + lower.
Parameters:
n - Number of columns/vertices
ia - Starting index of each column in *ja* and *a*
ja - Row index of each element
a - Value of each element,can be NULL
newn - New number of column
newia - Starting index of each column in *ja* and *a*
newja - Row index of each element
newa - Value of each element,can be NULL
malloc_flag - flag to indicate if function call is intern to pastix or extern.
*/
int z_csc_symgraph_int (pastix_int_t n,
const pastix_int_t *ia,
const pastix_int_t *ja,
const pastix_complex64_t *a,
pastix_int_t *newn,
pastix_int_t **newia,
pastix_int_t **newja,
pastix_complex64_t **newa,
int malloc_flag)
{
pastix_int_t * nbrEltCol = NULL; /* nbrEltCol[i] = Number of elt to add in column i */
pastix_int_t * cia = NULL; /* ia of diff between good CSC and bad CSC */
pastix_int_t * cja = NULL; /* ja of diff between good CSC and bad CSC */
pastix_int_t nbr2add; /* Number of elt to add */
pastix_int_t itercol, iterrow, iterrow2; /* iterators */
pastix_int_t l = ia[n] -1;
pastix_int_t newl;
/* Ncol=Nrow don't need change */
*newn = n;
MALLOC_INTERN(nbrEltCol, n, pastix_int_t);
/* !! Need check for malloc */
/* Init nbrEltCol */
for (itercol=0; itercol<n; itercol++)
{
nbrEltCol[itercol]=0;
}
/* Compute number of element by col to add for correcting the CSC */
for (itercol=0; itercol<n; itercol++)
{
for (iterrow=ia[itercol]-1; iterrow<ia[itercol+1]-1; iterrow++)
{
if (ja[iterrow] != (itercol+1))
{
/* Not diagonal elt */
/* So we have a (i,j) and we are looking for a (j,i) elt */
/* i = itercol+1, j=ja[iterrow] */
int rowidx=ja[iterrow]-1;
int flag=0;
for (iterrow2=ia[rowidx]-1; iterrow2<ia[rowidx+1]-1; iterrow2++)
{
if (ja[iterrow2] == itercol+1)
{
/* Ok we found (j,i) so stop this madness */
flag = 1;
break;
}
}
if (flag==0)
{
/* We never find (j,i) so increase nbrEltCol[j] */
(nbrEltCol[ja[iterrow]-1])++;
}
}
}
}
/* Compute number of element to add */
/* And cia=ia part of csc of element to add */
/* kind of a diff between the corrected one and the original CSC */
MALLOC_INTERN(cia, n+1, pastix_int_t);
/* !! Need checking good alloc) */
nbr2add=0;
for (itercol=0;itercol<n;itercol++)
{
cia[itercol]=nbr2add;
nbr2add += nbrEltCol[itercol];
}
cia[n]=nbr2add;
/*fprintf(stderr, "nbr of elt to add %ld\n", nbr2add);*/
if (nbr2add != 0)
{
/* Build cja */
/* like cia, cja is ja part of diff CSC */
MALLOC_INTERN(cja, nbr2add, pastix_int_t);
/* !! again we need check of memAlloc */
/* We walkthrough again the csc */
for (itercol=0;itercol<n;itercol++)
{
for (iterrow=ia[itercol]-1;iterrow<ia[itercol+1]-1;iterrow++)
{
if (ja[iterrow] != itercol+1)
{
/* we find (i,j) need to find (j,i) */
int rowidx=ja[iterrow]-1;
int flag=0;
for (iterrow2=ia[rowidx]-1;iterrow2<ia[rowidx+1]-1;iterrow2++)
{
if (ja[iterrow2] == itercol+1)
{
/* find (j,i) */
flag=1;
break;
}
}
if (flag==0)
{
/* We don't find (j,i) so put in diff CSC (cia,cja,0) */
pastix_int_t index=ja[iterrow]-1;
/* cia[index] = index to put in cja the elt */
cja[cia[index]] = itercol+1;
(cia[index])++;
}
}
}
}
/* Restore cia */
cia[0]=0;
for (itercol=0;itercol<n;itercol++)
{
cia[itercol+1]=cia[itercol]+nbrEltCol[itercol];
}
memFree_null(nbrEltCol);
/* Build corrected csc */
newl = l+nbr2add;
if (malloc_flag == API_NO)
{
/* Ici on a des malloc car le free est externe */
MALLOC_EXTERN(*newia, n+1, pastix_int_t);
MALLOC_EXTERN(*newja, newl, pastix_int_t);
if (a != NULL)
MALLOC_EXTERN(*newa, newl, pastix_complex64_t);
}
else
{
/* Ici on a des memAlloc car le free est interne */
MALLOC_INTERN(*newia, n+1, pastix_int_t);
MALLOC_INTERN(*newja, newl, pastix_int_t);
if (a != NULL)
MALLOC_INTERN(*newa, newl, pastix_complex64_t);
}
iterrow2 = 0; /* iterator of the CSC diff */
for (itercol=0; itercol<n; itercol++)
{
(*newia)[itercol] = ia[itercol]+iterrow2;
for (iterrow=ia[itercol]-1;iterrow<ia[itercol+1]-1;iterrow++)
{
/* we add the new elt with respect of order in row */
while ((iterrow2<cia[itercol+1]) &&
(ja[iterrow] > cja[iterrow2]))
{
/* we have elt(s) to add with a row lower than ja[iterrow] */
(*newja)[iterrow+iterrow2]=cja[iterrow2];
if (a != NULL)
(*newa)[iterrow+iterrow2]=0.;
iterrow2++;
}
/* Put the elt from the origin CSC */
(*newja)[iterrow+iterrow2] = ja[iterrow];
if (a != NULL)
(*newa)[iterrow+iterrow2] = a[iterrow];
}
/* Since we put elt with a row lower than elt in the origin CSC */
/* We could have some elt to add after the last elt in the column */
while(iterrow2<cia[itercol+1])
{
(*newja)[iterrow+iterrow2]=cja[iterrow2];
if (a != NULL)
(*newa)[iterrow+iterrow2]=0.;
iterrow2++;
}
}
(*newia)[n]=ia[n]+iterrow2;
memFree_null(cja);
}
else
{
/* No correction to do */
memFree_null(nbrEltCol);
newl = l;
if (malloc_flag == API_NO)
{
/* ici on a des mallocs car le free est externe */
MALLOC_EXTERN(*newia, n+1, pastix_int_t);
MALLOC_EXTERN(*newja, l, pastix_int_t);
if (a != NULL)
MALLOC_EXTERN(*newa, l, pastix_complex64_t);
}
else
{
/* ici on a des memAllocs car le free est interne */
MALLOC_INTERN(*newia, n+1, pastix_int_t);
MALLOC_INTERN(*newja, l, pastix_int_t);
if (a != NULL)
MALLOC_INTERN(*newa, l, pastix_complex64_t);
}
memcpy((*newia), ia, (n+1)*sizeof(pastix_int_t));
memcpy((*newja), ja, l * sizeof(pastix_int_t));
if (a != NULL)
memcpy((*newa) , a , l * sizeof(pastix_complex64_t));
}
memFree_null(cia);
return EXIT_SUCCESS;
}
/**
Function: z_csc_noDiag
Supress diagonal term.
After this call, *ja* can be reallocated to *ia[n] -1*.
Parameters:
n - size of the matrix.
ia - Index in *ja* and *a* of the first element of each column
ja - row of each element
a - value of each element, can be set to NULL
Returns:
ia and ja tabulars modified.
*/
void z_csc_noDiag(pastix_int_t baseval,
pastix_int_t n,
pastix_int_t *ia,
pastix_int_t *ja,
pastix_complex64_t *a)
{
pastix_int_t i, j;
pastix_int_t indj;
pastix_int_t *old_ia = NULL;
MALLOC_INTERN(old_ia, n+1, pastix_int_t);
memcpy(old_ia, ia, sizeof(pastix_int_t)*(n+1));
ASSERT(ia[0]==baseval,MOD_SOPALIN);
indj = 0;
/*fprintf(stdout, "NNZ with diag = %ld \n", ia[n]);*/
for(i=0;i<n;i++)
{
/* ia[i] = number of column already counted */
ia[i] = indj+baseval;
/* for each row number in each column i */
for(j=old_ia[i];j<old_ia[i+1];j++)
/* if element is not diagonal
we add it in ja and we count it */
if(ja[j-baseval] != i+baseval)
{
ja[indj] = ja[j-baseval];
if (a != NULL)
a[indj] = a [j -baseval];
indj++;
}
}
ia[n] = indj+baseval;
assert( ia[n] <= old_ia[n] );
/*fprintf(stdout, "NNZ without diag = %ld \n", ia[n]);*/
memFree_null(old_ia);
}
/*
Function: z_csc_check_doubles
Check if the csc contains doubles and if correct if asked
Assumes that the CSC is sorted.
Assumes that the CSC is Fortran numeroted (base 1)
Parameters:
n - Size of the matrix.
colptr - Index in *rows* and *values* of the first element of each column
rows - row of each element
values - value of each element (Can be NULL)
dof - Number of degrees of freedom
flag - Indicate if user wants correction (<API_BOOLEAN>)
flagalloc - indicate if allocation on CSC uses internal malloc.
Returns:
API_YES - If the matrix contained no double or was successfully corrected.
API_NO - Otherwise.
*/
int z_csc_check_doubles(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t **rowptr,
pastix_complex64_t **values,
int dof,
int flag,
int flagalloc)
{
pastix_int_t i,j,k,d;
int doubles = 0;
pastix_int_t * tmprows = NULL;
pastix_complex64_t * tmpvals = NULL;
pastix_int_t index = 0;
pastix_int_t lastindex = 0;
ASSERT(values == NULL || dof > 0, MOD_SOPALIN);
ASSERT(flag == API_NO || flag == API_YES, MOD_SOPALIN);
ASSERT(colptr[0] == 1, MOD_SOPALIN);
ASSERT(n >= 0, MOD_SOPALIN);
for (i = 0; i < n; i++)
{
for (j = colptr[i]-1; j < colptr[i+1]-1; j = k)
{
(*rowptr)[index] = (*rowptr)[j];
if (values != NULL)
for (d = 0; d < dof*dof; d++)
(*values)[index*dof*dof+d] = (*values)[j*dof*dof+d];
k = j+1;
while (k < colptr[i+1]-1 && (*rowptr)[j] == (*rowptr)[k])
{
if (flag == API_NO)
return API_NO;
if (values != NULL)
for (d = 0; d < dof*dof; d++)
(*values)[index*dof*dof+d] += (*values)[k*dof*dof+d];
doubles++;
k++;
}
index++;
}
colptr[i] = lastindex+1;
lastindex = index;
}
if (flag == API_NO)
return API_YES;
ASSERT(index == colptr[n]-1-doubles, MOD_SOPALIN);
if (doubles > 0)
{
colptr[n] = lastindex+1;
if (flagalloc == API_NO)
{
MALLOC_EXTERN(tmprows, lastindex, pastix_int_t);
if (values != NULL)
MALLOC_EXTERN(tmpvals, lastindex*dof*dof, pastix_complex64_t);
}
else
{
MALLOC_INTERN(tmprows, lastindex, pastix_int_t);
if (values != NULL)
MALLOC_INTERN(tmpvals, lastindex*dof*dof, pastix_complex64_t);
}
memcpy(tmprows, *rowptr, lastindex*sizeof(pastix_int_t));
if (values != NULL)
memcpy(tmpvals, *values, lastindex*dof*dof*sizeof(pastix_complex64_t));
if (flagalloc == API_NO)
{
free(*rowptr);
if (values != NULL)
free(*values);
}
else
{
memFree_null(*rowptr);
if (values != NULL)
memFree_null(*values);
}
*rowptr = tmprows;
if (values != NULL)
*values = tmpvals;
}
return API_YES;
}
/*
Function: z_csc_checksym
Check if the CSC graph is symetric.
For all local column C,
For all row R in the column C,
We look in column R if we have the row number C.
If we can correct we had missing non zeros.
Assumes that the CSC is Fortran numbered (1 based).
Assumes that the matrix is sorted.
Parameters:
n - Number of local columns
colptr - Starting index of each columns in *ja*
rows - Row of each element.
values - Value of each element.
correct - Flag indicating if we can correct the symmetry.
alloc - indicate if allocation on CSC uses internal malloc.
dof - Number of degrees of freedom.
*/
int z_csc_checksym(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t **rows,
pastix_complex64_t **values,
int correct,
int alloc,
int dof)
{
pastix_int_t i,j,k,l,d;
pastix_int_t index1;
pastix_int_t index2;
int found;
pastix_int_t toaddsize;
pastix_int_t toaddcnt;
pastix_int_t * toadd = NULL;
pastix_int_t * tmpcolptr = NULL;
pastix_int_t * tmprows = NULL;
pastix_complex64_t * tmpvals = NULL;
/* For all local column C,
For all row R in the column C,
If the row number R correspond to a local column,
We look in column R if we have the row number C.
Else,
*/
toaddcnt = 0;
toaddsize = 0;
for (i = 0; i < n; i++)
{
for (j = (colptr)[i]-1; j < (colptr)[i+1]-1; j++)
{
if ((*rows)[j] != i+1)
{
/* not in diagonal */
k = (*rows)[j];
found = 0;
for (l = (colptr)[k-1]-1; l < (colptr)[k-1+1]-1; l++)
{
if (i+1 == (*rows)[l])
{
found = 1;
break;
}
if (i+1 < (*rows)[l])
{
/* The CSC is sorted */
found = 0;
break;
}
}
if (found == 0)
{
if (correct == API_NO)
return EXIT_FAILURE;
else
{
if (toaddsize == 0)
{
toaddsize = n/2;
MALLOC_INTERN(toadd, 2*toaddsize, pastix_int_t);
}
if (toaddcnt >= toaddsize)
{
toaddsize += toaddsize/2 + 1;
if (NULL ==
(toadd =
(pastix_int_t*)memRealloc(toadd,
2*toaddsize*sizeof(pastix_int_t))))
MALLOC_ERROR("toadd");
}
toadd[2*toaddcnt] = (*rows)[j];
toadd[2*toaddcnt + 1] = i+1;
/* fprintf(stdout, "Adding %ld, %ld\n", (long)(i+1), (long)(*rows)[j]); */
toaddcnt++;
}
}
}
}
}
if (toaddcnt > 0)
{
intSort2asc1(toadd, toaddcnt);
/* Correct here is API_YES, otherwise we would have return EXIT_FAILURE
Or toaddcnt == 0*/
MALLOC_INTERN(tmpcolptr, n + 1, pastix_int_t);
if (alloc == API_NO)
{
MALLOC_EXTERN(tmprows, colptr[n]-1 + toaddcnt, pastix_int_t);
if (values != NULL)
{
MALLOC_EXTERN(tmpvals, colptr[n]-1 + toaddcnt, pastix_complex64_t);
}
}
else
{
MALLOC_INTERN(tmprows, colptr[n]-1 + toaddcnt, pastix_int_t);
if (values != NULL)
{
MALLOC_INTERN(tmpvals, colptr[n]-1 + toaddcnt, pastix_complex64_t);
}
}
/* Build tmpcolptr
tmpcolptr[i+1] will contain the number of element of
the column i
*/
index1 = 0;
index2 = 0;
for (i = 0; i < n; i++)
{
tmpcolptr[i] = index2+1;
for (j = colptr[i]-1; j < colptr[i+1]-1; j++)
{
if (index1 < toaddcnt &&
(toadd[2*index1] == i+1) &&
(toadd[2*index1+1] < (*rows)[j]))
{
tmprows[index2] = toadd[2*index1+1];
if (values != NULL)
{
for (d = 0; d < dof*dof ; d++)
tmpvals[index2*dof*dof+d] = 0.0;
}
index1++;
j--; /* hack do not increment j this step of the loop */
}
else
{
tmprows[index2] = (*rows)[j];
if (values != NULL)
{
for (d = 0; d < dof*dof ; d++)
tmpvals[index2*dof*dof+d] = (*values)[j*dof*dof+d];
}
}
index2++;
}
while(index1 < toaddcnt && toadd[2*index1] == i+1)
{
tmprows[index2] = toadd[2*index1+1];
if (values != NULL)
{
for (d = 0; d < dof*dof ; d++)
tmpvals[index2*dof*dof+d] = 0.0;
}
index1++;
index2++;
}
}
tmpcolptr[n] = index2+1;
ASSERT((tmpcolptr[n] - 1) == (colptr[n] - 1 + toaddcnt), MOD_SOPALIN);
memcpy(colptr, tmpcolptr, (n+1)*sizeof(pastix_int_t));
memFree_null(tmpcolptr);
memFree_null(toadd);
if (alloc == API_NO)
{
free(*rows);
if (values != NULL)
{
free(*values);
}
}
else
{
memFree_null(*rows);
if (values != NULL)
{
memFree_null(*values);
}
}
*rows = tmprows;
if (values != NULL)
{
*values = tmpvals;
}
}
return EXIT_SUCCESS;
}
/*
Function: z_csc_colPerm
Performs column permutation on a CSC
Parameters:
n - Size of the matrix.
ia - Index of first element of each column in *ia* and *a*
ja - Rows of non zeros of the matrix.
a - Values of non zeros of the matrix.
cperm - Permutation to perform
*/
void z_csc_colPerm(pastix_int_t n, pastix_int_t *ia, pastix_int_t *ja, pastix_complex64_t *a, pastix_int_t *cperm)
{
pastix_int_t i, k;
pastix_int_t *newja = NULL;
pastix_int_t *newia = NULL;
pastix_complex64_t *newa = NULL;
int numflag, numflag2;
numflag = ia[0];
numflag2 = 1;
for(i=0;i<n;i++)
if(cperm[i] == 0)
{
numflag2 = 0;
break;
}
if(numflag2 != numflag)
{
errorPrint("CSC_colPerm: rperm not in same numbering than the CSC.");
exit(-1);
}
if(numflag == 1)
{
z_csc_Fnum2Cnum(ja, ia, n);
for(i=0;i<n;i++)
cperm[i]--;
}
MALLOC_INTERN(newia, n+1, pastix_int_t);
MALLOC_INTERN(newja, ia[n], pastix_int_t);
MALLOC_INTERN(newa, ia[n], pastix_complex64_t);
newia[0] = 0;
for(i=0;i<n;i++)
{
#ifdef DEBUG_KASS
ASSERT(cperm[i]>=0 && cperm[i] < n, MOD_KASS);
#endif
newia[cperm[i]+1] = ia[i+1]-ia[i];
}
#ifdef DEBUG_KASS
for(i=1;i<=n;i++)
ASSERT(newia[i] >0, MOD_KASS);
#endif
for(i=1;i<=n;i++)
newia[i] += newia[i-1];
#ifdef DEBUG_KASS
ASSERT(newia[n] == ia[n], MOD_KASS);
#endif
for(i=0;i<n;i++)
{
k = cperm[i];
#ifdef DEBUG_KASS
ASSERT(newia[k+1]-newia[k] == ia[i+1]-ia[i], MOD_KASS);
#endif
memcpy(newja + newia[k], ja + ia[i], sizeof(pastix_int_t)*(ia[i+1]-ia[i]));
memcpy(newa + newia[k], a + ia[i], sizeof(pastix_complex64_t)*(ia[i+1]-ia[i]));
}
memcpy(ia, newia, sizeof(pastix_int_t)*(n+1));
memcpy(ja, newja, sizeof(pastix_int_t)*ia[n]);
memcpy(a, newa, sizeof(pastix_complex64_t)*ia[n]);
memFree(newia);
memFree(newja);
memFree(newa);
if(numflag == 1)
{
z_csc_Cnum2Fnum(ja, ia, n);
for(i=0;i<n;i++)
cperm[i]++;
}
}
/*
Function: z_csc_colScale
Moved from kass, only used in MC64
*/
void z_csc_colScale(pastix_int_t n,
pastix_int_t *ia,
pastix_int_t *ja,
pastix_complex64_t *a,
pastix_complex64_t *dcol)
{
pastix_int_t i, j;
int numflag;
pastix_complex64_t d;
numflag = ia[0];
if(numflag == 1)
z_csc_Fnum2Cnum(ja, ia, n);
for(i=0;i<n;i++)
{
d = dcol[i];
for(j=ia[i];j<ia[i+1];j++)
{
/***@@@ OIMBE DSCAL **/
a[j] *= d;
}
}
if(numflag == 1)
z_csc_Cnum2Fnum(ja, ia, n);
}
/*
Function: z_csc_rowScale
Moved from kass, only used in MC64
*/
void z_csc_rowScale(pastix_int_t n,
pastix_int_t *ia,
pastix_int_t *ja,
pastix_complex64_t *a,
pastix_complex64_t *drow)
{
pastix_int_t i, j;
int numflag;
numflag = ia[0];
if(numflag == 1)
z_csc_Fnum2Cnum(ja, ia, n);
for(i=0;i<n;i++)
{
for(j=ia[i];j<ia[i+1];j++)
{
#ifdef DEBUG_KASS
ASSERT(ja[j]>0 && ja[j] <n, MOD_KASS);
#endif
a[j] *= drow[ja[j]];
}
}
if(numflag == 1)
z_csc_Cnum2Fnum(ja, ia, n);
}
/*
* z_csc_sort:
*
* Sort CSC columns
*
* Parameters:
* n - Number of columns
* ia - Index of first element of each column in *ia*.
* ja - Rows of each non zeros.
* a - Values of each non zeros.
*/
void z_csc_sort(pastix_int_t n,
pastix_int_t *ia,
pastix_int_t *ja,
pastix_complex64_t *a,
pastix_int_t ndof)
{
pastix_int_t i;
int numflag;
pastix_int_t ndof2 = ndof * ndof;
void * sortptr[3];
numflag = ia[0];
if(numflag == 1)
z_csc_Fnum2Cnum(ja, ia, n);
if (a != NULL)
{
for(i=0;i<n;i++)
{
sortptr[0] = &ja[ia[i]];
sortptr[1] = &a[ia[i]*ndof2];
sortptr[2] = &ndof2;
z_qsortIntFloatAsc(sortptr, ia[i+1] - ia[i]);
}
}
else
{
for(i=0;i<n;i++)
intSort1asc1(&ja[ia[i]], ia[i+1] - ia[i]);
}
if(numflag == 1)
z_csc_Cnum2Fnum(ja, ia, n);
}
/*
Function: z_csc_Fnum2Cnum
Convert CSC numbering from fortran numbering to C numbering.
Parameters:
ja - Rows of each element.
ia - First index of each column in *ja*
n - Number of columns
*/
void z_csc_Fnum2Cnum(pastix_int_t *ja,
pastix_int_t *ia,
pastix_int_t n)
{
pastix_int_t i, j;
for(i=0;i<=n;i++)
ia[i]--;
for(i=0;i<n;i++)
for(j=ia[i];j<ia[i+1];j++)
ja[j]--;
}
/*
Function: z_csc_Cnum2Fnum
Convert CSC numbering from C numbering to Fortran numbering.
Parameters:
ja - Rows of each element.
ia - First index of each column in *ja*
n - Number of columns
*/
void z_csc_Cnum2Fnum(pastix_int_t *ja,
pastix_int_t *ia,
pastix_int_t n)
{
pastix_int_t i, j;
for(i=0;i<n;i++)
for(j=ia[i];j<ia[i+1];j++)
ja[j]++;
for(i=0;i<=n;i++)
ia[i]++;
}
/*
Function: z_csc_buildZerosAndNonZerosGraphs
Separate a graph in two graphs, following
wether the diagonal term of a column is null or not.
Parameters:
n, colptr, rows, values - The initial CSC
n_nz, colptr_nz, rows_nz - The graph of the non-null diagonal part.
n_z, colptr_z, rows_z - The graph of the null diagonal part.
perm - Permutation to go from the first graph to
the one composed of the two graph concatenated.
revperm - Reverse permutation tabular.
criteria - Value beside which a number is said null.
*/
int z_csc_buildZerosAndNonZerosGraphs(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t *rows,
pastix_complex64_t *values,
pastix_int_t *n_nz,
pastix_int_t **colptr_nz,
pastix_int_t **rows_nz,
pastix_int_t *n_z,
pastix_int_t **colptr_z,
pastix_int_t **rows_z,
pastix_int_t *perm,
pastix_int_t *revperm,
double criteria)
{
pastix_int_t itercol;
pastix_int_t iterrow;
pastix_int_t ncoefszeros = 0;
pastix_int_t ncoefsnzeros = 0;
pastix_int_t itercol_nz = 0;
pastix_int_t itercol_z = 0;
int seen;
pastix_int_t cntrows;
for (itercol = 0; itercol <n; itercol++)
{
seen = 0;
for (iterrow = colptr[itercol]-1; iterrow < colptr[itercol+1]-1; iterrow++)
{
if (itercol == rows[iterrow] -1 )
{
if (ABS_FLOAT(values[iterrow]) < criteria)
{
(*n_z) ++;
ncoefszeros += colptr[itercol+1] - colptr[itercol];
seen = 1;
}
else
{
(*n_nz) ++;
ncoefsnzeros += colptr[itercol+1] - colptr[itercol];
seen = 1;
}
break;
}
}
if (colptr[itercol+1] == colptr[itercol]) /* empty column */
{
(*n_z)++;
seen = 1;
}
if (seen == 0)/* column without diag*/
{
(*n_z)++;
ncoefszeros += colptr[itercol+1] - colptr[itercol];
}
}
fprintf(stdout, "n_z %ld\n", (long)*n_z);
fprintf(stdout, "n_nz %ld\n", (long)*n_nz);
ASSERT(*n_z+*n_nz == n, MOD_SOPALIN);
if (*n_z == 0 || *n_nz == 0)
return PASTIX_SUCCESS;
for (itercol = 0; itercol <n; itercol++)
{
seen = 0;
for (iterrow = colptr[itercol]-1; iterrow < colptr[itercol+1]-1; iterrow++)
{
if (itercol == rows[iterrow] -1 )
{
if (ABS_FLOAT(values[iterrow]) < criteria)
{
perm[itercol] = (*n_nz) + itercol_z + 1;
itercol_z++;
seen = 1;
}
else
{
perm[itercol] = itercol_nz + 1;
itercol_nz++;
seen = 1;
}
}
}
if (colptr[itercol] == colptr[itercol+1])
{ /* empty column */
perm[itercol] = (*n_nz) + itercol_z + 1;
itercol_z++;
seen =1;
}
if (seen == 0)/* column without diag*/
{
perm[itercol] = (*n_nz) + itercol_z + 1;
itercol_z++;
}
}
ASSERT(itercol_nz == *n_nz, MOD_SOPALIN);
ASSERT(itercol_z == *n_z, MOD_SOPALIN);
for(itercol = 0; itercol < n; itercol++)
revperm[perm[itercol]-1] = itercol + 1;
MALLOC_INTERN(*colptr_nz, *n_nz + 1, pastix_int_t);
MALLOC_INTERN(*rows_nz, ncoefsnzeros, pastix_int_t);
cntrows = 0;
for (itercol = 0; itercol <*n_nz; itercol++)
{
(*colptr_nz)[itercol] = cntrows + 1;
for (iterrow = colptr[revperm[itercol]-1]-1; iterrow < colptr[revperm[itercol]-1+1]-1; iterrow++)
{
if (perm[rows[iterrow]-1] - 1 < *n_nz )
{
(*rows_nz)[cntrows] = perm[rows[iterrow]-1];
cntrows++;
}
}
}
(*colptr_nz)[*n_nz] = cntrows+1;
MALLOC_INTERN(*colptr_z, *n_z + 1, pastix_int_t);
MALLOC_INTERN(*rows_z, ncoefszeros, pastix_int_t);
cntrows = 0;
for (itercol = 0; itercol <*n_z; itercol++)
{
(*colptr_z)[itercol] = cntrows + 1;
for (iterrow = colptr[revperm[itercol+*n_nz]-1]-1; iterrow < colptr[revperm[itercol+*n_nz]-1+1]-1; iterrow++)
{
if (perm[rows[iterrow]-1] > *n_nz )
{
(*rows_z)[cntrows] = perm[rows[iterrow]-1] - *n_nz;
cntrows++;
}
}
}
(*colptr_z)[*n_z] = cntrows+1;
return PASTIX_SUCCESS;
}
/*
Function: z_csc_isolate
Isolate a list of unknowns at the end of the CSC.
Parameters:
n - Number of columns.
colptr - Index of first element of each column in *ia*.
rows - Rows of each non zeros.
n_isolate - Number of unknow to isolate.
isolate_list - List of unknown to isolate.
perm - permutation tabular.
revperm - reverse permutation tabular.
*/
int z_csc_isolate(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t *rows,
pastix_int_t n_isolate,
pastix_int_t *isolate_list,
pastix_int_t *perm,
pastix_int_t *revperm)
{
pastix_int_t itercol;
pastix_int_t iterrow;
pastix_int_t iter_isolate = 0;
pastix_int_t iter_non_isolate = 0;
pastix_int_t *tmpcolptr = NULL;
pastix_int_t *tmprows = NULL;
if (n_isolate == 0)
{
errorPrintW("No schur complement\n");
return PASTIX_SUCCESS;
}
intSort1asc1(isolate_list, n_isolate);
for (itercol = 0; itercol <n; itercol++)
{
if (iter_isolate < n_isolate &&
itercol == isolate_list[iter_isolate]-1)
{
revperm[n-n_isolate+iter_isolate] = itercol;
iter_isolate++;
}
else
{
revperm[iter_non_isolate] = itercol;
iter_non_isolate++;
}
}
ASSERT(iter_non_isolate == n - n_isolate, MOD_SOPALIN);
ASSERT(iter_isolate == n_isolate, MOD_SOPALIN);
MALLOC_INTERN(tmpcolptr, n - n_isolate + 1, pastix_int_t);
memset(tmpcolptr, 0, (n - n_isolate + 1)*sizeof(pastix_int_t));
for(itercol = 0; itercol < n; itercol++)
perm[revperm[itercol]] = itercol;
for(itercol = 0; itercol < n; itercol++)
{
ASSERT(perm[itercol] < n, MOD_SOPALIN);
ASSERT(perm[itercol] > -1, MOD_SOPALIN);
}
tmpcolptr[0] = 1;
for (itercol = 0; itercol <n; itercol++)
{
if (perm[itercol] < n - n_isolate)
{
for (iterrow = colptr[itercol]-1; iterrow < colptr[itercol+1]-1; iterrow ++)
{
/* Count edges in each column of the new graph */
if (perm[rows[iterrow]-1] < n-n_isolate)
{
tmpcolptr[perm[itercol]+1]++;
}
}
}
}
for (itercol = 0; itercol <n - n_isolate; itercol++)
tmpcolptr[itercol+1] += tmpcolptr[itercol];
MALLOC_INTERN(tmprows, tmpcolptr[n- n_isolate]-1, pastix_int_t);
for (itercol = 0; itercol <n; itercol++)
{
if (perm[itercol] < n - n_isolate)
{
for (iterrow = colptr[itercol]-1; iterrow < colptr[itercol+1]-1; iterrow ++)
{
/* Count edges in each column of the new graph */
if (perm[rows[iterrow]-1] < n-n_isolate)
{
tmprows[tmpcolptr[perm[itercol]]-1] = perm[rows[iterrow]-1]+1;
tmpcolptr[perm[itercol]]++;
}
}
}
}
/* restore tmpcolptr */
for (itercol = 1; itercol <n - n_isolate ; itercol++)
{
tmpcolptr[n - n_isolate - itercol] = tmpcolptr[n - n_isolate - itercol - 1];
}
tmpcolptr[0] = 1;
ASSERT(colptr[n] >= tmpcolptr[n-n_isolate], MOD_SOPALIN);
memcpy(colptr, tmpcolptr, (n-n_isolate + 1)*sizeof(pastix_int_t));
memcpy(rows, tmprows, (colptr[n-n_isolate]-1)*sizeof(pastix_int_t));
memFree_null(tmpcolptr);
memFree_null(tmprows);
return PASTIX_SUCCESS;
}
/*
Function: csc_save
Save a csc on disk.
Parameters:
n - number of columns
colptr - First cscd starting index of each column in *ja* and *a*
rows - Row of each element in first CSCD
values - value of each cscd in first CSCD (can be NULL)
dof - Number of degrees of freedom
outfile - Output stream.
Return:
PASTIX_SUCCESS
*/
int z_csc_save(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t *rows,
pastix_complex64_t *values,
int dof,
FILE *outfile)
{
pastix_int_t i;
fprintf(outfile, "%ld %ld %d\n", (long)n, (long)dof, ((values == NULL)?0:1));
/* Copie du colptr */
for (i=0; i<n+1; i++)
{
fprintf(outfile, "%ld ", (long)colptr[i]);
if (i%4 == 3) fprintf(outfile, "\n");
}
if ((i-1)%4 !=3) fprintf(outfile, "\n");
/* Copie de JA */
for (i=0; i<colptr[n]-1; i++)
{
fprintf(outfile, "%ld ", (long)rows[i]);
if (i%4 == 3) fprintf(outfile, "\n");
}
if ((i-1)%4 !=3) fprintf(outfile, "\n");
/* Copie de Avals */
if (values != NULL)
{
for (i=0; i<(colptr[n]-1)*dof*dof; i++)
{
#ifdef TYPE_COMPLEX
fprintf(outfile, "%lg %lg ", (double)(creal(values[i])), (double)(cimag(values[i])));
#else
fprintf(outfile, "%lg ", (double)(values[i]));
#endif
if (i%4 == 3) fprintf(outfile, "\n");
}
if ((i-1)%4 !=3) fprintf(outfile, "\n");
}
return PASTIX_SUCCESS;
}
/*
Function: csc_load
Load a csc from disk.
Fill *n*, *colptr*, *rows*, *values* and *dof* from *infile*.
Parameters:
n - number of columns
colptr - First cscd starting index of each column in *ja* and *a*
rows - Row of each element in first CSCD
values - value of each cscd in first CSCD (can be NULL)
dof - Number of degrees of freedom
outfile - Output stream.
Return:
PASTIX_SUCCESS
*/
int z_csc_load(pastix_int_t *n,
pastix_int_t **colptr,
pastix_int_t **rows,
pastix_complex64_t **values,
int *dof,
FILE *infile)
{
int hasval;
long tmp1, tmp2, tmp3, tmp4;
double tmpflt1, tmpflt2, tmpflt3, tmpflt4;
#ifdef TYPE_COMPLEX
double tmpflt5, tmpflt6, tmpflt7, tmpflt8;
#endif
pastix_int_t i;
if (3 != fscanf(infile, "%ld %ld %d\n", &tmp1, &tmp2, &hasval)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
*n = (pastix_int_t)tmp1;
*dof = (int)tmp2;
/* Copie de IA */
*colptr = NULL;
MALLOC_INTERN(*colptr, *n+1, pastix_int_t);
for (i=0; i<*n+1+1-4; i+=4)
{
if (4 != fscanf(infile, "%ld %ld %ld %ld", &tmp1, &tmp2, &tmp3, &tmp4)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*colptr)[i ] = tmp1;
(*colptr)[i+1] = tmp2;
(*colptr)[i+2] = tmp3;
(*colptr)[i+3] = tmp4;
}
switch (*n +1 - i)
{
case 3:
if (3 != fscanf(infile, "%ld %ld %ld", &tmp1, &tmp2, &tmp3)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*colptr)[i ] = tmp1;
(*colptr)[i+1] = tmp2;
(*colptr)[i+2] = tmp3;
break;
case 2:
if (2 != fscanf(infile, "%ld %ld", &tmp1, &tmp2)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*colptr)[i ] = tmp1;
(*colptr)[i+1] = tmp2;
break;
case 1:
if (1 != fscanf(infile, "%ld", &tmp1)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*colptr)[i ] = tmp1;
break;
}
/* Copie de JA */
(*rows) = NULL;
MALLOC_INTERN(*rows, (*colptr)[*n]-(*colptr)[0], pastix_int_t);
for (i=0; i< (*colptr)[*n]-(*colptr)[0]+1-4; i+=4)
{
if (4 != fscanf(infile, "%ld %ld %ld %ld", &tmp1, &tmp2, &tmp3, &tmp4)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*rows)[i ] = tmp1;
(*rows)[i+1] = tmp2;
(*rows)[i+2] = tmp3;
(*rows)[i+3] = tmp4;
}
switch ( (*colptr)[*n]-(*colptr)[0] - i)
{
case 3:
if (3 != fscanf(infile, "%ld %ld %ld", &tmp1, &tmp2, &tmp3)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*rows)[i ] = tmp1;
(*rows)[i+1] = tmp2;
(*rows)[i+2] = tmp3;
break;
case 2:
if (2 != fscanf(infile, "%ld %ld", &tmp1, &tmp2)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*rows)[i ] = tmp1;
(*rows)[i+1] = tmp2;
break;
case 1:
if (1 != fscanf(infile, "%ld", &tmp1)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*rows)[i ] = tmp1;
break;
}
/* Copie de Avals */
if (hasval)
{
(*values) = NULL;
MALLOC_INTERN(*values, (*colptr)[*n]-(*colptr)[0], pastix_complex64_t);
for (i=0; i< (*colptr)[*n]-(*colptr)[0]+1-4; i+=4)
{
#ifdef TYPE_COMPLEX
if (8 != fscanf(infile, "%lg %lg %lg %lg %lg %lg %lg %lg",
&tmpflt1, &tmpflt2, &tmpflt3, &tmpflt4,
&tmpflt5, &tmpflt6, &tmpflt7, &tmpflt8)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*values)[i ] = (pastix_complex64_t)(tmpflt1 + I * tmpflt2);
(*values)[i+1] = (pastix_complex64_t)(tmpflt3 + I * tmpflt4);
(*values)[i+2] = (pastix_complex64_t)(tmpflt5 + I * tmpflt6);
(*values)[i+3] = (pastix_complex64_t)(tmpflt7 + I * tmpflt8);
#else
if (4 != fscanf(infile, "%lg %lg %lg %lg",
&tmpflt1, &tmpflt2, &tmpflt3, &tmpflt4)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*values)[i ] = (pastix_complex64_t)tmpflt1;
(*values)[i+1] = (pastix_complex64_t)tmpflt2;
(*values)[i+2] = (pastix_complex64_t)tmpflt3;
(*values)[i+3] = (pastix_complex64_t)tmpflt4;
#endif
}
switch ( (*colptr)[*n]-(*colptr)[0] - i )
{
case 3:
#ifdef TYPE_COMPLEX
if (6 != fscanf(infile, "%lg %lg %lg %lg %lg %lg",
&tmpflt1, &tmpflt2, &tmpflt3, &tmpflt4,
&tmpflt5, &tmpflt6)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*values)[i ] = (pastix_complex64_t)(tmpflt1 + I * tmpflt2);
(*values)[i+1] = (pastix_complex64_t)(tmpflt3 + I * tmpflt4);
(*values)[i+2] = (pastix_complex64_t)(tmpflt5 + I * tmpflt6);
#else
if (3 != fscanf(infile, "%lg %lg %lg",
&tmpflt1, &tmpflt2, &tmpflt3)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*values)[i ] = (pastix_complex64_t)tmpflt1;
(*values)[i+1] = (pastix_complex64_t)tmpflt2;
(*values)[i+2] = (pastix_complex64_t)tmpflt3;
#endif
break;
case 2:
#ifdef TYPE_COMPLEX
if (4 != fscanf(infile, "%lg %lg %lg %lg",
&tmpflt1, &tmpflt2, &tmpflt3, &tmpflt4)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*values)[i ] = (pastix_complex64_t)(tmpflt1 + I * tmpflt2);
(*values)[i+1] = (pastix_complex64_t)(tmpflt3 + I * tmpflt4);
#else
if (2 != fscanf(infile, "%lg %lg",
&tmpflt1, &tmpflt2)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*values)[i ] = (pastix_complex64_t)tmpflt1;
(*values)[i+1] = (pastix_complex64_t)tmpflt2;
#endif
break;
case 1:
#ifdef TYPE_COMPLEX
if (2 != fscanf(infile, "%lg %lg",
&tmpflt1, &tmpflt2)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*values)[i ] = (pastix_complex64_t)(tmpflt1 + I * tmpflt2);
#else
if (1 != fscanf(infile, "%lg",
&tmpflt1)){
errorPrint("CSCD badly formated");
return EXIT_FAILURE;
}
(*values)[i ] = (pastix_complex64_t)tmpflt1;
#endif
break;
}
}
return PASTIX_SUCCESS;
}
/**
* PaStiX CSC management routines.
*
* PaStiX is a software package provided by Inria Bordeaux - Sud-Ouest,
* LaBRI, University of Bordeaux 1 and IPB.
*
* @version 1.0.0
* @author Mathieu Faverge
* @author Pierre Ramet
* @author Xavier Lacoste
* @date 2011-11-11
* @precisions normal z -> c d s
*
**/
#ifndef CSC_UTILS_H
#define CSC_UTILS_H
/**
*
* @ingroup csc_utils
*
* Modify the CSC to a symetric graph one.
* Don't use it on a lower symetric CSC
* it would give you all the CSC upper + lower.
*
* @param[in] n Number of columns/vertices
* @param[in] ia Starting index of each column in *ja* and *a*
* @param[in] ja Row index of each element
* @param[in] a Value of each element,can be NULL
* @param[out] newn New number of column
* @param[out] newia Starting index of each column in *ja* and *a*
* @param[out] newja Row index of each element
* @param[out] newa Value of each element,can be NULL
**/
int z_csc_symgraph ( pastix_int_t n,
const pastix_int_t *ia,
const pastix_int_t *ja,
const pastix_complex64_t *a,
pastix_int_t *newn,
pastix_int_t **newia,
pastix_int_t **newja,
pastix_complex64_t **newa);
/**
*
* @ingroup csc_utils
*
* Modify the CSC to a symetric graph one.
* Don't use it on a lower symetric CSC
* it would give you all the CSC upper + lower.
*
* Internal function.
*
* @param[in] n Number of columns/vertices
* @param[in] ia Starting index of each column in *ja* and *a*
* @param[in] ja Row index of each element
* @param[in] a Value of each element,can be NULL
* @param[out] newn New number of column
* @param[out] newia Starting index of each column in *ja* and *a*
* @param[out] newja Row index of each element
* @param[out] newa Value of each element,can be NULL
* @param[in] malloc_flag flag to indicate if function call is intern to pastix
* or extern.
**/
int z_csc_symgraph_int ( pastix_int_t n,
const pastix_int_t *ia,
const pastix_int_t *ja,
const pastix_complex64_t *a,
pastix_int_t *newn,
pastix_int_t **newia,
pastix_int_t **newja,
pastix_complex64_t **newa,
int malloc_flag);
/**
*
* @ingroup csc_utils
*
* Supress diagonal term.
* After this call, *ja* can be reallocated to *ia[n] -1*.
*
* @param[in] baseval Initial numbering value (0 or 1).
* @param[in] n Number of columns/vertices
* @param[in,out] ia Starting index of each column in *ja* and *a*
* @param[in,out] ja Row index of each element
* @param[in,out] a Value of each element,can be NULL
**/
void z_csc_noDiag( pastix_int_t baseval,
pastix_int_t n,
pastix_int_t *ia,
pastix_int_t *ja,
pastix_complex64_t *a);
/**
*
* @ingroup csc_utils
*
* Check if the csc contains doubles and if correct if asked
*
* Assumes that the CSC is sorted.
*
* Assumes that the CSC is Fortran numeroted (base 1)
*
* @param[in] n Size of the matrix.
* @param[in,out] colptr Index in *rows* and *values* of the first element
* of each column
* @param[in,out] rows row of each element
* @param[in,out] values value of each element
* @param[in] dof Number of degrees of freedom
* @param[in] flag Indicate if user wants correction (<API_BOOLEAN>)
* @param[in] flagalloc indicate if allocation on CSC uses internal malloc.
*
*
* @Returns:
* API_YES - If the matrix contained no double or was successfully corrected.
* API_NO - Otherwise.
*/
int z_csc_check_doubles(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t **rows,
pastix_complex64_t **values,
int dof,
int flag,
int flagalloc);
/**
*
* @ingroup csc_utils
*
* Check if the CSC graph is symetric.
*
* For all local column C,
*
* For all row R in the column C,
*
* We look in column R if we have the row number C.
*
* If we can correct we had missing non zeros.
*
* Assumes that the CSC is Fortran numbered (1 based).
*
* Assumes that the matrix is sorted.
*
* @param[in] n Number of local columns
* @param[in,out] colptr Starting index of each columns in *ja*
* @param[in,out] rows Row of each element.
* @param[in,out] values Value of each element.
* @param[in] correct Flag indicating if we can correct the symmetry.
* @param[in] alloc indicate if allocation on CSC uses internal malloc.
* @param[in] dof Number of degrees of freedom.
*/
int z_csc_checksym(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t **rows,
pastix_complex64_t **values,
int correct,
int alloc,
int dof);
void z_csc_colPerm(pastix_int_t n, pastix_int_t *ia, pastix_int_t *ja, pastix_complex64_t *a, pastix_int_t *cperm);
void z_csc_colScale(pastix_int_t n, pastix_int_t *ia, pastix_int_t *ja, pastix_complex64_t *a, pastix_complex64_t *dcol);
void z_csc_rowScale(pastix_int_t n, pastix_int_t *ia, pastix_int_t *ja, pastix_complex64_t *a, pastix_complex64_t *drow);
void z_csc_sort(pastix_int_t n, pastix_int_t *ia, pastix_int_t *ja, pastix_complex64_t *a, pastix_int_t ndof);
void z_csc_Fnum2Cnum(pastix_int_t *ja, pastix_int_t *ia, pastix_int_t n);
void z_csc_Cnum2Fnum(pastix_int_t *ja, pastix_int_t *ia, pastix_int_t n);
/*
Function: CSC_buildZerosAndNonZerosGraphs
Separate a graph in two graphs, following
wether the diagonal term of a column is null or not.
Parameters:
n, colptr, rows, values - The initial CSC
n_nz, colptr_nz, rows_nz - The graph of the non-null diagonal part.
n_z, colptr_z, rows_z - The graph of the null diagonal part.
perm - Permutation to go from the first graph to
the one composed of the two graph concatenated.
revperm - Reverse permutation tabular.
criteria - Value beside which a number is said null.
*/
int z_csc_buildZerosAndNonZerosGraphs(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t *rows,
pastix_complex64_t *values,
pastix_int_t *n_nz,
pastix_int_t **colptr_nz,
pastix_int_t **rows_nz,
pastix_int_t *n_z,
pastix_int_t **colptr_z,
pastix_int_t **rows_z,
pastix_int_t *perm,
pastix_int_t *revperm,
double criteria);
/*
Function: CSC_isolate
Isolate a list of unknowns at the end of the CSC.
Parameters:
n - Number of columns.
colptr - Index of first element of each column in *ia*.
rows - Rows of each non zeros.
n_isolate - Number of unknow to isolate.
isolate_list - List of unknown to isolate.
*/
int z_csc_isolate(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t *rows,
pastix_int_t n_isolate,
pastix_int_t *isolate_list,
pastix_int_t *perm,
pastix_int_t *revperm);
/*
Function: csc_save
Save a csc on disk.
Parameters:
n - number of columns
colptr - First cscd starting index of each column in *ja* and *a*
rows - Row of each element in first CSCD
values - value of each cscd in first CSCD (can be NULL)
dof - Number of degrees of freedom
outfile - Output stream.
Return:
NO_ERR
*/
int z_csc_save(pastix_int_t n,
pastix_int_t * colptr,
pastix_int_t * rows,
pastix_complex64_t * values,
int dof,
FILE * outfile);
/*
Function: csc_load
Load a csc from disk.
Fill *n*, *colptr*, *rows*, *values* and *dof* from *infile*.
Parameters:
n - number of columns
colptr - First cscd starting index of each column in *ja* and *a*
rows - Row of each element in first CSCD
values - value of each cscd in first CSCD (can be NULL)
dof - Number of degrees of freedom
outfile - Output stream.
Return:
NO_ERR
*/
int z_csc_load(pastix_int_t * n,
pastix_int_t ** colptr,
pastix_int_t ** rows,
pastix_complex64_t ** values,
int * dof,
FILE * infile);
#endif /* CSC_UTILS_H */
This diff is collapsed.
/**
* PaStiX distributed CSC management routines.
*
* PaStiX is a software package provided by Inria Bordeaux - Sud-Ouest,
* LaBRI, University of Bordeaux 1 and IPB.
*
* @version 1.0.0
* @author Mathieu Faverge
* @author Pierre Ramet
* @author Xavier Lacoste
* @date 2011-11-11
* @precisions normal z -> c d s
*
**/
#ifndef Z_CSCD_UTILS_H
#define Z_CSCD_UTILS_H
/*
* Enum: CSCD_OPERATIONS
*
* Operation when adding CSCD
*
* CSCD_ADD - Add coefficient values.
* CSCD_KEEP - Keep value from first CSCD.
* CSCD_MAX - Keep maximum of first and second CSCD.
* CSCD_MIN - Keep minimum of first and second CSCD.
* CSCD_OVW - Overwrite with second CSCD value.
*/
enum CSCD_OPERATIONS {
CSCD_ADD,
CSCD_KEEP,
CSCD_MAX,
CSCD_MIN,
CSCD_OVW
};
typedef enum CSCD_OPERATIONS CSCD_OPERATIONS_t;
/*
* Enum: CSC_DISPATCH_OP
*
* Operation when dispatching the csc into a cscd
*
* CSC_DISP_SIMPLE - Reparts linearly the columns over the proc.
* CSC_DISP_CYCLIC - Reparts cyclicly the columns over the proc.
*
*/
enum CSC_DISPATCH_OP {
CSC_DISP_SIMPLE,
CSC_DISP_CYCLIC
};
typedef enum CSC_DISPATCH_OP CSCD_DISPATCH_OP_t;
/* Section: Functions */
/*
* Function: z_csc_dispatch
*
* Distribute a CSC to a CSCD
*
* Parameters:
* gN - global number of columns
* gcolptr - global starting index of each column in grows ans gavals.
* grows - global rows of each element.
* gavals - global values of each element.
* gperm - global permutation tabular.
* ginvp - global reverse permutation tabular.
* lN - local number of columns (output).
* lcolptr - starting index of each local column (output).
* lrowptr - row number of each local element (output).
* lavals - values of each local element (output).
* lrhs - local part of the right hand side (output).
* lperm - local part of the permutation tabular (output).
* loc2glob - global numbers of local columns (before permutation).
* dispatch - choose how to dispatch the csc
* pastix_comm - PaStiX MPI communicator.
*/
void z_csc_dispatch(pastix_int_t gN, pastix_int_t * gcolptr, pastix_int_t * grow, pastix_complex64_t * gavals,
pastix_complex64_t * grhs, pastix_int_t * gperm, pastix_int_t * ginvp,
pastix_int_t *lN, pastix_int_t ** lcolptr, pastix_int_t ** lrow, pastix_complex64_t ** lavals,
pastix_complex64_t ** lrhs, pastix_int_t ** lperm,
pastix_int_t **loc2glob, int dispatch, MPI_Comm pastix_comm);
/*
* Function: csc_cyclic_distribution
*
* Distribute the CSC cyclicaly.
*
* Parameters:
* column - column number to distribute
* columnnbr - Number of colmuns.
* pastix_comm - PaStiX MPI communicator
*
* Return:
* owner of the column (column%commSize)
*/
pastix_int_t z_csc_cyclic_distribution(pastix_int_t column, pastix_int_t columnnbr, MPI_Comm pastix_comm);
/*
* Function: csc_simple_distribution
*
* Distribute the CSC.
* First columns are for first proc and so on.
*
* Parameters:
* column - column number to distribute
* columnnbr - Number of colmuns.
* pastix_comm - PaStiX MPI communicator
*
* Return:
* owner of the column (column/commSize)
*/
pastix_int_t z_csc_simple_distribution(pastix_int_t column, pastix_int_t columnnbr, MPI_Comm pastix_comm);
/*
* Function: cscd_symgraph
*
* Check if the CSCD graph is symetric.
*
* Parameters:
* n - Number of local columns
* ia - Starting index of each columns in *ja* and *a*
* ja - Row of each element.
* a - Values of each element.
* newn - New number of local columns
* newia - Starting index of each columns in *newja* and *newa*
* newja - Row of each element.
* newa - Values of each element.
* l2g - global number of each local column.
* malloc_flag - flag to indicate if function call is intern to pastix or extern.
*/
int z_cscd_symgraph(pastix_int_t n, const pastix_int_t *ia, const pastix_int_t *ja, const pastix_complex64_t *a,
pastix_int_t * newn, pastix_int_t ** newia, pastix_int_t ** newja, pastix_complex64_t ** newa,
pastix_int_t * l2g, MPI_Comm comm);
/*
* Function: cscd_addlocal
*
* Add second cscd to first cscd into third cscd (unallocated)
*
* Parameters:
* n - First cscd size
* ia - First cscd starting index of each column in *ja* and *a*
* ja - Row of each element in first CSCD
* a - value of each cscd in first CSCD (can be NULL)
* l2g - local 2 global column numbers for first cscd
* addn - CSCD to add size
* addia - CSCD to add starting index of each column in *addja* and *adda*
* addja - Row of each element in second CSCD
* adda - value of each cscd in second CSCD (can be NULL -> add 0)
* addl2g - local 2 global column numbers for second cscd
* newn - new cscd size (same as first)
* newia - CSCD to add starting index of each column in *newja* and *newwa*
* newja - Row of each element in third CSCD
* newa - value of each cscd in third CSCD
* OP - Operation to manage common CSCD coefficients.
* dof - Number of degrees of freedom.
*/
int z_cscd_addlocal(pastix_int_t n , pastix_int_t * ia , pastix_int_t * ja , pastix_complex64_t * a , pastix_int_t * l2g,
pastix_int_t addn, pastix_int_t * addia, pastix_int_t * addja, pastix_complex64_t * adda, pastix_int_t * addl2g,
pastix_int_t * newn, pastix_int_t ** newia, pastix_int_t ** newja, pastix_complex64_t ** newa, CSCD_OPERATIONS_t OP, int dof);
/**
* Function: csc2cscd
*
* Transform a csc to a cscd.
* Allocate the CSCD.
* If grhs == NULL forget right hand side part.
* If gperm == NULL forget permutation and reverse permutation part.
*
* Parameters:
* gN - global number of columns
* gcolptr - global starting index of each column in grows ans gavals.
* grows - global rows of each element.
* gavals - global values of each element.
* gperm - global permutation tabular.
* ginvp - global reverse permutation tabular.
* lN - local number of columns.
* lcolptr - starting index of each local column.
* lrowptr - row number of each local element.
* lavals - values of each local element.
* lrhs - local part of the right hand side (output).
* lperm - local part of the permutation tabular (output).
* linvp - local part of the reverse permutation tabular (output).
* loc2glob - global numbers of local columns (before permutation).
*/
void z_csc2cscd(pastix_int_t gN, pastix_int_t * gcolptr, pastix_int_t * grow, pastix_complex64_t * gavals,
pastix_complex64_t * grhs, pastix_int_t * gperm, pastix_int_t * ginvp,
pastix_int_t lN, pastix_int_t ** lcolptr, pastix_int_t ** lrow, pastix_complex64_t ** lavals,
pastix_complex64_t ** lrhs, pastix_int_t ** lperm, pastix_int_t ** linvp,
pastix_int_t *loc2glob);
/**
* Function: cscd2csc
*
* Transform a cscd to a csc.
* colptr2, row2, avals2, rhs2, perm2, invp2 are allocated here.
*
* Parameters:
* lN - number of local column.
* lcolptr - starting index of each local column in row and avals.
* lrow _ row number of each local element.
* lavals - values of each local element.
* lrhs - local part of the right hand side.
* lperm - local part of the permutation tabular.
* linvp - local part of the reverse permutation tabular.
* gN - global number of columns (output).
* gcolptr - starting index of each column in row2 and avals2 (output).
* grow - row number of each element (output).
* gavals - values of each element (output).
* grhs - global right hand side (output).
* gperm - global permutation tabular (output).
* ginvp - global reverse permutation tabular (output).
* loc2glob - global number of each local column.
* pastix_comm - PaStiX MPI communicator.
* ndof - Number of degree f freedom by node.
*
*/
void z_cscd2csc(pastix_int_t lN, pastix_int_t * lcolptr, pastix_int_t * lrow, pastix_complex64_t * lavals,
pastix_complex64_t * lrhs, pastix_int_t * lperm, pastix_int_t * linvp,
pastix_int_t *gN, pastix_int_t ** gcolptr, pastix_int_t **grow, pastix_complex64_t **gavals,
pastix_complex64_t **grhs, pastix_int_t **gperm, pastix_int_t **ginvp,
pastix_int_t *loc2glob, MPI_Comm pastix_comm, pastix_int_t ndof);
/*
* Function: cscd_redispatch
*
* Redistribute the first cscd into a new one using *dl2g*.
*
* - gather all new loc2globs on all processors.
* - allocate *dia*, *dja* and *da*.
* - Create new CSC for each processor and send it.
* - Merge all new CSC to the new local CSC with <cscd_addlocal_int>.
*
* If communicator size is one, check that n = dn and
* l2g = dl2g and simply create a copy of the first cscd.
*
* Parameters:
* n - Number of local columns
* ia - First cscd starting index of each column in *ja* and *a*
* ja - Row of each element in first CSCD
* a - value of each cscd in first CSCD (can be NULL)
* rhs - right-hand-side member corresponding to the first CSCD
* (can be NULL)
* nrhs - number of right-hand-side.
* l2g - local 2 global column numbers for first cscd
* dn - Number of local columns
* dia - New cscd starting index of each column in *ja* and *a*
* dja - Row of each element in new CSCD
* da - value of each cscd in new CSCD
* rhs - right-hand-side member corresponding to the new CSCD
* dl2g - local 2 global column numbers for new cscd
* comm - MPI communicator
*
* Returns:
* EXIT_SUCCESS - If all goes well
* EXIT_FAILURE - If commsize = 1 and *n* != *dn* or *l2g* != *dl2g*.
*/
int z_cscd_redispatch(pastix_int_t n, pastix_int_t * ia, pastix_int_t * ja, pastix_complex64_t * a,
pastix_complex64_t * rhs, pastix_int_t nrhs, pastix_int_t * l2g,
pastix_int_t dn, pastix_int_t ** dia, pastix_int_t ** dja, pastix_complex64_t ** da,
pastix_complex64_t ** drhs, pastix_int_t * dl2g,
MPI_Comm comm, pastix_int_t dof);
/*
* Function: cscd_save
*
* save a distributed csc to disk.
* files are called $(filename) and $(filename)$(RANK)
* if filename is NULL then filename = cscd_matrix.
*
* file filename contains the number of processors/files
* on first line. Then each line contain the name of each file
* (here $(filename)$(RANK)).
*
*
*
* Parameters:
* n - Number of local columns
* ia - First cscd starting index of each column in *ja* and *a*
* ja - Row of each element in first CSCD
* a - value of each cscd in first CSCD (can be NULL)
* rhs - Right hand side.
* l2g - local 2 global column numbers for first cscd
* dof - Number of degrees of freedom
* filename - name of the files.
* comm - MPI communicator
*/
int z_cscd_save(pastix_int_t n, pastix_int_t *ia, pastix_int_t *ja, pastix_complex64_t * a, pastix_complex64_t * rhs, pastix_int_t* l2g,
int dof, const char * filename, MPI_Comm comm);
/*
* Function: cscd_load
*
* Loads a distributed csc from disk.
* if filename is NULL then filename = cscd_matrix.
*
* Parameters:
* n - Number of local columns
* ia - First cscd starting index of each column in *ja* and *a*
* ja - Row of each element in first CSCD
* a - value of each cscd in first CSCD (can be NULL)
* rhs - Right hand side.
* l2g - local 2 global column numbers for first cscd
* filename - name of the files.
* comm - MPI communicator
*/
int z_cscd_load(pastix_int_t *n, pastix_int_t ** ia, pastix_int_t ** ja, pastix_complex64_t ** a, pastix_complex64_t ** rhs, pastix_int_t ** l2g,
const char * filename, MPI_Comm mpi_comm);
#endif /* Z_CSCD_UTILS_H */
/**
* PaStiX CSC management routines.
*
* PaStiX is a software package provided by Inria Bordeaux - Sud-Ouest,
* LaBRI, University of Bordeaux 1 and IPB.
*
* @version 1.0.0
* @author Mathieu Faverge
* @author Pierre Ramet
* @author Xavier Lacoste
* @date 2011-11-11
* @precisions normal z -> c d s
*
**/
/*
File: pastix_fortran.c
Interface to the PaStiX API functions.
*/
#include "common.h"
#include "z_cscd_utils.h"
#define FORTRAN_NAME(nu,nl,pl,pc) \
void nl pl; \
void nu pl \
{ nl pc; } \
void nl ## _ pl \
{ nl pc; } \
void nl ## __ pl \
{ nl pc; }
/*
Struct: csc_data_
Contains the new CSCD
*/
struct csc_data_ {
pastix_int_t n;
pastix_int_t *colptr;
pastix_int_t *rows;
pastix_complex64_t *values;
pastix_complex64_t *rhs;
pastix_int_t nrhs;
pastix_int_t *perm;
pastix_int_t *l2g;
pastix_int_t dof;
};
/*
Typedef: csc_data_t
Type coresponding to the struct <csc_data_>
*/
typedef struct csc_data_ csc_data_t;
FORTRAN_NAME(Z_CSC_DISPATCH_FORTRAN,
z_csc_dispatch_fortran,
(csc_data_t **csc_data,
pastix_int_t *gN,
pastix_int_t *gcolptr,
pastix_int_t *grow,
pastix_complex64_t *gavals,
pastix_complex64_t *grhs,
pastix_int_t *gperm,
pastix_int_t *ginvp,
int *dispatch,
pastix_int_t *newn,
pastix_int_t *newnnz,
MPI_Fint *fortran_comm),
(csc_data,
gN,
gcolptr,
grow,
gavals,
grhs,
gperm,
ginvp,
dispatch,
newn,
newnnz,
fortran_comm))
void z_csc_dispatch_fortran(csc_data_t **csc_data,
pastix_int_t *gN,
pastix_int_t *gcolptr,
pastix_int_t *grow,
pastix_complex64_t *gavals,
pastix_complex64_t *grhs,
pastix_int_t *gperm,
pastix_int_t *ginvp,
int *dispatch,
pastix_int_t *newn,
pastix_int_t *newnnz,
MPI_Fint *fortran_comm)
{
MPI_Comm pastix_comm;
(void)fortran_comm;
pastix_comm = MPI_Comm_f2c(*fortran_comm);
MALLOC_INTERN(*csc_data, 1, struct csc_data_);
(*csc_data)->n = 0;
(*csc_data)->colptr = NULL;
(*csc_data)->rows = NULL;
(*csc_data)->values = NULL;
(*csc_data)->rhs = NULL;
(*csc_data)->perm = NULL;
(*csc_data)->l2g = NULL;
z_csc_dispatch(*gN, gcolptr, grow, gavals, grhs, gperm, ginvp,
&((*csc_data)->n), &((*csc_data)->colptr), &((*csc_data)->rows), &((*csc_data)->values),
&((*csc_data)->rhs), &((*csc_data)->perm),
&((*csc_data)->l2g), *dispatch, pastix_comm);
*newn = (*csc_data)->n;
*newnnz = (*csc_data)->colptr[(*csc_data)->n]-1;
}
FORTRAN_NAME(Z_CSC_DISPATCH_FORTRAN_END,
z_csc_dispatch_fortran_end,
(csc_data_t **csc_data,
pastix_int_t *lcolptr,
pastix_int_t *lrow,
pastix_complex64_t *lavals,
pastix_complex64_t *lrhs,
pastix_int_t *lperm,
pastix_int_t *l2g),
(csc_data,
lcolptr,
lrow,
lavals,
lrhs,
lperm,
l2g))
void z_csc_dispatch_fortran_end(csc_data_t **csc_data,
pastix_int_t *lcolptr,
pastix_int_t *lrow,
pastix_complex64_t *lavals,
pastix_complex64_t *lrhs,
pastix_int_t *lperm,
pastix_int_t *l2g)
{
pastix_int_t nnz = 0;
if ((*csc_data)->colptr != NULL) {
nnz = (*csc_data)->colptr[(*csc_data)->n]-1;
memcpy(lcolptr, (*csc_data)->colptr, (1+(*csc_data)->n)*sizeof(pastix_int_t));
free((*csc_data)->colptr);
}
if ((*csc_data)->rows != NULL) {
memcpy(lrow, (*csc_data)->rows, nnz*sizeof(pastix_int_t));
free((*csc_data)->rows);
}
if ((*csc_data)->values != NULL) {
memcpy(lavals, (*csc_data)->values, nnz*sizeof(pastix_complex64_t));
free((*csc_data)->values);
}
if ((*csc_data)->rhs != NULL) {
memcpy(lrhs, (*csc_data)->rhs, (*csc_data)->n*sizeof(pastix_complex64_t));
free((*csc_data)->rhs);
}
if ((*csc_data)->perm != NULL) {
memcpy(lperm, (*csc_data)->perm, (*csc_data)->n*sizeof(pastix_int_t));
free((*csc_data)->perm);
}
if ((*csc_data)->l2g != NULL) {
memcpy(l2g, (*csc_data)->l2g, (*csc_data)->n*sizeof(pastix_int_t));
free((*csc_data)->l2g);
}
}
FORTRAN_NAME(Z_CSCD_REDISPATCH_FORTRAN,
z_cscd_redispatch_fortran,
(csc_data_t **csc_data,
pastix_int_t *n,
pastix_int_t *ia,
pastix_int_t *ja,
pastix_complex64_t *a,
pastix_complex64_t *rhs,
pastix_int_t *nrhs,
pastix_int_t *l2g,
pastix_int_t *newn,
pastix_int_t *newl2g,
pastix_int_t *newnnz,
MPI_Fint *fortran_comm,
pastix_int_t *dof,
int *ierr),
(csc_data,
n,
ia,
ja,
a,
rhs,
nrhs,
l2g,
newn,
newl2g,
newnnz,
fortran_comm,
dof,
ierr))
void z_cscd_redispatch_fortran(csc_data_t **csc_data,
pastix_int_t *n,
pastix_int_t *ia,
pastix_int_t *ja,
pastix_complex64_t *a,
pastix_complex64_t *rhs,
pastix_int_t *nrhs,
pastix_int_t *l2g,
pastix_int_t *newn,
pastix_int_t *newl2g,
pastix_int_t *newnnz,
MPI_Fint *fortran_comm,
pastix_int_t *dof,
int *ierr)
{
MPI_Comm pastix_comm;
(void)newnnz; (void)fortran_comm;
pastix_comm = MPI_Comm_f2c(*fortran_comm);
MALLOC_INTERN(*csc_data, 1, struct csc_data_);
(*csc_data)->n = 0;
(*csc_data)->colptr = NULL;
(*csc_data)->rows = NULL;
(*csc_data)->values = NULL;
(*csc_data)->rhs = NULL;
(*csc_data)->nrhs = *nrhs;
(*csc_data)->perm = NULL;
(*csc_data)->l2g = NULL;
(*csc_data)->dof = *dof;
*ierr = z_cscd_redispatch(*n, ia, ja, a, rhs, *nrhs, l2g,
*newn, &((*csc_data)->colptr), &((*csc_data)->rows), &((*csc_data)->values), &((*csc_data)->rhs), newl2g,
pastix_comm, (*csc_data)->dof);
}
FORTRAN_NAME(Z_CSCD_REDISPATCH_FORTRAN_END,
z_cscd_redispatch_fortran_end,
(csc_data_t **csc_data,
pastix_int_t *dcolptr,
pastix_int_t *drow,
pastix_complex64_t *davals,
pastix_complex64_t *drhs),
(csc_data,
dcolptr,
drow,
davals,
drhs))
void z_cscd_redispatch_fortran_end(csc_data_t **csc_data,
pastix_int_t *dcolptr,
pastix_int_t *drow,
pastix_complex64_t *davals,
pastix_complex64_t *drhs)
{
pastix_int_t nnz = 0;
if ((*csc_data)->colptr != NULL) {
nnz = (*csc_data)->colptr[(*csc_data)->n]-1;
memcpy(dcolptr, (*csc_data)->colptr, (1+(*csc_data)->n)*sizeof(pastix_int_t));
free((*csc_data)->colptr);
}
if ((*csc_data)->rows != NULL) {
memcpy(drow, (*csc_data)->rows, nnz*sizeof(pastix_int_t));
free((*csc_data)->rows);
}
if ((*csc_data)->values != NULL) {
memcpy(davals, (*csc_data)->values,
(*csc_data)->dof*(*csc_data)->dof*nnz*sizeof(pastix_complex64_t));
free((*csc_data)->values);
}
if ((*csc_data)->rhs != NULL) {
memcpy(drhs, (*csc_data)->rhs, (*csc_data)->nrhs*(*csc_data)->n*sizeof(pastix_complex64_t));
free((*csc_data)->rhs);
}
memFree_null(*csc_data);
}
/**
* PaStiX distributed CSC management routines.
*
* PaStiX is a software package provided by Inria Bordeaux - Sud-Ouest,
* LaBRI, University of Bordeaux 1 and IPB.
*
* @version 1.0.0
* @author Mathieu Faverge
* @author Pierre Ramet
* @author Xavier Lacoste
* @date 2011-11-11
* @precisions normal z -> c d s
*
**/
#include "z_cscd_utils.h"
#ifndef CSCD_UTILS_INTERN_H
#define CSCD_UTILS_INTERN_H
int z_cscd_addlocal_int(pastix_int_t n , const pastix_int_t * ia , const pastix_int_t * ja , const pastix_complex64_t * a , const pastix_int_t * l2g,
pastix_int_t addn, const pastix_int_t * addia, pastix_int_t * addja, const pastix_complex64_t * adda, const pastix_int_t * addl2g,
pastix_int_t * newn, pastix_int_t ** newia, pastix_int_t ** newja, pastix_complex64_t ** newa,
CSCD_OPERATIONS_t OP, int dof, int malloc_flag);
/*
* Function: cscd_redispatch_int
*
* Redistribute the first cscd into a new one using *dl2g*.
*
* - gather all new loc2globs on all processors.
* - allocate *dia*, *dja* and *da*.
* - Create new CSC for each processor and send it.
* - Merge all new CSC to the new local CSC with <cscd_addlocal_int>.
*
* If communicator size is one, check that n = dn and
* l2g = dl2g and simply create a copy of the first cscd.
*
* Parameters:
* n - Number of local columns
* ia - First cscd starting index of each column in *ja* and *a*
* ja - Row of each element in first CSCD
* a - value of each cscd in first CSCD (can be NULL)
* rhs - right-hand-side member corresponding to the first CSCD (can be NULL)
* nrhs - number of right-hand-side.
* l2g - local 2 global column numbers for first cscd
* dn - Number of local columns
* dia - New cscd starting index of each column in *ja* and *a*
* dja - Row of each element in new CSCD
* da - value of each cscd in new CSCD
* rhs - right-hand-side member corresponding to the new CSCD
* dl2g - local 2 global column numbers for new cscd
* malloc_flag - Internal (API_YES) or external (API_NO) malloc use.
* comm - MPI communicator
*
* Returns:
* EXIT_SUCCESS - If all goes well
* EXIT_FAILURE - If commsize = 1 and *n* != *dn* or *l2g* != *dl2g*.
*/
int z_cscd_redispatch_int(pastix_int_t n, pastix_int_t * ia, pastix_int_t * ja, pastix_complex64_t * a, pastix_complex64_t * rhs, pastix_int_t nrhs, pastix_int_t * l2g,
pastix_int_t dn, pastix_int_t ** dia, pastix_int_t ** dja, pastix_complex64_t ** da, pastix_complex64_t ** drhs, pastix_int_t * dl2g,
int malloc_flag, MPI_Comm comm, pastix_int_t dof);
int z_cscd_symgraph_int(pastix_int_t n, const pastix_int_t *ia, const pastix_int_t *ja, const pastix_complex64_t *a,
pastix_int_t * newn, pastix_int_t ** newia, pastix_int_t ** newja, pastix_complex64_t ** newa,
pastix_int_t * l2g, MPI_Comm comm, int malloc_flag);
/*
Function: cscd_build_g2l
Construct global to local tabular containing local number of global columns
if one column is local, and -owner if column is not local.
For i in 0, gN
g2l[i] = i local number if i is local
g2l[i] = -p if p is the owner of the column i
Parameters:
n - Number of local columns
colptr - Starting index of each columns in *ja*
rows - Row of each element.
values - Value of each element.
l2g - global number of each local column.
correct - Flag indicating if we can correct the symmetry.
dof - Number of degrees of freedom.
comm - MPI communicator
*/
int z_cscd_build_g2l( pastix_int_t ncol,
pastix_int_t *loc2glob,
MPI_Comm comm,
pastix_int_t *gN,
pastix_int_t **g2l);
/*
Function: cscd_noDiag
Removes diagonal elements from a CSCD.
*ja* and *a* can be reallocated to
ia[n]-1 elements after this call.
Parameters:
n - Number of local columns
ia - First cscd starting index of each column in *ja* and *a*
ja - Row of each element in first CSCD
a - value of each cscd in first CSCD (can be NULL)
l2g - local 2 global column numbers for first cscd
*/
int z_cscd_noDiag(pastix_int_t n, pastix_int_t *ia, pastix_int_t *ja, pastix_complex64_t * a, const pastix_int_t * l2g);
/*
Function: cscd_checksym
Check if the CSCD graph is symetric.
Parameters:
n - Number of local columns
ia - Starting index of each columns in *ja*
ja - Row of each element.
l2g - global number of each local column.
correct - Flag indicating if we can correct the symmetry.
alloc - indicate if allocation on CSC uses internal malloc.
dof - Number of degrees of freedom.
comm - MPI communicator
*/
int z_cscd_checksym(pastix_int_t n,
pastix_int_t *colptr,
pastix_int_t **rows,
pastix_complex64_t **values,
pastix_int_t *l2g,
int correct,
int alloc,
int dof,
MPI_Comm comm);
/**
* Function: cscd2csc_int
*
* Transform a cscd to a csc.
* colptr2, row2, avals2, rhs2, perm2, invp2 are allocated here.
*
* External function, allocation are not of the internal type.
*
* Parameters:
* lN - number of local column.
* lcolptr - starting index of each local column in row and avals.
* lrow _ row number of each local element.
* lavals - values of each local element.
* lrhs - local part of the right hand side.
* lperm - local part of the permutation tabular.
* linvp - Means nothing, to suppress.
* gN - global number of columns (output).
* gcolptr - starting index of each column in row2 and avals2 (output).
* grow - row number of each element (output).
* gavals - values of each element (output).
* grhs - global right hand side (output).
* gperm - global permutation tabular (output).
* ginvp - global reverse permutation tabular (output).
* loc2glob - global number of each local column.
* pastix_comm - PaStiX MPI communicator.
* ndof - Number of degree of freedom per node.
* intern_flag - Decide if malloc will use internal or external macros.
*/
void z_cscd2csc_int(pastix_int_t lN, pastix_int_t * lcolptr, pastix_int_t * lrow, pastix_complex64_t * lavals,
pastix_complex64_t * lrhs, pastix_int_t * lperm, pastix_int_t * linvp,
pastix_int_t *gN, pastix_int_t ** gcolptr, pastix_int_t **grow, pastix_complex64_t **gavals,
pastix_complex64_t **grhs, pastix_int_t **gperm, pastix_int_t **ginvp,
pastix_int_t *loc2glob, MPI_Comm pastix_comm, pastix_int_t ndof, int intern_flag);
/*
Function: cscd_redispatch_scotch
Renumber the columns to have first columns on first proc for Scotch
Parameters:
n - Number of local columns
ia - First cscd starting index of each column in *ja* and *a*
ja - Row of each element in first CSCD
a - value of each cscd in first CSCD (can be NULL)
l2g - local 2 global column numbers for first cscd
dn - Number of local columns
dia - First cscd starting index of each column in *ja* and *a*
dja - Row of each element in first CSCD
da - value of each cscd in first CSCD (can be NULL)
l2g - local 2 global column numbers for first cscd
comm - MPI communicator
Returns:
EXIT_SUCCESS if already well distributed, 2 if redistributed
*/
int z_cscd_redispatch_scotch(pastix_int_t n, pastix_int_t * ia, pastix_int_t * ja, pastix_complex64_t * a, pastix_int_t * l2g,
pastix_int_t *dn, pastix_int_t ** dia, pastix_int_t ** dja, pastix_complex64_t ** da, pastix_int_t ** dl2g,
MPI_Comm comm);
#endif /* CSCD_UTILS_INTERN_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment