14222ddf1SHong Zhang 24222ddf1SHong Zhang /* 34222ddf1SHong Zhang Routines for matrix products. Calling procedure: 44222ddf1SHong Zhang 54222ddf1SHong Zhang MatProductCreate(A,B,C,&D); or MatProductCreateWithMat(A,B,C,D); 64222ddf1SHong Zhang MatProductSetType(D, MATPRODUCT_AB/AtB/ABt/PtAP/RARt/ABC); 74222ddf1SHong Zhang MatProductSetAlgorithm(D, alg); 84222ddf1SHong Zhang MatProductSetFill(D,fill); 94222ddf1SHong Zhang MatProductSetFromOptions(D); 104222ddf1SHong Zhang -> MatProductSetFromOptions_producttype(D): 114222ddf1SHong Zhang # Check matrix global sizes 124222ddf1SHong Zhang -> MatProductSetFromOptions_Atype_Btype_Ctype(D); 134222ddf1SHong Zhang ->MatProductSetFromOptions_Atype_Btype_Ctype_productype(D): 144222ddf1SHong Zhang # Check matrix local sizes for mpi matrices 154222ddf1SHong Zhang # Set default algorithm 164222ddf1SHong Zhang # Get runtime option 174222ddf1SHong Zhang # Set D->ops->productsymbolic = MatProductSymbolic_productype_Atype_Btype_Ctype; 184222ddf1SHong Zhang 194222ddf1SHong Zhang PetscLogEventBegin() 204222ddf1SHong Zhang MatProductSymbolic(D): 214222ddf1SHong Zhang # Call MatxxxSymbolic_Atype_Btype_Ctype(); 224222ddf1SHong Zhang # Set D->ops->productnumeric = MatProductNumeric_productype_Atype_Btype_Ctype; 234222ddf1SHong Zhang PetscLogEventEnd() 244222ddf1SHong Zhang 254222ddf1SHong Zhang PetscLogEventBegin() 264222ddf1SHong Zhang MatProductNumeric(D); 274222ddf1SHong Zhang # Call (D->ops->matxxxnumeric)(); 284222ddf1SHong Zhang PetscLogEventEnd() 294222ddf1SHong Zhang */ 304222ddf1SHong Zhang 314222ddf1SHong Zhang #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 324222ddf1SHong Zhang 33544a5e07SHong Zhang const char *const MatProductTypes[] = {"AB","AtB","ABt","PtAP","RARt","ABC","MatProductType","MAT_Product_",0}; 34544a5e07SHong Zhang 354222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_PtAP_Basic(Mat C) 364222ddf1SHong Zhang { 374222ddf1SHong Zhang PetscErrorCode ierr; 384222ddf1SHong Zhang Mat_Product *product = C->product; 394222ddf1SHong Zhang Mat P = product->B,AP = product->Dwork; 404222ddf1SHong Zhang 414222ddf1SHong Zhang PetscFunctionBegin; 424222ddf1SHong Zhang /* AP = A*P */ 434222ddf1SHong Zhang ierr = MatProductNumeric(AP);CHKERRQ(ierr); 444222ddf1SHong Zhang /* C = P^T*AP */ 45*7a3c3d58SStefano Zampini if (!C->ops->transposematmultnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing numeric stage"); 46*7a3c3d58SStefano Zampini ierr = (*C->ops->transposematmultnumeric)(P,AP,C);CHKERRQ(ierr); 474222ddf1SHong Zhang PetscFunctionReturn(0); 484222ddf1SHong Zhang } 494222ddf1SHong Zhang 504222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_Basic(Mat C) 514222ddf1SHong Zhang { 524222ddf1SHong Zhang PetscErrorCode ierr; 534222ddf1SHong Zhang Mat_Product *product = C->product; 544222ddf1SHong Zhang Mat A=product->A,P=product->B,AP; 554222ddf1SHong Zhang PetscReal fill=product->fill; 564222ddf1SHong Zhang 574222ddf1SHong Zhang PetscFunctionBegin; 584222ddf1SHong Zhang /* AP = A*P */ 594222ddf1SHong Zhang ierr = MatProductCreate(A,P,NULL,&AP);CHKERRQ(ierr); 604222ddf1SHong Zhang ierr = MatProductSetType(AP,MATPRODUCT_AB);CHKERRQ(ierr); 61*7a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(AP,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 624222ddf1SHong Zhang ierr = MatProductSetFill(AP,fill);CHKERRQ(ierr); 634222ddf1SHong Zhang ierr = MatProductSetFromOptions(AP);CHKERRQ(ierr); 644222ddf1SHong Zhang ierr = MatProductSymbolic(AP);CHKERRQ(ierr); 654222ddf1SHong Zhang 664222ddf1SHong Zhang /* C = P^T*AP */ 674222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_AtB);CHKERRQ(ierr); 68*7a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 694222ddf1SHong Zhang product->A = P; 704222ddf1SHong Zhang product->B = AP; 714222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 724222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 734222ddf1SHong Zhang 744222ddf1SHong Zhang /* resume user's original input matrix setting for A and B */ 754222ddf1SHong Zhang product->A = A; 764222ddf1SHong Zhang product->B = P; 774222ddf1SHong Zhang product->Dwork = AP; 784222ddf1SHong Zhang 794222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP_Basic; 804222ddf1SHong Zhang PetscFunctionReturn(0); 814222ddf1SHong Zhang } 824222ddf1SHong Zhang 834222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_RARt_Basic(Mat C) 844222ddf1SHong Zhang { 854222ddf1SHong Zhang PetscErrorCode ierr; 864222ddf1SHong Zhang Mat_Product *product = C->product; 874222ddf1SHong Zhang Mat R=product->B,RA=product->Dwork; 884222ddf1SHong Zhang 894222ddf1SHong Zhang PetscFunctionBegin; 904222ddf1SHong Zhang /* RA = R*A */ 914222ddf1SHong Zhang ierr = MatProductNumeric(RA);CHKERRQ(ierr); 924222ddf1SHong Zhang /* C = RA*R^T */ 93*7a3c3d58SStefano Zampini if (!C->ops->mattransposemultnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing numeric stage"); 94*7a3c3d58SStefano Zampini ierr = (*C->ops->mattransposemultnumeric)(RA,R,C);CHKERRQ(ierr); 954222ddf1SHong Zhang PetscFunctionReturn(0); 964222ddf1SHong Zhang } 974222ddf1SHong Zhang 984222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_RARt_Basic(Mat C) 994222ddf1SHong Zhang { 1004222ddf1SHong Zhang PetscErrorCode ierr; 1014222ddf1SHong Zhang Mat_Product *product = C->product; 1024222ddf1SHong Zhang Mat A=product->A,R=product->B,RA; 1034222ddf1SHong Zhang PetscReal fill=product->fill; 1044222ddf1SHong Zhang 1054222ddf1SHong Zhang PetscFunctionBegin; 1064222ddf1SHong Zhang /* RA = R*A */ 1074222ddf1SHong Zhang ierr = MatProductCreate(R,A,NULL,&RA);CHKERRQ(ierr); 1084222ddf1SHong Zhang ierr = MatProductSetType(RA,MATPRODUCT_AB);CHKERRQ(ierr); 109*7a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(RA,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1104222ddf1SHong Zhang ierr = MatProductSetFill(RA,fill);CHKERRQ(ierr); 1114222ddf1SHong Zhang ierr = MatProductSetFromOptions(RA);CHKERRQ(ierr); 1124222ddf1SHong Zhang ierr = MatProductSymbolic(RA);CHKERRQ(ierr); 1134222ddf1SHong Zhang 1144222ddf1SHong Zhang /* C = RA*R^T */ 1154222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_ABt);CHKERRQ(ierr); 116*7a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1174222ddf1SHong Zhang product->A = RA; 1184222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 1194222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 1204222ddf1SHong Zhang 1214222ddf1SHong Zhang /* resume user's original input matrix setting for A */ 1224222ddf1SHong Zhang product->A = A; 1234222ddf1SHong Zhang product->Dwork = RA; /* save here so it will be destroyed with product C */ 1244222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_Basic; 1254222ddf1SHong Zhang PetscFunctionReturn(0); 1264222ddf1SHong Zhang } 1274222ddf1SHong Zhang 1284222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_ABC_Basic(Mat mat) 1294222ddf1SHong Zhang { 1304222ddf1SHong Zhang PetscErrorCode ierr; 1314222ddf1SHong Zhang Mat_Product *product = mat->product; 1324222ddf1SHong Zhang Mat A=product->A,BC=product->Dwork; 1334222ddf1SHong Zhang 1344222ddf1SHong Zhang PetscFunctionBegin; 1354222ddf1SHong Zhang /* Numeric BC = B*C */ 1364222ddf1SHong Zhang ierr = MatProductNumeric(BC);CHKERRQ(ierr); 1374222ddf1SHong Zhang /* Numeric mat = A*BC */ 138*7a3c3d58SStefano Zampini if (!mat->ops->transposematmultnumeric) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric stage"); 139*7a3c3d58SStefano Zampini ierr = (*mat->ops->matmultnumeric)(A,BC,mat);CHKERRQ(ierr); 1404222ddf1SHong Zhang PetscFunctionReturn(0); 1414222ddf1SHong Zhang } 1424222ddf1SHong Zhang 1434222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_ABC_Basic(Mat mat) 1444222ddf1SHong Zhang { 1454222ddf1SHong Zhang PetscErrorCode ierr; 1464222ddf1SHong Zhang Mat_Product *product = mat->product; 1474222ddf1SHong Zhang Mat B=product->B,C=product->C,BC; 1484222ddf1SHong Zhang PetscReal fill=product->fill; 1494222ddf1SHong Zhang 1504222ddf1SHong Zhang PetscFunctionBegin; 1514222ddf1SHong Zhang /* Symbolic BC = B*C */ 1524222ddf1SHong Zhang ierr = MatProductCreate(B,C,NULL,&BC);CHKERRQ(ierr); 1534222ddf1SHong Zhang ierr = MatProductSetType(BC,MATPRODUCT_AB);CHKERRQ(ierr); 154*7a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(BC,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1554222ddf1SHong Zhang ierr = MatProductSetFill(BC,fill);CHKERRQ(ierr); 1564222ddf1SHong Zhang ierr = MatProductSetFromOptions(BC);CHKERRQ(ierr); 1574222ddf1SHong Zhang ierr = MatProductSymbolic(BC);CHKERRQ(ierr); 1584222ddf1SHong Zhang 1594222ddf1SHong Zhang /* Symbolic mat = A*BC */ 1604222ddf1SHong Zhang ierr = MatProductSetType(mat,MATPRODUCT_AB);CHKERRQ(ierr); 161*7a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(mat,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1624222ddf1SHong Zhang product->B = BC; 1634222ddf1SHong Zhang product->Dwork = BC; 1644222ddf1SHong Zhang ierr = MatProductSetFromOptions(mat);CHKERRQ(ierr); 1654222ddf1SHong Zhang ierr = MatProductSymbolic(mat);CHKERRQ(ierr); 1664222ddf1SHong Zhang 1674222ddf1SHong Zhang /* resume user's original input matrix setting for B */ 1684222ddf1SHong Zhang product->B = B; 1694222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC_Basic; 1704222ddf1SHong Zhang PetscFunctionReturn(0); 1714222ddf1SHong Zhang } 1724222ddf1SHong Zhang 1734222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_Basic(Mat mat) 1744222ddf1SHong Zhang { 1754222ddf1SHong Zhang PetscErrorCode ierr; 1764222ddf1SHong Zhang Mat_Product *product = mat->product; 1774222ddf1SHong Zhang 1784222ddf1SHong Zhang PetscFunctionBegin; 1794222ddf1SHong Zhang switch (product->type) { 1804222ddf1SHong Zhang case MATPRODUCT_PtAP: 181*7a3c3d58SStefano Zampini ierr = PetscInfo2((PetscObject)mat, "MatProduct_Basic_PtAP() for A %s, P %s is used\n",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name);CHKERRQ(ierr); 1824222ddf1SHong Zhang ierr = MatProductSymbolic_PtAP_Basic(mat);CHKERRQ(ierr); 1834222ddf1SHong Zhang break; 1844222ddf1SHong Zhang case MATPRODUCT_RARt: 185*7a3c3d58SStefano Zampini ierr = PetscInfo2((PetscObject)mat, "MatProduct_Basic_RARt() for A %s, R %s is used\n",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name);CHKERRQ(ierr); 1864222ddf1SHong Zhang ierr = MatProductSymbolic_RARt_Basic(mat);CHKERRQ(ierr); 1874222ddf1SHong Zhang break; 1884222ddf1SHong Zhang case MATPRODUCT_ABC: 189*7a3c3d58SStefano Zampini ierr = PetscInfo3((PetscObject)mat, "MatProduct_Basic_ABC() for A %s, B %s, C %s is used\n",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name,((PetscObject)product->C)->type_name);CHKERRQ(ierr); 1904222ddf1SHong Zhang ierr = MatProductSymbolic_ABC_Basic(mat);CHKERRQ(ierr); 1914222ddf1SHong Zhang break; 1924222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType is not supported"); 1934222ddf1SHong Zhang } 1944222ddf1SHong Zhang PetscFunctionReturn(0); 1954222ddf1SHong Zhang } 1964222ddf1SHong Zhang 1974222ddf1SHong Zhang /* ----------------------------------------------- */ 1984222ddf1SHong Zhang /*@C 1994222ddf1SHong Zhang MatProductReplaceMats - Replace input matrices for a matrix product. 2004222ddf1SHong Zhang 2014222ddf1SHong Zhang Collective on Mat 2024222ddf1SHong Zhang 2034222ddf1SHong Zhang Input Parameters: 2044222ddf1SHong Zhang + A - the matrix or NULL if not being replaced 2054222ddf1SHong Zhang . B - the matrix or NULL if not being replaced 2064222ddf1SHong Zhang . C - the matrix or NULL if not being replaced 2074222ddf1SHong Zhang - D - the matrix product 2084222ddf1SHong Zhang 2094222ddf1SHong Zhang Level: intermediate 2104222ddf1SHong Zhang 2114222ddf1SHong Zhang Notes: 2124222ddf1SHong Zhang Input matrix must have exactly same data structure as replaced one. 2134222ddf1SHong Zhang 2144222ddf1SHong Zhang .seealso: MatProductCreate() 2154222ddf1SHong Zhang @*/ 2164222ddf1SHong Zhang PetscErrorCode MatProductReplaceMats(Mat A,Mat B,Mat C,Mat D) 2174222ddf1SHong Zhang { 2184417c5e8SHong Zhang PetscErrorCode ierr; 2194222ddf1SHong Zhang Mat_Product *product=D->product; 2204222ddf1SHong Zhang 2214222ddf1SHong Zhang PetscFunctionBegin; 222*7a3c3d58SStefano Zampini PetscValidHeaderSpecific(D,MAT_CLASSID,4); 223*7a3c3d58SStefano Zampini if (!product) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ORDER,"Mat D does not have struct 'product'. Call MatProductReplaceProduct()"); 2244222ddf1SHong Zhang if (A) { 225*7a3c3d58SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2264222ddf1SHong Zhang if (!product->Areplaced) { 2274417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); /* take ownership of input */ 2284417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); /* release old reference */ 2294222ddf1SHong Zhang product->A = A; 2304222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"Matrix A was changed by a PETSc internal routine, cannot be replaced"); 2314222ddf1SHong Zhang } 2324222ddf1SHong Zhang if (B) { 233*7a3c3d58SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,2); 2344222ddf1SHong Zhang if (!product->Breplaced) { 2354417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); /* take ownership of input */ 2364417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); /* release old reference */ 2374222ddf1SHong Zhang product->B = B; 2384222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"Matrix B was changed by a PETSc internal routine, cannot be replaced"); 2394222ddf1SHong Zhang } 2404417c5e8SHong Zhang if (C) { 241*7a3c3d58SStefano Zampini PetscValidHeaderSpecific(C,MAT_CLASSID,3); 2424417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); /* take ownership of input */ 2434417c5e8SHong Zhang ierr = MatDestroy(&product->C);CHKERRQ(ierr); /* release old reference */ 2444417c5e8SHong Zhang product->C = C; 2454417c5e8SHong Zhang } 2464222ddf1SHong Zhang PetscFunctionReturn(0); 2474222ddf1SHong Zhang } 2484222ddf1SHong Zhang 249*7a3c3d58SStefano Zampini static PetscErrorCode MatProductNumeric_X_Dense(Mat C) 250*7a3c3d58SStefano Zampini { 251*7a3c3d58SStefano Zampini PetscErrorCode ierr; 252*7a3c3d58SStefano Zampini Mat_Product *product = C->product; 253*7a3c3d58SStefano Zampini Mat A = product->A, B = product->B; 254*7a3c3d58SStefano Zampini PetscInt k, K = B->cmap->N; 255*7a3c3d58SStefano Zampini PetscBool t = PETSC_TRUE,iscuda = PETSC_FALSE; 256*7a3c3d58SStefano Zampini PetscBool Bcpu = PETSC_TRUE, Ccpu = PETSC_TRUE; 257*7a3c3d58SStefano Zampini char *Btype = NULL,*Ctype = NULL; 258*7a3c3d58SStefano Zampini 259*7a3c3d58SStefano Zampini PetscFunctionBegin; 260*7a3c3d58SStefano Zampini switch (product->type) { 261*7a3c3d58SStefano Zampini case MATPRODUCT_AB: 262*7a3c3d58SStefano Zampini t = PETSC_FALSE; 263*7a3c3d58SStefano Zampini case MATPRODUCT_AtB: 264*7a3c3d58SStefano Zampini break; 265*7a3c3d58SStefano Zampini default: SETERRQ3(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProductNumeric type %s not supported for %s and %s matrices",MatProductTypes[product->type],((PetscObject)A)->type_name,((PetscObject)B)->type_name); 266*7a3c3d58SStefano Zampini } 267*7a3c3d58SStefano Zampini if (PetscDefined(HAVE_CUDA)) { 268*7a3c3d58SStefano Zampini VecType vtype; 269*7a3c3d58SStefano Zampini 270*7a3c3d58SStefano Zampini ierr = MatGetVecType(A,&vtype);CHKERRQ(ierr); 271*7a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECCUDA,&iscuda);CHKERRQ(ierr); 272*7a3c3d58SStefano Zampini if (!iscuda) { 273*7a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECSEQCUDA,&iscuda);CHKERRQ(ierr); 274*7a3c3d58SStefano Zampini } 275*7a3c3d58SStefano Zampini if (!iscuda) { 276*7a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECMPICUDA,&iscuda);CHKERRQ(ierr); 277*7a3c3d58SStefano Zampini } 278*7a3c3d58SStefano Zampini if (iscuda) { /* Make sure we have up-to-date data on the GPU */ 279*7a3c3d58SStefano Zampini ierr = PetscStrallocpy(((PetscObject)B)->type_name,&Btype);CHKERRQ(ierr); 280*7a3c3d58SStefano Zampini ierr = PetscStrallocpy(((PetscObject)C)->type_name,&Ctype);CHKERRQ(ierr); 281*7a3c3d58SStefano Zampini ierr = MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 282*7a3c3d58SStefano Zampini if (!C->assembled) { /* need to flag the matrix as assembled, otherwise MatConvert will complain */ 283*7a3c3d58SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 284*7a3c3d58SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 285*7a3c3d58SStefano Zampini } 286*7a3c3d58SStefano Zampini ierr = MatConvert(C,MATDENSECUDA,MAT_INPLACE_MATRIX,&C);CHKERRQ(ierr); 287*7a3c3d58SStefano Zampini } else { /* Make sure we have up-to-date data on the CPU */ 288*7a3c3d58SStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 289*7a3c3d58SStefano Zampini Bcpu = B->boundtocpu; 290*7a3c3d58SStefano Zampini Ccpu = C->boundtocpu; 291*7a3c3d58SStefano Zampini #endif 292*7a3c3d58SStefano Zampini ierr = MatBindToCPU(B,PETSC_TRUE);CHKERRQ(ierr); 293*7a3c3d58SStefano Zampini ierr = MatBindToCPU(C,PETSC_TRUE);CHKERRQ(ierr); 294*7a3c3d58SStefano Zampini } 295*7a3c3d58SStefano Zampini } 296*7a3c3d58SStefano Zampini for (k=0;k<K;k++) { 297*7a3c3d58SStefano Zampini Vec x,y; 298*7a3c3d58SStefano Zampini 299*7a3c3d58SStefano Zampini ierr = MatDenseGetColumnVecRead(B,k,&x);CHKERRQ(ierr); 300*7a3c3d58SStefano Zampini ierr = MatDenseGetColumnVecWrite(C,k,&y);CHKERRQ(ierr); 301*7a3c3d58SStefano Zampini if (t) { 302*7a3c3d58SStefano Zampini ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 303*7a3c3d58SStefano Zampini } else { 304*7a3c3d58SStefano Zampini ierr = MatMult(A,x,y);CHKERRQ(ierr); 305*7a3c3d58SStefano Zampini } 306*7a3c3d58SStefano Zampini ierr = MatDenseRestoreColumnVecRead(B,k,&x);CHKERRQ(ierr); 307*7a3c3d58SStefano Zampini ierr = MatDenseRestoreColumnVecWrite(C,k,&y);CHKERRQ(ierr); 308*7a3c3d58SStefano Zampini } 309*7a3c3d58SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 310*7a3c3d58SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 311*7a3c3d58SStefano Zampini if (PetscDefined(HAVE_CUDA)) { 312*7a3c3d58SStefano Zampini if (iscuda) { 313*7a3c3d58SStefano Zampini ierr = MatConvert(B,Btype,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 314*7a3c3d58SStefano Zampini ierr = MatConvert(C,Ctype,MAT_INPLACE_MATRIX,&C);CHKERRQ(ierr); 315*7a3c3d58SStefano Zampini } else { 316*7a3c3d58SStefano Zampini ierr = MatBindToCPU(B,Bcpu);CHKERRQ(ierr); 317*7a3c3d58SStefano Zampini ierr = MatBindToCPU(C,Ccpu);CHKERRQ(ierr); 318*7a3c3d58SStefano Zampini } 319*7a3c3d58SStefano Zampini } 320*7a3c3d58SStefano Zampini ierr = PetscFree(Btype);CHKERRQ(ierr); 321*7a3c3d58SStefano Zampini ierr = PetscFree(Ctype);CHKERRQ(ierr); 322*7a3c3d58SStefano Zampini PetscFunctionReturn(0); 323*7a3c3d58SStefano Zampini } 324*7a3c3d58SStefano Zampini 325*7a3c3d58SStefano Zampini static PetscErrorCode MatProductSymbolic_X_Dense(Mat C) 326*7a3c3d58SStefano Zampini { 327*7a3c3d58SStefano Zampini PetscErrorCode ierr; 328*7a3c3d58SStefano Zampini Mat_Product *product = C->product; 329*7a3c3d58SStefano Zampini Mat A = product->A, B = product->B; 330*7a3c3d58SStefano Zampini PetscBool isdense; 331*7a3c3d58SStefano Zampini 332*7a3c3d58SStefano Zampini PetscFunctionBegin; 333*7a3c3d58SStefano Zampini switch (product->type) { 334*7a3c3d58SStefano Zampini case MATPRODUCT_AB: 335*7a3c3d58SStefano Zampini ierr = MatSetSizes(C,A->rmap->n,B->cmap->n,A->rmap->N,B->cmap->N);CHKERRQ(ierr); 336*7a3c3d58SStefano Zampini break; 337*7a3c3d58SStefano Zampini case MATPRODUCT_AtB: 338*7a3c3d58SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,B->cmap->n,A->cmap->N,B->cmap->N);CHKERRQ(ierr); 339*7a3c3d58SStefano Zampini break; 340*7a3c3d58SStefano Zampini default: SETERRQ3(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProductSymbolic type %s not supported for %s and %s matrices",MatProductTypes[product->type],((PetscObject)A)->type_name,((PetscObject)B)->type_name); 341*7a3c3d58SStefano Zampini } 342*7a3c3d58SStefano Zampini ierr = PetscObjectBaseTypeCompareAny((PetscObject)C,&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 343*7a3c3d58SStefano Zampini if (!isdense) { 344*7a3c3d58SStefano Zampini ierr = MatSetType(C,((PetscObject)B)->type_name);CHKERRQ(ierr); 345*7a3c3d58SStefano Zampini /* If matrix type of C was not set or not dense, we need to reset this pointers */ 346*7a3c3d58SStefano Zampini C->ops->productsymbolic = MatProductSymbolic_X_Dense; 347*7a3c3d58SStefano Zampini C->ops->productnumeric = MatProductNumeric_X_Dense; 348*7a3c3d58SStefano Zampini } 349*7a3c3d58SStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 350*7a3c3d58SStefano Zampini PetscFunctionReturn(0); 351*7a3c3d58SStefano Zampini } 352*7a3c3d58SStefano Zampini 353*7a3c3d58SStefano Zampini static PetscErrorCode MatProductSetFromOptions_X_Dense(Mat C) 354*7a3c3d58SStefano Zampini { 355*7a3c3d58SStefano Zampini Mat_Product *product = C->product; 356*7a3c3d58SStefano Zampini Mat A = product->A, B = product->B; 357*7a3c3d58SStefano Zampini 358*7a3c3d58SStefano Zampini PetscFunctionBegin; 359*7a3c3d58SStefano Zampini C->ops->productsymbolic = NULL; 360*7a3c3d58SStefano Zampini C->ops->productnumeric = NULL; 361*7a3c3d58SStefano Zampini switch (product->type) { 362*7a3c3d58SStefano Zampini case MATPRODUCT_AB: 363*7a3c3d58SStefano Zampini case MATPRODUCT_AtB: 364*7a3c3d58SStefano Zampini C->ops->productsymbolic = MatProductSymbolic_X_Dense; 365*7a3c3d58SStefano Zampini C->ops->productnumeric = MatProductNumeric_X_Dense; 366*7a3c3d58SStefano Zampini break; 367*7a3c3d58SStefano Zampini default: SETERRQ3(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s not supported for %s and %s matrices",MatProductTypes[product->type],((PetscObject)A)->type_name,((PetscObject)B)->type_name); 368*7a3c3d58SStefano Zampini } 369*7a3c3d58SStefano Zampini PetscFunctionReturn(0); 370*7a3c3d58SStefano Zampini } 371*7a3c3d58SStefano Zampini 3724222ddf1SHong Zhang /* ----------------------------------------------- */ 3734222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_AB(Mat mat) 3744222ddf1SHong Zhang { 3754222ddf1SHong Zhang PetscErrorCode ierr; 3764222ddf1SHong Zhang Mat_Product *product = mat->product; 3774222ddf1SHong Zhang Mat A=product->A,B=product->B; 3784222ddf1SHong Zhang PetscBool sametype; 3794222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 3804222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 3814222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 3824222ddf1SHong Zhang PetscBool A_istrans,B_istrans; 3834222ddf1SHong Zhang 3844222ddf1SHong Zhang PetscFunctionBegin; 3854222ddf1SHong Zhang /* Check matrix global sizes */ 3864222ddf1SHong Zhang if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 3874222ddf1SHong Zhang 3884222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 3894222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 3904222ddf1SHong Zhang 3914222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 3924222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&A_istrans);CHKERRQ(ierr); 3934222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&B_istrans);CHKERRQ(ierr); 3946896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, B %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 3954222ddf1SHong Zhang 3964222ddf1SHong Zhang if (fB == fA && sametype && (!A_istrans || !B_istrans)) { 3976896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 3984222ddf1SHong Zhang f = fB; 3994222ddf1SHong Zhang } else { 4004222ddf1SHong Zhang char mtypes[256]; 4014222ddf1SHong Zhang PetscBool At_istrans=PETSC_TRUE,Bt_istrans=PETSC_TRUE; 4024222ddf1SHong Zhang Mat At = NULL,Bt = NULL; 4034222ddf1SHong Zhang 4044222ddf1SHong Zhang if (A_istrans && !B_istrans) { 4054222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&At);CHKERRQ(ierr); 4064222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)At,MATTRANSPOSEMAT,&At_istrans);CHKERRQ(ierr); 4074222ddf1SHong Zhang if (At_istrans) { /* mat = ATT * B */ 4084222ddf1SHong Zhang Mat Att = NULL; 4094222ddf1SHong Zhang ierr = MatTransposeGetMat(At,&Att);CHKERRQ(ierr); 4104417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Att);CHKERRQ(ierr); 4114417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 4124222ddf1SHong Zhang A = Att; 4134222ddf1SHong Zhang product->A = Att; /* use Att for matproduct */ 4144222ddf1SHong Zhang product->Areplaced = PETSC_TRUE; /* Att = A, but has native matrix type */ 4154222ddf1SHong Zhang } else { /* !At_istrans: mat = At^T*B */ 4164417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)At);CHKERRQ(ierr); 4174417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 4184222ddf1SHong Zhang A = At; 4194222ddf1SHong Zhang product->A = At; 4204222ddf1SHong Zhang product->Areplaced = PETSC_TRUE; 4214222ddf1SHong Zhang product->type = MATPRODUCT_AtB; 4224222ddf1SHong Zhang } 4234222ddf1SHong Zhang } else if (!A_istrans && B_istrans) { 4244222ddf1SHong Zhang ierr = MatTransposeGetMat(B,&Bt);CHKERRQ(ierr); 4254222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)Bt,MATTRANSPOSEMAT,&Bt_istrans);CHKERRQ(ierr); 4264222ddf1SHong Zhang if (Bt_istrans) { /* mat = A * BTT */ 4274222ddf1SHong Zhang Mat Btt = NULL; 4284222ddf1SHong Zhang ierr = MatTransposeGetMat(Bt,&Btt);CHKERRQ(ierr); 4294417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Btt);CHKERRQ(ierr); 4304417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 4314222ddf1SHong Zhang B = Btt; 4324222ddf1SHong Zhang product->B = Btt; /* use Btt for matproduct */ 4334222ddf1SHong Zhang product->Breplaced = PETSC_TRUE; 4344222ddf1SHong Zhang } else { /* !Bt_istrans */ 4354222ddf1SHong Zhang /* mat = A*Bt^T */ 4364417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Bt);CHKERRQ(ierr); 4374417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 4384222ddf1SHong Zhang B = Bt; 4394222ddf1SHong Zhang product->B = Bt; 4404222ddf1SHong Zhang product->Breplaced = PETSC_TRUE; 4414222ddf1SHong Zhang product->type = MATPRODUCT_ABt; 4424222ddf1SHong Zhang } 4434222ddf1SHong Zhang } else if (A_istrans && B_istrans) { /* mat = At^T * Bt^T */ 4444222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&At);CHKERRQ(ierr); 4454222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)At,MATTRANSPOSEMAT,&At_istrans);CHKERRQ(ierr); 4464222ddf1SHong Zhang ierr = MatTransposeGetMat(B,&Bt);CHKERRQ(ierr); 4474222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)Bt,MATTRANSPOSEMAT,&Bt_istrans);CHKERRQ(ierr); 4484222ddf1SHong Zhang if (At_istrans && Bt_istrans) { 4494222ddf1SHong Zhang Mat Att= NULL,Btt = NULL; 4504222ddf1SHong Zhang ierr = MatTransposeGetMat(At,&Att);CHKERRQ(ierr); 4514222ddf1SHong Zhang ierr = MatTransposeGetMat(Bt,&Btt);CHKERRQ(ierr); 4524417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Att);CHKERRQ(ierr); 4534417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Btt);CHKERRQ(ierr); 4544417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 4554417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 4564222ddf1SHong Zhang A = Att; 4574222ddf1SHong Zhang product->A = Att; product->Areplaced = PETSC_TRUE; 4584222ddf1SHong Zhang B = Btt; 4594222ddf1SHong Zhang product->B = Btt; product->Breplaced = PETSC_TRUE; 4604222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not supported yet"); 4614222ddf1SHong Zhang } 4624222ddf1SHong Zhang 4634222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 4644222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 4654222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4664222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4674222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4684222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 4694222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 470*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 4714222ddf1SHong Zhang if (!f) { 4724222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 473*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 4744222ddf1SHong Zhang } 4754222ddf1SHong Zhang } 4764222ddf1SHong Zhang 477*7a3c3d58SStefano Zampini /* last chance, we can still compute the product if B is of type dense */ 478*7a3c3d58SStefano Zampini if (!f && (product->type == MATPRODUCT_AB || product->type == MATPRODUCT_AtB)) { 479*7a3c3d58SStefano Zampini PetscBool isdense; 480*7a3c3d58SStefano Zampini 481*7a3c3d58SStefano Zampini ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 482*7a3c3d58SStefano Zampini if (isdense) { 483*7a3c3d58SStefano Zampini f = MatProductSetFromOptions_X_Dense; 484*7a3c3d58SStefano Zampini ierr = PetscInfo(mat," using basic looping over columns of a dense matrix\n");CHKERRQ(ierr); 485*7a3c3d58SStefano Zampini } 486*7a3c3d58SStefano Zampini } 487*7a3c3d58SStefano Zampini 488*7a3c3d58SStefano Zampini if (f) { 4894222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 490*7a3c3d58SStefano Zampini } else { /* reset pointers since the matrix types combination is not available */ 491*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," for A %s and B %s is not supported\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 492*7a3c3d58SStefano Zampini mat->ops->productsymbolic = NULL; 493*7a3c3d58SStefano Zampini mat->ops->productnumeric = NULL; 494*7a3c3d58SStefano Zampini } 4954222ddf1SHong Zhang PetscFunctionReturn(0); 4964222ddf1SHong Zhang } 4974222ddf1SHong Zhang 4984222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_AtB(Mat mat) 4994222ddf1SHong Zhang { 5004222ddf1SHong Zhang PetscErrorCode ierr; 5014222ddf1SHong Zhang Mat_Product *product = mat->product; 5024222ddf1SHong Zhang Mat A=product->A,B=product->B; 5034222ddf1SHong Zhang PetscBool sametype; 5044222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 5054222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 5064222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 5074222ddf1SHong Zhang 5084222ddf1SHong Zhang PetscFunctionBegin; 5094222ddf1SHong Zhang /* Check matrix global sizes */ 5104222ddf1SHong Zhang if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N); 5114222ddf1SHong Zhang 5124222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 5134222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 5144222ddf1SHong Zhang 5154222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 5166896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, B %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 5174222ddf1SHong Zhang 5184222ddf1SHong Zhang if (fB == fA && sametype) { 5196896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 5204222ddf1SHong Zhang f = fB; 5214222ddf1SHong Zhang } else { 5224222ddf1SHong Zhang char mtypes[256]; 5234222ddf1SHong Zhang PetscBool istrans; 5244222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 5254222ddf1SHong Zhang if (!istrans) { 5264222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 5274222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 5284222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5294222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 5304222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5314222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 5324222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 533*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 5344222ddf1SHong Zhang } else { 5354222ddf1SHong Zhang Mat T = NULL; 5364222ddf1SHong Zhang SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_AtB for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 5374222ddf1SHong Zhang 5384222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 5394222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 5404222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)T)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5414222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 5424222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5434222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 5444222ddf1SHong Zhang 5454222ddf1SHong Zhang product->type = MATPRODUCT_AtB; 5464222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 547*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 5484222ddf1SHong Zhang } 5494222ddf1SHong Zhang 5504222ddf1SHong Zhang if (!f) { 5514222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 552*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 5534222ddf1SHong Zhang } 5544222ddf1SHong Zhang } 5554222ddf1SHong Zhang 556*7a3c3d58SStefano Zampini /* last chance, we can still compute the product if B is of type dense */ 557*7a3c3d58SStefano Zampini if (!f && (product->type == MATPRODUCT_AB || product->type == MATPRODUCT_AtB)) { 558*7a3c3d58SStefano Zampini PetscBool isdense; 559*7a3c3d58SStefano Zampini 560*7a3c3d58SStefano Zampini ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 561*7a3c3d58SStefano Zampini if (isdense) { 562*7a3c3d58SStefano Zampini f = MatProductSetFromOptions_X_Dense; 563*7a3c3d58SStefano Zampini ierr = PetscInfo(mat," using basic looping over columns of a dense matrix\n");CHKERRQ(ierr); 564*7a3c3d58SStefano Zampini } 565*7a3c3d58SStefano Zampini } 566*7a3c3d58SStefano Zampini 567*7a3c3d58SStefano Zampini if (f) { 5684222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 569*7a3c3d58SStefano Zampini } else { /* reset pointers since the matrix types combination is not available */ 570*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," for A %s and B %s is not supported\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 571*7a3c3d58SStefano Zampini mat->ops->productsymbolic = NULL; 572*7a3c3d58SStefano Zampini mat->ops->productnumeric = NULL; 573*7a3c3d58SStefano Zampini } 5744222ddf1SHong Zhang PetscFunctionReturn(0); 5754222ddf1SHong Zhang } 5764222ddf1SHong Zhang 5774222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_ABt(Mat mat) 5784222ddf1SHong Zhang { 5794222ddf1SHong Zhang PetscErrorCode ierr; 5804222ddf1SHong Zhang Mat_Product *product = mat->product; 5814222ddf1SHong Zhang Mat A=product->A,B=product->B; 5824222ddf1SHong Zhang PetscBool sametype; 5834222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 5844222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 5854222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 5864222ddf1SHong Zhang 5874222ddf1SHong Zhang PetscFunctionBegin; 5884222ddf1SHong Zhang /* Check matrix global sizes */ 5894222ddf1SHong Zhang if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N); 5904222ddf1SHong Zhang 5914222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 5924222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 5934222ddf1SHong Zhang 5944222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 5956896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, B %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 5964222ddf1SHong Zhang if (fB == fA && sametype) { 5976896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 5984222ddf1SHong Zhang f = fB; 5994222ddf1SHong Zhang } else { 6004222ddf1SHong Zhang char mtypes[256]; 6014222ddf1SHong Zhang PetscBool istrans; 6024222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 6034222ddf1SHong Zhang if (!istrans) { 6044222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 6054222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 6064222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6074222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 6084222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6094222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 6104222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 611*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 6124222ddf1SHong Zhang } else { 6134222ddf1SHong Zhang Mat T = NULL; 6144222ddf1SHong Zhang SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_ABt for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 6154222ddf1SHong Zhang 6164222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 6174222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 6184222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)T)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6194222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 6204222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6214222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 6224222ddf1SHong Zhang 6234222ddf1SHong Zhang product->type = MATPRODUCT_ABt; 6244222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 625*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s (ABt)? %p\n",mtypes,f);CHKERRQ(ierr); 6264222ddf1SHong Zhang } 6274222ddf1SHong Zhang 6284222ddf1SHong Zhang if (!f) { 6294222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 630*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s (ABt)? %p\n",mtypes,f);CHKERRQ(ierr); 6314222ddf1SHong Zhang } 6324222ddf1SHong Zhang } 6334222ddf1SHong Zhang 634*7a3c3d58SStefano Zampini /* last chance, we can still compute the product if B is of type dense */ 635*7a3c3d58SStefano Zampini if (!f && (product->type == MATPRODUCT_AB || product->type == MATPRODUCT_AtB)) { 636*7a3c3d58SStefano Zampini PetscBool isdense; 637*7a3c3d58SStefano Zampini 638*7a3c3d58SStefano Zampini ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 639*7a3c3d58SStefano Zampini if (isdense) { 640*7a3c3d58SStefano Zampini f = MatProductSetFromOptions_X_Dense; 641*7a3c3d58SStefano Zampini ierr = PetscInfo(mat," using basic looping over columns of a dense matrix\n");CHKERRQ(ierr); 642*7a3c3d58SStefano Zampini } 643*7a3c3d58SStefano Zampini } 644*7a3c3d58SStefano Zampini 645*7a3c3d58SStefano Zampini if (f) { 6464222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 647*7a3c3d58SStefano Zampini } else { /* reset pointers since the matrix types combination is not available */ 648*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," for A %s and B %s is not supported\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 649*7a3c3d58SStefano Zampini mat->ops->productsymbolic = NULL; 650*7a3c3d58SStefano Zampini mat->ops->productnumeric = NULL; 651*7a3c3d58SStefano Zampini } 6524222ddf1SHong Zhang PetscFunctionReturn(0); 6534222ddf1SHong Zhang } 6544222ddf1SHong Zhang 6554222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_PtAP(Mat mat) 6564222ddf1SHong Zhang { 6574222ddf1SHong Zhang PetscErrorCode ierr; 6584222ddf1SHong Zhang Mat_Product *product = mat->product; 6594222ddf1SHong Zhang Mat A=product->A,B=product->B; 6604222ddf1SHong Zhang PetscBool sametype; 6614222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 6624222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 6634222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 6644222ddf1SHong Zhang 6654222ddf1SHong Zhang PetscFunctionBegin; 6664222ddf1SHong Zhang /* Check matrix global sizes */ 6674222ddf1SHong Zhang if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N); 6684222ddf1SHong Zhang if (B->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 6694222ddf1SHong Zhang 6704222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 6714222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 6724222ddf1SHong Zhang 6736896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, P %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 6744222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 6754222ddf1SHong Zhang if (fB == fA && sametype) { 6766896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 6774222ddf1SHong Zhang f = fB; 6784222ddf1SHong Zhang } else { 6794222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 6804222ddf1SHong Zhang char mtypes[256]; 6814222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 6824222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6834222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 6844222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6854222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 6864222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 687*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 6884222ddf1SHong Zhang 6894222ddf1SHong Zhang if (!f) { 6904222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 691*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 6924222ddf1SHong Zhang } 6934222ddf1SHong Zhang } 6944222ddf1SHong Zhang 6954222ddf1SHong Zhang if (f) { 6964222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 6974222ddf1SHong Zhang } else { 698*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," for A %s, P %s uses MatProduct_Basic() implementation\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 6994222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 7004222ddf1SHong Zhang } 7014222ddf1SHong Zhang PetscFunctionReturn(0); 7024222ddf1SHong Zhang } 7034222ddf1SHong Zhang 7044222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_RARt(Mat mat) 7054222ddf1SHong Zhang { 7064222ddf1SHong Zhang PetscErrorCode ierr; 7074222ddf1SHong Zhang Mat_Product *product = mat->product; 7084222ddf1SHong Zhang Mat A=product->A,B=product->B; 7094222ddf1SHong Zhang PetscBool sametype; 7104222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 7114222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 7124222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 7134222ddf1SHong Zhang 7144222ddf1SHong Zhang PetscFunctionBegin; 7154222ddf1SHong Zhang /* Check matrix global sizes */ 7164222ddf1SHong Zhang if (A->rmap->N != B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N); 7174222ddf1SHong Zhang if (B->cmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->cmap->N,A->cmap->N); 7184222ddf1SHong Zhang 7194222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 7204222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 7214222ddf1SHong Zhang 7224222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 7236896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, B %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 7244222ddf1SHong Zhang if (fB == fA && sametype) { 7256896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 7264222ddf1SHong Zhang f = fB; 7274222ddf1SHong Zhang } else { 7284222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 7294222ddf1SHong Zhang char mtypes[256]; 7304222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 7314222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 7324222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 7334222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 7344222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 7354222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 736*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 7374222ddf1SHong Zhang 7384222ddf1SHong Zhang if (!f) { 7394222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 740*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 7414222ddf1SHong Zhang } 7424222ddf1SHong Zhang } 7434222ddf1SHong Zhang 7444222ddf1SHong Zhang if (f) { 7454222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 7464222ddf1SHong Zhang } else { 747*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," for A %s, P %s uses MatProduct_Basic() implementation\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 7484222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 7494222ddf1SHong Zhang } 7504222ddf1SHong Zhang PetscFunctionReturn(0); 7514222ddf1SHong Zhang } 7524222ddf1SHong Zhang 7534222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_ABC(Mat mat) 7544222ddf1SHong Zhang { 7554222ddf1SHong Zhang PetscErrorCode ierr; 7564222ddf1SHong Zhang Mat_Product *product = mat->product; 7574222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 7584222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 7594222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 7604222ddf1SHong Zhang PetscErrorCode (*fC)(Mat); 7614222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 7624222ddf1SHong Zhang 7634222ddf1SHong Zhang PetscFunctionBegin; 7644222ddf1SHong Zhang /* Check matrix global sizes */ 7654222ddf1SHong Zhang if (B->rmap->N!= A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 7664222ddf1SHong Zhang if (C->rmap->N!= B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N); 7674222ddf1SHong Zhang 7684222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 7694222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 7704222ddf1SHong Zhang fC = C->ops->productsetfromoptions; 7716896283bSStefano Zampini ierr = PetscInfo3(mat,"for A %s, B %s and C %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);CHKERRQ(ierr); 7724222ddf1SHong Zhang if (fA == fB && fA == fC && fA) { 7736896283bSStefano Zampini ierr = PetscInfo(mat," matching op\n");CHKERRQ(ierr); 7744222ddf1SHong Zhang f = fA; 7754222ddf1SHong Zhang } else { 7764222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype_Ctype */ 7774222ddf1SHong Zhang char mtypes[256]; 7784222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 7794222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 7804222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 7814222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 7824222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 7834222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)C)->type_name,sizeof(mtypes));CHKERRQ(ierr); 7844222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 7854222ddf1SHong Zhang 7864222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 787*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 7884222ddf1SHong Zhang if (!f) { 7894222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 790*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 7914222ddf1SHong Zhang } 7924222ddf1SHong Zhang if (!f) { 7934222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)C,mtypes,&f);CHKERRQ(ierr); 794*7a3c3d58SStefano Zampini ierr = PetscInfo2(mat," querying %s? %p\n",mtypes,f);CHKERRQ(ierr); 7954222ddf1SHong Zhang } 7964222ddf1SHong Zhang } 7974222ddf1SHong Zhang 7984222ddf1SHong Zhang if (f) { 7994222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 8004222ddf1SHong Zhang } else { /* use MatProductSymbolic/Numeric_Basic() */ 8016896283bSStefano Zampini ierr = PetscInfo3(mat," for A %s, B %s and C %s uses MatProduct_Basic() implementation",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name);CHKERRQ(ierr); 8024222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 8034222ddf1SHong Zhang } 8044222ddf1SHong Zhang PetscFunctionReturn(0); 8054222ddf1SHong Zhang } 8064222ddf1SHong Zhang 8074222ddf1SHong Zhang /*@C 8084222ddf1SHong Zhang MatProductSetFromOptions - Creates a matrix product where the type, the algorithm etc are determined from the options database. 8094222ddf1SHong Zhang 8104222ddf1SHong Zhang Logically Collective on Mat 8114222ddf1SHong Zhang 8124222ddf1SHong Zhang Input Parameter: 8134222ddf1SHong Zhang . mat - the matrix 8144222ddf1SHong Zhang 8154222ddf1SHong Zhang Level: beginner 8164222ddf1SHong Zhang 8174222ddf1SHong Zhang .seealso: MatSetFromOptions() 8184222ddf1SHong Zhang @*/ 8194222ddf1SHong Zhang PetscErrorCode MatProductSetFromOptions(Mat mat) 8204222ddf1SHong Zhang { 8214222ddf1SHong Zhang PetscErrorCode ierr; 8224222ddf1SHong Zhang 8234222ddf1SHong Zhang PetscFunctionBegin; 8244222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8254222ddf1SHong Zhang if (mat->ops->productsetfromoptions) { 8264222ddf1SHong Zhang ierr = (*mat->ops->productsetfromoptions)(mat);CHKERRQ(ierr); 827*7a3c3d58SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Call MatProductSetType() first"); 8284222ddf1SHong Zhang PetscFunctionReturn(0); 8294222ddf1SHong Zhang } 8304222ddf1SHong Zhang 8314222ddf1SHong Zhang /* ----------------------------------------------- */ 8324222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AB(Mat mat) 8334222ddf1SHong Zhang { 8344222ddf1SHong Zhang PetscErrorCode ierr; 8354222ddf1SHong Zhang Mat_Product *product = mat->product; 8364222ddf1SHong Zhang Mat A=product->A,B=product->B; 8374222ddf1SHong Zhang 8384222ddf1SHong Zhang PetscFunctionBegin; 839*7a3c3d58SStefano Zampini if (!mat->ops->matmultnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 8404222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 841*7a3c3d58SStefano Zampini ierr = (*mat->ops->matmultnumeric)(A,B,mat);CHKERRQ(ierr); 8424222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 8434222ddf1SHong Zhang PetscFunctionReturn(0); 8444222ddf1SHong Zhang } 8454222ddf1SHong Zhang 8464222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AtB(Mat mat) 8474222ddf1SHong Zhang { 8484222ddf1SHong Zhang PetscErrorCode ierr; 8494222ddf1SHong Zhang Mat_Product *product = mat->product; 8504222ddf1SHong Zhang Mat A=product->A,B=product->B; 8514222ddf1SHong Zhang 8524222ddf1SHong Zhang PetscFunctionBegin; 853*7a3c3d58SStefano Zampini if (!mat->ops->transposematmultnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 8544222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 855*7a3c3d58SStefano Zampini ierr = (*mat->ops->transposematmultnumeric)(A,B,mat);CHKERRQ(ierr); 8564222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 8574222ddf1SHong Zhang PetscFunctionReturn(0); 8584222ddf1SHong Zhang } 8594222ddf1SHong Zhang 8604222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABt(Mat mat) 8614222ddf1SHong Zhang { 8624222ddf1SHong Zhang PetscErrorCode ierr; 8634222ddf1SHong Zhang Mat_Product *product = mat->product; 8644222ddf1SHong Zhang Mat A=product->A,B=product->B; 8654222ddf1SHong Zhang 8664222ddf1SHong Zhang PetscFunctionBegin; 867*7a3c3d58SStefano Zampini if (!mat->ops->mattransposemultnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 8684222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 869*7a3c3d58SStefano Zampini ierr = (*mat->ops->mattransposemultnumeric)(A,B,mat);CHKERRQ(ierr); 8704222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 8714222ddf1SHong Zhang PetscFunctionReturn(0); 8724222ddf1SHong Zhang } 8734222ddf1SHong Zhang 8744222ddf1SHong Zhang PetscErrorCode MatProductNumeric_PtAP(Mat mat) 8754222ddf1SHong Zhang { 8764222ddf1SHong Zhang PetscErrorCode ierr; 8774222ddf1SHong Zhang Mat_Product *product = mat->product; 8784222ddf1SHong Zhang Mat A=product->A,B=product->B; 8794222ddf1SHong Zhang 8804222ddf1SHong Zhang PetscFunctionBegin; 881*7a3c3d58SStefano Zampini if (!mat->ops->ptapnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 8824222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 883*7a3c3d58SStefano Zampini ierr = (*mat->ops->ptapnumeric)(A,B,mat);CHKERRQ(ierr); 8844222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 8854222ddf1SHong Zhang PetscFunctionReturn(0); 8864222ddf1SHong Zhang } 8874222ddf1SHong Zhang 8884222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt(Mat mat) 8894222ddf1SHong Zhang { 8904222ddf1SHong Zhang PetscErrorCode ierr; 8914222ddf1SHong Zhang Mat_Product *product = mat->product; 8924222ddf1SHong Zhang Mat A=product->A,B=product->B; 8934222ddf1SHong Zhang 8944222ddf1SHong Zhang PetscFunctionBegin; 895*7a3c3d58SStefano Zampini if (!mat->ops->rartnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 8964222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 897*7a3c3d58SStefano Zampini ierr = (*mat->ops->rartnumeric)(A,B,mat);CHKERRQ(ierr); 8984222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 8994222ddf1SHong Zhang PetscFunctionReturn(0); 9004222ddf1SHong Zhang } 9014222ddf1SHong Zhang 9024222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABC(Mat mat) 9034222ddf1SHong Zhang { 9044222ddf1SHong Zhang PetscErrorCode ierr; 9054222ddf1SHong Zhang Mat_Product *product = mat->product; 9064222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 9074222ddf1SHong Zhang 9084222ddf1SHong Zhang PetscFunctionBegin; 909*7a3c3d58SStefano Zampini if (!mat->ops->matmatmultnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 9104222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 911*7a3c3d58SStefano Zampini ierr = (*mat->ops->matmatmultnumeric)(A,B,C,mat);CHKERRQ(ierr); 9124222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 9134222ddf1SHong Zhang PetscFunctionReturn(0); 9144222ddf1SHong Zhang } 9154222ddf1SHong Zhang 9164222ddf1SHong Zhang /*@ 9174222ddf1SHong Zhang MatProductNumeric - Implement a matrix product with numerical values. 9184222ddf1SHong Zhang 9194222ddf1SHong Zhang Collective on Mat 9204222ddf1SHong Zhang 9214222ddf1SHong Zhang Input Parameters: 9224222ddf1SHong Zhang . mat - the matrix to hold a product 9234222ddf1SHong Zhang 9244222ddf1SHong Zhang Output Parameters: 9254222ddf1SHong Zhang . mat - the matrix product 9264222ddf1SHong Zhang 9274222ddf1SHong Zhang Level: intermediate 9284222ddf1SHong Zhang 9294222ddf1SHong Zhang .seealso: MatProductCreate(), MatSetType() 9304222ddf1SHong Zhang @*/ 9314222ddf1SHong Zhang PetscErrorCode MatProductNumeric(Mat mat) 9324222ddf1SHong Zhang { 9334222ddf1SHong Zhang PetscErrorCode ierr; 9344222ddf1SHong Zhang 9354222ddf1SHong Zhang PetscFunctionBegin; 9364222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9374222ddf1SHong Zhang if (mat->ops->productnumeric) { 9384222ddf1SHong Zhang ierr = (*mat->ops->productnumeric)(mat);CHKERRQ(ierr); 939*7a3c3d58SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Call MatProductSymbolic() first"); 9404222ddf1SHong Zhang PetscFunctionReturn(0); 9414222ddf1SHong Zhang } 9424222ddf1SHong Zhang 9434222ddf1SHong Zhang /* ----------------------------------------------- */ 9444222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AB(Mat mat) 9454222ddf1SHong Zhang { 9464222ddf1SHong Zhang PetscErrorCode ierr; 9474222ddf1SHong Zhang Mat_Product *product = mat->product; 9484222ddf1SHong Zhang Mat A=product->A,B=product->B; 9494222ddf1SHong Zhang 9504222ddf1SHong Zhang PetscFunctionBegin; 951*7a3c3d58SStefano Zampini if (!mat->ops->matmultsymbolic) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 952*7a3c3d58SStefano Zampini ierr = (*mat->ops->matmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 9534222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AB; 9544222ddf1SHong Zhang PetscFunctionReturn(0); 9554222ddf1SHong Zhang } 9564222ddf1SHong Zhang 9574222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AtB(Mat mat) 9584222ddf1SHong Zhang { 9594222ddf1SHong Zhang PetscErrorCode ierr; 9604222ddf1SHong Zhang Mat_Product *product = mat->product; 9614222ddf1SHong Zhang Mat A=product->A,B=product->B; 9624222ddf1SHong Zhang 9634222ddf1SHong Zhang PetscFunctionBegin; 964*7a3c3d58SStefano Zampini if (!mat->ops->transposematmultsymbolic) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 965*7a3c3d58SStefano Zampini ierr = (*mat->ops->transposematmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 9664222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AtB; 9674222ddf1SHong Zhang PetscFunctionReturn(0); 9684222ddf1SHong Zhang } 9694222ddf1SHong Zhang 9704222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABt(Mat mat) 9714222ddf1SHong Zhang { 9724222ddf1SHong Zhang PetscErrorCode ierr; 9734222ddf1SHong Zhang Mat_Product *product = mat->product; 9744222ddf1SHong Zhang Mat A=product->A,B=product->B; 9754222ddf1SHong Zhang 9764222ddf1SHong Zhang PetscFunctionBegin; 977*7a3c3d58SStefano Zampini if (!mat->ops->mattransposemultsymbolic) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 978*7a3c3d58SStefano Zampini ierr = (*mat->ops->mattransposemultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 9794222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABt; 9804222ddf1SHong Zhang PetscFunctionReturn(0); 9814222ddf1SHong Zhang } 9824222ddf1SHong Zhang 9834222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABC(Mat mat) 9844222ddf1SHong Zhang { 9854222ddf1SHong Zhang PetscErrorCode ierr; 9864222ddf1SHong Zhang Mat_Product *product = mat->product; 9874222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 9884222ddf1SHong Zhang 9894222ddf1SHong Zhang PetscFunctionBegin; 990*7a3c3d58SStefano Zampini if (!mat->ops->matmatmultsymbolic) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 991*7a3c3d58SStefano Zampini ierr = (*mat->ops->matmatmultsymbolic)(A,B,C,product->fill,mat);CHKERRQ(ierr); 9924222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC; 9934222ddf1SHong Zhang PetscFunctionReturn(0); 9944222ddf1SHong Zhang } 9954222ddf1SHong Zhang 9964222ddf1SHong Zhang /*@ 9974222ddf1SHong Zhang MatProductSymbolic - Perform the symbolic portion of a matrix product, this creates a data structure for use with the numerical produce. 9984222ddf1SHong Zhang 9994222ddf1SHong Zhang Collective on Mat 10004222ddf1SHong Zhang 10014222ddf1SHong Zhang Input Parameters: 10024222ddf1SHong Zhang . mat - the matrix to hold a product 10034222ddf1SHong Zhang 10044222ddf1SHong Zhang Output Parameters: 10054222ddf1SHong Zhang . mat - the matrix product data structure 10064222ddf1SHong Zhang 10074222ddf1SHong Zhang Level: intermediate 10084222ddf1SHong Zhang 10094222ddf1SHong Zhang .seealso: MatProductCreate(), MatSetType(), MatProductNumeric(), MatProductType, MatProductAlgorithm 10104222ddf1SHong Zhang @*/ 10114222ddf1SHong Zhang PetscErrorCode MatProductSymbolic(Mat mat) 10124222ddf1SHong Zhang { 10134222ddf1SHong Zhang PetscErrorCode ierr; 10144222ddf1SHong Zhang Mat_Product *product = mat->product; 10154222ddf1SHong Zhang MatProductType productype = product->type; 10164222ddf1SHong Zhang PetscLogEvent eventtype=-1; 10174222ddf1SHong Zhang 10184222ddf1SHong Zhang PetscFunctionBegin; 10194222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10204222ddf1SHong Zhang 10214222ddf1SHong Zhang /* log event */ 10224222ddf1SHong Zhang switch (productype) { 10234222ddf1SHong Zhang case MATPRODUCT_AB: 10244222ddf1SHong Zhang eventtype = MAT_MatMultSymbolic; 10254222ddf1SHong Zhang break; 10264222ddf1SHong Zhang case MATPRODUCT_AtB: 10274222ddf1SHong Zhang eventtype = MAT_TransposeMatMultSymbolic; 10284222ddf1SHong Zhang break; 10294222ddf1SHong Zhang case MATPRODUCT_ABt: 10304222ddf1SHong Zhang eventtype = MAT_MatTransposeMultSymbolic; 10314222ddf1SHong Zhang break; 10324222ddf1SHong Zhang case MATPRODUCT_PtAP: 10334222ddf1SHong Zhang eventtype = MAT_PtAPSymbolic; 10344222ddf1SHong Zhang break; 10354222ddf1SHong Zhang case MATPRODUCT_RARt: 10364222ddf1SHong Zhang eventtype = MAT_RARtSymbolic; 10374222ddf1SHong Zhang break; 10384222ddf1SHong Zhang case MATPRODUCT_ABC: 10394222ddf1SHong Zhang eventtype = MAT_MatMatMultSymbolic; 10404222ddf1SHong Zhang break; 10414222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MATPRODUCT type is not supported"); 10424222ddf1SHong Zhang } 10434222ddf1SHong Zhang 10444222ddf1SHong Zhang if (mat->ops->productsymbolic) { 10454222ddf1SHong Zhang ierr = PetscLogEventBegin(eventtype,mat,0,0,0);CHKERRQ(ierr); 10464222ddf1SHong Zhang ierr = (*mat->ops->productsymbolic)(mat);CHKERRQ(ierr); 10474222ddf1SHong Zhang ierr = PetscLogEventEnd(eventtype,mat,0,0,0);CHKERRQ(ierr); 1048*7a3c3d58SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Call MatProductSetFromOptions() first"); 10494222ddf1SHong Zhang PetscFunctionReturn(0); 10504222ddf1SHong Zhang } 10514222ddf1SHong Zhang 10524222ddf1SHong Zhang /*@ 10534222ddf1SHong Zhang MatProductSetFill - Set an expected fill of the matrix product. 10544222ddf1SHong Zhang 10554222ddf1SHong Zhang Collective on Mat 10564222ddf1SHong Zhang 10574222ddf1SHong Zhang Input Parameters: 10584222ddf1SHong Zhang + mat - the matrix product 10594222ddf1SHong Zhang - fill - expected fill as ratio of nnz(mat)/(nnz(A) + nnz(B) + nnz(C)); use PETSC_DEFAULT if you do not have a good estimate. If the product is a dense matrix, this is irrelevent. 10604222ddf1SHong Zhang 10614222ddf1SHong Zhang Level: intermediate 10624222ddf1SHong Zhang 10634222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetAlgorithm(), MatProductCreate() 10644222ddf1SHong Zhang @*/ 10654222ddf1SHong Zhang PetscErrorCode MatProductSetFill(Mat mat,PetscReal fill) 10664222ddf1SHong Zhang { 10674222ddf1SHong Zhang Mat_Product *product = mat->product; 10684222ddf1SHong Zhang 10694222ddf1SHong Zhang PetscFunctionBegin; 10704222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1071*7a3c3d58SStefano Zampini if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Data struct Mat_Product is not created, call MatProductCreate() first"); 1072*7a3c3d58SStefano Zampini if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) product->fill = 2.0; 1073*7a3c3d58SStefano Zampini else product->fill = fill; 10744222ddf1SHong Zhang PetscFunctionReturn(0); 10754222ddf1SHong Zhang } 10764222ddf1SHong Zhang 10774222ddf1SHong Zhang /*@ 10784222ddf1SHong Zhang MatProductSetAlgorithm - Requests a particular algorithm for a matrix product implementation. 10794222ddf1SHong Zhang 10804222ddf1SHong Zhang Collective on Mat 10814222ddf1SHong Zhang 10824222ddf1SHong Zhang Input Parameters: 10834222ddf1SHong Zhang + mat - the matrix product 10844222ddf1SHong Zhang - alg - particular implementation algorithm of the matrix product, e.g., MATPRODUCTALGORITHM_DEFAULT. 10854222ddf1SHong Zhang 10864222ddf1SHong Zhang Level: intermediate 10874222ddf1SHong Zhang 10884222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetFill(), MatProductCreate() 10894222ddf1SHong Zhang @*/ 10904222ddf1SHong Zhang PetscErrorCode MatProductSetAlgorithm(Mat mat,MatProductAlgorithm alg) 10914222ddf1SHong Zhang { 1092*7a3c3d58SStefano Zampini PetscErrorCode ierr; 10934222ddf1SHong Zhang Mat_Product *product = mat->product; 10944222ddf1SHong Zhang 10954222ddf1SHong Zhang PetscFunctionBegin; 10964222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1097*7a3c3d58SStefano Zampini if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Data struct Mat_Product is not created, call MatProductCreate() first"); 1098*7a3c3d58SStefano Zampini ierr = PetscFree(product->alg);CHKERRQ(ierr); 1099*7a3c3d58SStefano Zampini ierr = PetscStrallocpy(alg,&product->alg);CHKERRQ(ierr); 11004222ddf1SHong Zhang PetscFunctionReturn(0); 11014222ddf1SHong Zhang } 11024222ddf1SHong Zhang 11034222ddf1SHong Zhang /*@ 11044222ddf1SHong Zhang MatProductSetType - Sets a particular matrix product type, for example Mat*Mat. 11054222ddf1SHong Zhang 11064222ddf1SHong Zhang Collective on Mat 11074222ddf1SHong Zhang 11084222ddf1SHong Zhang Input Parameters: 11094222ddf1SHong Zhang + mat - the matrix 11104222ddf1SHong Zhang - productype - matrix product type, e.g., MATPRODUCT_AB,MATPRODUCT_AtB,MATPRODUCT_ABt,MATPRODUCT_PtAP,MATPRODUCT_RARt,MATPRODUCT_ABC. 11114222ddf1SHong Zhang 11124222ddf1SHong Zhang Level: intermediate 11134222ddf1SHong Zhang 11144222ddf1SHong Zhang .seealso: MatProductCreate(), MatProductType, MatProductAlgorithm 11154222ddf1SHong Zhang @*/ 11164222ddf1SHong Zhang PetscErrorCode MatProductSetType(Mat mat,MatProductType productype) 11174222ddf1SHong Zhang { 11184222ddf1SHong Zhang Mat_Product *product = mat->product; 11194222ddf1SHong Zhang 11204222ddf1SHong Zhang PetscFunctionBegin; 11214222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1122*7a3c3d58SStefano Zampini PetscValidLogicalCollectiveEnum(mat,productype,2); 1123*7a3c3d58SStefano Zampini if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Data struct Mat_Product is not created, call MatProductCreate() first"); 11244222ddf1SHong Zhang product->type = productype; 11254222ddf1SHong Zhang 11264222ddf1SHong Zhang switch (productype) { 11274222ddf1SHong Zhang case MATPRODUCT_AB: 11284222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_AB; 11294222ddf1SHong Zhang break; 11304222ddf1SHong Zhang case MATPRODUCT_AtB: 11314222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_AtB; 11324222ddf1SHong Zhang break; 11334222ddf1SHong Zhang case MATPRODUCT_ABt: 11344222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_ABt; 11354222ddf1SHong Zhang break; 11364222ddf1SHong Zhang case MATPRODUCT_PtAP: 11374222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_PtAP; 11384222ddf1SHong Zhang break; 11394222ddf1SHong Zhang case MATPRODUCT_RARt: 11404222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_RARt; 11414222ddf1SHong Zhang break; 11424222ddf1SHong Zhang case MATPRODUCT_ABC: 11434222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_ABC; 11444222ddf1SHong Zhang break; 1145544a5e07SHong Zhang default: SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[product->type]); 11464222ddf1SHong Zhang } 11474222ddf1SHong Zhang PetscFunctionReturn(0); 11484222ddf1SHong Zhang } 11494222ddf1SHong Zhang 11504417c5e8SHong Zhang /*@ 11514417c5e8SHong Zhang MatProductClear - Clears matrix product internal structure. 11524417c5e8SHong Zhang 11534417c5e8SHong Zhang Collective on Mat 11544417c5e8SHong Zhang 11554417c5e8SHong Zhang Input Parameters: 11564417c5e8SHong Zhang . mat - the product matrix 11574417c5e8SHong Zhang 11584417c5e8SHong Zhang Level: intermediate 11594417c5e8SHong Zhang @*/ 11604417c5e8SHong Zhang PetscErrorCode MatProductClear(Mat mat) 11614417c5e8SHong Zhang { 11624417c5e8SHong Zhang PetscErrorCode ierr; 11634417c5e8SHong Zhang Mat_Product *product = mat->product; 11644417c5e8SHong Zhang 11654417c5e8SHong Zhang PetscFunctionBegin; 1166*7a3c3d58SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 11674417c5e8SHong Zhang if (product) { 11684417c5e8SHong Zhang /* release reference */ 11694417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 11704417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 11714417c5e8SHong Zhang ierr = MatDestroy(&product->C);CHKERRQ(ierr); 1172*7a3c3d58SStefano Zampini ierr = PetscFree(product->alg);CHKERRQ(ierr); 11734417c5e8SHong Zhang ierr = MatDestroy(&product->Dwork);CHKERRQ(ierr); 11744417c5e8SHong Zhang ierr = PetscFree(mat->product);CHKERRQ(ierr); 11754417c5e8SHong Zhang } 11764417c5e8SHong Zhang PetscFunctionReturn(0); 11774417c5e8SHong Zhang } 11784417c5e8SHong Zhang 11794222ddf1SHong Zhang /* Create a supporting struct and attach it to the matrix product */ 11804417c5e8SHong Zhang PetscErrorCode MatProductCreate_Private(Mat A,Mat B,Mat C,Mat D) 11814222ddf1SHong Zhang { 11824222ddf1SHong Zhang PetscErrorCode ierr; 11834222ddf1SHong Zhang Mat_Product *product=NULL; 11844222ddf1SHong Zhang 11854222ddf1SHong Zhang PetscFunctionBegin; 11864222ddf1SHong Zhang ierr = PetscNewLog(D,&product);CHKERRQ(ierr); 11874222ddf1SHong Zhang product->A = A; 11884222ddf1SHong Zhang product->B = B; 11894222ddf1SHong Zhang product->C = C; 11904222ddf1SHong Zhang product->Dwork = NULL; 11914222ddf1SHong Zhang product->fill = 2.0; /* PETSC_DEFAULT */ 11924222ddf1SHong Zhang product->Areplaced = PETSC_FALSE; 11934222ddf1SHong Zhang product->Breplaced = PETSC_FALSE; 11944222ddf1SHong Zhang product->api_user = PETSC_FALSE; 11954222ddf1SHong Zhang D->product = product; 11964417c5e8SHong Zhang 1197*7a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(D,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1198*7a3c3d58SStefano Zampini 11994417c5e8SHong Zhang /* take ownership */ 12004417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 12014417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 12024417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); 12034222ddf1SHong Zhang PetscFunctionReturn(0); 12044222ddf1SHong Zhang } 12054222ddf1SHong Zhang 12064222ddf1SHong Zhang /*@ 12074222ddf1SHong Zhang MatProductCreateWithMat - Setup a given matrix as a matrix product. 12084222ddf1SHong Zhang 12094222ddf1SHong Zhang Collective on Mat 12104222ddf1SHong Zhang 12114222ddf1SHong Zhang Input Parameters: 12124222ddf1SHong Zhang + A - the first matrix 12134222ddf1SHong Zhang . B - the second matrix 12144222ddf1SHong Zhang . C - the third matrix (optional) 12154222ddf1SHong Zhang - D - the matrix which will be used as a product 12164222ddf1SHong Zhang 12174222ddf1SHong Zhang Output Parameters: 12184222ddf1SHong Zhang . D - the product matrix 12194222ddf1SHong Zhang 12204222ddf1SHong Zhang Level: intermediate 12214222ddf1SHong Zhang 12224222ddf1SHong Zhang .seealso: MatProductCreate() 12234222ddf1SHong Zhang @*/ 12244222ddf1SHong Zhang PetscErrorCode MatProductCreateWithMat(Mat A,Mat B,Mat C,Mat D) 12254222ddf1SHong Zhang { 12264222ddf1SHong Zhang PetscErrorCode ierr; 12274222ddf1SHong Zhang 12284222ddf1SHong Zhang PetscFunctionBegin; 12294222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 12304222ddf1SHong Zhang PetscValidType(A,1); 12314222ddf1SHong Zhang MatCheckPreallocated(A,1); 12324222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 12334222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 12344222ddf1SHong Zhang 12354222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 12364222ddf1SHong Zhang PetscValidType(B,2); 12374222ddf1SHong Zhang MatCheckPreallocated(B,2); 12384222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 12394222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 12404222ddf1SHong Zhang 12414222ddf1SHong Zhang if (C) { 12424222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 12434222ddf1SHong Zhang PetscValidType(C,3); 12444222ddf1SHong Zhang MatCheckPreallocated(C,3); 12454222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 12464222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 12474222ddf1SHong Zhang } 12484222ddf1SHong Zhang 12494222ddf1SHong Zhang PetscValidHeaderSpecific(D,MAT_CLASSID,4); 12504222ddf1SHong Zhang PetscValidType(D,4); 12514222ddf1SHong Zhang MatCheckPreallocated(D,4); 12524222ddf1SHong Zhang if (!D->assembled) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 12534222ddf1SHong Zhang if (D->factortype) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 12544222ddf1SHong Zhang 12554222ddf1SHong Zhang /* Create a supporting struct and attach it to D */ 12564222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,D);CHKERRQ(ierr); 12574222ddf1SHong Zhang PetscFunctionReturn(0); 12584222ddf1SHong Zhang } 12594222ddf1SHong Zhang 12604222ddf1SHong Zhang /*@ 12614222ddf1SHong Zhang MatProductCreate - create a matrix product object that can be used to compute various matrix times matrix operations. 12624222ddf1SHong Zhang 12634222ddf1SHong Zhang Collective on Mat 12644222ddf1SHong Zhang 12654222ddf1SHong Zhang Input Parameters: 12664222ddf1SHong Zhang + A - the first matrix 12674222ddf1SHong Zhang . B - the second matrix 12684222ddf1SHong Zhang - C - the third matrix (optional) 12694222ddf1SHong Zhang 12704222ddf1SHong Zhang Output Parameters: 12714222ddf1SHong Zhang . D - the product matrix 12724222ddf1SHong Zhang 12734222ddf1SHong Zhang Level: intermediate 12744222ddf1SHong Zhang 12754222ddf1SHong Zhang .seealso: MatProductCreateWithMat(), MatProductSetType(), MatProductSetAlgorithm() 12764222ddf1SHong Zhang @*/ 12774222ddf1SHong Zhang PetscErrorCode MatProductCreate(Mat A,Mat B,Mat C,Mat *D) 12784222ddf1SHong Zhang { 12794222ddf1SHong Zhang PetscErrorCode ierr; 12804222ddf1SHong Zhang 12814222ddf1SHong Zhang PetscFunctionBegin; 12824222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 12834222ddf1SHong Zhang PetscValidType(A,1); 12844222ddf1SHong Zhang MatCheckPreallocated(A,1); 12854222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 12864222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 12874222ddf1SHong Zhang 12884222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 12894222ddf1SHong Zhang PetscValidType(B,2); 12904222ddf1SHong Zhang MatCheckPreallocated(B,2); 12914222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 12924222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 12934222ddf1SHong Zhang 12944222ddf1SHong Zhang if (C) { 12954222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 12964222ddf1SHong Zhang PetscValidType(C,3); 12974222ddf1SHong Zhang MatCheckPreallocated(C,3); 12984222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 12994222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 13004222ddf1SHong Zhang } 13014222ddf1SHong Zhang 13024222ddf1SHong Zhang PetscValidPointer(D,4); 13034222ddf1SHong Zhang 13044222ddf1SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A),D);CHKERRQ(ierr); 13054222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,*D);CHKERRQ(ierr); 13064222ddf1SHong Zhang PetscFunctionReturn(0); 13074222ddf1SHong Zhang } 1308