xref: /petsc/src/mat/impls/aij/mpi/mpiviennacl/mpiaijviennacl.cxx (revision 2ef1f0ff6e3530e8731eb06ad663081f5844f49f)
199acd6aaSStefano Zampini #define PETSC_SKIP_IMMINTRIN_H_CUDAWORKAROUND 1
299acd6aaSStefano Zampini 
3aaa7dc30SBarry Smith #include <petscconf.h>
48f86e40fSKarl Rupp #include <../src/mat/impls/aij/mpi/mpiaij.h> /*I "petscmat.h" I*/
565e3cb35SKarl Rupp #include <../src/mat/impls/aij/seq/seqviennacl/viennaclmatimpl.h>
68f86e40fSKarl Rupp 
7d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMPIAIJSetPreallocation_MPIAIJViennaCL(Mat B, PetscInt d_nz, const PetscInt d_nnz[], PetscInt o_nz, const PetscInt o_nnz[])
8d71ae5a4SJacob Faibussowitsch {
98f86e40fSKarl Rupp   Mat_MPIAIJ *b = (Mat_MPIAIJ *)B->data;
108f86e40fSKarl Rupp 
118f86e40fSKarl Rupp   PetscFunctionBegin;
129566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
139566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
148f86e40fSKarl Rupp   if (!B->preallocated) {
158f86e40fSKarl Rupp     /* Explicitly create the two MATSEQAIJVIENNACL matrices. */
169566063dSJacob Faibussowitsch     PetscCall(MatCreate(PETSC_COMM_SELF, &b->A));
179566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(b->A, B->rmap->n, B->cmap->n, B->rmap->n, B->cmap->n));
189566063dSJacob Faibussowitsch     PetscCall(MatSetType(b->A, MATSEQAIJVIENNACL));
199566063dSJacob Faibussowitsch     PetscCall(MatCreate(PETSC_COMM_SELF, &b->B));
209566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(b->B, B->rmap->n, B->cmap->N, B->rmap->n, B->cmap->N));
219566063dSJacob Faibussowitsch     PetscCall(MatSetType(b->B, MATSEQAIJVIENNACL));
228f86e40fSKarl Rupp   }
239566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJSetPreallocation(b->A, d_nz, d_nnz));
249566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJSetPreallocation(b->B, o_nz, o_nnz));
258f86e40fSKarl Rupp   B->preallocated = PETSC_TRUE;
263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
278f86e40fSKarl Rupp }
288f86e40fSKarl Rupp 
29d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAssemblyEnd_MPIAIJViennaCL(Mat A, MatAssemblyType mode)
30d71ae5a4SJacob Faibussowitsch {
3174fd8ad3SBarry Smith   Mat_MPIAIJ *b = (Mat_MPIAIJ *)A->data;
3274fd8ad3SBarry Smith   PetscBool   v;
3374fd8ad3SBarry Smith 
3474fd8ad3SBarry Smith   PetscFunctionBegin;
359566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd_MPIAIJ(A, mode));
369566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)b->lvec, VECSEQVIENNACL, &v));
3774fd8ad3SBarry Smith   if (!v) {
3874fd8ad3SBarry Smith     PetscInt m;
399566063dSJacob Faibussowitsch     PetscCall(VecGetSize(b->lvec, &m));
409566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&b->lvec));
419566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqViennaCL(PETSC_COMM_SELF, m, &b->lvec));
4274fd8ad3SBarry Smith   }
433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4474fd8ad3SBarry Smith }
458f86e40fSKarl Rupp 
46d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_MPIAIJViennaCL(Mat A)
47d71ae5a4SJacob Faibussowitsch {
488f86e40fSKarl Rupp   PetscFunctionBegin;
499566063dSJacob Faibussowitsch   PetscCall(MatDestroy_MPIAIJ(A));
503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
518f86e40fSKarl Rupp }
528f86e40fSKarl Rupp 
53d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCreate_MPIAIJViennaCL(Mat A)
54d71ae5a4SJacob Faibussowitsch {
558f86e40fSKarl Rupp   PetscFunctionBegin;
569566063dSJacob Faibussowitsch   PetscCall(MatCreate_MPIAIJ(A));
576f3d89d0SStefano Zampini   A->boundtocpu = PETSC_FALSE;
589566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->defaultvectype));
599566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(VECVIENNACL, &A->defaultvectype));
609566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)A, "MatMPIAIJSetPreallocation_C", MatMPIAIJSetPreallocation_MPIAIJViennaCL));
6174fd8ad3SBarry Smith   A->ops->assemblyend = MatAssemblyEnd_MPIAIJViennaCL;
629566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)A, MATMPIAIJVIENNACL));
633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
648f86e40fSKarl Rupp }
658f86e40fSKarl Rupp 
66cab5ea25SPierre Jolivet /*@C
6711a5261eSBarry Smith    MatCreateAIJViennaCL - Creates a sparse matrix in `MATAIJ` (compressed row) format
68023073b3SKarl Rupp    (the default parallel PETSc format).  This matrix will ultimately be pushed down
698f86e40fSKarl Rupp    to GPUs and use the ViennaCL library for calculations. For good matrix
708f86e40fSKarl Rupp    assembly performance the user should preallocate the matrix storage by setting
718f86e40fSKarl Rupp    the parameter nz (or the array nnz).  By setting these parameters accurately,
728f86e40fSKarl Rupp    performance during matrix assembly can be increased substantially.
738f86e40fSKarl Rupp 
74d083f849SBarry Smith    Collective
758f86e40fSKarl Rupp 
768f86e40fSKarl Rupp    Input Parameters:
7711a5261eSBarry Smith +  comm - MPI communicator, set to `PETSC_COMM_SELF`
788f86e40fSKarl Rupp .  m - number of rows
798f86e40fSKarl Rupp .  n - number of columns
808f86e40fSKarl Rupp .  nz - number of nonzeros per row (same for all rows)
818f86e40fSKarl Rupp -  nnz - array containing the number of nonzeros in the various rows
828f86e40fSKarl Rupp          (possibly different for each row) or NULL
838f86e40fSKarl Rupp 
848f86e40fSKarl Rupp    Output Parameter:
858f86e40fSKarl Rupp .  A - the matrix
868f86e40fSKarl Rupp 
8711a5261eSBarry Smith    It is recommended that one use the `MatCreate()`, `MatSetType()` and/or `MatSetFromOptions()`,
888f86e40fSKarl Rupp    MatXXXXSetPreallocation() paradigm instead of this routine directly.
8911a5261eSBarry Smith    [MatXXXXSetPreallocation() is, for example, `MatSeqAIJSetPreallocation()`]
908f86e40fSKarl Rupp 
918f86e40fSKarl Rupp    Notes:
928f86e40fSKarl Rupp    If nnz is given then nz is ignored
938f86e40fSKarl Rupp 
9411a5261eSBarry Smith    The AIJ format, also called
95*2ef1f0ffSBarry Smith    compressed row storage), is fully compatible with standard Fortran
968f86e40fSKarl Rupp    storage.  That is, the stored row and column indices can begin at
978f86e40fSKarl Rupp    either one (as in Fortran) or zero.  See the users' manual for details.
988f86e40fSKarl Rupp 
998f86e40fSKarl Rupp    Specify the preallocated storage with either nz or nnz (not both).
10011a5261eSBarry Smith    Set nz = `PETSC_DEFAULT` and nnz = NULL for PETSc to control dynamic memory
1018f86e40fSKarl Rupp    allocation.  For large problems you MUST preallocate memory or you
1028f86e40fSKarl Rupp    will get TERRIBLE performance, see the users' manual chapter on matrices.
1038f86e40fSKarl Rupp 
1048f86e40fSKarl Rupp    Level: intermediate
1058f86e40fSKarl Rupp 
106db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateAIJ()`, `MatCreateAIJCUSPARSE()`, `MatSetValues()`, `MatSeqAIJSetColumnIndices()`, `MatCreateSeqAIJWithArrays()`, `MatCreateAIJ()`, `MATMPIAIJVIENNACL`, `MATAIJVIENNACL`
1078f86e40fSKarl Rupp @*/
108d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateAIJViennaCL(MPI_Comm comm, PetscInt m, PetscInt n, PetscInt M, PetscInt N, PetscInt d_nz, const PetscInt d_nnz[], PetscInt o_nz, const PetscInt o_nnz[], Mat *A)
109d71ae5a4SJacob Faibussowitsch {
1108f86e40fSKarl Rupp   PetscMPIInt size;
1118f86e40fSKarl Rupp 
1128f86e40fSKarl Rupp   PetscFunctionBegin;
1139566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
1149566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, M, N));
1159566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
1168f86e40fSKarl Rupp   if (size > 1) {
1179566063dSJacob Faibussowitsch     PetscCall(MatSetType(*A, MATMPIAIJVIENNACL));
1189566063dSJacob Faibussowitsch     PetscCall(MatMPIAIJSetPreallocation(*A, d_nz, d_nnz, o_nz, o_nnz));
1198f86e40fSKarl Rupp   } else {
1209566063dSJacob Faibussowitsch     PetscCall(MatSetType(*A, MATSEQAIJVIENNACL));
1219566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(*A, d_nz, d_nnz));
1228f86e40fSKarl Rupp   }
1233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1248f86e40fSKarl Rupp }
1258f86e40fSKarl Rupp 
1263ca39a21SBarry Smith /*MC
1278f86e40fSKarl Rupp    MATAIJVIENNACL - MATMPIAIJVIENNACL= "aijviennacl" = "mpiaijviennacl" - A matrix type to be used for sparse matrices.
1288f86e40fSKarl Rupp 
1298f86e40fSKarl Rupp    A matrix type (CSR format) whose data resides on GPUs.
1308f86e40fSKarl Rupp    All matrix calculations are performed using the ViennaCL library.
1318f86e40fSKarl Rupp 
13211a5261eSBarry Smith    This matrix type is identical to `MATSEQAIJVIENNACL` when constructed with a single process communicator,
13311a5261eSBarry Smith    and `MATMPIAIJVIENNACL` otherwise.  As a result, for single process communicators,
13411a5261eSBarry Smith    `MatSeqAIJSetPreallocation()` is supported, and similarly `MatMPIAIJSetPreallocation()` is supported
1358f86e40fSKarl Rupp    for communicators controlling multiple processes.  It is recommended that you call both of
1368f86e40fSKarl Rupp    the above preallocation routines for simplicity.
1378f86e40fSKarl Rupp 
1388f86e40fSKarl Rupp    Options Database Keys:
13911a5261eSBarry Smith .  -mat_type mpiaijviennacl - sets the matrix type to `MATAIJVIENNACL` during a call to `MatSetFromOptions()`
1408f86e40fSKarl Rupp 
1418f86e40fSKarl Rupp   Level: beginner
1428f86e40fSKarl Rupp 
143db781477SPatrick Sanan  .seealso: `MatCreateAIJViennaCL()`, `MATSEQAIJVIENNACL`, `MatCreateSeqAIJVIENNACL()`
1448f86e40fSKarl Rupp M*/
145