16f79c3a4SBarry Smith 2af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 36f79c3a4SBarry Smith 4d54c938cSPierre Jolivet static PetscErrorCode MatTransposeAXPY_Private(Mat Y,PetscScalar a,Mat X,MatStructure str,Mat T) 5d54c938cSPierre Jolivet { 6d54c938cSPierre Jolivet PetscErrorCode ierr,(*f)(Mat,Mat*); 7d54c938cSPierre Jolivet Mat A,F; 8d54c938cSPierre Jolivet 9d54c938cSPierre Jolivet PetscFunctionBegin; 10d54c938cSPierre Jolivet ierr = PetscObjectQueryFunction((PetscObject)T,"MatTransposeGetMat_C",&f);CHKERRQ(ierr); 11d54c938cSPierre Jolivet if (f) { 12d54c938cSPierre Jolivet ierr = MatTransposeGetMat(T,&A);CHKERRQ(ierr); 13d54c938cSPierre Jolivet if (T == X) { 14d54c938cSPierre Jolivet ierr = PetscInfo(NULL,"Explicitly transposing X of type MATTRANSPOSEMAT to perform MatAXPY()\n");CHKERRQ(ierr); 15d54c938cSPierre Jolivet ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&F);CHKERRQ(ierr); 16d54c938cSPierre Jolivet A = Y; 17d54c938cSPierre Jolivet } else { 18d54c938cSPierre Jolivet ierr = PetscInfo(NULL,"Transposing X because Y of type MATTRANSPOSEMAT to perform MatAXPY()\n");CHKERRQ(ierr); 19d54c938cSPierre Jolivet ierr = MatTranspose(X,MAT_INITIAL_MATRIX,&F);CHKERRQ(ierr); 20d54c938cSPierre Jolivet } 21d54c938cSPierre Jolivet } else { 22d54c938cSPierre Jolivet ierr = MatHermitianTransposeGetMat(T,&A);CHKERRQ(ierr); 23d54c938cSPierre Jolivet if (T == X) { 24d54c938cSPierre Jolivet ierr = PetscInfo(NULL,"Explicitly Hermitian transposing X of type MATTRANSPOSEMAT to perform MatAXPY()\n");CHKERRQ(ierr); 25d54c938cSPierre Jolivet ierr = MatHermitianTranspose(A,MAT_INITIAL_MATRIX,&F);CHKERRQ(ierr); 26d54c938cSPierre Jolivet A = Y; 27d54c938cSPierre Jolivet } else { 28d54c938cSPierre Jolivet ierr = PetscInfo(NULL,"Hermitian transposing X because Y of type MATTRANSPOSEMAT to perform MatAXPY()\n");CHKERRQ(ierr); 29d54c938cSPierre Jolivet ierr = MatHermitianTranspose(X,MAT_INITIAL_MATRIX,&F);CHKERRQ(ierr); 30d54c938cSPierre Jolivet } 31d54c938cSPierre Jolivet } 32d54c938cSPierre Jolivet ierr = MatAXPY(A,a,F,str);CHKERRQ(ierr); 33d54c938cSPierre Jolivet ierr = MatDestroy(&F);CHKERRQ(ierr); 34d54c938cSPierre Jolivet PetscFunctionReturn(0); 35d54c938cSPierre Jolivet } 36d54c938cSPierre Jolivet 3706be10caSBarry Smith /*@ 3821c89e3eSBarry Smith MatAXPY - Computes Y = a*X + Y. 396f79c3a4SBarry Smith 403f9fe445SBarry Smith Logically Collective on Mat 41fee21e36SBarry Smith 4298a79cdbSBarry Smith Input Parameters: 43607cd303SBarry Smith + a - the scalar multiplier 44607cd303SBarry Smith . X - the first matrix 45607cd303SBarry Smith . Y - the second matrix 46407f6b05SHong Zhang - str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN 47407f6b05SHong Zhang or SUBSET_NONZERO_PATTERN (nonzeros of X is a subset of Y's) 4898a79cdbSBarry Smith 492860a424SLois Curfman McInnes Level: intermediate 502860a424SLois Curfman McInnes 512860a424SLois Curfman McInnes .seealso: MatAYPX() 5206be10caSBarry Smith @*/ 537087cfbeSBarry Smith PetscErrorCode MatAXPY(Mat Y,PetscScalar a,Mat X,MatStructure str) 546f79c3a4SBarry Smith { 55d54c938cSPierre Jolivet PetscErrorCode ierr; 56646531bbSStefano Zampini PetscInt M1,M2,N1,N2; 57c1ac3661SBarry Smith PetscInt m1,m2,n1,n2; 58a683ea4aSPierre Jolivet MatType t1,t2; 59a683ea4aSPierre Jolivet PetscBool sametype,transpose; 606f79c3a4SBarry Smith 613a40ed3dSBarry Smith PetscFunctionBegin; 620700a824SBarry Smith PetscValidHeaderSpecific(Y,MAT_CLASSID,1); 63c5eb9154SBarry Smith PetscValidLogicalCollectiveScalar(Y,a,2); 64646531bbSStefano Zampini PetscValidHeaderSpecific(X,MAT_CLASSID,3); 65646531bbSStefano Zampini PetscCheckSameComm(Y,1,X,3); 66646531bbSStefano Zampini ierr = MatGetSize(X,&M1,&N1);CHKERRQ(ierr); 67646531bbSStefano Zampini ierr = MatGetSize(Y,&M2,&N2);CHKERRQ(ierr); 68646531bbSStefano Zampini ierr = MatGetLocalSize(X,&m1,&n1);CHKERRQ(ierr); 69646531bbSStefano Zampini ierr = MatGetLocalSize(Y,&m2,&n2);CHKERRQ(ierr); 70646531bbSStefano Zampini if (M1 != M2 || N1 != N2) SETERRQ4(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_SIZ,"Non conforming matrix add: global sizes %D x %D, %D x %D",M1,M2,N1,N2); 71646531bbSStefano Zampini if (m1 != m2 || n1 != n2) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Non conforming matrix add: local sizes %D x %D, %D x %D",m1,m2,n1,n2); 721987afe7SBarry Smith 73a683ea4aSPierre Jolivet ierr = MatGetType(X,&t1);CHKERRQ(ierr); 74a683ea4aSPierre Jolivet ierr = MatGetType(Y,&t2);CHKERRQ(ierr); 75a683ea4aSPierre Jolivet ierr = PetscStrcmp(t1,t2,&sametype);CHKERRQ(ierr); 76e8136da8SHong Zhang ierr = PetscLogEventBegin(MAT_AXPY,Y,0,0,0);CHKERRQ(ierr); 770ff8bee4SStefano Zampini if (Y->ops->axpy && sametype) { 78f4df32b1SMatthew Knepley ierr = (*Y->ops->axpy)(Y,a,X,str);CHKERRQ(ierr); 79d4bb536fSBarry Smith } else { 80a683ea4aSPierre Jolivet ierr = PetscStrcmp(t1,MATTRANSPOSEMAT,&transpose);CHKERRQ(ierr); 81a683ea4aSPierre Jolivet if (transpose) { 82d54c938cSPierre Jolivet ierr = MatTransposeAXPY_Private(Y,a,X,str,X);CHKERRQ(ierr); 83a683ea4aSPierre Jolivet } else { 84a683ea4aSPierre Jolivet ierr = PetscStrcmp(t2,MATTRANSPOSEMAT,&transpose);CHKERRQ(ierr); 85a683ea4aSPierre Jolivet if (transpose) { 86d54c938cSPierre Jolivet ierr = MatTransposeAXPY_Private(Y,a,X,str,Y);CHKERRQ(ierr); 87a683ea4aSPierre Jolivet } else { 88646531bbSStefano Zampini if (str != DIFFERENT_NONZERO_PATTERN) { 89f4df32b1SMatthew Knepley ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 90646531bbSStefano Zampini } else { 91646531bbSStefano Zampini Mat B; 92646531bbSStefano Zampini 93646531bbSStefano Zampini ierr = MatAXPY_Basic_Preallocate(Y,X,&B);CHKERRQ(ierr); 94646531bbSStefano Zampini ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 95646531bbSStefano Zampini ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 96646531bbSStefano Zampini } 97607cd303SBarry Smith } 98a683ea4aSPierre Jolivet } 99a683ea4aSPierre Jolivet } 100e8136da8SHong Zhang ierr = PetscLogEventEnd(MAT_AXPY,Y,0,0,0);CHKERRQ(ierr); 101fd314934SBarry Smith #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 102b8ced49eSKarl Rupp if (Y->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 103b8ced49eSKarl Rupp Y->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 104c41cb2e2SAlejandro Lamas Daviña } 105d67ff14aSKarl Rupp #endif 106607cd303SBarry Smith PetscFunctionReturn(0); 107607cd303SBarry Smith } 108607cd303SBarry Smith 109646531bbSStefano Zampini PetscErrorCode MatAXPY_Basic_Preallocate(Mat Y, Mat X, Mat *B) 110646531bbSStefano Zampini { 111646531bbSStefano Zampini PetscErrorCode ierr; 11227afe9e8SStefano Zampini PetscErrorCode (*preall)(Mat,Mat,Mat*) = NULL; 113646531bbSStefano Zampini 114646531bbSStefano Zampini PetscFunctionBegin; 115646531bbSStefano Zampini /* look for any available faster alternative to the general preallocator */ 116646531bbSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)Y,"MatAXPYGetPreallocation_C",&preall);CHKERRQ(ierr); 117646531bbSStefano Zampini if (preall) { 118646531bbSStefano Zampini ierr = (*preall)(Y,X,B);CHKERRQ(ierr); 119646531bbSStefano Zampini } else { /* Use MatPrellocator, assumes same row-col distribution */ 120646531bbSStefano Zampini Mat preallocator; 121646531bbSStefano Zampini PetscInt r,rstart,rend; 122646531bbSStefano Zampini PetscInt m,n,M,N; 123646531bbSStefano Zampini 1246eab9c35SStefano Zampini ierr = MatGetRowUpperTriangular(Y);CHKERRQ(ierr); 1256eab9c35SStefano Zampini ierr = MatGetRowUpperTriangular(X);CHKERRQ(ierr); 126646531bbSStefano Zampini ierr = MatGetSize(Y,&M,&N);CHKERRQ(ierr); 127646531bbSStefano Zampini ierr = MatGetLocalSize(Y,&m,&n);CHKERRQ(ierr); 128646531bbSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)Y),&preallocator);CHKERRQ(ierr); 129646531bbSStefano Zampini ierr = MatSetType(preallocator,MATPREALLOCATOR);CHKERRQ(ierr); 130646531bbSStefano Zampini ierr = MatSetSizes(preallocator,m,n,M,N);CHKERRQ(ierr); 131646531bbSStefano Zampini ierr = MatSetUp(preallocator);CHKERRQ(ierr); 132646531bbSStefano Zampini ierr = MatGetOwnershipRange(preallocator,&rstart,&rend);CHKERRQ(ierr); 133646531bbSStefano Zampini for (r = rstart; r < rend; ++r) { 134646531bbSStefano Zampini PetscInt ncols; 135646531bbSStefano Zampini const PetscInt *row; 136646531bbSStefano Zampini const PetscScalar *vals; 137646531bbSStefano Zampini 138646531bbSStefano Zampini ierr = MatGetRow(Y,r,&ncols,&row,&vals);CHKERRQ(ierr); 139646531bbSStefano Zampini ierr = MatSetValues(preallocator,1,&r,ncols,row,vals,INSERT_VALUES);CHKERRQ(ierr); 140646531bbSStefano Zampini ierr = MatRestoreRow(Y,r,&ncols,&row,&vals);CHKERRQ(ierr); 141646531bbSStefano Zampini ierr = MatGetRow(X,r,&ncols,&row,&vals);CHKERRQ(ierr); 142646531bbSStefano Zampini ierr = MatSetValues(preallocator,1,&r,ncols,row,vals,INSERT_VALUES);CHKERRQ(ierr); 143646531bbSStefano Zampini ierr = MatRestoreRow(X,r,&ncols,&row,&vals);CHKERRQ(ierr); 144646531bbSStefano Zampini } 145646531bbSStefano Zampini ierr = MatAssemblyBegin(preallocator,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 146646531bbSStefano Zampini ierr = MatAssemblyEnd(preallocator,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1476eab9c35SStefano Zampini ierr = MatRestoreRowUpperTriangular(Y);CHKERRQ(ierr); 1486eab9c35SStefano Zampini ierr = MatRestoreRowUpperTriangular(X);CHKERRQ(ierr); 149646531bbSStefano Zampini 150646531bbSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)Y),B);CHKERRQ(ierr); 151646531bbSStefano Zampini ierr = MatSetType(*B,((PetscObject)Y)->type_name);CHKERRQ(ierr); 152646531bbSStefano Zampini ierr = MatSetSizes(*B,m,n,M,N);CHKERRQ(ierr); 153646531bbSStefano Zampini ierr = MatPreallocatorPreallocate(preallocator,PETSC_FALSE,*B);CHKERRQ(ierr); 154646531bbSStefano Zampini ierr = MatDestroy(&preallocator);CHKERRQ(ierr); 155646531bbSStefano Zampini } 156646531bbSStefano Zampini PetscFunctionReturn(0); 157646531bbSStefano Zampini } 158646531bbSStefano Zampini 159f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_Basic(Mat Y,PetscScalar a,Mat X,MatStructure str) 160607cd303SBarry Smith { 16138baddfdSBarry Smith PetscInt i,start,end,j,ncols,m,n; 1626849ba73SBarry Smith PetscErrorCode ierr; 16338baddfdSBarry Smith const PetscInt *row; 164b3cc6726SBarry Smith PetscScalar *val; 165b3cc6726SBarry Smith const PetscScalar *vals; 166607cd303SBarry Smith 167607cd303SBarry Smith PetscFunctionBegin; 1688dadbd76SSatish Balay ierr = MatGetSize(X,&m,&n);CHKERRQ(ierr); 16990f02eecSBarry Smith ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr); 1706eab9c35SStefano Zampini ierr = MatGetRowUpperTriangular(X);CHKERRQ(ierr); 171f4df32b1SMatthew Knepley if (a == 1.0) { 172d4bb536fSBarry Smith for (i = start; i < end; i++) { 173d4bb536fSBarry Smith ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 174d4bb536fSBarry Smith ierr = MatSetValues(Y,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); 175d4bb536fSBarry Smith ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 176d4bb536fSBarry Smith } 177d4bb536fSBarry Smith } else { 17821a3365eSStefano Zampini PetscInt vs = 100; 17921a3365eSStefano Zampini /* realloc if needed, as this function may be used in parallel */ 18021a3365eSStefano Zampini ierr = PetscMalloc1(vs,&val);CHKERRQ(ierr); 18106be10caSBarry Smith for (i=start; i<end; i++) { 182b3cc6726SBarry Smith ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 18321a3365eSStefano Zampini if (vs < ncols) { 18421a3365eSStefano Zampini vs = PetscMin(2*ncols,n); 18521a3365eSStefano Zampini ierr = PetscRealloc(vs*sizeof(*val),&val);CHKERRQ(ierr); 1866f79c3a4SBarry Smith } 18721a3365eSStefano Zampini for (j=0; j<ncols; j++) val[j] = a*vals[j]; 188b3cc6726SBarry Smith ierr = MatSetValues(Y,1,&i,ncols,row,val,ADD_VALUES);CHKERRQ(ierr); 189b3cc6726SBarry Smith ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 1906f79c3a4SBarry Smith } 191b3cc6726SBarry Smith ierr = PetscFree(val);CHKERRQ(ierr); 192d4bb536fSBarry Smith } 1936eab9c35SStefano Zampini ierr = MatRestoreRowUpperTriangular(X);CHKERRQ(ierr); 1946d4a8577SBarry Smith ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1956d4a8577SBarry Smith ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1963a40ed3dSBarry Smith PetscFunctionReturn(0); 1976f79c3a4SBarry Smith } 198052efed2SBarry Smith 199ec7775f6SShri Abhyankar PetscErrorCode MatAXPY_BasicWithPreallocation(Mat B,Mat Y,PetscScalar a,Mat X,MatStructure str) 200ec7775f6SShri Abhyankar { 201ec7775f6SShri Abhyankar PetscInt i,start,end,j,ncols,m,n; 202ec7775f6SShri Abhyankar PetscErrorCode ierr; 203ec7775f6SShri Abhyankar const PetscInt *row; 204ec7775f6SShri Abhyankar PetscScalar *val; 205ec7775f6SShri Abhyankar const PetscScalar *vals; 206ec7775f6SShri Abhyankar 207ec7775f6SShri Abhyankar PetscFunctionBegin; 208ec7775f6SShri Abhyankar ierr = MatGetSize(X,&m,&n);CHKERRQ(ierr); 209ec7775f6SShri Abhyankar ierr = MatGetOwnershipRange(X,&start,&end);CHKERRQ(ierr); 2106eab9c35SStefano Zampini ierr = MatGetRowUpperTriangular(Y);CHKERRQ(ierr); 2116eab9c35SStefano Zampini ierr = MatGetRowUpperTriangular(X);CHKERRQ(ierr); 212ec7775f6SShri Abhyankar if (a == 1.0) { 213ec7775f6SShri Abhyankar for (i = start; i < end; i++) { 214ec7775f6SShri Abhyankar ierr = MatGetRow(Y,i,&ncols,&row,&vals);CHKERRQ(ierr); 215ec7775f6SShri Abhyankar ierr = MatSetValues(B,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); 216ec7775f6SShri Abhyankar ierr = MatRestoreRow(Y,i,&ncols,&row,&vals);CHKERRQ(ierr); 217ec7775f6SShri Abhyankar 218ec7775f6SShri Abhyankar ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 219ec7775f6SShri Abhyankar ierr = MatSetValues(B,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); 220ec7775f6SShri Abhyankar ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 221ec7775f6SShri Abhyankar } 222ec7775f6SShri Abhyankar } else { 22321a3365eSStefano Zampini PetscInt vs = 100; 22421a3365eSStefano Zampini /* realloc if needed, as this function may be used in parallel */ 22521a3365eSStefano Zampini ierr = PetscMalloc1(vs,&val);CHKERRQ(ierr); 226ec7775f6SShri Abhyankar for (i=start; i<end; i++) { 227ec7775f6SShri Abhyankar ierr = MatGetRow(Y,i,&ncols,&row,&vals);CHKERRQ(ierr); 228ec7775f6SShri Abhyankar ierr = MatSetValues(B,1,&i,ncols,row,vals,ADD_VALUES);CHKERRQ(ierr); 229ec7775f6SShri Abhyankar ierr = MatRestoreRow(Y,i,&ncols,&row,&vals);CHKERRQ(ierr); 230ec7775f6SShri Abhyankar 231ec7775f6SShri Abhyankar ierr = MatGetRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 23221a3365eSStefano Zampini if (vs < ncols) { 23321a3365eSStefano Zampini vs = PetscMin(2*ncols,n); 23421a3365eSStefano Zampini ierr = PetscRealloc(vs*sizeof(*val),&val);CHKERRQ(ierr); 235ec7775f6SShri Abhyankar } 23621a3365eSStefano Zampini for (j=0; j<ncols; j++) val[j] = a*vals[j]; 237ec7775f6SShri Abhyankar ierr = MatSetValues(B,1,&i,ncols,row,val,ADD_VALUES);CHKERRQ(ierr); 238ec7775f6SShri Abhyankar ierr = MatRestoreRow(X,i,&ncols,&row,&vals);CHKERRQ(ierr); 239ec7775f6SShri Abhyankar } 240ec7775f6SShri Abhyankar ierr = PetscFree(val);CHKERRQ(ierr); 241ec7775f6SShri Abhyankar } 2426eab9c35SStefano Zampini ierr = MatRestoreRowUpperTriangular(Y);CHKERRQ(ierr); 2436eab9c35SStefano Zampini ierr = MatRestoreRowUpperTriangular(X);CHKERRQ(ierr); 244ec7775f6SShri Abhyankar ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 245ec7775f6SShri Abhyankar ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 246ec7775f6SShri Abhyankar PetscFunctionReturn(0); 247ec7775f6SShri Abhyankar } 248ec7775f6SShri Abhyankar 249052efed2SBarry Smith /*@ 25087828ca2SBarry Smith MatShift - Computes Y = Y + a I, where a is a PetscScalar and I is the identity matrix. 251052efed2SBarry Smith 2523f9fe445SBarry Smith Neighbor-wise Collective on Mat 253fee21e36SBarry Smith 25498a79cdbSBarry Smith Input Parameters: 25598a79cdbSBarry Smith + Y - the matrices 25687828ca2SBarry Smith - a - the PetscScalar 25798a79cdbSBarry Smith 2582860a424SLois Curfman McInnes Level: intermediate 2592860a424SLois Curfman McInnes 26095452b02SPatrick Sanan Notes: 26195452b02SPatrick Sanan If the matrix Y is missing some diagonal entries this routine can be very slow. To make it fast one should initially 2626f33a894SBarry Smith fill the matrix so that all diagonal entries have a value (with a value of zero for those locations that would not have an 2636f33a894SBarry Smith entry). 2646f33a894SBarry Smith 2650c0fd78eSBarry Smith To form Y = Y + diag(V) use MatDiagonalSet() 2660c0fd78eSBarry Smith 2676f33a894SBarry Smith Developers Note: If the local "diagonal part" of the matrix Y has no entries then the local diagonal part is 2686f33a894SBarry Smith preallocated with 1 nonzero per row for the to be added values. This allows for fast shifting of an empty matrix. 2696f33a894SBarry Smith 2700c0fd78eSBarry Smith .seealso: MatDiagonalSet(), MatScale(), MatDiagonalScale() 271052efed2SBarry Smith @*/ 2727087cfbeSBarry Smith PetscErrorCode MatShift(Mat Y,PetscScalar a) 273052efed2SBarry Smith { 2746849ba73SBarry Smith PetscErrorCode ierr; 275052efed2SBarry Smith 2763a40ed3dSBarry Smith PetscFunctionBegin; 2770700a824SBarry Smith PetscValidHeaderSpecific(Y,MAT_CLASSID,1); 278ce94432eSBarry Smith if (!Y->assembled) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 279ce94432eSBarry Smith if (Y->factortype) SETERRQ(PetscObjectComm((PetscObject)Y),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2804994cf47SJed Brown MatCheckPreallocated(Y,1); 2811b71c1a7SBarry Smith if (a == 0.0) PetscFunctionReturn(0); 282b50b34bdSBarry Smith 2831c738b47SStefano Zampini if (Y->ops->shift) { 284f4df32b1SMatthew Knepley ierr = (*Y->ops->shift)(Y,a);CHKERRQ(ierr); 2851c738b47SStefano Zampini } else { 2861c738b47SStefano Zampini ierr = MatShift_Basic(Y,a);CHKERRQ(ierr); 2871c738b47SStefano Zampini } 2887d68702bSBarry Smith 2895528ad4fSTristan Konolige ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 290fd314934SBarry Smith #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 291b8ced49eSKarl Rupp if (Y->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 292b8ced49eSKarl Rupp Y->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 293c41cb2e2SAlejandro Lamas Daviña } 294d67ff14aSKarl Rupp #endif 2953a40ed3dSBarry Smith PetscFunctionReturn(0); 296052efed2SBarry Smith } 2976d84be18SBarry Smith 2987087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_Default(Mat Y,Vec D,InsertMode is) 29909f38230SBarry Smith { 30009f38230SBarry Smith PetscErrorCode ierr; 30167576b8bSBarry Smith PetscInt i,start,end; 30209f38230SBarry Smith PetscScalar *v; 30309f38230SBarry Smith 30409f38230SBarry Smith PetscFunctionBegin; 30509f38230SBarry Smith ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); 30609f38230SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 30709f38230SBarry Smith for (i=start; i<end; i++) { 30809f38230SBarry Smith ierr = MatSetValues(Y,1,&i,1,&i,v+i-start,is);CHKERRQ(ierr); 30909f38230SBarry Smith } 31009f38230SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 31109f38230SBarry Smith ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 31209f38230SBarry Smith ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 31309f38230SBarry Smith PetscFunctionReturn(0); 31409f38230SBarry Smith } 31509f38230SBarry Smith 3166d84be18SBarry Smith /*@ 317f56f2b3fSBarry Smith MatDiagonalSet - Computes Y = Y + D, where D is a diagonal matrix 318f56f2b3fSBarry Smith that is represented as a vector. Or Y[i,i] = D[i] if InsertMode is 319f56f2b3fSBarry Smith INSERT_VALUES. 3206d84be18SBarry Smith 3216d84be18SBarry Smith Input Parameters: 32298a79cdbSBarry Smith + Y - the input matrix 323f56f2b3fSBarry Smith . D - the diagonal matrix, represented as a vector 324f56f2b3fSBarry Smith - i - INSERT_VALUES or ADD_VALUES 3256d84be18SBarry Smith 326*d083f849SBarry Smith Neighbor-wise Collective on Mat 327fee21e36SBarry Smith 32895452b02SPatrick Sanan Notes: 32995452b02SPatrick Sanan If the matrix Y is missing some diagonal entries this routine can be very slow. To make it fast one should initially 3306f33a894SBarry Smith fill the matrix so that all diagonal entries have a value (with a value of zero for those locations that would not have an 3316f33a894SBarry Smith entry). 3326f33a894SBarry Smith 3332860a424SLois Curfman McInnes Level: intermediate 3342860a424SLois Curfman McInnes 3350c0fd78eSBarry Smith .seealso: MatShift(), MatScale(), MatDiagonalScale() 3366d84be18SBarry Smith @*/ 3377087cfbeSBarry Smith PetscErrorCode MatDiagonalSet(Mat Y,Vec D,InsertMode is) 3386d84be18SBarry Smith { 3396849ba73SBarry Smith PetscErrorCode ierr; 34067576b8bSBarry Smith PetscInt matlocal,veclocal; 3416d84be18SBarry Smith 3423a40ed3dSBarry Smith PetscFunctionBegin; 3430700a824SBarry Smith PetscValidHeaderSpecific(Y,MAT_CLASSID,1); 3440700a824SBarry Smith PetscValidHeaderSpecific(D,VEC_CLASSID,2); 34567576b8bSBarry Smith ierr = MatGetLocalSize(Y,&matlocal,NULL);CHKERRQ(ierr); 34667576b8bSBarry Smith ierr = VecGetLocalSize(D,&veclocal);CHKERRQ(ierr); 34767576b8bSBarry Smith if (matlocal != veclocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number local rows of matrix %D does not match that of vector for diagonal %D",matlocal,veclocal); 348f56f2b3fSBarry Smith if (Y->ops->diagonalset) { 349f56f2b3fSBarry Smith ierr = (*Y->ops->diagonalset)(Y,D,is);CHKERRQ(ierr); 35094d884c6SBarry Smith } else { 35109f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 3526d84be18SBarry Smith } 3535528ad4fSTristan Konolige ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 3543a40ed3dSBarry Smith PetscFunctionReturn(0); 3556d84be18SBarry Smith } 356d4bb536fSBarry Smith 357d4bb536fSBarry Smith /*@ 35804aac2b0SHong Zhang MatAYPX - Computes Y = a*Y + X. 359d4bb536fSBarry Smith 3603f9fe445SBarry Smith Logically on Mat 361fee21e36SBarry Smith 36298a79cdbSBarry Smith Input Parameters: 36304aac2b0SHong Zhang + a - the PetscScalar multiplier 36404aac2b0SHong Zhang . Y - the first matrix 36504aac2b0SHong Zhang . X - the second matrix 36604aac2b0SHong Zhang - str - either SAME_NONZERO_PATTERN, DIFFERENT_NONZERO_PATTERN or SUBSET_NONZERO_PATTERN 367d4bb536fSBarry Smith 3682860a424SLois Curfman McInnes Level: intermediate 3692860a424SLois Curfman McInnes 3702860a424SLois Curfman McInnes .seealso: MatAXPY() 371d4bb536fSBarry Smith @*/ 3727087cfbeSBarry Smith PetscErrorCode MatAYPX(Mat Y,PetscScalar a,Mat X,MatStructure str) 373d4bb536fSBarry Smith { 37487828ca2SBarry Smith PetscScalar one = 1.0; 3756849ba73SBarry Smith PetscErrorCode ierr; 37638baddfdSBarry Smith PetscInt mX,mY,nX,nY; 377d4bb536fSBarry Smith 3783a40ed3dSBarry Smith PetscFunctionBegin; 379c5eb9154SBarry Smith PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3800700a824SBarry Smith PetscValidHeaderSpecific(Y,MAT_CLASSID,1); 381c5eb9154SBarry Smith PetscValidLogicalCollectiveScalar(Y,a,2); 382329f5518SBarry Smith ierr = MatGetSize(X,&mX,&nX);CHKERRQ(ierr); 383329f5518SBarry Smith ierr = MatGetSize(X,&mY,&nY);CHKERRQ(ierr); 384e32f2f54SBarry Smith if (mX != mY || nX != nY) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Non conforming matrices: %D %D first %D %D second",mX,mY,nX,nY); 385f4df32b1SMatthew Knepley ierr = MatScale(Y,a);CHKERRQ(ierr); 386cb9801acSJed Brown ierr = MatAXPY(Y,one,X,str);CHKERRQ(ierr); 3873a40ed3dSBarry Smith PetscFunctionReturn(0); 388d4bb536fSBarry Smith } 389b0a32e0cSBarry Smith 390b0a32e0cSBarry Smith /*@ 3910bacdadaSStefano Zampini MatComputeOperator - Computes the explicit matrix 392b0a32e0cSBarry Smith 393b0a32e0cSBarry Smith Collective on Mat 394b0a32e0cSBarry Smith 395b0a32e0cSBarry Smith Input Parameter: 396186a3e20SStefano Zampini + inmat - the matrix 397186a3e20SStefano Zampini - mattype - the matrix type for the explicit operator 398b0a32e0cSBarry Smith 399b0a32e0cSBarry Smith Output Parameter: 400f3b1f45cSBarry Smith . mat - the explict operator 401b0a32e0cSBarry Smith 402b0a32e0cSBarry Smith Notes: 403186a3e20SStefano Zampini This computation is done by applying the operators to columns of the identity matrix. 404186a3e20SStefano Zampini This routine is costly in general, and is recommended for use only with relatively small systems. 405186a3e20SStefano Zampini Currently, this routine uses a dense matrix format if mattype == NULL. 406b0a32e0cSBarry Smith 407b0a32e0cSBarry Smith Level: advanced 408b0a32e0cSBarry Smith 409b0a32e0cSBarry Smith @*/ 4100bacdadaSStefano Zampini PetscErrorCode MatComputeOperator(Mat inmat,MatType mattype,Mat *mat) 411b0a32e0cSBarry Smith { 412dfbe8321SBarry Smith PetscErrorCode ierr; 413b0a32e0cSBarry Smith 414b0a32e0cSBarry Smith PetscFunctionBegin; 4150700a824SBarry Smith PetscValidHeaderSpecific(inmat,MAT_CLASSID,1); 416186a3e20SStefano Zampini PetscValidPointer(mat,3); 417186a3e20SStefano Zampini ierr = MatConvert_Shell(inmat,mattype ? mattype : MATDENSE,MAT_INITIAL_MATRIX,mat);CHKERRQ(ierr); 41824f910e3SHong Zhang PetscFunctionReturn(0); 41924f910e3SHong Zhang } 4204325cce7SMatthew G Knepley 4214325cce7SMatthew G Knepley /*@ 4220bacdadaSStefano Zampini MatComputeOperatorTranspose - Computes the explicit matrix representation of 423f3b1f45cSBarry Smith a give matrix that can apply MatMultTranspose() 424f3b1f45cSBarry Smith 425f3b1f45cSBarry Smith Collective on Mat 426f3b1f45cSBarry Smith 427f3b1f45cSBarry Smith Input Parameter: 428f3b1f45cSBarry Smith . inmat - the matrix 429f3b1f45cSBarry Smith 430f3b1f45cSBarry Smith Output Parameter: 431f3b1f45cSBarry Smith . mat - the explict operator transposed 432f3b1f45cSBarry Smith 433f3b1f45cSBarry Smith Notes: 434186a3e20SStefano Zampini This computation is done by applying the transpose of the operator to columns of the identity matrix. 435186a3e20SStefano Zampini This routine is costly in general, and is recommended for use only with relatively small systems. 436186a3e20SStefano Zampini Currently, this routine uses a dense matrix format if mattype == NULL. 437f3b1f45cSBarry Smith 438f3b1f45cSBarry Smith Level: advanced 439f3b1f45cSBarry Smith 440f3b1f45cSBarry Smith @*/ 4410bacdadaSStefano Zampini PetscErrorCode MatComputeOperatorTranspose(Mat inmat,MatType mattype,Mat *mat) 442f3b1f45cSBarry Smith { 443186a3e20SStefano Zampini Mat A; 444f3b1f45cSBarry Smith PetscErrorCode ierr; 445f3b1f45cSBarry Smith 446f3b1f45cSBarry Smith PetscFunctionBegin; 447f3b1f45cSBarry Smith PetscValidHeaderSpecific(inmat,MAT_CLASSID,1); 448186a3e20SStefano Zampini PetscValidPointer(mat,3); 449186a3e20SStefano Zampini ierr = MatCreateTranspose(inmat,&A);CHKERRQ(ierr); 450186a3e20SStefano Zampini ierr = MatConvert_Shell(A,mattype ? mattype : MATDENSE,MAT_INITIAL_MATRIX,mat);CHKERRQ(ierr); 451186a3e20SStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 452f3b1f45cSBarry Smith PetscFunctionReturn(0); 453f3b1f45cSBarry Smith } 454f3b1f45cSBarry Smith 455f3b1f45cSBarry Smith /*@ 4564325cce7SMatthew G Knepley MatChop - Set all values in the matrix less than the tolerance to zero 4574325cce7SMatthew G Knepley 4584325cce7SMatthew G Knepley Input Parameters: 4594325cce7SMatthew G Knepley + A - The matrix 4604325cce7SMatthew G Knepley - tol - The zero tolerance 4614325cce7SMatthew G Knepley 4624325cce7SMatthew G Knepley Output Parameters: 4634325cce7SMatthew G Knepley . A - The chopped matrix 4644325cce7SMatthew G Knepley 4654325cce7SMatthew G Knepley Level: intermediate 4664325cce7SMatthew G Knepley 4674325cce7SMatthew G Knepley .seealso: MatCreate(), MatZeroEntries() 4683fc99919SSatish Balay @*/ 4694325cce7SMatthew G Knepley PetscErrorCode MatChop(Mat A, PetscReal tol) 4704325cce7SMatthew G Knepley { 4714325cce7SMatthew G Knepley PetscScalar *newVals; 4724325cce7SMatthew G Knepley PetscInt *newCols; 4734325cce7SMatthew G Knepley PetscInt rStart, rEnd, numRows, maxRows, r, colMax = 0; 4744325cce7SMatthew G Knepley PetscErrorCode ierr; 4754325cce7SMatthew G Knepley 4764325cce7SMatthew G Knepley PetscFunctionBegin; 4774325cce7SMatthew G Knepley ierr = MatGetOwnershipRange(A, &rStart, &rEnd);CHKERRQ(ierr); 4784325cce7SMatthew G Knepley for (r = rStart; r < rEnd; ++r) { 4794325cce7SMatthew G Knepley PetscInt ncols; 4804325cce7SMatthew G Knepley 4810298fd71SBarry Smith ierr = MatGetRow(A, r, &ncols, NULL, NULL);CHKERRQ(ierr); 4824325cce7SMatthew G Knepley colMax = PetscMax(colMax, ncols);CHKERRQ(ierr); 4830298fd71SBarry Smith ierr = MatRestoreRow(A, r, &ncols, NULL, NULL);CHKERRQ(ierr); 4844325cce7SMatthew G Knepley } 4854325cce7SMatthew G Knepley numRows = rEnd - rStart; 486b2566f29SBarry Smith ierr = MPIU_Allreduce(&numRows, &maxRows, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 487dcca6d9dSJed Brown ierr = PetscMalloc2(colMax,&newCols,colMax,&newVals);CHKERRQ(ierr); 4884325cce7SMatthew G Knepley for (r = rStart; r < rStart+maxRows; ++r) { 4894325cce7SMatthew G Knepley const PetscScalar *vals; 4904325cce7SMatthew G Knepley const PetscInt *cols; 491fad45679SMatthew G. Knepley PetscInt ncols, newcols, c; 4924325cce7SMatthew G Knepley 4934325cce7SMatthew G Knepley if (r < rEnd) { 4944325cce7SMatthew G Knepley ierr = MatGetRow(A, r, &ncols, &cols, &vals);CHKERRQ(ierr); 4954325cce7SMatthew G Knepley for (c = 0; c < ncols; ++c) { 4964325cce7SMatthew G Knepley newCols[c] = cols[c]; 4974325cce7SMatthew G Knepley newVals[c] = PetscAbsScalar(vals[c]) < tol ? 0.0 : vals[c]; 4984325cce7SMatthew G Knepley } 499fad45679SMatthew G. Knepley newcols = ncols; 5004325cce7SMatthew G Knepley ierr = MatRestoreRow(A, r, &ncols, &cols, &vals);CHKERRQ(ierr); 501fad45679SMatthew G. Knepley ierr = MatSetValues(A, 1, &r, newcols, newCols, newVals, INSERT_VALUES);CHKERRQ(ierr); 5024325cce7SMatthew G Knepley } 5034325cce7SMatthew G Knepley ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5044325cce7SMatthew G Knepley ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5054325cce7SMatthew G Knepley } 5064325cce7SMatthew G Knepley ierr = PetscFree2(newCols,newVals);CHKERRQ(ierr); 5074325cce7SMatthew G Knepley PetscFunctionReturn(0); 5084325cce7SMatthew G Knepley } 509