xref: /petsc/src/mat/impls/aij/mpi/crl/mcrl.c (revision d0e6bf2ad94dcc89b258ce16c7987200a4714786)
15fa1c062SBarry Smith /*
21472f72bSBarry Smith   Defines a matrix-vector product for the MATMPIAIJCRL matrix class.
31472f72bSBarry Smith   This class is derived from the MATMPIAIJ class and retains the
45fa1c062SBarry Smith   compressed row storage (aka Yale sparse matrix format) but augments
55fa1c062SBarry Smith   it with a column oriented storage that is more efficient for
65fa1c062SBarry Smith   matrix vector products on Vector machines.
75fa1c062SBarry Smith 
85fa1c062SBarry Smith   CRL stands for constant row length (that is the same number of columns
95fa1c062SBarry Smith   is kept (padded with zeros) for each row of the sparse matrix.
101472f72bSBarry Smith 
111472f72bSBarry Smith    See src/mat/impls/aij/seq/crl/crl.c for the sequential version
125fa1c062SBarry Smith */
135fa1c062SBarry Smith 
14c6db04a5SJed Brown #include <../src/mat/impls/aij/mpi/mpiaij.h>
15c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/crl/crl.h>
165fa1c062SBarry Smith 
MatDestroy_MPIAIJCRL(Mat A)1766976f2fSJacob Faibussowitsch static PetscErrorCode MatDestroy_MPIAIJCRL(Mat A)
18d71ae5a4SJacob Faibussowitsch {
195a11e1b2SBarry Smith   Mat_AIJCRL *aijcrl = (Mat_AIJCRL *)A->spptr;
205fa1c062SBarry Smith 
21362febeeSStefano Zampini   PetscFunctionBegin;
22bf0cc555SLisandro Dalcin   if (aijcrl) {
239566063dSJacob Faibussowitsch     PetscCall(PetscFree2(aijcrl->acols, aijcrl->icols));
249566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&aijcrl->fwork));
259566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&aijcrl->xwork));
269566063dSJacob Faibussowitsch     PetscCall(PetscFree(aijcrl->array));
27bf0cc555SLisandro Dalcin   }
289566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->spptr));
295fa1c062SBarry Smith 
309566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)A, MATMPIAIJ));
319566063dSJacob Faibussowitsch   PetscCall(MatDestroy_MPIAIJ(A));
323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
335fa1c062SBarry Smith }
345fa1c062SBarry Smith 
MatMPIAIJCRL_create_aijcrl(Mat A)3566976f2fSJacob Faibussowitsch static PetscErrorCode MatMPIAIJCRL_create_aijcrl(Mat A)
36d71ae5a4SJacob Faibussowitsch {
37*57508eceSPierre Jolivet   Mat_MPIAIJ  *a   = (Mat_MPIAIJ *)A->data;
38f4f49eeaSPierre Jolivet   Mat_SeqAIJ  *Aij = (Mat_SeqAIJ *)a->A->data, *Bij = (Mat_SeqAIJ *)a->B->data;
395a11e1b2SBarry Smith   Mat_AIJCRL  *aijcrl = (Mat_AIJCRL *)A->spptr;
40d0f46423SBarry Smith   PetscInt     m      = A->rmap->n;       /* Number of rows in the matrix. */
41d0f46423SBarry Smith   PetscInt     nd     = a->A->cmap->n;    /* number of columns in diagonal portion */
421472f72bSBarry Smith   PetscInt    *aj = Aij->j, *bj = Bij->j; /* From the CSR representation; points to the beginning  of each row. */
431472f72bSBarry Smith   PetscInt     i, j, rmax = 0, *icols, *ailen = Aij->ilen, *bilen = Bij->ilen;
446873f782SBarry Smith   PetscScalar *aa = Aij->a, *ba = Bij->a, *acols, *array;
455fa1c062SBarry Smith 
465fa1c062SBarry Smith   PetscFunctionBegin;
471472f72bSBarry Smith   /* determine the row with the most columns */
48ad540459SPierre Jolivet   for (i = 0; i < m; i++) rmax = PetscMax(rmax, ailen[i] + bilen[i]);
495a11e1b2SBarry Smith   aijcrl->nz   = Aij->nz + Bij->nz;
505a11e1b2SBarry Smith   aijcrl->m    = A->rmap->n;
515a11e1b2SBarry Smith   aijcrl->rmax = rmax;
522205254eSKarl Rupp 
539566063dSJacob Faibussowitsch   PetscCall(PetscFree2(aijcrl->acols, aijcrl->icols));
549566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(rmax * m, &aijcrl->acols, rmax * m, &aijcrl->icols));
555a11e1b2SBarry Smith   acols = aijcrl->acols;
565a11e1b2SBarry Smith   icols = aijcrl->icols;
575fa1c062SBarry Smith   for (i = 0; i < m; i++) {
581472f72bSBarry Smith     for (j = 0; j < ailen[i]; j++) {
595fa1c062SBarry Smith       acols[j * m + i] = *aa++;
605fa1c062SBarry Smith       icols[j * m + i] = *aj++;
615fa1c062SBarry Smith     }
621472f72bSBarry Smith     for (; j < ailen[i] + bilen[i]; j++) {
631472f72bSBarry Smith       acols[j * m + i] = *ba++;
6411285404SBarry Smith       icols[j * m + i] = nd + *bj++;
651472f72bSBarry Smith     }
665fa1c062SBarry Smith     for (; j < rmax; j++) { /* empty column entries */
675fa1c062SBarry Smith       acols[j * m + i] = 0.0;
685fa1c062SBarry Smith       icols[j * m + i] = (j) ? icols[(j - 1) * m + i] : 0; /* handle case where row is EMPTY */
695fa1c062SBarry Smith     }
705fa1c062SBarry Smith   }
718564c97fSStefano Zampini   PetscCall(PetscInfo(A, "Percentage of 0's introduced for vectorized multiply %g\n", 1.0 - ((double)aijcrl->nz) / PetscMax((double)rmax * m, 1)));
721472f72bSBarry Smith 
739566063dSJacob Faibussowitsch   PetscCall(PetscFree(aijcrl->array));
749566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(a->B->cmap->n + nd, &array));
75483e0693SBarry Smith   /* xwork array is actually B->n+nd long, but we define xwork this length so can copy into it */
769566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&aijcrl->xwork));
779566063dSJacob Faibussowitsch   PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), 1, nd, PETSC_DECIDE, array, &aijcrl->xwork));
789566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&aijcrl->fwork));
799566063dSJacob Faibussowitsch   PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF, 1, a->B->cmap->n, array + nd, &aijcrl->fwork));
802205254eSKarl Rupp 
815a11e1b2SBarry Smith   aijcrl->array = array;
825a11e1b2SBarry Smith   aijcrl->xscat = a->Mvctx;
833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
845fa1c062SBarry Smith }
855fa1c062SBarry Smith 
MatAssemblyEnd_MPIAIJCRL(Mat A,MatAssemblyType mode)8666976f2fSJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_MPIAIJCRL(Mat A, MatAssemblyType mode)
87d71ae5a4SJacob Faibussowitsch {
881472f72bSBarry Smith   Mat_MPIAIJ *a   = (Mat_MPIAIJ *)A->data;
89f4f49eeaSPierre Jolivet   Mat_SeqAIJ *Aij = (Mat_SeqAIJ *)a->A->data, *Bij = (Mat_SeqAIJ *)a->A->data;
905fa1c062SBarry Smith 
915fa1c062SBarry Smith   PetscFunctionBegin;
921472f72bSBarry Smith   Aij->inode.use = PETSC_FALSE;
931472f72bSBarry Smith   Bij->inode.use = PETSC_FALSE;
942205254eSKarl Rupp 
959566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd_MPIAIJ(A, mode));
963ba16761SJacob Faibussowitsch   if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(PETSC_SUCCESS);
975fa1c062SBarry Smith 
981472f72bSBarry Smith   /* Now calculate the permutation and grouping information. */
999566063dSJacob Faibussowitsch   PetscCall(MatMPIAIJCRL_create_aijcrl(A));
1003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1015fa1c062SBarry Smith }
1025fa1c062SBarry Smith 
1035a11e1b2SBarry Smith extern PetscErrorCode MatMult_AIJCRL(Mat, Vec, Vec);
1045a11e1b2SBarry Smith extern PetscErrorCode MatDuplicate_AIJCRL(Mat, MatDuplicateOption, Mat *);
1055fa1c062SBarry Smith 
1065a11e1b2SBarry Smith /* MatConvert_MPIAIJ_MPIAIJCRL converts a MPIAIJ matrix into a
1075a11e1b2SBarry Smith  * MPIAIJCRL matrix.  This routine is called by the MatCreate_MPIAIJCRL()
1081472f72bSBarry Smith  * routine, but can also be used to convert an assembled MPIAIJ matrix
1095a11e1b2SBarry Smith  * into a MPIAIJCRL one. */
110b2573a8aSBarry Smith 
MatConvert_MPIAIJ_MPIAIJCRL(Mat A,MatType type,MatReuse reuse,Mat * newmat)111d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_MPIAIJ_MPIAIJCRL(Mat A, MatType type, MatReuse reuse, Mat *newmat)
112d71ae5a4SJacob Faibussowitsch {
1135fa1c062SBarry Smith   Mat         B = *newmat;
1145a11e1b2SBarry Smith   Mat_AIJCRL *aijcrl;
1155fa1c062SBarry Smith 
1165fa1c062SBarry Smith   PetscFunctionBegin;
11748a46eb9SPierre Jolivet   if (reuse == MAT_INITIAL_MATRIX) PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B));
1185fa1c062SBarry Smith 
1194dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&aijcrl));
1205a11e1b2SBarry Smith   B->spptr = (void *)aijcrl;
1215fa1c062SBarry Smith 
12217667f90SBarry Smith   /* Set function pointers for methods that we inherit from AIJ but override. */
1235a11e1b2SBarry Smith   B->ops->duplicate   = MatDuplicate_AIJCRL;
1245a11e1b2SBarry Smith   B->ops->assemblyend = MatAssemblyEnd_MPIAIJCRL;
1255a11e1b2SBarry Smith   B->ops->destroy     = MatDestroy_MPIAIJCRL;
1265a11e1b2SBarry Smith   B->ops->mult        = MatMult_AIJCRL;
1275fa1c062SBarry Smith 
1285fa1c062SBarry Smith   /* If A has already been assembled, compute the permutation. */
1291baa6e33SBarry Smith   if (A->assembled) PetscCall(MatMPIAIJCRL_create_aijcrl(B));
1309566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATMPIAIJCRL));
1315fa1c062SBarry Smith   *newmat = B;
1323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1335fa1c062SBarry Smith }
1345fa1c062SBarry Smith 
1355fa1c062SBarry Smith /*@C
13611a5261eSBarry Smith   MatCreateMPIAIJCRL - Creates a sparse matrix of type `MATMPIAIJCRL`.
1375fa1c062SBarry Smith 
138d083f849SBarry Smith   Collective
1395fa1c062SBarry Smith 
1405fa1c062SBarry Smith   Input Parameters:
14111a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF`
1425fa1c062SBarry Smith . m    - number of rows
1435fa1c062SBarry Smith . n    - number of columns
14420f4b53cSBarry Smith . nz   - number of nonzeros per row (same for all rows), for the "diagonal" submatrix
14520f4b53cSBarry Smith . nnz  - array containing the number of nonzeros in the various rows (possibly different for each row) or `NULL`, for the "diagonal" submatrix
14620f4b53cSBarry Smith . onz  - number of nonzeros per row (same for all rows), for the "off-diagonal" submatrix
14720f4b53cSBarry Smith - onnz - array containing the number of nonzeros in the various rows (possibly different for each row) or `NULL`, for the "off-diagonal" submatrix
1485fa1c062SBarry Smith 
1495fa1c062SBarry Smith   Output Parameter:
1505fa1c062SBarry Smith . A - the matrix
1515fa1c062SBarry Smith 
1522ef1f0ffSBarry Smith   Level: intermediate
1532ef1f0ffSBarry Smith 
1542920cce0SJacob Faibussowitsch   Notes:
1552920cce0SJacob Faibussowitsch   This type inherits from `MATAIJ`, but stores some additional information that is used to
1562920cce0SJacob Faibussowitsch   allow better vectorization of the matrix-vector product. At the cost of increased storage,
1572920cce0SJacob Faibussowitsch   the AIJ formatted matrix can be copied to a format in which pieces of the matrix are stored
1582920cce0SJacob Faibussowitsch   in ELLPACK format, allowing the vectorized matrix multiply routine to use stride-1 memory
1592920cce0SJacob Faibussowitsch   accesses.
1602920cce0SJacob Faibussowitsch 
16120f4b53cSBarry Smith   If `nnz` is given then `nz` is ignored
1625fa1c062SBarry Smith 
1631cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, [Sparse Matrix Creation](sec_matsparse), `MATAIJ`, `MATAIJSELL`, `MATAIJPERM`, `MATAIJMKL`, `MatCreate()`, `MatCreateMPIAIJPERM()`, `MatSetValues()`
1645fa1c062SBarry Smith @*/
MatCreateMPIAIJCRL(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],PetscInt onz,const PetscInt onnz[],Mat * A)165d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIAIJCRL(MPI_Comm comm, PetscInt m, PetscInt n, PetscInt nz, const PetscInt nnz[], PetscInt onz, const PetscInt onnz[], Mat *A)
166d71ae5a4SJacob Faibussowitsch {
1675fa1c062SBarry Smith   PetscFunctionBegin;
1689566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
1699566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
1709566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATMPIAIJCRL));
1719566063dSJacob Faibussowitsch   PetscCall(MatMPIAIJSetPreallocation_MPIAIJ(*A, nz, (PetscInt *)nnz, onz, (PetscInt *)onnz));
1723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1735fa1c062SBarry Smith }
1745fa1c062SBarry Smith 
MatCreate_MPIAIJCRL(Mat A)175d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreate_MPIAIJCRL(Mat A)
176d71ae5a4SJacob Faibussowitsch {
1775fa1c062SBarry Smith   PetscFunctionBegin;
1789566063dSJacob Faibussowitsch   PetscCall(MatSetType(A, MATMPIAIJ));
1799566063dSJacob Faibussowitsch   PetscCall(MatConvert_MPIAIJ_MPIAIJCRL(A, MATMPIAIJCRL, MAT_INPLACE_MATRIX, &A));
1803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1815fa1c062SBarry Smith }
182