161e22dc2SBarry Smith 2c6db04a5SJed Brown #include <../src/mat/impls/baij/seq/baij.h> 361e22dc2SBarry Smith 4d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqBAIJ_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 5d71ae5a4SJacob Faibussowitsch { 6676c34cdSKris Buschelman Mat B; 70f6d62edSLisandro Dalcin Mat_SeqAIJ *b; 80f6d62edSLisandro Dalcin PetscBool roworiented; 961e22dc2SBarry Smith Mat_SeqBAIJ *a = (Mat_SeqBAIJ *)A->data; 10d0f46423SBarry Smith PetscInt bs = A->rmap->bs, *ai = a->i, *aj = a->j, n = A->rmap->N / bs, i, j, k; 11690b6cddSBarry Smith PetscInt *rowlengths, *rows, *cols, maxlen = 0, ncols; 12dd6ea824SBarry Smith MatScalar *aa = a->a; 1361e22dc2SBarry Smith 1461e22dc2SBarry Smith PetscFunctionBegin; 150f6d62edSLisandro Dalcin if (reuse == MAT_REUSE_MATRIX) { 160f6d62edSLisandro Dalcin B = *newmat; 17ad540459SPierre Jolivet for (i = 0; i < n; i++) maxlen = PetscMax(maxlen, (ai[i + 1] - ai[i])); 180f6d62edSLisandro Dalcin } else { 199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n * bs, &rowlengths)); 2061e22dc2SBarry Smith for (i = 0; i < n; i++) { 21b9b97703SBarry Smith maxlen = PetscMax(maxlen, (ai[i + 1] - ai[i])); 22ad540459SPierre Jolivet for (j = 0; j < bs; j++) rowlengths[i * bs + j] = bs * (ai[i + 1] - ai[i]); 2361e22dc2SBarry Smith } 249566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 259566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 269566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 279566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizes(B, A->rmap->bs, A->cmap->bs)); 289566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, 0, rowlengths)); 299566063dSJacob Faibussowitsch PetscCall(PetscFree(rowlengths)); 300f6d62edSLisandro Dalcin } 310f6d62edSLisandro Dalcin b = (Mat_SeqAIJ *)B->data; 320f6d62edSLisandro Dalcin roworiented = b->roworiented; 3361e22dc2SBarry Smith 349566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_ROW_ORIENTED, PETSC_FALSE)); 359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bs, &rows)); 369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bs * maxlen, &cols)); 37b9b97703SBarry Smith for (i = 0; i < n; i++) { 38ad540459SPierre Jolivet for (j = 0; j < bs; j++) rows[j] = i * bs + j; 39b9b97703SBarry Smith ncols = ai[i + 1] - ai[i]; 40b9b97703SBarry Smith for (k = 0; k < ncols; k++) { 41ad540459SPierre Jolivet for (j = 0; j < bs; j++) cols[k * bs + j] = bs * (*aj) + j; 42b9b97703SBarry Smith aj++; 43b9b97703SBarry Smith } 449566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, bs, rows, bs * ncols, cols, aa, INSERT_VALUES)); 45b9b97703SBarry Smith aa += ncols * bs * bs; 46b9b97703SBarry Smith } 479566063dSJacob Faibussowitsch PetscCall(PetscFree(cols)); 489566063dSJacob Faibussowitsch PetscCall(PetscFree(rows)); 499566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 509566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 519566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_ROW_ORIENTED, roworiented)); 52521d7252SBarry Smith 53511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 549566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 55ae8d29abSPierre Jolivet } else *newmat = B; 563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5761e22dc2SBarry Smith } 5861e22dc2SBarry Smith 59c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> 6085fc7724SBarry Smith 61247fa90bSBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqBAIJ_Preallocate(Mat A, PetscInt **nnz) 62247fa90bSBarry Smith { 63247fa90bSBarry Smith Mat_SeqAIJ *Aa = (Mat_SeqAIJ *)A->data; 64*f85a0629SBarry Smith PetscInt m, n, bs = PetscAbs(A->rmap->bs); 65*f85a0629SBarry Smith const PetscInt *ai = Aa->i, *aj = Aa->j; 66247fa90bSBarry Smith 67247fa90bSBarry Smith PetscFunctionBegin; 68247fa90bSBarry Smith PetscCall(MatGetSize(A, &m, &n)); 69247fa90bSBarry Smith 70*f85a0629SBarry Smith if (bs == 1) { 71*f85a0629SBarry Smith PetscCall(PetscMalloc1(m, nnz)); 72*f85a0629SBarry Smith for (PetscInt i = 0; i < m; i++) (*nnz)[i] = ai[i + 1] - ai[i]; 73*f85a0629SBarry Smith } else { 74*f85a0629SBarry Smith PetscHSetIJ ht; 75*f85a0629SBarry Smith PetscInt k; 76*f85a0629SBarry Smith PetscHashIJKey key; 77*f85a0629SBarry Smith PetscBool missing; 78*f85a0629SBarry Smith 79*f85a0629SBarry Smith PetscCall(PetscHSetIJCreate(&ht)); 80*f85a0629SBarry Smith PetscCall(PetscCalloc1(m / bs, nnz)); 81*f85a0629SBarry Smith for (PetscInt i = 0; i < m; i++) { 82*f85a0629SBarry Smith key.i = i / bs; 83*f85a0629SBarry Smith for (k = ai[i]; k < ai[i + 1]; k++) { 84*f85a0629SBarry Smith key.j = aj[k] / bs; 85*f85a0629SBarry Smith PetscCall(PetscHSetIJQueryAdd(ht, key, &missing)); 86*f85a0629SBarry Smith if (missing) (*nnz)[key.i]++; 87247fa90bSBarry Smith } 88247fa90bSBarry Smith } 89*f85a0629SBarry Smith PetscCall(PetscHSetIJDestroy(&ht)); 90247fa90bSBarry Smith } 913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92247fa90bSBarry Smith } 93247fa90bSBarry Smith 94d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqBAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 95d71ae5a4SJacob Faibussowitsch { 96676c34cdSKris Buschelman Mat B; 9785fc7724SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 9885fc7724SBarry Smith Mat_SeqBAIJ *b; 99247fa90bSBarry Smith PetscInt m = A->rmap->N, n = A->cmap->N, *rowlengths, bs = PetscAbs(A->rmap->bs); 10085fc7724SBarry Smith 10185fc7724SBarry Smith PetscFunctionBegin; 102345dab1aSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 103247fa90bSBarry Smith PetscCall(MatConvert_SeqAIJ_SeqBAIJ_Preallocate(A, &rowlengths)); 1049566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1059566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, m, n)); 1069566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQBAIJ)); 1079566063dSJacob Faibussowitsch PetscCall(MatSeqBAIJSetPreallocation(B, bs, 0, rowlengths)); 1089566063dSJacob Faibussowitsch PetscCall(PetscFree(rowlengths)); 109345dab1aSStefano Zampini } else B = *newmat; 11085fc7724SBarry Smith 111ae8d29abSPierre Jolivet if (bs == 1) { 112676c34cdSKris Buschelman b = (Mat_SeqBAIJ *)(B->data); 11385fc7724SBarry Smith 1149566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(b->i, a->i, m + 1)); 1159566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(b->ilen, a->ilen, m)); 1169566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(b->j, a->j, a->nz)); 1179566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(b->a, a->a, a->nz)); 11885fc7724SBarry Smith 1199566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_ROW_ORIENTED, PETSC_TRUE)); 1209566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 1219566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 122ae8d29abSPierre Jolivet } else { 123ae8d29abSPierre Jolivet /* reuse may not be equal to MAT_REUSE_MATRIX, but the basic converter will reallocate or replace newmat if this value is not used */ 124ae8d29abSPierre Jolivet /* if reuse is equal to MAT_INITIAL_MATRIX, it has been appropriately preallocated before */ 125ae8d29abSPierre Jolivet /* MAT_INPLACE_MATRIX, it will be replaced with MatHeaderReplace below */ 1269566063dSJacob Faibussowitsch PetscCall(MatConvert_Basic(A, newtype, MAT_REUSE_MATRIX, &B)); 127ae8d29abSPierre Jolivet } 128676c34cdSKris Buschelman 129511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 1309566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 131ae8d29abSPierre Jolivet } else *newmat = B; 1323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13385fc7724SBarry Smith } 134