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 */ 454222ddf1SHong Zhang ierr = (C->ops->transposematmultnumeric)(P,AP,C);CHKERRQ(ierr); 464222ddf1SHong Zhang PetscFunctionReturn(0); 474222ddf1SHong Zhang } 484222ddf1SHong Zhang 494222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_Basic(Mat C) 504222ddf1SHong Zhang { 514222ddf1SHong Zhang PetscErrorCode ierr; 524222ddf1SHong Zhang Mat_Product *product = C->product; 534222ddf1SHong Zhang Mat A=product->A,P=product->B,AP; 544222ddf1SHong Zhang PetscReal fill=product->fill; 554222ddf1SHong Zhang 564222ddf1SHong Zhang PetscFunctionBegin; 574222ddf1SHong Zhang /* AP = A*P */ 584222ddf1SHong Zhang ierr = MatProductCreate(A,P,NULL,&AP);CHKERRQ(ierr); 594222ddf1SHong Zhang ierr = MatProductSetType(AP,MATPRODUCT_AB);CHKERRQ(ierr); 604222ddf1SHong Zhang ierr = MatProductSetAlgorithm(AP,"default");CHKERRQ(ierr); 614222ddf1SHong Zhang ierr = MatProductSetFill(AP,fill);CHKERRQ(ierr); 624222ddf1SHong Zhang ierr = MatProductSetFromOptions(AP);CHKERRQ(ierr); 634222ddf1SHong Zhang ierr = MatProductSymbolic(AP);CHKERRQ(ierr); 644222ddf1SHong Zhang 654222ddf1SHong Zhang /* C = P^T*AP */ 664222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_AtB);CHKERRQ(ierr); 674222ddf1SHong Zhang product->alg = "default"; 684222ddf1SHong Zhang product->A = P; 694222ddf1SHong Zhang product->B = AP; 704222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 714222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 724222ddf1SHong Zhang 734222ddf1SHong Zhang /* resume user's original input matrix setting for A and B */ 744222ddf1SHong Zhang product->A = A; 754222ddf1SHong Zhang product->B = P; 764222ddf1SHong Zhang product->Dwork = AP; 774222ddf1SHong Zhang 784222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP_Basic; 794222ddf1SHong Zhang PetscFunctionReturn(0); 804222ddf1SHong Zhang } 814222ddf1SHong Zhang 824222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_RARt_Basic(Mat C) 834222ddf1SHong Zhang { 844222ddf1SHong Zhang PetscErrorCode ierr; 854222ddf1SHong Zhang Mat_Product *product = C->product; 864222ddf1SHong Zhang Mat R=product->B,RA=product->Dwork; 874222ddf1SHong Zhang 884222ddf1SHong Zhang PetscFunctionBegin; 894222ddf1SHong Zhang /* RA = R*A */ 904222ddf1SHong Zhang ierr = MatProductNumeric(RA);CHKERRQ(ierr); 914222ddf1SHong Zhang /* C = RA*R^T */ 924222ddf1SHong Zhang ierr = (C->ops->mattransposemultnumeric)(RA,R,C);CHKERRQ(ierr); 934222ddf1SHong Zhang PetscFunctionReturn(0); 944222ddf1SHong Zhang } 954222ddf1SHong Zhang 964222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_RARt_Basic(Mat C) 974222ddf1SHong Zhang { 984222ddf1SHong Zhang PetscErrorCode ierr; 994222ddf1SHong Zhang Mat_Product *product = C->product; 1004222ddf1SHong Zhang Mat A=product->A,R=product->B,RA; 1014222ddf1SHong Zhang PetscReal fill=product->fill; 1024222ddf1SHong Zhang 1034222ddf1SHong Zhang PetscFunctionBegin; 1044222ddf1SHong Zhang /* RA = R*A */ 1054222ddf1SHong Zhang ierr = MatProductCreate(R,A,NULL,&RA);CHKERRQ(ierr); 1064222ddf1SHong Zhang ierr = MatProductSetType(RA,MATPRODUCT_AB);CHKERRQ(ierr); 1074222ddf1SHong Zhang ierr = MatProductSetAlgorithm(RA,"default");CHKERRQ(ierr); 1084222ddf1SHong Zhang ierr = MatProductSetFill(RA,fill);CHKERRQ(ierr); 1094222ddf1SHong Zhang ierr = MatProductSetFromOptions(RA);CHKERRQ(ierr); 1104222ddf1SHong Zhang ierr = MatProductSymbolic(RA);CHKERRQ(ierr); 1114222ddf1SHong Zhang 1124222ddf1SHong Zhang /* C = RA*R^T */ 1134222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_ABt);CHKERRQ(ierr); 1144222ddf1SHong Zhang product->alg = "default"; 1154222ddf1SHong Zhang product->A = RA; 1164222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 1174222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 1184222ddf1SHong Zhang 1194222ddf1SHong Zhang /* resume user's original input matrix setting for A */ 1204222ddf1SHong Zhang product->A = A; 1214222ddf1SHong Zhang product->Dwork = RA; /* save here so it will be destroyed with product C */ 1224222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_Basic; 1234222ddf1SHong Zhang PetscFunctionReturn(0); 1244222ddf1SHong Zhang } 1254222ddf1SHong Zhang 1264222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_ABC_Basic(Mat mat) 1274222ddf1SHong Zhang { 1284222ddf1SHong Zhang PetscErrorCode ierr; 1294222ddf1SHong Zhang Mat_Product *product = mat->product; 1304222ddf1SHong Zhang Mat A=product->A,BC=product->Dwork; 1314222ddf1SHong Zhang 1324222ddf1SHong Zhang PetscFunctionBegin; 1334222ddf1SHong Zhang /* Numeric BC = B*C */ 1344222ddf1SHong Zhang ierr = MatProductNumeric(BC);CHKERRQ(ierr); 1354222ddf1SHong Zhang /* Numeric mat = A*BC */ 1364222ddf1SHong Zhang ierr = (mat->ops->matmultnumeric)(A,BC,mat);CHKERRQ(ierr); 1374222ddf1SHong Zhang PetscFunctionReturn(0); 1384222ddf1SHong Zhang } 1394222ddf1SHong Zhang 1404222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_ABC_Basic(Mat mat) 1414222ddf1SHong Zhang { 1424222ddf1SHong Zhang PetscErrorCode ierr; 1434222ddf1SHong Zhang Mat_Product *product = mat->product; 1444222ddf1SHong Zhang Mat B=product->B,C=product->C,BC; 1454222ddf1SHong Zhang PetscReal fill=product->fill; 1464222ddf1SHong Zhang 1474222ddf1SHong Zhang PetscFunctionBegin; 1484222ddf1SHong Zhang /* Symbolic BC = B*C */ 1494222ddf1SHong Zhang ierr = MatProductCreate(B,C,NULL,&BC);CHKERRQ(ierr); 1504222ddf1SHong Zhang ierr = MatProductSetType(BC,MATPRODUCT_AB);CHKERRQ(ierr); 1514222ddf1SHong Zhang ierr = MatProductSetAlgorithm(BC,"default");CHKERRQ(ierr); 1524222ddf1SHong Zhang ierr = MatProductSetFill(BC,fill);CHKERRQ(ierr); 1534222ddf1SHong Zhang ierr = MatProductSetFromOptions(BC);CHKERRQ(ierr); 1544222ddf1SHong Zhang ierr = MatProductSymbolic(BC);CHKERRQ(ierr); 1554222ddf1SHong Zhang 1564222ddf1SHong Zhang /* Symbolic mat = A*BC */ 1574222ddf1SHong Zhang ierr = MatProductSetType(mat,MATPRODUCT_AB);CHKERRQ(ierr); 1584222ddf1SHong Zhang product->alg = "default"; 1594222ddf1SHong Zhang product->B = BC; 1604222ddf1SHong Zhang product->Dwork = BC; 1614222ddf1SHong Zhang ierr = MatProductSetFromOptions(mat);CHKERRQ(ierr); 1624222ddf1SHong Zhang ierr = MatProductSymbolic(mat);CHKERRQ(ierr); 1634222ddf1SHong Zhang 1644222ddf1SHong Zhang /* resume user's original input matrix setting for B */ 1654222ddf1SHong Zhang product->B = B; 1664222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC_Basic; 1674222ddf1SHong Zhang PetscFunctionReturn(0); 1684222ddf1SHong Zhang } 1694222ddf1SHong Zhang 1704222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_Basic(Mat mat) 1714222ddf1SHong Zhang { 1724222ddf1SHong Zhang PetscErrorCode ierr; 1734222ddf1SHong Zhang Mat_Product *product = mat->product; 1744222ddf1SHong Zhang 1754222ddf1SHong Zhang PetscFunctionBegin; 1764222ddf1SHong Zhang switch (product->type) { 1774222ddf1SHong Zhang case MATPRODUCT_PtAP: 1784222ddf1SHong Zhang PetscInfo2((PetscObject)mat, "MatProduct_Basic_PtAP() for A %s, P %s is used",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name); 1794222ddf1SHong Zhang ierr = MatProductSymbolic_PtAP_Basic(mat);CHKERRQ(ierr); 1804222ddf1SHong Zhang break; 1814222ddf1SHong Zhang case MATPRODUCT_RARt: 1824222ddf1SHong Zhang PetscInfo2((PetscObject)mat, "MatProduct_Basic_RARt() for A %s, R %s is used",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name); 1834222ddf1SHong Zhang ierr = MatProductSymbolic_RARt_Basic(mat);CHKERRQ(ierr); 1844222ddf1SHong Zhang break; 1854222ddf1SHong Zhang case MATPRODUCT_ABC: 1864222ddf1SHong Zhang PetscInfo3((PetscObject)mat, "MatProduct_Basic_ABC() for A %s, B %s, C %s is used",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name,((PetscObject)product->C)->type_name); 1874222ddf1SHong Zhang ierr = MatProductSymbolic_ABC_Basic(mat);CHKERRQ(ierr); 1884222ddf1SHong Zhang break; 1894222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType is not supported"); 1904222ddf1SHong Zhang } 1914222ddf1SHong Zhang PetscFunctionReturn(0); 1924222ddf1SHong Zhang } 1934222ddf1SHong Zhang 1944222ddf1SHong Zhang /* ----------------------------------------------- */ 1954222ddf1SHong Zhang /*@C 1964222ddf1SHong Zhang MatProductReplaceMats - Replace input matrices for a matrix product. 1974222ddf1SHong Zhang 1984222ddf1SHong Zhang Collective on Mat 1994222ddf1SHong Zhang 2004222ddf1SHong Zhang Input Parameters: 2014222ddf1SHong Zhang + A - the matrix or NULL if not being replaced 2024222ddf1SHong Zhang . B - the matrix or NULL if not being replaced 2034222ddf1SHong Zhang . C - the matrix or NULL if not being replaced 2044222ddf1SHong Zhang - D - the matrix product 2054222ddf1SHong Zhang 2064222ddf1SHong Zhang Level: intermediate 2074222ddf1SHong Zhang 2084222ddf1SHong Zhang Notes: 2094222ddf1SHong Zhang Input matrix must have exactly same data structure as replaced one. 2104222ddf1SHong Zhang 2114222ddf1SHong Zhang .seealso: MatProductCreate() 2124222ddf1SHong Zhang @*/ 2134222ddf1SHong Zhang PetscErrorCode MatProductReplaceMats(Mat A,Mat B,Mat C,Mat D) 2144222ddf1SHong Zhang { 2154417c5e8SHong Zhang PetscErrorCode ierr; 2164222ddf1SHong Zhang Mat_Product *product=D->product; 2174222ddf1SHong Zhang 2184222ddf1SHong Zhang PetscFunctionBegin; 2194222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_NULL,"Mat D does not have struct 'product'. Call MatProductReplaceProduct(). \n"); 2204222ddf1SHong Zhang if (A) { 2214222ddf1SHong Zhang if (!product->Areplaced) { 2224417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); /* take ownership of input */ 2234417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); /* release old reference */ 2244222ddf1SHong Zhang product->A = A; 2254222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"Matrix A was changed by a PETSc internal routine, cannot be replaced"); 2264222ddf1SHong Zhang } 2274222ddf1SHong Zhang if (B) { 2284222ddf1SHong Zhang if (!product->Breplaced) { 2294417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); /* take ownership of input */ 2304417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); /* release old reference */ 2314222ddf1SHong Zhang product->B = B; 2324222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_SUP,"Matrix B was changed by a PETSc internal routine, cannot be replaced"); 2334222ddf1SHong Zhang } 2344417c5e8SHong Zhang if (C) { 2354417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); /* take ownership of input */ 2364417c5e8SHong Zhang ierr = MatDestroy(&product->C);CHKERRQ(ierr); /* release old reference */ 2374417c5e8SHong Zhang product->C = C; 2384417c5e8SHong Zhang } 2394222ddf1SHong Zhang PetscFunctionReturn(0); 2404222ddf1SHong Zhang } 2414222ddf1SHong Zhang 2424222ddf1SHong Zhang /* ----------------------------------------------- */ 2434222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_AB(Mat mat) 2444222ddf1SHong Zhang { 2454222ddf1SHong Zhang PetscErrorCode ierr; 2464222ddf1SHong Zhang Mat_Product *product = mat->product; 2474222ddf1SHong Zhang Mat A=product->A,B=product->B; 2484222ddf1SHong Zhang PetscBool sametype; 2494222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 2504222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 2514222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 2524222ddf1SHong Zhang PetscBool A_istrans,B_istrans; 2534222ddf1SHong Zhang 2544222ddf1SHong Zhang PetscFunctionBegin; 2554222ddf1SHong Zhang /* Check matrix global sizes */ 2564222ddf1SHong 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); 2574222ddf1SHong Zhang 2584222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 2594222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 2604222ddf1SHong Zhang 2614222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 2624222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&A_istrans);CHKERRQ(ierr); 2634222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&B_istrans);CHKERRQ(ierr); 264*6896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, B %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 2654222ddf1SHong Zhang 2664222ddf1SHong Zhang if (fB == fA && sametype && (!A_istrans || !B_istrans)) { 267*6896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 2684222ddf1SHong Zhang f = fB; 2694222ddf1SHong Zhang } else { 2704222ddf1SHong Zhang char mtypes[256]; 2714222ddf1SHong Zhang PetscBool At_istrans=PETSC_TRUE,Bt_istrans=PETSC_TRUE; 2724222ddf1SHong Zhang Mat At = NULL,Bt = NULL; 2734222ddf1SHong Zhang 2744222ddf1SHong Zhang if (A_istrans && !B_istrans) { 2754222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&At);CHKERRQ(ierr); 2764222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)At,MATTRANSPOSEMAT,&At_istrans);CHKERRQ(ierr); 2774222ddf1SHong Zhang if (At_istrans) { /* mat = ATT * B */ 2784222ddf1SHong Zhang Mat Att = NULL; 2794222ddf1SHong Zhang ierr = MatTransposeGetMat(At,&Att);CHKERRQ(ierr); 2804417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Att);CHKERRQ(ierr); 2814417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 2824222ddf1SHong Zhang A = Att; 2834222ddf1SHong Zhang product->A = Att; /* use Att for matproduct */ 2844222ddf1SHong Zhang product->Areplaced = PETSC_TRUE; /* Att = A, but has native matrix type */ 2854222ddf1SHong Zhang } else { /* !At_istrans: mat = At^T*B */ 2864417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)At);CHKERRQ(ierr); 2874417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 2884222ddf1SHong Zhang A = At; 2894222ddf1SHong Zhang product->A = At; 2904222ddf1SHong Zhang product->Areplaced = PETSC_TRUE; 2914222ddf1SHong Zhang product->type = MATPRODUCT_AtB; 2924222ddf1SHong Zhang } 2934222ddf1SHong Zhang } else if (!A_istrans && B_istrans) { 2944222ddf1SHong Zhang ierr = MatTransposeGetMat(B,&Bt);CHKERRQ(ierr); 2954222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)Bt,MATTRANSPOSEMAT,&Bt_istrans);CHKERRQ(ierr); 2964222ddf1SHong Zhang if (Bt_istrans) { /* mat = A * BTT */ 2974222ddf1SHong Zhang Mat Btt = NULL; 2984222ddf1SHong Zhang ierr = MatTransposeGetMat(Bt,&Btt);CHKERRQ(ierr); 2994417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Btt);CHKERRQ(ierr); 3004417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 3014222ddf1SHong Zhang B = Btt; 3024222ddf1SHong Zhang product->B = Btt; /* use Btt for matproduct */ 3034222ddf1SHong Zhang product->Breplaced = PETSC_TRUE; 3044222ddf1SHong Zhang } else { /* !Bt_istrans */ 3054222ddf1SHong Zhang /* mat = A*Bt^T */ 3064417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Bt);CHKERRQ(ierr); 3074417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 3084222ddf1SHong Zhang B = Bt; 3094222ddf1SHong Zhang product->B = Bt; 3104222ddf1SHong Zhang product->Breplaced = PETSC_TRUE; 3114222ddf1SHong Zhang product->type = MATPRODUCT_ABt; 3124222ddf1SHong Zhang } 3134222ddf1SHong Zhang } else if (A_istrans && B_istrans) { /* mat = At^T * Bt^T */ 3144222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&At);CHKERRQ(ierr); 3154222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)At,MATTRANSPOSEMAT,&At_istrans);CHKERRQ(ierr); 3164222ddf1SHong Zhang ierr = MatTransposeGetMat(B,&Bt);CHKERRQ(ierr); 3174222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)Bt,MATTRANSPOSEMAT,&Bt_istrans);CHKERRQ(ierr); 3184222ddf1SHong Zhang if (At_istrans && Bt_istrans) { 3194222ddf1SHong Zhang Mat Att= NULL,Btt = NULL; 3204222ddf1SHong Zhang ierr = MatTransposeGetMat(At,&Att);CHKERRQ(ierr); 3214222ddf1SHong Zhang ierr = MatTransposeGetMat(Bt,&Btt);CHKERRQ(ierr); 3224417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Att);CHKERRQ(ierr); 3234417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)Btt);CHKERRQ(ierr); 3244417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 3254417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 3264222ddf1SHong Zhang A = Att; 3274222ddf1SHong Zhang product->A = Att; product->Areplaced = PETSC_TRUE; 3284222ddf1SHong Zhang B = Btt; 3294222ddf1SHong Zhang product->B = Btt; product->Breplaced = PETSC_TRUE; 3304222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not supported yet"); 3314222ddf1SHong Zhang } 3324222ddf1SHong Zhang 3334222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 3344222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 3354222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3364222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 3374222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3384222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 339*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 3404222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 3414222ddf1SHong Zhang if (!f) { 342*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 3434222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 3444222ddf1SHong Zhang } 3454222ddf1SHong Zhang } 3464222ddf1SHong Zhang 3474222ddf1SHong Zhang if (!f) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_AB for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 3484222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 3494222ddf1SHong Zhang PetscFunctionReturn(0); 3504222ddf1SHong Zhang } 3514222ddf1SHong Zhang 3524222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_AtB(Mat mat) 3534222ddf1SHong Zhang { 3544222ddf1SHong Zhang PetscErrorCode ierr; 3554222ddf1SHong Zhang Mat_Product *product = mat->product; 3564222ddf1SHong Zhang Mat A=product->A,B=product->B; 3574222ddf1SHong Zhang PetscBool sametype; 3584222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 3594222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 3604222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 3614222ddf1SHong Zhang 3624222ddf1SHong Zhang PetscFunctionBegin; 3634222ddf1SHong Zhang /* Check matrix global sizes */ 3644222ddf1SHong 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); 3654222ddf1SHong Zhang 3664222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 3674222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 3684222ddf1SHong Zhang 3694222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 370*6896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, B %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 3714222ddf1SHong Zhang 3724222ddf1SHong Zhang if (fB == fA && sametype) { 373*6896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 3744222ddf1SHong Zhang f = fB; 3754222ddf1SHong Zhang } else { 3764222ddf1SHong Zhang char mtypes[256]; 3774222ddf1SHong Zhang PetscBool istrans; 3784222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 3794222ddf1SHong Zhang if (!istrans) { 3804222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 3814222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 3824222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3834222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 3844222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3854222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 386*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 3874222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 3884222ddf1SHong Zhang } else { 3894222ddf1SHong Zhang Mat T = NULL; 3904222ddf1SHong 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); 3914222ddf1SHong Zhang 3924222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 3934222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 3944222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)T)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3954222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 3964222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 3974222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 3984222ddf1SHong Zhang 3994222ddf1SHong Zhang product->type = MATPRODUCT_AtB; 400*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 4014222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 4024222ddf1SHong Zhang } 4034222ddf1SHong Zhang 4044222ddf1SHong Zhang if (!f) { 405*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 4064222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 4074222ddf1SHong Zhang } 4084222ddf1SHong Zhang } 4094222ddf1SHong Zhang if (!f) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_AB for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 4104222ddf1SHong Zhang 4114222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 4124222ddf1SHong Zhang PetscFunctionReturn(0); 4134222ddf1SHong Zhang } 4144222ddf1SHong Zhang 4154222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_ABt(Mat mat) 4164222ddf1SHong Zhang { 4174222ddf1SHong Zhang PetscErrorCode ierr; 4184222ddf1SHong Zhang Mat_Product *product = mat->product; 4194222ddf1SHong Zhang Mat A=product->A,B=product->B; 4204222ddf1SHong Zhang PetscBool sametype; 4214222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 4224222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 4234222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 4244222ddf1SHong Zhang 4254222ddf1SHong Zhang PetscFunctionBegin; 4264222ddf1SHong Zhang /* Check matrix global sizes */ 4274222ddf1SHong 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); 4284222ddf1SHong Zhang 4294222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 4304222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 4314222ddf1SHong Zhang 4324222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 433*6896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, B %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 4344222ddf1SHong Zhang if (fB == fA && sametype) { 435*6896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 4364222ddf1SHong Zhang f = fB; 4374222ddf1SHong Zhang } else { 4384222ddf1SHong Zhang char mtypes[256]; 4394222ddf1SHong Zhang PetscBool istrans; 4404222ddf1SHong Zhang ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 4414222ddf1SHong Zhang if (!istrans) { 4424222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 4434222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 4444222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4454222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4464222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4474222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 448*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 4494222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 4504222ddf1SHong Zhang } else { 4514222ddf1SHong Zhang Mat T = NULL; 4524222ddf1SHong 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); 4534222ddf1SHong Zhang 4544222ddf1SHong Zhang ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 4554222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 4564222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)T)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4574222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4584222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4594222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 4604222ddf1SHong Zhang 4614222ddf1SHong Zhang product->type = MATPRODUCT_ABt; 462*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s (ABt)\n",f);CHKERRQ(ierr); 4634222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 4644222ddf1SHong Zhang } 4654222ddf1SHong Zhang 4664222ddf1SHong Zhang if (!f) { 467*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 4684222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 4694222ddf1SHong Zhang } 4704222ddf1SHong Zhang } 4714222ddf1SHong Zhang if (!f) { 4724222ddf1SHong Zhang SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatProductSetFromOptions_AB for A %s and B %s is not supported",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 4734222ddf1SHong Zhang } 4744222ddf1SHong Zhang 4754222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 4764222ddf1SHong Zhang PetscFunctionReturn(0); 4774222ddf1SHong Zhang } 4784222ddf1SHong Zhang 4794222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_PtAP(Mat mat) 4804222ddf1SHong Zhang { 4814222ddf1SHong Zhang PetscErrorCode ierr; 4824222ddf1SHong Zhang Mat_Product *product = mat->product; 4834222ddf1SHong Zhang Mat A=product->A,B=product->B; 4844222ddf1SHong Zhang PetscBool sametype; 4854222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 4864222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 4874222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 4884222ddf1SHong Zhang 4894222ddf1SHong Zhang PetscFunctionBegin; 4904222ddf1SHong Zhang /* Check matrix global sizes */ 4914222ddf1SHong 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); 4924222ddf1SHong 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); 4934222ddf1SHong Zhang 4944222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 4954222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 4964222ddf1SHong Zhang 497*6896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, P %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 4984222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 4994222ddf1SHong Zhang if (fB == fA && sametype) { 500*6896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 5014222ddf1SHong Zhang f = fB; 5024222ddf1SHong Zhang } else { 5034222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 5044222ddf1SHong Zhang char mtypes[256]; 5054222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 5064222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5074222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 5084222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5094222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 510*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 5114222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 5124222ddf1SHong Zhang 5134222ddf1SHong Zhang if (!f) { 514*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 5154222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 5164222ddf1SHong Zhang } 5174222ddf1SHong Zhang } 5184222ddf1SHong Zhang 5194222ddf1SHong Zhang if (f) { 5204222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 5214222ddf1SHong Zhang } else { 5224222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 523*6896283bSStefano Zampini ierr = PetscInfo2(mat," for A %s, P %s uses MatProduct_Basic() implementation",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 5244222ddf1SHong Zhang } 5254222ddf1SHong Zhang PetscFunctionReturn(0); 5264222ddf1SHong Zhang } 5274222ddf1SHong Zhang 5284222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_RARt(Mat mat) 5294222ddf1SHong Zhang { 5304222ddf1SHong Zhang PetscErrorCode ierr; 5314222ddf1SHong Zhang Mat_Product *product = mat->product; 5324222ddf1SHong Zhang Mat A=product->A,B=product->B; 5334222ddf1SHong Zhang PetscBool sametype; 5344222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 5354222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 5364222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 5374222ddf1SHong Zhang 5384222ddf1SHong Zhang PetscFunctionBegin; 5394222ddf1SHong Zhang /* Check matrix global sizes */ 5404222ddf1SHong 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); 5414222ddf1SHong 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); 5424222ddf1SHong Zhang 5434222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 5444222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 5454222ddf1SHong Zhang 5464222ddf1SHong Zhang ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)B)->type_name,&sametype);CHKERRQ(ierr); 547*6896283bSStefano Zampini ierr = PetscInfo2(mat,"for A %s, B %s\n",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 5484222ddf1SHong Zhang if (fB == fA && sametype) { 549*6896283bSStefano Zampini ierr = PetscInfo(mat," sametype and matching op\n");CHKERRQ(ierr); 5504222ddf1SHong Zhang f = fB; 5514222ddf1SHong Zhang } else { 5524222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype */ 5534222ddf1SHong Zhang char mtypes[256]; 5544222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 5554222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5564222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 5574222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 5584222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 559*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 5604222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 5614222ddf1SHong Zhang 5624222ddf1SHong Zhang if (!f) { 563*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 5644222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 5654222ddf1SHong Zhang } 5664222ddf1SHong Zhang } 5674222ddf1SHong Zhang 5684222ddf1SHong Zhang if (f) { 5694222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 5704222ddf1SHong Zhang } else { 571*6896283bSStefano Zampini ierr = PetscInfo2(mat," for A %s, P %s uses MatProduct_Basic() implementation",((PetscObject)A)->type_name,((PetscObject)B)->type_name);CHKERRQ(ierr); 5724222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 5734222ddf1SHong Zhang } 5744222ddf1SHong Zhang PetscFunctionReturn(0); 5754222ddf1SHong Zhang } 5764222ddf1SHong Zhang 5774222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_ABC(Mat mat) 5784222ddf1SHong Zhang { 5794222ddf1SHong Zhang PetscErrorCode ierr; 5804222ddf1SHong Zhang Mat_Product *product = mat->product; 5814222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 5824222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 5834222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 5844222ddf1SHong Zhang PetscErrorCode (*fC)(Mat); 5854222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 5864222ddf1SHong Zhang 5874222ddf1SHong Zhang PetscFunctionBegin; 5884222ddf1SHong Zhang /* Check matrix global sizes */ 5894222ddf1SHong 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); 5904222ddf1SHong 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); 5914222ddf1SHong Zhang 5924222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 5934222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 5944222ddf1SHong Zhang fC = C->ops->productsetfromoptions; 595*6896283bSStefano 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); 5964222ddf1SHong Zhang if (fA == fB && fA == fC && fA) { 597*6896283bSStefano Zampini ierr = PetscInfo(mat," matching op\n");CHKERRQ(ierr); 5984222ddf1SHong Zhang f = fA; 5994222ddf1SHong Zhang } else { 6004222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype_Ctype */ 6014222ddf1SHong Zhang char mtypes[256]; 6024222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 6034222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6044222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 6054222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6064222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 6074222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)C)->type_name,sizeof(mtypes));CHKERRQ(ierr); 6084222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 6094222ddf1SHong Zhang 610*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 6114222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 6124222ddf1SHong Zhang if (!f) { 613*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 6144222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 6154222ddf1SHong Zhang } 6164222ddf1SHong Zhang if (!f) { 617*6896283bSStefano Zampini ierr = PetscInfo1(mat," querying %s\n",f);CHKERRQ(ierr); 6184222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)C,mtypes,&f);CHKERRQ(ierr); 6194222ddf1SHong Zhang } 6204222ddf1SHong Zhang } 6214222ddf1SHong Zhang 6224222ddf1SHong Zhang if (f) { 6234222ddf1SHong Zhang ierr = (*f)(mat);CHKERRQ(ierr); 6244222ddf1SHong Zhang } else { /* use MatProductSymbolic/Numeric_Basic() */ 625*6896283bSStefano 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); 6264222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 6274222ddf1SHong Zhang } 6284222ddf1SHong Zhang PetscFunctionReturn(0); 6294222ddf1SHong Zhang } 6304222ddf1SHong Zhang 6314222ddf1SHong Zhang /*@C 6324222ddf1SHong Zhang MatProductSetFromOptions - Creates a matrix product where the type, the algorithm etc are determined from the options database. 6334222ddf1SHong Zhang 6344222ddf1SHong Zhang Logically Collective on Mat 6354222ddf1SHong Zhang 6364222ddf1SHong Zhang Input Parameter: 6374222ddf1SHong Zhang . mat - the matrix 6384222ddf1SHong Zhang 6394222ddf1SHong Zhang Level: beginner 6404222ddf1SHong Zhang 6414222ddf1SHong Zhang .seealso: MatSetFromOptions() 6424222ddf1SHong Zhang @*/ 6434222ddf1SHong Zhang PetscErrorCode MatProductSetFromOptions(Mat mat) 6444222ddf1SHong Zhang { 6454222ddf1SHong Zhang PetscErrorCode ierr; 6464222ddf1SHong Zhang 6474222ddf1SHong Zhang PetscFunctionBegin; 6484222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6494222ddf1SHong Zhang 6504222ddf1SHong Zhang if (mat->ops->productsetfromoptions) { 6514222ddf1SHong Zhang ierr = (*mat->ops->productsetfromoptions)(mat);CHKERRQ(ierr); 6524222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Call MatProductSetType() first"); 6534222ddf1SHong Zhang PetscFunctionReturn(0); 6544222ddf1SHong Zhang } 6554222ddf1SHong Zhang 6564222ddf1SHong Zhang /* ----------------------------------------------- */ 6574222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AB(Mat mat) 6584222ddf1SHong Zhang { 6594222ddf1SHong Zhang PetscErrorCode ierr; 6604222ddf1SHong Zhang Mat_Product *product = mat->product; 6614222ddf1SHong Zhang Mat A=product->A,B=product->B; 6624222ddf1SHong Zhang 6634222ddf1SHong Zhang PetscFunctionBegin; 6644222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 6654222ddf1SHong Zhang ierr = (mat->ops->matmultnumeric)(A,B,mat);CHKERRQ(ierr); 6664222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 6674222ddf1SHong Zhang PetscFunctionReturn(0); 6684222ddf1SHong Zhang } 6694222ddf1SHong Zhang 6704222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AtB(Mat mat) 6714222ddf1SHong Zhang { 6724222ddf1SHong Zhang PetscErrorCode ierr; 6734222ddf1SHong Zhang Mat_Product *product = mat->product; 6744222ddf1SHong Zhang Mat A=product->A,B=product->B; 6754222ddf1SHong Zhang 6764222ddf1SHong Zhang PetscFunctionBegin; 6774222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 6784222ddf1SHong Zhang ierr = (mat->ops->transposematmultnumeric)(A,B,mat);CHKERRQ(ierr); 6794222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 6804222ddf1SHong Zhang PetscFunctionReturn(0); 6814222ddf1SHong Zhang } 6824222ddf1SHong Zhang 6834222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABt(Mat mat) 6844222ddf1SHong Zhang { 6854222ddf1SHong Zhang PetscErrorCode ierr; 6864222ddf1SHong Zhang Mat_Product *product = mat->product; 6874222ddf1SHong Zhang Mat A=product->A,B=product->B; 6884222ddf1SHong Zhang 6894222ddf1SHong Zhang PetscFunctionBegin; 6904222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 6914222ddf1SHong Zhang ierr = (mat->ops->mattransposemultnumeric)(A,B,mat);CHKERRQ(ierr); 6924222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 6934222ddf1SHong Zhang PetscFunctionReturn(0); 6944222ddf1SHong Zhang } 6954222ddf1SHong Zhang 6964222ddf1SHong Zhang PetscErrorCode MatProductNumeric_PtAP(Mat mat) 6974222ddf1SHong Zhang { 6984222ddf1SHong Zhang PetscErrorCode ierr; 6994222ddf1SHong Zhang Mat_Product *product = mat->product; 7004222ddf1SHong Zhang Mat A=product->A,B=product->B; 7014222ddf1SHong Zhang 7024222ddf1SHong Zhang PetscFunctionBegin; 7034222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 7044222ddf1SHong Zhang ierr = (mat->ops->ptapnumeric)(A,B,mat);CHKERRQ(ierr); 7054222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 7064222ddf1SHong Zhang PetscFunctionReturn(0); 7074222ddf1SHong Zhang } 7084222ddf1SHong Zhang 7094222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt(Mat mat) 7104222ddf1SHong Zhang { 7114222ddf1SHong Zhang PetscErrorCode ierr; 7124222ddf1SHong Zhang Mat_Product *product = mat->product; 7134222ddf1SHong Zhang Mat A=product->A,B=product->B; 7144222ddf1SHong Zhang 7154222ddf1SHong Zhang PetscFunctionBegin; 7164222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 7174222ddf1SHong Zhang ierr = (mat->ops->rartnumeric)(A,B,mat);CHKERRQ(ierr); 7184222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 7194222ddf1SHong Zhang PetscFunctionReturn(0); 7204222ddf1SHong Zhang } 7214222ddf1SHong Zhang 7224222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABC(Mat mat) 7234222ddf1SHong Zhang { 7244222ddf1SHong Zhang PetscErrorCode ierr; 7254222ddf1SHong Zhang Mat_Product *product = mat->product; 7264222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 7274222ddf1SHong Zhang 7284222ddf1SHong Zhang PetscFunctionBegin; 7294222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 7304222ddf1SHong Zhang ierr = (mat->ops->matmatmultnumeric)(A,B,C,mat);CHKERRQ(ierr); 7314222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 7324222ddf1SHong Zhang PetscFunctionReturn(0); 7334222ddf1SHong Zhang } 7344222ddf1SHong Zhang 7354222ddf1SHong Zhang /*@ 7364222ddf1SHong Zhang MatProductNumeric - Implement a matrix product with numerical values. 7374222ddf1SHong Zhang 7384222ddf1SHong Zhang Collective on Mat 7394222ddf1SHong Zhang 7404222ddf1SHong Zhang Input Parameters: 7414222ddf1SHong Zhang . mat - the matrix to hold a product 7424222ddf1SHong Zhang 7434222ddf1SHong Zhang Output Parameters: 7444222ddf1SHong Zhang . mat - the matrix product 7454222ddf1SHong Zhang 7464222ddf1SHong Zhang Level: intermediate 7474222ddf1SHong Zhang 7484222ddf1SHong Zhang .seealso: MatProductCreate(), MatSetType() 7494222ddf1SHong Zhang @*/ 7504222ddf1SHong Zhang PetscErrorCode MatProductNumeric(Mat mat) 7514222ddf1SHong Zhang { 7524222ddf1SHong Zhang PetscErrorCode ierr; 7534222ddf1SHong Zhang 7544222ddf1SHong Zhang PetscFunctionBegin; 7554222ddf1SHong Zhang PetscValidPointer(mat,1); 7564222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7574222ddf1SHong Zhang 7584222ddf1SHong Zhang if (mat->ops->productnumeric) { 7594222ddf1SHong Zhang ierr = (*mat->ops->productnumeric)(mat);CHKERRQ(ierr); 7604222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_USER,"Call MatProductSymbolic() first"); 7614222ddf1SHong Zhang PetscFunctionReturn(0); 7624222ddf1SHong Zhang } 7634222ddf1SHong Zhang 7644222ddf1SHong Zhang /* ----------------------------------------------- */ 7654222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AB(Mat mat) 7664222ddf1SHong Zhang { 7674222ddf1SHong Zhang PetscErrorCode ierr; 7684222ddf1SHong Zhang Mat_Product *product = mat->product; 7694222ddf1SHong Zhang Mat A=product->A,B=product->B; 7704222ddf1SHong Zhang 7714222ddf1SHong Zhang PetscFunctionBegin; 7724222ddf1SHong Zhang ierr = (mat->ops->matmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7734222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AB; 7744222ddf1SHong Zhang PetscFunctionReturn(0); 7754222ddf1SHong Zhang } 7764222ddf1SHong Zhang 7774222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AtB(Mat mat) 7784222ddf1SHong Zhang { 7794222ddf1SHong Zhang PetscErrorCode ierr; 7804222ddf1SHong Zhang Mat_Product *product = mat->product; 7814222ddf1SHong Zhang Mat A=product->A,B=product->B; 7824222ddf1SHong Zhang 7834222ddf1SHong Zhang PetscFunctionBegin; 7844222ddf1SHong Zhang ierr = (mat->ops->transposematmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7854222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AtB; 7864222ddf1SHong Zhang PetscFunctionReturn(0); 7874222ddf1SHong Zhang } 7884222ddf1SHong Zhang 7894222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABt(Mat mat) 7904222ddf1SHong Zhang { 7914222ddf1SHong Zhang PetscErrorCode ierr; 7924222ddf1SHong Zhang Mat_Product *product = mat->product; 7934222ddf1SHong Zhang Mat A=product->A,B=product->B; 7944222ddf1SHong Zhang 7954222ddf1SHong Zhang PetscFunctionBegin; 7964222ddf1SHong Zhang ierr = (mat->ops->mattransposemultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7974222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABt; 7984222ddf1SHong Zhang PetscFunctionReturn(0); 7994222ddf1SHong Zhang } 8004222ddf1SHong Zhang 8014222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABC(Mat mat) 8024222ddf1SHong Zhang { 8034222ddf1SHong Zhang PetscErrorCode ierr; 8044222ddf1SHong Zhang Mat_Product *product = mat->product; 8054222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 8064222ddf1SHong Zhang 8074222ddf1SHong Zhang PetscFunctionBegin; 8084222ddf1SHong Zhang ierr = (mat->ops->matmatmultsymbolic)(A,B,C,product->fill,mat);CHKERRQ(ierr); 8094222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC; 8104222ddf1SHong Zhang PetscFunctionReturn(0); 8114222ddf1SHong Zhang } 8124222ddf1SHong Zhang 8134222ddf1SHong Zhang /*@ 8144222ddf1SHong Zhang MatProductSymbolic - Perform the symbolic portion of a matrix product, this creates a data structure for use with the numerical produce. 8154222ddf1SHong Zhang 8164222ddf1SHong Zhang Collective on Mat 8174222ddf1SHong Zhang 8184222ddf1SHong Zhang Input Parameters: 8194222ddf1SHong Zhang . mat - the matrix to hold a product 8204222ddf1SHong Zhang 8214222ddf1SHong Zhang Output Parameters: 8224222ddf1SHong Zhang . mat - the matrix product data structure 8234222ddf1SHong Zhang 8244222ddf1SHong Zhang Level: intermediate 8254222ddf1SHong Zhang 8264222ddf1SHong Zhang .seealso: MatProductCreate(), MatSetType(), MatProductNumeric(), MatProductType, MatProductAlgorithm 8274222ddf1SHong Zhang @*/ 8284222ddf1SHong Zhang PetscErrorCode MatProductSymbolic(Mat mat) 8294222ddf1SHong Zhang { 8304222ddf1SHong Zhang PetscErrorCode ierr; 8314222ddf1SHong Zhang Mat_Product *product = mat->product; 8324222ddf1SHong Zhang MatProductType productype = product->type; 8334222ddf1SHong Zhang PetscLogEvent eventtype=-1; 8344222ddf1SHong Zhang 8354222ddf1SHong Zhang PetscFunctionBegin; 8364222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8374222ddf1SHong Zhang 8384222ddf1SHong Zhang /* log event */ 8394222ddf1SHong Zhang switch (productype) { 8404222ddf1SHong Zhang case MATPRODUCT_AB: 8414222ddf1SHong Zhang eventtype = MAT_MatMultSymbolic; 8424222ddf1SHong Zhang break; 8434222ddf1SHong Zhang case MATPRODUCT_AtB: 8444222ddf1SHong Zhang eventtype = MAT_TransposeMatMultSymbolic; 8454222ddf1SHong Zhang break; 8464222ddf1SHong Zhang case MATPRODUCT_ABt: 8474222ddf1SHong Zhang eventtype = MAT_MatTransposeMultSymbolic; 8484222ddf1SHong Zhang break; 8494222ddf1SHong Zhang case MATPRODUCT_PtAP: 8504222ddf1SHong Zhang eventtype = MAT_PtAPSymbolic; 8514222ddf1SHong Zhang break; 8524222ddf1SHong Zhang case MATPRODUCT_RARt: 8534222ddf1SHong Zhang eventtype = MAT_RARtSymbolic; 8544222ddf1SHong Zhang break; 8554222ddf1SHong Zhang case MATPRODUCT_ABC: 8564222ddf1SHong Zhang eventtype = MAT_MatMatMultSymbolic; 8574222ddf1SHong Zhang break; 8584222ddf1SHong Zhang default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MATPRODUCT type is not supported"); 8594222ddf1SHong Zhang } 8604222ddf1SHong Zhang 8614222ddf1SHong Zhang if (mat->ops->productsymbolic) { 8624222ddf1SHong Zhang ierr = PetscLogEventBegin(eventtype,mat,0,0,0);CHKERRQ(ierr); 8634222ddf1SHong Zhang ierr = (*mat->ops->productsymbolic)(mat);CHKERRQ(ierr); 8644222ddf1SHong Zhang ierr = PetscLogEventEnd(eventtype,mat,0,0,0);CHKERRQ(ierr); 8654222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_USER,"Call MatProductSetFromOptions() first"); 8664222ddf1SHong Zhang PetscFunctionReturn(0); 8674222ddf1SHong Zhang } 8684222ddf1SHong Zhang 8694222ddf1SHong Zhang /*@ 8704222ddf1SHong Zhang MatProductSetFill - Set an expected fill of the matrix product. 8714222ddf1SHong Zhang 8724222ddf1SHong Zhang Collective on Mat 8734222ddf1SHong Zhang 8744222ddf1SHong Zhang Input Parameters: 8754222ddf1SHong Zhang + mat - the matrix product 8764222ddf1SHong 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. 8774222ddf1SHong Zhang 8784222ddf1SHong Zhang Level: intermediate 8794222ddf1SHong Zhang 8804222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetAlgorithm(), MatProductCreate() 8814222ddf1SHong Zhang @*/ 8824222ddf1SHong Zhang PetscErrorCode MatProductSetFill(Mat mat,PetscReal fill) 8834222ddf1SHong Zhang { 8844222ddf1SHong Zhang Mat_Product *product = mat->product; 8854222ddf1SHong Zhang 8864222ddf1SHong Zhang PetscFunctionBegin; 8874222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8884222ddf1SHong Zhang 8894222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 8904222ddf1SHong Zhang if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) { 8914222ddf1SHong Zhang product->fill = 2.0; 8924222ddf1SHong Zhang } else product->fill = fill; 8934222ddf1SHong Zhang PetscFunctionReturn(0); 8944222ddf1SHong Zhang } 8954222ddf1SHong Zhang 8964222ddf1SHong Zhang /*@ 8974222ddf1SHong Zhang MatProductSetAlgorithm - Requests a particular algorithm for a matrix product implementation. 8984222ddf1SHong Zhang 8994222ddf1SHong Zhang Collective on Mat 9004222ddf1SHong Zhang 9014222ddf1SHong Zhang Input Parameters: 9024222ddf1SHong Zhang + mat - the matrix product 9034222ddf1SHong Zhang - alg - particular implementation algorithm of the matrix product, e.g., MATPRODUCTALGORITHM_DEFAULT. 9044222ddf1SHong Zhang 9054222ddf1SHong Zhang Level: intermediate 9064222ddf1SHong Zhang 9074222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetFill(), MatProductCreate() 9084222ddf1SHong Zhang @*/ 9094222ddf1SHong Zhang PetscErrorCode MatProductSetAlgorithm(Mat mat,MatProductAlgorithm alg) 9104222ddf1SHong Zhang { 9114222ddf1SHong Zhang Mat_Product *product = mat->product; 9124222ddf1SHong Zhang 9134222ddf1SHong Zhang PetscFunctionBegin; 9144222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9154222ddf1SHong Zhang 9164222ddf1SHong Zhang if (!product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 9174222ddf1SHong Zhang product->alg = alg; 9184222ddf1SHong Zhang PetscFunctionReturn(0); 9194222ddf1SHong Zhang } 9204222ddf1SHong Zhang 9214222ddf1SHong Zhang /*@ 9224222ddf1SHong Zhang MatProductSetType - Sets a particular matrix product type, for example Mat*Mat. 9234222ddf1SHong Zhang 9244222ddf1SHong Zhang Collective on Mat 9254222ddf1SHong Zhang 9264222ddf1SHong Zhang Input Parameters: 9274222ddf1SHong Zhang + mat - the matrix 9284222ddf1SHong Zhang - productype - matrix product type, e.g., MATPRODUCT_AB,MATPRODUCT_AtB,MATPRODUCT_ABt,MATPRODUCT_PtAP,MATPRODUCT_RARt,MATPRODUCT_ABC. 9294222ddf1SHong Zhang 9304222ddf1SHong Zhang Level: intermediate 9314222ddf1SHong Zhang 9324222ddf1SHong Zhang .seealso: MatProductCreate(), MatProductType, MatProductAlgorithm 9334222ddf1SHong Zhang @*/ 9344222ddf1SHong Zhang PetscErrorCode MatProductSetType(Mat mat,MatProductType productype) 9354222ddf1SHong Zhang { 9364222ddf1SHong Zhang PetscErrorCode ierr; 9374222ddf1SHong Zhang Mat_Product *product = mat->product; 9384222ddf1SHong Zhang MPI_Comm comm; 9394222ddf1SHong Zhang 9404222ddf1SHong Zhang PetscFunctionBegin; 9414222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9424222ddf1SHong Zhang 9434222ddf1SHong Zhang ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9444222ddf1SHong Zhang if (!product) SETERRQ(comm,PETSC_ERR_ARG_NULL,"Data struc Mat_Product is not created, call MatProductCreate() first"); 9454222ddf1SHong Zhang product->type = productype; 9464222ddf1SHong Zhang 9474222ddf1SHong Zhang switch (productype) { 9484222ddf1SHong Zhang case MATPRODUCT_AB: 9494222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_AB; 9504222ddf1SHong Zhang break; 9514222ddf1SHong Zhang case MATPRODUCT_AtB: 9524222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_AtB; 9534222ddf1SHong Zhang break; 9544222ddf1SHong Zhang case MATPRODUCT_ABt: 9554222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_ABt; 9564222ddf1SHong Zhang break; 9574222ddf1SHong Zhang case MATPRODUCT_PtAP: 9584222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_PtAP; 9594222ddf1SHong Zhang break; 9604222ddf1SHong Zhang case MATPRODUCT_RARt: 9614222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_RARt; 9624222ddf1SHong Zhang break; 9634222ddf1SHong Zhang case MATPRODUCT_ABC: 9644222ddf1SHong Zhang mat->ops->productsetfromoptions = MatProductSetFromOptions_ABC; 9654222ddf1SHong Zhang break; 966544a5e07SHong Zhang default: SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[product->type]); 9674222ddf1SHong Zhang } 9684222ddf1SHong Zhang PetscFunctionReturn(0); 9694222ddf1SHong Zhang } 9704222ddf1SHong Zhang 9714417c5e8SHong Zhang /*@ 9724417c5e8SHong Zhang MatProductClear - Clears matrix product internal structure. 9734417c5e8SHong Zhang 9744417c5e8SHong Zhang Collective on Mat 9754417c5e8SHong Zhang 9764417c5e8SHong Zhang Input Parameters: 9774417c5e8SHong Zhang . mat - the product matrix 9784417c5e8SHong Zhang 9794417c5e8SHong Zhang Level: intermediate 9804417c5e8SHong Zhang @*/ 9814417c5e8SHong Zhang PetscErrorCode MatProductClear(Mat mat) 9824417c5e8SHong Zhang { 9834417c5e8SHong Zhang PetscErrorCode ierr; 9844417c5e8SHong Zhang Mat_Product *product = mat->product; 9854417c5e8SHong Zhang 9864417c5e8SHong Zhang PetscFunctionBegin; 9874417c5e8SHong Zhang if (product) { 9884417c5e8SHong Zhang /* release reference */ 9894417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 9904417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 9914417c5e8SHong Zhang ierr = MatDestroy(&product->C);CHKERRQ(ierr); 9924417c5e8SHong Zhang ierr = MatDestroy(&product->Dwork);CHKERRQ(ierr); 9934417c5e8SHong Zhang ierr = PetscFree(mat->product);CHKERRQ(ierr); 9944417c5e8SHong Zhang } 9954417c5e8SHong Zhang PetscFunctionReturn(0); 9964417c5e8SHong Zhang } 9974417c5e8SHong Zhang 9984222ddf1SHong Zhang /* Create a supporting struct and attach it to the matrix product */ 9994417c5e8SHong Zhang PetscErrorCode MatProductCreate_Private(Mat A,Mat B,Mat C,Mat D) 10004222ddf1SHong Zhang { 10014222ddf1SHong Zhang PetscErrorCode ierr; 10024222ddf1SHong Zhang Mat_Product *product=NULL; 10034222ddf1SHong Zhang 10044222ddf1SHong Zhang PetscFunctionBegin; 10054222ddf1SHong Zhang ierr = PetscNewLog(D,&product);CHKERRQ(ierr); 10064222ddf1SHong Zhang product->A = A; 10074222ddf1SHong Zhang product->B = B; 10084222ddf1SHong Zhang product->C = C; 10094222ddf1SHong Zhang product->Dwork = NULL; 10104222ddf1SHong Zhang product->alg = MATPRODUCTALGORITHM_DEFAULT; 10114222ddf1SHong Zhang product->fill = 2.0; /* PETSC_DEFAULT */ 10124222ddf1SHong Zhang product->Areplaced = PETSC_FALSE; 10134222ddf1SHong Zhang product->Breplaced = PETSC_FALSE; 10144222ddf1SHong Zhang product->api_user = PETSC_FALSE; 10154222ddf1SHong Zhang D->product = product; 10164417c5e8SHong Zhang 10174417c5e8SHong Zhang /* take ownership */ 10184417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 10194417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 10204417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); 10214222ddf1SHong Zhang PetscFunctionReturn(0); 10224222ddf1SHong Zhang } 10234222ddf1SHong Zhang 10244222ddf1SHong Zhang /*@ 10254222ddf1SHong Zhang MatProductCreateWithMat - Setup a given matrix as a matrix product. 10264222ddf1SHong Zhang 10274222ddf1SHong Zhang Collective on Mat 10284222ddf1SHong Zhang 10294222ddf1SHong Zhang Input Parameters: 10304222ddf1SHong Zhang + A - the first matrix 10314222ddf1SHong Zhang . B - the second matrix 10324222ddf1SHong Zhang . C - the third matrix (optional) 10334222ddf1SHong Zhang - D - the matrix which will be used as a product 10344222ddf1SHong Zhang 10354222ddf1SHong Zhang Output Parameters: 10364222ddf1SHong Zhang . D - the product matrix 10374222ddf1SHong Zhang 10384222ddf1SHong Zhang Level: intermediate 10394222ddf1SHong Zhang 10404222ddf1SHong Zhang .seealso: MatProductCreate() 10414222ddf1SHong Zhang @*/ 10424222ddf1SHong Zhang PetscErrorCode MatProductCreateWithMat(Mat A,Mat B,Mat C,Mat D) 10434222ddf1SHong Zhang { 10444222ddf1SHong Zhang PetscErrorCode ierr; 10454222ddf1SHong Zhang 10464222ddf1SHong Zhang PetscFunctionBegin; 10474222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10484222ddf1SHong Zhang PetscValidType(A,1); 10494222ddf1SHong Zhang MatCheckPreallocated(A,1); 10504222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10514222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10524222ddf1SHong Zhang 10534222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10544222ddf1SHong Zhang PetscValidType(B,2); 10554222ddf1SHong Zhang MatCheckPreallocated(B,2); 10564222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10574222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10584222ddf1SHong Zhang 10594222ddf1SHong Zhang if (C) { 10604222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10614222ddf1SHong Zhang PetscValidType(C,3); 10624222ddf1SHong Zhang MatCheckPreallocated(C,3); 10634222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10644222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10654222ddf1SHong Zhang } 10664222ddf1SHong Zhang 10674222ddf1SHong Zhang PetscValidHeaderSpecific(D,MAT_CLASSID,4); 10684222ddf1SHong Zhang PetscValidType(D,4); 10694222ddf1SHong Zhang MatCheckPreallocated(D,4); 10704222ddf1SHong Zhang if (!D->assembled) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10714222ddf1SHong Zhang if (D->factortype) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10724222ddf1SHong Zhang 10734222ddf1SHong Zhang /* Create a supporting struct and attach it to D */ 10744222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,D);CHKERRQ(ierr); 10754222ddf1SHong Zhang PetscFunctionReturn(0); 10764222ddf1SHong Zhang } 10774222ddf1SHong Zhang 10784222ddf1SHong Zhang /*@ 10794222ddf1SHong Zhang MatProductCreate - create a matrix product object that can be used to compute various matrix times matrix operations. 10804222ddf1SHong Zhang 10814222ddf1SHong Zhang Collective on Mat 10824222ddf1SHong Zhang 10834222ddf1SHong Zhang Input Parameters: 10844222ddf1SHong Zhang + A - the first matrix 10854222ddf1SHong Zhang . B - the second matrix 10864222ddf1SHong Zhang - C - the third matrix (optional) 10874222ddf1SHong Zhang 10884222ddf1SHong Zhang Output Parameters: 10894222ddf1SHong Zhang . D - the product matrix 10904222ddf1SHong Zhang 10914222ddf1SHong Zhang Level: intermediate 10924222ddf1SHong Zhang 10934222ddf1SHong Zhang .seealso: MatProductCreateWithMat(), MatProductSetType(), MatProductSetAlgorithm() 10944222ddf1SHong Zhang @*/ 10954222ddf1SHong Zhang PetscErrorCode MatProductCreate(Mat A,Mat B,Mat C,Mat *D) 10964222ddf1SHong Zhang { 10974222ddf1SHong Zhang PetscErrorCode ierr; 10984222ddf1SHong Zhang 10994222ddf1SHong Zhang PetscFunctionBegin; 11004222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 11014222ddf1SHong Zhang PetscValidType(A,1); 11024222ddf1SHong Zhang MatCheckPreallocated(A,1); 11034222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 11044222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 11054222ddf1SHong Zhang 11064222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 11074222ddf1SHong Zhang PetscValidType(B,2); 11084222ddf1SHong Zhang MatCheckPreallocated(B,2); 11094222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 11104222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 11114222ddf1SHong Zhang 11124222ddf1SHong Zhang if (C) { 11134222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 11144222ddf1SHong Zhang PetscValidType(C,3); 11154222ddf1SHong Zhang MatCheckPreallocated(C,3); 11164222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 11174222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 11184222ddf1SHong Zhang } 11194222ddf1SHong Zhang 11204222ddf1SHong Zhang PetscValidPointer(D,4); 11214222ddf1SHong Zhang 11224222ddf1SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A),D);CHKERRQ(ierr); 11234222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,*D);CHKERRQ(ierr); 11244222ddf1SHong Zhang PetscFunctionReturn(0); 11254222ddf1SHong Zhang } 1126