14222ddf1SHong Zhang 24222ddf1SHong Zhang /* 34222ddf1SHong Zhang Routines for matrix products. Calling procedure: 44222ddf1SHong Zhang 56718818eSStefano Zampini MatProductCreate(A,B,C,&D); or MatProductCreateWithMat(A,B,C,D) 66718818eSStefano Zampini MatProductSetType(D, MATPRODUCT_AB/AtB/ABt/PtAP/RARt/ABC) 76718818eSStefano Zampini MatProductSetAlgorithm(D, alg) 86718818eSStefano Zampini MatProductSetFill(D,fill) 96718818eSStefano Zampini MatProductSetFromOptions(D) 106718818eSStefano Zampini -> MatProductSetFromOptions_Private(D) 114222ddf1SHong Zhang # Check matrix global sizes 126718818eSStefano Zampini if the matrices have the same setfromoptions routine, use it 136718818eSStefano Zampini if not, try: 146718818eSStefano Zampini -> Query MatProductSetFromOptions_Atype_Btype_Ctype_C(D) from A, B and C (in order) 156718818eSStefano Zampini if found -> run the specific setup that must set the symbolic operation (these callbacks should never fail) 166718818eSStefano Zampini if callback not found or no symbolic operation set 176718818eSStefano Zampini -> Query MatProductSetFromOptions_anytype_C(D) from A, B and C (in order) (e.g, matrices may have inner matrices like MATTRANPOSEMAT) 186718818eSStefano Zampini if dispatch found but combination still not present do 196718818eSStefano Zampini -> check if B is dense and product type AtB or AB -> if true, basic looping of dense columns 206718818eSStefano Zampini -> check if triple product (PtAP, RARt or ABC) -> if true, set the Basic routines 216718818eSStefano Zampini 226718818eSStefano Zampini # The setfromoptions calls MatProductSetFromOptions_Atype_Btype_Ctype should 234222ddf1SHong Zhang # Check matrix local sizes for mpi matrices 244222ddf1SHong Zhang # Set default algorithm 254222ddf1SHong Zhang # Get runtime option 266718818eSStefano Zampini # Set D->ops->productsymbolic = MatProductSymbolic_productype_Atype_Btype_Ctype if found 274222ddf1SHong Zhang 286718818eSStefano Zampini MatProductSymbolic(D) 296718818eSStefano Zampini # Call MatProductSymbolic_productype_Atype_Btype_Ctype() 306718818eSStefano Zampini the callback must set the numeric phase D->ops->productnumeric = MatProductNumeric_productype_Atype_Btype_Ctype 314222ddf1SHong Zhang 326718818eSStefano Zampini MatProductNumeric(D) 336718818eSStefano Zampini # Call the numeric phase 346718818eSStefano Zampini 356718818eSStefano Zampini # The symbolic phases are allowed to set extra data structures and attach those to the product 366718818eSStefano Zampini # this additional data can be reused between multiple numeric phases with the same matrices 376718818eSStefano Zampini # if not needed, call 386718818eSStefano Zampini MatProductClear(D) 394222ddf1SHong Zhang */ 404222ddf1SHong Zhang 414222ddf1SHong Zhang #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 424222ddf1SHong Zhang 436718818eSStefano Zampini const char *const MatProductTypes[] = {"UNSPECIFIED","AB","AtB","ABt","PtAP","RARt","ABC"}; 44544a5e07SHong Zhang 456718818eSStefano Zampini /* these are basic implementations relying on the old function pointers 466718818eSStefano Zampini * they are dangerous and should be removed in the future */ 475415d71bSStefano Zampini static PetscErrorCode MatProductNumeric_PtAP_Unsafe(Mat C) 484222ddf1SHong Zhang { 494222ddf1SHong Zhang PetscErrorCode ierr; 504222ddf1SHong Zhang Mat_Product *product = C->product; 514222ddf1SHong Zhang Mat P = product->B,AP = product->Dwork; 524222ddf1SHong Zhang 534222ddf1SHong Zhang PetscFunctionBegin; 544222ddf1SHong Zhang /* AP = A*P */ 554222ddf1SHong Zhang ierr = MatProductNumeric(AP);CHKERRQ(ierr); 564222ddf1SHong Zhang /* C = P^T*AP */ 57*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!C->ops->transposematmultnumeric,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing numeric stage"); 587a3c3d58SStefano Zampini ierr = (*C->ops->transposematmultnumeric)(P,AP,C);CHKERRQ(ierr); 594222ddf1SHong Zhang PetscFunctionReturn(0); 604222ddf1SHong Zhang } 614222ddf1SHong Zhang 625415d71bSStefano Zampini static PetscErrorCode MatProductSymbolic_PtAP_Unsafe(Mat C) 634222ddf1SHong Zhang { 644222ddf1SHong Zhang PetscErrorCode ierr; 654222ddf1SHong Zhang Mat_Product *product = C->product; 664222ddf1SHong Zhang Mat A=product->A,P=product->B,AP; 674222ddf1SHong Zhang PetscReal fill=product->fill; 684222ddf1SHong Zhang 694222ddf1SHong Zhang PetscFunctionBegin; 707d3de750SJacob Faibussowitsch ierr = PetscInfo((PetscObject)C,"for A %s, P %s is used\n",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name);CHKERRQ(ierr); 714222ddf1SHong Zhang /* AP = A*P */ 724222ddf1SHong Zhang ierr = MatProductCreate(A,P,NULL,&AP);CHKERRQ(ierr); 734222ddf1SHong Zhang ierr = MatProductSetType(AP,MATPRODUCT_AB);CHKERRQ(ierr); 743e662e0bSHong Zhang ierr = MatProductSetAlgorithm(AP,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 754222ddf1SHong Zhang ierr = MatProductSetFill(AP,fill);CHKERRQ(ierr); 764222ddf1SHong Zhang ierr = MatProductSetFromOptions(AP);CHKERRQ(ierr); 774222ddf1SHong Zhang ierr = MatProductSymbolic(AP);CHKERRQ(ierr); 784222ddf1SHong Zhang 794222ddf1SHong Zhang /* C = P^T*AP */ 804222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_AtB);CHKERRQ(ierr); 813e662e0bSHong Zhang ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 824222ddf1SHong Zhang product->A = P; 834222ddf1SHong Zhang product->B = AP; 844222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 854222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 864222ddf1SHong Zhang 874222ddf1SHong Zhang /* resume user's original input matrix setting for A and B */ 884222ddf1SHong Zhang product->A = A; 894222ddf1SHong Zhang product->B = P; 904222ddf1SHong Zhang product->Dwork = AP; 914222ddf1SHong Zhang 925415d71bSStefano Zampini C->ops->productnumeric = MatProductNumeric_PtAP_Unsafe; 934222ddf1SHong Zhang PetscFunctionReturn(0); 944222ddf1SHong Zhang } 954222ddf1SHong Zhang 965415d71bSStefano Zampini static PetscErrorCode MatProductNumeric_RARt_Unsafe(Mat C) 974222ddf1SHong Zhang { 984222ddf1SHong Zhang PetscErrorCode ierr; 994222ddf1SHong Zhang Mat_Product *product = C->product; 1004222ddf1SHong Zhang Mat R=product->B,RA=product->Dwork; 1014222ddf1SHong Zhang 1024222ddf1SHong Zhang PetscFunctionBegin; 1034222ddf1SHong Zhang /* RA = R*A */ 1044222ddf1SHong Zhang ierr = MatProductNumeric(RA);CHKERRQ(ierr); 1054222ddf1SHong Zhang /* C = RA*R^T */ 106*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!C->ops->mattransposemultnumeric,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing numeric stage"); 1077a3c3d58SStefano Zampini ierr = (*C->ops->mattransposemultnumeric)(RA,R,C);CHKERRQ(ierr); 1084222ddf1SHong Zhang PetscFunctionReturn(0); 1094222ddf1SHong Zhang } 1104222ddf1SHong Zhang 1115415d71bSStefano Zampini static PetscErrorCode MatProductSymbolic_RARt_Unsafe(Mat C) 1124222ddf1SHong Zhang { 1134222ddf1SHong Zhang PetscErrorCode ierr; 1144222ddf1SHong Zhang Mat_Product *product = C->product; 1154222ddf1SHong Zhang Mat A=product->A,R=product->B,RA; 1164222ddf1SHong Zhang PetscReal fill=product->fill; 1174222ddf1SHong Zhang 1184222ddf1SHong Zhang PetscFunctionBegin; 1197d3de750SJacob Faibussowitsch ierr = PetscInfo((PetscObject)C,"for A %s, R %s is used\n",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name);CHKERRQ(ierr); 1204222ddf1SHong Zhang /* RA = R*A */ 1214222ddf1SHong Zhang ierr = MatProductCreate(R,A,NULL,&RA);CHKERRQ(ierr); 1224222ddf1SHong Zhang ierr = MatProductSetType(RA,MATPRODUCT_AB);CHKERRQ(ierr); 1233e662e0bSHong Zhang ierr = MatProductSetAlgorithm(RA,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 1244222ddf1SHong Zhang ierr = MatProductSetFill(RA,fill);CHKERRQ(ierr); 1254222ddf1SHong Zhang ierr = MatProductSetFromOptions(RA);CHKERRQ(ierr); 1264222ddf1SHong Zhang ierr = MatProductSymbolic(RA);CHKERRQ(ierr); 1274222ddf1SHong Zhang 1284222ddf1SHong Zhang /* C = RA*R^T */ 1294222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_ABt);CHKERRQ(ierr); 1303e662e0bSHong Zhang ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 1314222ddf1SHong Zhang product->A = RA; 1324222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 1334222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 1344222ddf1SHong Zhang 1354222ddf1SHong Zhang /* resume user's original input matrix setting for A */ 1364222ddf1SHong Zhang product->A = A; 1374222ddf1SHong Zhang product->Dwork = RA; /* save here so it will be destroyed with product C */ 1385415d71bSStefano Zampini C->ops->productnumeric = MatProductNumeric_RARt_Unsafe; 1394222ddf1SHong Zhang PetscFunctionReturn(0); 1404222ddf1SHong Zhang } 1414222ddf1SHong Zhang 1425415d71bSStefano Zampini static PetscErrorCode MatProductNumeric_ABC_Unsafe(Mat mat) 1434222ddf1SHong Zhang { 1444222ddf1SHong Zhang PetscErrorCode ierr; 1454222ddf1SHong Zhang Mat_Product *product = mat->product; 1464222ddf1SHong Zhang Mat A=product->A,BC=product->Dwork; 1474222ddf1SHong Zhang 1484222ddf1SHong Zhang PetscFunctionBegin; 1494222ddf1SHong Zhang /* Numeric BC = B*C */ 1504222ddf1SHong Zhang ierr = MatProductNumeric(BC);CHKERRQ(ierr); 1514222ddf1SHong Zhang /* Numeric mat = A*BC */ 152*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->transposematmultnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric stage"); 1537a3c3d58SStefano Zampini ierr = (*mat->ops->matmultnumeric)(A,BC,mat);CHKERRQ(ierr); 1544222ddf1SHong Zhang PetscFunctionReturn(0); 1554222ddf1SHong Zhang } 1564222ddf1SHong Zhang 1575415d71bSStefano Zampini static PetscErrorCode MatProductSymbolic_ABC_Unsafe(Mat mat) 1584222ddf1SHong Zhang { 1594222ddf1SHong Zhang PetscErrorCode ierr; 1604222ddf1SHong Zhang Mat_Product *product = mat->product; 1614222ddf1SHong Zhang Mat B=product->B,C=product->C,BC; 1624222ddf1SHong Zhang PetscReal fill=product->fill; 1634222ddf1SHong Zhang 1644222ddf1SHong Zhang PetscFunctionBegin; 1657d3de750SJacob Faibussowitsch ierr = PetscInfo((PetscObject)mat,"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); 1664222ddf1SHong Zhang /* Symbolic BC = B*C */ 1674222ddf1SHong Zhang ierr = MatProductCreate(B,C,NULL,&BC);CHKERRQ(ierr); 1684222ddf1SHong Zhang ierr = MatProductSetType(BC,MATPRODUCT_AB);CHKERRQ(ierr); 1693e662e0bSHong Zhang ierr = MatProductSetAlgorithm(BC,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 1704222ddf1SHong Zhang ierr = MatProductSetFill(BC,fill);CHKERRQ(ierr); 1714222ddf1SHong Zhang ierr = MatProductSetFromOptions(BC);CHKERRQ(ierr); 1724222ddf1SHong Zhang ierr = MatProductSymbolic(BC);CHKERRQ(ierr); 1734222ddf1SHong Zhang 1744222ddf1SHong Zhang /* Symbolic mat = A*BC */ 1754222ddf1SHong Zhang ierr = MatProductSetType(mat,MATPRODUCT_AB);CHKERRQ(ierr); 1763e662e0bSHong Zhang ierr = MatProductSetAlgorithm(mat,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 1774222ddf1SHong Zhang product->B = BC; 1784222ddf1SHong Zhang product->Dwork = BC; 1794222ddf1SHong Zhang ierr = MatProductSetFromOptions(mat);CHKERRQ(ierr); 1804222ddf1SHong Zhang ierr = MatProductSymbolic(mat);CHKERRQ(ierr); 1814222ddf1SHong Zhang 1824222ddf1SHong Zhang /* resume user's original input matrix setting for B */ 1834222ddf1SHong Zhang product->B = B; 1845415d71bSStefano Zampini mat->ops->productnumeric = MatProductNumeric_ABC_Unsafe; 1854222ddf1SHong Zhang PetscFunctionReturn(0); 1864222ddf1SHong Zhang } 1874222ddf1SHong Zhang 1885415d71bSStefano Zampini static PetscErrorCode MatProductSymbolic_Unsafe(Mat mat) 1894222ddf1SHong Zhang { 1904222ddf1SHong Zhang PetscErrorCode ierr; 1914222ddf1SHong Zhang Mat_Product *product = mat->product; 1924222ddf1SHong Zhang 1934222ddf1SHong Zhang PetscFunctionBegin; 1944222ddf1SHong Zhang switch (product->type) { 1954222ddf1SHong Zhang case MATPRODUCT_PtAP: 1965415d71bSStefano Zampini ierr = MatProductSymbolic_PtAP_Unsafe(mat);CHKERRQ(ierr); 1974222ddf1SHong Zhang break; 1984222ddf1SHong Zhang case MATPRODUCT_RARt: 1995415d71bSStefano Zampini ierr = MatProductSymbolic_RARt_Unsafe(mat);CHKERRQ(ierr); 2004222ddf1SHong Zhang break; 2014222ddf1SHong Zhang case MATPRODUCT_ABC: 2025415d71bSStefano Zampini ierr = MatProductSymbolic_ABC_Unsafe(mat);CHKERRQ(ierr); 2034222ddf1SHong Zhang break; 20498921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[product->type]); 2054222ddf1SHong Zhang } 2064222ddf1SHong Zhang PetscFunctionReturn(0); 2074222ddf1SHong Zhang } 2084222ddf1SHong Zhang 2094222ddf1SHong Zhang /* ----------------------------------------------- */ 2104222ddf1SHong Zhang /*@C 2114222ddf1SHong Zhang MatProductReplaceMats - Replace input matrices for a matrix product. 2124222ddf1SHong Zhang 2134222ddf1SHong Zhang Collective on Mat 2144222ddf1SHong Zhang 2154222ddf1SHong Zhang Input Parameters: 2164222ddf1SHong Zhang + A - the matrix or NULL if not being replaced 2174222ddf1SHong Zhang . B - the matrix or NULL if not being replaced 2184222ddf1SHong Zhang . C - the matrix or NULL if not being replaced 2194222ddf1SHong Zhang - D - the matrix product 2204222ddf1SHong Zhang 2214222ddf1SHong Zhang Level: intermediate 2224222ddf1SHong Zhang 2234222ddf1SHong Zhang Notes: 2246718818eSStefano Zampini To reuse the symbolic phase, input matrices must have exactly the same data structure as the replaced one. 225fa046f9fSJunchao Zhang If the type of any of the input matrices is different than what was previously used, or their symmetry changed but 226fa046f9fSJunchao Zhang the symbolic phase took advantage of their symmetry, the product is cleared and MatProductSetFromOptions()/MatProductSymbolic() are invoked again. 2274222ddf1SHong Zhang 2286718818eSStefano Zampini .seealso: MatProductCreate(), MatProductSetFromOptions(), MatProductSymbolic(). MatProductClear() 2294222ddf1SHong Zhang @*/ 2304222ddf1SHong Zhang PetscErrorCode MatProductReplaceMats(Mat A,Mat B,Mat C,Mat D) 2314222ddf1SHong Zhang { 2324417c5e8SHong Zhang PetscErrorCode ierr; 2336718818eSStefano Zampini Mat_Product *product; 2346718818eSStefano Zampini PetscBool flgA = PETSC_TRUE,flgB = PETSC_TRUE,flgC = PETSC_TRUE; 2354222ddf1SHong Zhang 2364222ddf1SHong Zhang PetscFunctionBegin; 2377a3c3d58SStefano Zampini PetscValidHeaderSpecific(D,MAT_CLASSID,4); 2386718818eSStefano Zampini MatCheckProduct(D,4); 2396718818eSStefano Zampini product = D->product; 2404222ddf1SHong Zhang if (A) { 2417a3c3d58SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2426718818eSStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 2436718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)product->A,((PetscObject)A)->type_name,&flgA);CHKERRQ(ierr); 244fa046f9fSJunchao Zhang if (product->symbolic_used_the_fact_A_is_symmetric && !A->symmetric) { /* symbolic was built around a symmetric A, but the new A is not anymore */ 245fa046f9fSJunchao Zhang flgA = PETSC_FALSE; 246fa046f9fSJunchao Zhang product->symbolic_used_the_fact_A_is_symmetric = PETSC_FALSE; /* reinit */ 247fa046f9fSJunchao Zhang } 2486718818eSStefano Zampini ierr = MatDestroy(&product->A);CHKERRQ(ierr); 2494222ddf1SHong Zhang product->A = A; 2504222ddf1SHong Zhang } 2514222ddf1SHong Zhang if (B) { 2527a3c3d58SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,2); 2536718818eSStefano Zampini ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 2546718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)product->B,((PetscObject)B)->type_name,&flgB);CHKERRQ(ierr); 255fa046f9fSJunchao Zhang if (product->symbolic_used_the_fact_B_is_symmetric && !B->symmetric) { 256fa046f9fSJunchao Zhang flgB = PETSC_FALSE; 257fa046f9fSJunchao Zhang product->symbolic_used_the_fact_B_is_symmetric = PETSC_FALSE; /* reinit */ 258fa046f9fSJunchao Zhang } 2596718818eSStefano Zampini ierr = MatDestroy(&product->B);CHKERRQ(ierr); 2604222ddf1SHong Zhang product->B = B; 2614222ddf1SHong Zhang } 2624417c5e8SHong Zhang if (C) { 2637a3c3d58SStefano Zampini PetscValidHeaderSpecific(C,MAT_CLASSID,3); 2646718818eSStefano Zampini ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); 2656718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)product->C,((PetscObject)C)->type_name,&flgC);CHKERRQ(ierr); 266fa046f9fSJunchao Zhang if (product->symbolic_used_the_fact_C_is_symmetric && !C->symmetric) { 267fa046f9fSJunchao Zhang flgC = PETSC_FALSE; 268fa046f9fSJunchao Zhang product->symbolic_used_the_fact_C_is_symmetric = PETSC_FALSE; /* reinit */ 269fa046f9fSJunchao Zhang } 2706718818eSStefano Zampini ierr = MatDestroy(&product->C);CHKERRQ(ierr); 2714417c5e8SHong Zhang product->C = C; 2724417c5e8SHong Zhang } 2736718818eSStefano Zampini /* Any of the replaced mats is of a different type, reset */ 2746718818eSStefano Zampini if (!flgA || !flgB || !flgC) { 2756718818eSStefano Zampini if (D->product->destroy) { 2766718818eSStefano Zampini ierr = (*D->product->destroy)(D->product->data);CHKERRQ(ierr); 2776718818eSStefano Zampini } 2786718818eSStefano Zampini D->product->destroy = NULL; 2796718818eSStefano Zampini D->product->data = NULL; 2806718818eSStefano Zampini if (D->ops->productnumeric || D->ops->productsymbolic) { 2816718818eSStefano Zampini ierr = MatProductSetFromOptions(D);CHKERRQ(ierr); 2826718818eSStefano Zampini ierr = MatProductSymbolic(D);CHKERRQ(ierr); 2836718818eSStefano Zampini } 2846718818eSStefano Zampini } 2854222ddf1SHong Zhang PetscFunctionReturn(0); 2864222ddf1SHong Zhang } 2874222ddf1SHong Zhang 2887a3c3d58SStefano Zampini static PetscErrorCode MatProductNumeric_X_Dense(Mat C) 2897a3c3d58SStefano Zampini { 2907a3c3d58SStefano Zampini PetscErrorCode ierr; 2917a3c3d58SStefano Zampini Mat_Product *product = C->product; 2927a3c3d58SStefano Zampini Mat A = product->A, B = product->B; 2937a3c3d58SStefano Zampini PetscInt k, K = B->cmap->N; 2947a3c3d58SStefano Zampini PetscBool t = PETSC_TRUE,iscuda = PETSC_FALSE; 2957a3c3d58SStefano Zampini PetscBool Bcpu = PETSC_TRUE, Ccpu = PETSC_TRUE; 2967a3c3d58SStefano Zampini char *Btype = NULL,*Ctype = NULL; 2977a3c3d58SStefano Zampini 2987a3c3d58SStefano Zampini PetscFunctionBegin; 2997a3c3d58SStefano Zampini switch (product->type) { 3007a3c3d58SStefano Zampini case MATPRODUCT_AB: 3017a3c3d58SStefano Zampini t = PETSC_FALSE; 3027a3c3d58SStefano Zampini case MATPRODUCT_AtB: 3037a3c3d58SStefano Zampini break; 30498921bdaSJacob Faibussowitsch default: SETERRQ(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); 3057a3c3d58SStefano Zampini } 3067a3c3d58SStefano Zampini if (PetscDefined(HAVE_CUDA)) { 3077a3c3d58SStefano Zampini VecType vtype; 3087a3c3d58SStefano Zampini 3097a3c3d58SStefano Zampini ierr = MatGetVecType(A,&vtype);CHKERRQ(ierr); 3107a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECCUDA,&iscuda);CHKERRQ(ierr); 3117a3c3d58SStefano Zampini if (!iscuda) { 3127a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECSEQCUDA,&iscuda);CHKERRQ(ierr); 3137a3c3d58SStefano Zampini } 3147a3c3d58SStefano Zampini if (!iscuda) { 3157a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECMPICUDA,&iscuda);CHKERRQ(ierr); 3167a3c3d58SStefano Zampini } 3177a3c3d58SStefano Zampini if (iscuda) { /* Make sure we have up-to-date data on the GPU */ 3187a3c3d58SStefano Zampini ierr = PetscStrallocpy(((PetscObject)B)->type_name,&Btype);CHKERRQ(ierr); 3197a3c3d58SStefano Zampini ierr = PetscStrallocpy(((PetscObject)C)->type_name,&Ctype);CHKERRQ(ierr); 3207a3c3d58SStefano Zampini ierr = MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 3217a3c3d58SStefano Zampini if (!C->assembled) { /* need to flag the matrix as assembled, otherwise MatConvert will complain */ 3227a3c3d58SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3237a3c3d58SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3247a3c3d58SStefano Zampini } 3257a3c3d58SStefano Zampini ierr = MatConvert(C,MATDENSECUDA,MAT_INPLACE_MATRIX,&C);CHKERRQ(ierr); 3267a3c3d58SStefano Zampini } else { /* Make sure we have up-to-date data on the CPU */ 3277a3c3d58SStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 3287a3c3d58SStefano Zampini Bcpu = B->boundtocpu; 3297a3c3d58SStefano Zampini Ccpu = C->boundtocpu; 3307a3c3d58SStefano Zampini #endif 3317a3c3d58SStefano Zampini ierr = MatBindToCPU(B,PETSC_TRUE);CHKERRQ(ierr); 3327a3c3d58SStefano Zampini ierr = MatBindToCPU(C,PETSC_TRUE);CHKERRQ(ierr); 3337a3c3d58SStefano Zampini } 3347a3c3d58SStefano Zampini } 3357a3c3d58SStefano Zampini for (k=0;k<K;k++) { 3367a3c3d58SStefano Zampini Vec x,y; 3377a3c3d58SStefano Zampini 3387a3c3d58SStefano Zampini ierr = MatDenseGetColumnVecRead(B,k,&x);CHKERRQ(ierr); 3397a3c3d58SStefano Zampini ierr = MatDenseGetColumnVecWrite(C,k,&y);CHKERRQ(ierr); 3407a3c3d58SStefano Zampini if (t) { 3417a3c3d58SStefano Zampini ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 3427a3c3d58SStefano Zampini } else { 3437a3c3d58SStefano Zampini ierr = MatMult(A,x,y);CHKERRQ(ierr); 3447a3c3d58SStefano Zampini } 3457a3c3d58SStefano Zampini ierr = MatDenseRestoreColumnVecRead(B,k,&x);CHKERRQ(ierr); 3467a3c3d58SStefano Zampini ierr = MatDenseRestoreColumnVecWrite(C,k,&y);CHKERRQ(ierr); 3477a3c3d58SStefano Zampini } 3487a3c3d58SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3497a3c3d58SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3507a3c3d58SStefano Zampini if (PetscDefined(HAVE_CUDA)) { 3517a3c3d58SStefano Zampini if (iscuda) { 3527a3c3d58SStefano Zampini ierr = MatConvert(B,Btype,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 3537a3c3d58SStefano Zampini ierr = MatConvert(C,Ctype,MAT_INPLACE_MATRIX,&C);CHKERRQ(ierr); 3547a3c3d58SStefano Zampini } else { 3557a3c3d58SStefano Zampini ierr = MatBindToCPU(B,Bcpu);CHKERRQ(ierr); 3567a3c3d58SStefano Zampini ierr = MatBindToCPU(C,Ccpu);CHKERRQ(ierr); 3577a3c3d58SStefano Zampini } 3587a3c3d58SStefano Zampini } 3597a3c3d58SStefano Zampini ierr = PetscFree(Btype);CHKERRQ(ierr); 3607a3c3d58SStefano Zampini ierr = PetscFree(Ctype);CHKERRQ(ierr); 3617a3c3d58SStefano Zampini PetscFunctionReturn(0); 3627a3c3d58SStefano Zampini } 3637a3c3d58SStefano Zampini 3647a3c3d58SStefano Zampini static PetscErrorCode MatProductSymbolic_X_Dense(Mat C) 3657a3c3d58SStefano Zampini { 3667a3c3d58SStefano Zampini PetscErrorCode ierr; 3677a3c3d58SStefano Zampini Mat_Product *product = C->product; 3687a3c3d58SStefano Zampini Mat A = product->A, B = product->B; 3697a3c3d58SStefano Zampini PetscBool isdense; 3707a3c3d58SStefano Zampini 3717a3c3d58SStefano Zampini PetscFunctionBegin; 3727a3c3d58SStefano Zampini switch (product->type) { 3737a3c3d58SStefano Zampini case MATPRODUCT_AB: 3747a3c3d58SStefano Zampini ierr = MatSetSizes(C,A->rmap->n,B->cmap->n,A->rmap->N,B->cmap->N);CHKERRQ(ierr); 3757a3c3d58SStefano Zampini break; 3767a3c3d58SStefano Zampini case MATPRODUCT_AtB: 3777a3c3d58SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,B->cmap->n,A->cmap->N,B->cmap->N);CHKERRQ(ierr); 3787a3c3d58SStefano Zampini break; 37998921bdaSJacob Faibussowitsch default: SETERRQ(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); 3807a3c3d58SStefano Zampini } 3817a3c3d58SStefano Zampini ierr = PetscObjectBaseTypeCompareAny((PetscObject)C,&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 3827a3c3d58SStefano Zampini if (!isdense) { 3837a3c3d58SStefano Zampini ierr = MatSetType(C,((PetscObject)B)->type_name);CHKERRQ(ierr); 3846718818eSStefano Zampini /* If matrix type of C was not set or not dense, we need to reset the pointer */ 3857a3c3d58SStefano Zampini C->ops->productsymbolic = MatProductSymbolic_X_Dense; 3867a3c3d58SStefano Zampini } 3876718818eSStefano Zampini C->ops->productnumeric = MatProductNumeric_X_Dense; 3887a3c3d58SStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 3897a3c3d58SStefano Zampini PetscFunctionReturn(0); 3907a3c3d58SStefano Zampini } 3917a3c3d58SStefano Zampini 3926718818eSStefano Zampini /* a single driver to query the dispatching */ 3936718818eSStefano Zampini static PetscErrorCode MatProductSetFromOptions_Private(Mat mat) 3944222ddf1SHong Zhang { 3954222ddf1SHong Zhang PetscErrorCode ierr; 3964222ddf1SHong Zhang Mat_Product *product = mat->product; 3976718818eSStefano Zampini PetscInt Am,An,Bm,Bn,Cm,Cn; 3984222ddf1SHong Zhang Mat A = product->A,B = product->B,C = product->C; 3996718818eSStefano Zampini const char* const Bnames[] = { "B", "R", "P" }; 4006718818eSStefano Zampini const char* bname; 4014222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 4024222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 4034222ddf1SHong Zhang PetscErrorCode (*fC)(Mat); 4044222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 4054222ddf1SHong Zhang 4064222ddf1SHong Zhang PetscFunctionBegin; 4076718818eSStefano Zampini mat->ops->productsymbolic = NULL; 4086718818eSStefano Zampini mat->ops->productnumeric = NULL; 4096718818eSStefano Zampini if (product->type == MATPRODUCT_UNSPECIFIED) PetscFunctionReturn(0); 410*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!A,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing A mat"); 411*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!B,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing B mat"); 412*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(product->type == MATPRODUCT_ABC && !C,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing C mat"); 4136718818eSStefano Zampini if (product->type != MATPRODUCT_ABC) C = NULL; /* do not use C if not needed */ 4146718818eSStefano Zampini if (product->type == MATPRODUCT_RARt) bname = Bnames[1]; 4156718818eSStefano Zampini else if (product->type == MATPRODUCT_PtAP) bname = Bnames[2]; 4166718818eSStefano Zampini else bname = Bnames[0]; 4176718818eSStefano Zampini 4186718818eSStefano Zampini /* Check matrices sizes */ 4196718818eSStefano Zampini Am = A->rmap->N; 4206718818eSStefano Zampini An = A->cmap->N; 4216718818eSStefano Zampini Bm = B->rmap->N; 4226718818eSStefano Zampini Bn = B->cmap->N; 4236718818eSStefano Zampini Cm = C ? C->rmap->N : 0; 4246718818eSStefano Zampini Cn = C ? C->cmap->N : 0; 4256718818eSStefano Zampini if (product->type == MATPRODUCT_RARt || product->type == MATPRODUCT_ABt) { PetscInt t = Bn; Bn = Bm; Bm = t; } 4266718818eSStefano Zampini if (product->type == MATPRODUCT_AtB) { PetscInt t = An; An = Am; Am = t; } 427*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(An != Bm,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Matrix dimensions of A and %s are incompatible for MatProductType %s: A %" PetscInt_FMT "x%" PetscInt_FMT ", %s %" PetscInt_FMT "x%" PetscInt_FMT,bname,MatProductTypes[product->type],A->rmap->N,A->cmap->N,bname,B->rmap->N,B->cmap->N); 428*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(Cm && Cm != Bn,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Matrix dimensions of B and C are incompatible for MatProductType %s: B %" PetscInt_FMT "x%" PetscInt_FMT ", C %" PetscInt_FMT "x%" PetscInt_FMT,MatProductTypes[product->type],B->rmap->N,B->cmap->N,Cm,Cn); 4294222ddf1SHong Zhang 4304222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 4314222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 4326718818eSStefano Zampini fC = C ? C->ops->productsetfromoptions : fA; 4336718818eSStefano Zampini if (C) { 4347d3de750SJacob Faibussowitsch ierr = PetscInfo(mat,"MatProductType %s for A %s, %s %s, C %s\n",MatProductTypes[product->type],((PetscObject)A)->type_name,bname,((PetscObject)B)->type_name,((PetscObject)C)->type_name);CHKERRQ(ierr); 4356718818eSStefano Zampini } else { 4367d3de750SJacob Faibussowitsch ierr = PetscInfo(mat,"MatProductType %s for A %s, %s %s\n",MatProductTypes[product->type],((PetscObject)A)->type_name,bname,((PetscObject)B)->type_name);CHKERRQ(ierr); 4376718818eSStefano Zampini } 4384222ddf1SHong Zhang if (fA == fB && fA == fC && fA) { 4396896283bSStefano Zampini ierr = PetscInfo(mat," matching op\n");CHKERRQ(ierr); 4406718818eSStefano Zampini ierr = (*fA)(mat);CHKERRQ(ierr); 4418d7b260cSStefano Zampini } 4428d7b260cSStefano Zampini /* We may have found f but it did not succeed */ 4438d7b260cSStefano Zampini if (!mat->ops->productsymbolic) { /* query MatProductSetFromOptions_Atype_Btype_Ctype */ 4444222ddf1SHong Zhang char mtypes[256]; 4454222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 4464222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4474222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4484222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4496718818eSStefano Zampini if (C) { 4504222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4514222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)C)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4526718818eSStefano Zampini } 4534222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 4544222ddf1SHong Zhang 4554222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 4567d3de750SJacob Faibussowitsch ierr = PetscInfo(mat," querying %s from A? %p\n",mtypes,f);CHKERRQ(ierr); 4574222ddf1SHong Zhang if (!f) { 4584222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 4597d3de750SJacob Faibussowitsch ierr = PetscInfo(mat," querying %s from %s? %p\n",mtypes,bname,f);CHKERRQ(ierr); 4604222ddf1SHong Zhang } 4616718818eSStefano Zampini if (!f && C) { 4624222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)C,mtypes,&f);CHKERRQ(ierr); 4637d3de750SJacob Faibussowitsch ierr = PetscInfo(mat," querying %s from C? %p\n",mtypes,f);CHKERRQ(ierr); 4644222ddf1SHong Zhang } 4656718818eSStefano Zampini if (f) { ierr = (*f)(mat);CHKERRQ(ierr); } 4666718818eSStefano Zampini 4676718818eSStefano Zampini /* We may have found f but it did not succeed */ 4686718818eSStefano Zampini /* some matrices (i.e. MATTRANSPOSE, MATSHELL constructed from MatConvert), knows what to do with their inner matrices */ 4696718818eSStefano Zampini if (!mat->ops->productsymbolic) { 4706718818eSStefano Zampini ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_anytype_C",sizeof(mtypes));CHKERRQ(ierr); 4716718818eSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 4727d3de750SJacob Faibussowitsch ierr = PetscInfo(mat," querying %s from A? %p\n",mtypes,f);CHKERRQ(ierr); 4736718818eSStefano Zampini if (!f) { 4746718818eSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 4757d3de750SJacob Faibussowitsch ierr = PetscInfo(mat," querying %s from %s? %p\n",mtypes,bname,f);CHKERRQ(ierr); 4766718818eSStefano Zampini } 4776718818eSStefano Zampini if (!f && C) { 4786718818eSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)C,mtypes,&f);CHKERRQ(ierr); 4797d3de750SJacob Faibussowitsch ierr = PetscInfo(mat," querying %s from C? %p\n",mtypes,f);CHKERRQ(ierr); 4806718818eSStefano Zampini } 4816718818eSStefano Zampini } 4826718818eSStefano Zampini if (f) { ierr = (*f)(mat);CHKERRQ(ierr); } 4834222ddf1SHong Zhang } 4844222ddf1SHong Zhang 4856718818eSStefano Zampini /* We may have found f but it did not succeed */ 4866718818eSStefano Zampini if (!mat->ops->productsymbolic) { 4876718818eSStefano Zampini /* we can still compute the product if B is of type dense */ 4886718818eSStefano Zampini if (product->type == MATPRODUCT_AB || product->type == MATPRODUCT_AtB) { 4896718818eSStefano Zampini PetscBool isdense; 4906718818eSStefano Zampini 4916718818eSStefano Zampini ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 4926718818eSStefano Zampini if (isdense) { 4936718818eSStefano Zampini 4946718818eSStefano Zampini mat->ops->productsymbolic = MatProductSymbolic_X_Dense; 4956718818eSStefano Zampini ierr = PetscInfo(mat," using basic looping over columns of a dense matrix\n");CHKERRQ(ierr); 4966718818eSStefano Zampini } 4975415d71bSStefano Zampini } else if (product->type != MATPRODUCT_ABt) { /* use MatProductSymbolic/Numeric_Unsafe() for triple products only */ 4986718818eSStefano Zampini /* 4996718818eSStefano Zampini TODO: this should be changed to a proper setfromoptions, not setting the symbolic pointer here, because we do not know if 5008d7b260cSStefano Zampini the combination will succeed. In order to be sure, we need MatProductGetProductType to return the type of the result 5016718818eSStefano Zampini before computing the symbolic phase 5026718818eSStefano Zampini */ 5035415d71bSStefano Zampini ierr = PetscInfo(mat," symbolic product not supported, using MatProductSymbolic_Unsafe() implementation\n");CHKERRQ(ierr); 5045415d71bSStefano Zampini mat->ops->productsymbolic = MatProductSymbolic_Unsafe; 5054222ddf1SHong Zhang } 5066718818eSStefano Zampini } 5076718818eSStefano Zampini if (!mat->ops->productsymbolic) { 5086718818eSStefano Zampini ierr = PetscInfo(mat," symbolic product is not supported\n");CHKERRQ(ierr); 5096718818eSStefano Zampini } 5104222ddf1SHong Zhang PetscFunctionReturn(0); 5114222ddf1SHong Zhang } 5124222ddf1SHong Zhang 5134222ddf1SHong Zhang /*@C 5144222ddf1SHong Zhang MatProductSetFromOptions - Creates a matrix product where the type, the algorithm etc are determined from the options database. 5154222ddf1SHong Zhang 5164222ddf1SHong Zhang Logically Collective on Mat 5174222ddf1SHong Zhang 5184222ddf1SHong Zhang Input Parameter: 5194222ddf1SHong Zhang . mat - the matrix 5204222ddf1SHong Zhang 5216718818eSStefano Zampini Options Database Keys: 5226718818eSStefano Zampini . -mat_product_clear - Clear intermediate data structures after MatProductNumeric() has been called 5234222ddf1SHong Zhang 5246718818eSStefano Zampini Level: intermediate 5256718818eSStefano Zampini 5266718818eSStefano Zampini .seealso: MatSetFromOptions(), MatProductCreate(), MatProductCreateWithMat() 5274222ddf1SHong Zhang @*/ 5284222ddf1SHong Zhang PetscErrorCode MatProductSetFromOptions(Mat mat) 5294222ddf1SHong Zhang { 5304222ddf1SHong Zhang PetscErrorCode ierr; 5314222ddf1SHong Zhang 5324222ddf1SHong Zhang PetscFunctionBegin; 5334222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5346718818eSStefano Zampini MatCheckProduct(mat,1); 535*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(mat->product->data,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Cannot call MatProductSetFromOptions with already present data"); 5366718818eSStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)mat);CHKERRQ(ierr); 5376718818eSStefano Zampini ierr = PetscOptionsBool("-mat_product_clear","Clear intermediate data structures after MatProductNumeric() has been called","MatProductClear",mat->product->clear,&mat->product->clear,NULL);CHKERRQ(ierr); 5386718818eSStefano Zampini ierr = PetscOptionsDeprecated("-mat_freeintermediatedatastructures","-mat_product_clear","3.13","Or call MatProductClear() after MatProductNumeric()");CHKERRQ(ierr); 5396718818eSStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 5406718818eSStefano Zampini ierr = MatProductSetFromOptions_Private(mat);CHKERRQ(ierr); 541*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->product,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing product after setup phase"); 5426718818eSStefano Zampini PetscFunctionReturn(0); 5436718818eSStefano Zampini } 5446718818eSStefano Zampini 5456718818eSStefano Zampini /*@C 5466718818eSStefano Zampini MatProductView - View a MatProduct 5476718818eSStefano Zampini 5486718818eSStefano Zampini Logically Collective on Mat 5496718818eSStefano Zampini 5506718818eSStefano Zampini Input Parameter: 5516718818eSStefano Zampini . mat - the matrix obtained with MatProductCreate() or MatProductCreateWithMat() 5526718818eSStefano Zampini 5536718818eSStefano Zampini Level: intermediate 5546718818eSStefano Zampini 5556718818eSStefano Zampini .seealso: MatView(), MatProductCreate(), MatProductCreateWithMat() 5566718818eSStefano Zampini @*/ 5576718818eSStefano Zampini PetscErrorCode MatProductView(Mat mat, PetscViewer viewer) 5586718818eSStefano Zampini { 5596718818eSStefano Zampini PetscErrorCode ierr; 5606718818eSStefano Zampini 5616718818eSStefano Zampini PetscFunctionBegin; 5626718818eSStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5636718818eSStefano Zampini if (!mat->product) PetscFunctionReturn(0); 5646718818eSStefano Zampini if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);} 5656718818eSStefano Zampini PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 5666718818eSStefano Zampini PetscCheckSameComm(mat,1,viewer,2); 5676718818eSStefano Zampini if (mat->product->view) { 5686718818eSStefano Zampini ierr = (*mat->product->view)(mat,viewer);CHKERRQ(ierr); 5696718818eSStefano Zampini } 5704222ddf1SHong Zhang PetscFunctionReturn(0); 5714222ddf1SHong Zhang } 5724222ddf1SHong Zhang 5734222ddf1SHong Zhang /* ----------------------------------------------- */ 5746718818eSStefano Zampini /* these are basic implementations relying on the old function pointers 5756718818eSStefano Zampini * they are dangerous and should be removed in the future */ 5764222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AB(Mat mat) 5774222ddf1SHong Zhang { 5784222ddf1SHong Zhang PetscErrorCode ierr; 5794222ddf1SHong Zhang Mat_Product *product = mat->product; 5804222ddf1SHong Zhang Mat A=product->A,B=product->B; 5814222ddf1SHong Zhang 5824222ddf1SHong Zhang PetscFunctionBegin; 583*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->matmultnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 5847a3c3d58SStefano Zampini ierr = (*mat->ops->matmultnumeric)(A,B,mat);CHKERRQ(ierr); 5854222ddf1SHong Zhang PetscFunctionReturn(0); 5864222ddf1SHong Zhang } 5874222ddf1SHong Zhang 5884222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AtB(Mat mat) 5894222ddf1SHong Zhang { 5904222ddf1SHong Zhang PetscErrorCode ierr; 5914222ddf1SHong Zhang Mat_Product *product = mat->product; 5924222ddf1SHong Zhang Mat A=product->A,B=product->B; 5934222ddf1SHong Zhang 5944222ddf1SHong Zhang PetscFunctionBegin; 595*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->transposematmultnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 5967a3c3d58SStefano Zampini ierr = (*mat->ops->transposematmultnumeric)(A,B,mat);CHKERRQ(ierr); 5974222ddf1SHong Zhang PetscFunctionReturn(0); 5984222ddf1SHong Zhang } 5994222ddf1SHong Zhang 6004222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABt(Mat mat) 6014222ddf1SHong Zhang { 6024222ddf1SHong Zhang PetscErrorCode ierr; 6034222ddf1SHong Zhang Mat_Product *product = mat->product; 6044222ddf1SHong Zhang Mat A=product->A,B=product->B; 6054222ddf1SHong Zhang 6064222ddf1SHong Zhang PetscFunctionBegin; 607*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->mattransposemultnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 6087a3c3d58SStefano Zampini ierr = (*mat->ops->mattransposemultnumeric)(A,B,mat);CHKERRQ(ierr); 6094222ddf1SHong Zhang PetscFunctionReturn(0); 6104222ddf1SHong Zhang } 6114222ddf1SHong Zhang 6124222ddf1SHong Zhang PetscErrorCode MatProductNumeric_PtAP(Mat mat) 6134222ddf1SHong Zhang { 6144222ddf1SHong Zhang PetscErrorCode ierr; 6154222ddf1SHong Zhang Mat_Product *product = mat->product; 6164222ddf1SHong Zhang Mat A=product->A,B=product->B; 6174222ddf1SHong Zhang 6184222ddf1SHong Zhang PetscFunctionBegin; 619*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->ptapnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 6207a3c3d58SStefano Zampini ierr = (*mat->ops->ptapnumeric)(A,B,mat);CHKERRQ(ierr); 6214222ddf1SHong Zhang PetscFunctionReturn(0); 6224222ddf1SHong Zhang } 6234222ddf1SHong Zhang 6244222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt(Mat mat) 6254222ddf1SHong Zhang { 6264222ddf1SHong Zhang PetscErrorCode ierr; 6274222ddf1SHong Zhang Mat_Product *product = mat->product; 6284222ddf1SHong Zhang Mat A=product->A,B=product->B; 6294222ddf1SHong Zhang 6304222ddf1SHong Zhang PetscFunctionBegin; 631*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->rartnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 6327a3c3d58SStefano Zampini ierr = (*mat->ops->rartnumeric)(A,B,mat);CHKERRQ(ierr); 6334222ddf1SHong Zhang PetscFunctionReturn(0); 6344222ddf1SHong Zhang } 6354222ddf1SHong Zhang 6364222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABC(Mat mat) 6374222ddf1SHong Zhang { 6384222ddf1SHong Zhang PetscErrorCode ierr; 6394222ddf1SHong Zhang Mat_Product *product = mat->product; 6404222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 6414222ddf1SHong Zhang 6424222ddf1SHong Zhang PetscFunctionBegin; 643*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->matmatmultnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 6447a3c3d58SStefano Zampini ierr = (*mat->ops->matmatmultnumeric)(A,B,C,mat);CHKERRQ(ierr); 6454222ddf1SHong Zhang PetscFunctionReturn(0); 6464222ddf1SHong Zhang } 6474222ddf1SHong Zhang 6486718818eSStefano Zampini /* ----------------------------------------------- */ 6496718818eSStefano Zampini 6504222ddf1SHong Zhang /*@ 6514222ddf1SHong Zhang MatProductNumeric - Implement a matrix product with numerical values. 6524222ddf1SHong Zhang 6534222ddf1SHong Zhang Collective on Mat 6544222ddf1SHong Zhang 6556718818eSStefano Zampini Input/Output Parameter: 6566718818eSStefano Zampini . mat - the matrix holding the product 6574222ddf1SHong Zhang 6584222ddf1SHong Zhang Level: intermediate 6594222ddf1SHong Zhang 6606718818eSStefano Zampini Notes: MatProductSymbolic() must have been called on mat before calling this function 6616718818eSStefano Zampini 6626718818eSStefano Zampini .seealso: MatProductCreate(), MatSetType(), MatProductSymbolic() 6634222ddf1SHong Zhang @*/ 6644222ddf1SHong Zhang PetscErrorCode MatProductNumeric(Mat mat) 6654222ddf1SHong Zhang { 6664222ddf1SHong Zhang PetscErrorCode ierr; 667e017e560SStefano Zampini PetscLogEvent eventtype = -1; 6682e105a96SStefano Zampini PetscBool missing = PETSC_FALSE; 6694222ddf1SHong Zhang 6704222ddf1SHong Zhang PetscFunctionBegin; 6714222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6726718818eSStefano Zampini MatCheckProduct(mat,1); 673e017e560SStefano Zampini switch (mat->product->type) { 674e017e560SStefano Zampini case MATPRODUCT_AB: 675e017e560SStefano Zampini eventtype = MAT_MatMultNumeric; 676e017e560SStefano Zampini break; 677e017e560SStefano Zampini case MATPRODUCT_AtB: 678e017e560SStefano Zampini eventtype = MAT_TransposeMatMultNumeric; 679e017e560SStefano Zampini break; 680e017e560SStefano Zampini case MATPRODUCT_ABt: 681e017e560SStefano Zampini eventtype = MAT_MatTransposeMultNumeric; 682e017e560SStefano Zampini break; 683e017e560SStefano Zampini case MATPRODUCT_PtAP: 684e017e560SStefano Zampini eventtype = MAT_PtAPNumeric; 685e017e560SStefano Zampini break; 686e017e560SStefano Zampini case MATPRODUCT_RARt: 687e017e560SStefano Zampini eventtype = MAT_RARtNumeric; 688e017e560SStefano Zampini break; 689e017e560SStefano Zampini case MATPRODUCT_ABC: 690e017e560SStefano Zampini eventtype = MAT_MatMatMultNumeric; 691e017e560SStefano Zampini break; 69298921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[mat->product->type]); 693e017e560SStefano Zampini } 6948d7b260cSStefano Zampini 6954222ddf1SHong Zhang if (mat->ops->productnumeric) { 696e017e560SStefano Zampini ierr = PetscLogEventBegin(eventtype,mat,0,0,0);CHKERRQ(ierr); 6974222ddf1SHong Zhang ierr = (*mat->ops->productnumeric)(mat);CHKERRQ(ierr); 698e017e560SStefano Zampini ierr = PetscLogEventEnd(eventtype,mat,0,0,0);CHKERRQ(ierr); 6992e105a96SStefano Zampini } else missing = PETSC_TRUE; 7002e105a96SStefano Zampini 7012e105a96SStefano Zampini if (missing || !mat->product) { 7022e105a96SStefano Zampini char errstr[256]; 7032e105a96SStefano Zampini 7042e105a96SStefano Zampini if (mat->product->type == MATPRODUCT_ABC) { 7052e105a96SStefano Zampini ierr = PetscSNPrintf(errstr,256,"%s with A %s, B %s, C %s",MatProductTypes[mat->product->type],((PetscObject)mat->product->A)->type_name,((PetscObject)mat->product->B)->type_name,((PetscObject)mat->product->C)->type_name);CHKERRQ(ierr); 7062e105a96SStefano Zampini } else { 7072e105a96SStefano Zampini ierr = PetscSNPrintf(errstr,256,"%s with A %s, B %s",MatProductTypes[mat->product->type],((PetscObject)mat->product->A)->type_name,((PetscObject)mat->product->B)->type_name);CHKERRQ(ierr); 7082e105a96SStefano Zampini } 709*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(missing,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Unspecified numeric phase for product %s",errstr); 710*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->product,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing struct after symbolic phase for product %s",errstr); 7112e105a96SStefano Zampini } 7122e105a96SStefano Zampini 7136718818eSStefano Zampini if (mat->product->clear) { 7146718818eSStefano Zampini ierr = MatProductClear(mat);CHKERRQ(ierr); 7156718818eSStefano Zampini } 7165415d71bSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 7174222ddf1SHong Zhang PetscFunctionReturn(0); 7184222ddf1SHong Zhang } 7194222ddf1SHong Zhang 7204222ddf1SHong Zhang /* ----------------------------------------------- */ 7216718818eSStefano Zampini /* these are basic implementations relying on the old function pointers 7226718818eSStefano Zampini * they are dangerous and should be removed in the future */ 7234222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AB(Mat mat) 7244222ddf1SHong Zhang { 7254222ddf1SHong Zhang PetscErrorCode ierr; 7264222ddf1SHong Zhang Mat_Product *product = mat->product; 7274222ddf1SHong Zhang Mat A=product->A,B=product->B; 7284222ddf1SHong Zhang 7294222ddf1SHong Zhang PetscFunctionBegin; 730*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->matmultsymbolic,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 7317a3c3d58SStefano Zampini ierr = (*mat->ops->matmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7324222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AB; 7334222ddf1SHong Zhang PetscFunctionReturn(0); 7344222ddf1SHong Zhang } 7354222ddf1SHong Zhang 7364222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AtB(Mat mat) 7374222ddf1SHong Zhang { 7384222ddf1SHong Zhang PetscErrorCode ierr; 7394222ddf1SHong Zhang Mat_Product *product = mat->product; 7404222ddf1SHong Zhang Mat A=product->A,B=product->B; 7414222ddf1SHong Zhang 7424222ddf1SHong Zhang PetscFunctionBegin; 743*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->transposematmultsymbolic,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 7447a3c3d58SStefano Zampini ierr = (*mat->ops->transposematmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7454222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AtB; 7464222ddf1SHong Zhang PetscFunctionReturn(0); 7474222ddf1SHong Zhang } 7484222ddf1SHong Zhang 7494222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABt(Mat mat) 7504222ddf1SHong Zhang { 7514222ddf1SHong Zhang PetscErrorCode ierr; 7524222ddf1SHong Zhang Mat_Product *product = mat->product; 7534222ddf1SHong Zhang Mat A=product->A,B=product->B; 7544222ddf1SHong Zhang 7554222ddf1SHong Zhang PetscFunctionBegin; 756*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->mattransposemultsymbolic,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 7577a3c3d58SStefano Zampini ierr = (*mat->ops->mattransposemultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7584222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABt; 7594222ddf1SHong Zhang PetscFunctionReturn(0); 7604222ddf1SHong Zhang } 7614222ddf1SHong Zhang 7624222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABC(Mat mat) 7634222ddf1SHong Zhang { 7644222ddf1SHong Zhang PetscErrorCode ierr; 7654222ddf1SHong Zhang Mat_Product *product = mat->product; 7664222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 7674222ddf1SHong Zhang 7684222ddf1SHong Zhang PetscFunctionBegin; 769*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->matmatmultsymbolic,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 7707a3c3d58SStefano Zampini ierr = (*mat->ops->matmatmultsymbolic)(A,B,C,product->fill,mat);CHKERRQ(ierr); 7714222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC; 7724222ddf1SHong Zhang PetscFunctionReturn(0); 7734222ddf1SHong Zhang } 7744222ddf1SHong Zhang 7756718818eSStefano Zampini /* ----------------------------------------------- */ 7766718818eSStefano Zampini 7774222ddf1SHong Zhang /*@ 7784222ddf1SHong Zhang MatProductSymbolic - Perform the symbolic portion of a matrix product, this creates a data structure for use with the numerical produce. 7794222ddf1SHong Zhang 7804222ddf1SHong Zhang Collective on Mat 7814222ddf1SHong Zhang 7826718818eSStefano Zampini Input/Output Parameter: 7834222ddf1SHong Zhang . mat - the matrix to hold a product 7844222ddf1SHong Zhang 7854222ddf1SHong Zhang Level: intermediate 7864222ddf1SHong Zhang 7876718818eSStefano Zampini Notes: MatProductSetFromOptions() must have been called on mat before calling this function 7886718818eSStefano Zampini 7896718818eSStefano Zampini .seealso: MatProductCreate(), MatProductCreateWithMat(), MatProductSetFromOptions(), MatProductNumeric(), MatProductSetType(), MatProductSetAlgorithm() 7904222ddf1SHong Zhang @*/ 7914222ddf1SHong Zhang PetscErrorCode MatProductSymbolic(Mat mat) 7924222ddf1SHong Zhang { 7934222ddf1SHong Zhang PetscErrorCode ierr; 7944222ddf1SHong Zhang PetscLogEvent eventtype = -1; 7952e105a96SStefano Zampini PetscBool missing = PETSC_FALSE; 7964222ddf1SHong Zhang 7974222ddf1SHong Zhang PetscFunctionBegin; 7984222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7996718818eSStefano Zampini MatCheckProduct(mat,1); 800*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(mat->product->data,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Cannot run symbolic phase. Product data not empty"); 8016718818eSStefano Zampini switch (mat->product->type) { 8024222ddf1SHong Zhang case MATPRODUCT_AB: 8034222ddf1SHong Zhang eventtype = MAT_MatMultSymbolic; 8044222ddf1SHong Zhang break; 8054222ddf1SHong Zhang case MATPRODUCT_AtB: 8064222ddf1SHong Zhang eventtype = MAT_TransposeMatMultSymbolic; 8074222ddf1SHong Zhang break; 8084222ddf1SHong Zhang case MATPRODUCT_ABt: 8094222ddf1SHong Zhang eventtype = MAT_MatTransposeMultSymbolic; 8104222ddf1SHong Zhang break; 8114222ddf1SHong Zhang case MATPRODUCT_PtAP: 8124222ddf1SHong Zhang eventtype = MAT_PtAPSymbolic; 8134222ddf1SHong Zhang break; 8144222ddf1SHong Zhang case MATPRODUCT_RARt: 8154222ddf1SHong Zhang eventtype = MAT_RARtSymbolic; 8164222ddf1SHong Zhang break; 8174222ddf1SHong Zhang case MATPRODUCT_ABC: 8184222ddf1SHong Zhang eventtype = MAT_MatMatMultSymbolic; 8194222ddf1SHong Zhang break; 82098921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[mat->product->type]); 8214222ddf1SHong Zhang } 8226718818eSStefano Zampini mat->ops->productnumeric = NULL; 8234222ddf1SHong Zhang if (mat->ops->productsymbolic) { 8244222ddf1SHong Zhang ierr = PetscLogEventBegin(eventtype,mat,0,0,0);CHKERRQ(ierr); 8254222ddf1SHong Zhang ierr = (*mat->ops->productsymbolic)(mat);CHKERRQ(ierr); 8264222ddf1SHong Zhang ierr = PetscLogEventEnd(eventtype,mat,0,0,0);CHKERRQ(ierr); 8272e105a96SStefano Zampini } else missing = PETSC_TRUE; 8282e105a96SStefano Zampini 8292e105a96SStefano Zampini if (missing || !mat->product || !mat->ops->productnumeric) { 8302e105a96SStefano Zampini char errstr[256]; 8312e105a96SStefano Zampini 8322e105a96SStefano Zampini if (mat->product->type == MATPRODUCT_ABC) { 8332e105a96SStefano Zampini ierr = PetscSNPrintf(errstr,256,"%s with A %s, B %s, C %s",MatProductTypes[mat->product->type],((PetscObject)mat->product->A)->type_name,((PetscObject)mat->product->B)->type_name,((PetscObject)mat->product->C)->type_name);CHKERRQ(ierr); 8342e105a96SStefano Zampini } else { 8352e105a96SStefano Zampini ierr = PetscSNPrintf(errstr,256,"%s with A %s, B %s",MatProductTypes[mat->product->type],((PetscObject)mat->product->A)->type_name,((PetscObject)mat->product->B)->type_name);CHKERRQ(ierr); 8362e105a96SStefano Zampini } 837*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(missing,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Unspecified symbolic phase for product %s. Call MatProductSetFromOptions() first",errstr); 838*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->productnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Unspecified numeric phase for product %s",errstr); 839*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->product,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing struct after symbolic phase for product %s",errstr); 8402e105a96SStefano Zampini } 8414222ddf1SHong Zhang PetscFunctionReturn(0); 8424222ddf1SHong Zhang } 8434222ddf1SHong Zhang 8444222ddf1SHong Zhang /*@ 8454222ddf1SHong Zhang MatProductSetFill - Set an expected fill of the matrix product. 8464222ddf1SHong Zhang 8474222ddf1SHong Zhang Collective on Mat 8484222ddf1SHong Zhang 8494222ddf1SHong Zhang Input Parameters: 8504222ddf1SHong Zhang + mat - the matrix product 851a5b23f4aSJose E. Roman - 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 irrelevant. 8524222ddf1SHong Zhang 8534222ddf1SHong Zhang Level: intermediate 8544222ddf1SHong Zhang 8554222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetAlgorithm(), MatProductCreate() 8564222ddf1SHong Zhang @*/ 8574222ddf1SHong Zhang PetscErrorCode MatProductSetFill(Mat mat,PetscReal fill) 8584222ddf1SHong Zhang { 8594222ddf1SHong Zhang PetscFunctionBegin; 8604222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8616718818eSStefano Zampini MatCheckProduct(mat,1); 8626718818eSStefano Zampini if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) mat->product->fill = 2.0; 8636718818eSStefano Zampini else mat->product->fill = fill; 8644222ddf1SHong Zhang PetscFunctionReturn(0); 8654222ddf1SHong Zhang } 8664222ddf1SHong Zhang 8674222ddf1SHong Zhang /*@ 8684222ddf1SHong Zhang MatProductSetAlgorithm - Requests a particular algorithm for a matrix product implementation. 8694222ddf1SHong Zhang 8704222ddf1SHong Zhang Collective on Mat 8714222ddf1SHong Zhang 8724222ddf1SHong Zhang Input Parameters: 8734222ddf1SHong Zhang + mat - the matrix product 8743e662e0bSHong Zhang - alg - particular implementation algorithm of the matrix product, e.g., MATPRODUCTALGORITHMDEFAULT. 8753e662e0bSHong Zhang 8763e662e0bSHong Zhang Options Database Key: 8773e662e0bSHong Zhang . -mat_product_algorithm <algorithm> - Sets the algorithm; use -help for a list 8783e662e0bSHong Zhang of available algorithms (for instance, scalable, outerproduct, etc.) 8794222ddf1SHong Zhang 8804222ddf1SHong Zhang Level: intermediate 8814222ddf1SHong Zhang 8826718818eSStefano Zampini .seealso: MatProductSetType(), MatProductSetFill(), MatProductCreate(), MatProductAlgorithm 8834222ddf1SHong Zhang @*/ 8844222ddf1SHong Zhang PetscErrorCode MatProductSetAlgorithm(Mat mat,MatProductAlgorithm alg) 8854222ddf1SHong Zhang { 8867a3c3d58SStefano Zampini PetscErrorCode ierr; 8874222ddf1SHong Zhang 8884222ddf1SHong Zhang PetscFunctionBegin; 8894222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8906718818eSStefano Zampini MatCheckProduct(mat,1); 8916718818eSStefano Zampini ierr = PetscFree(mat->product->alg);CHKERRQ(ierr); 8926718818eSStefano Zampini ierr = PetscStrallocpy(alg,&mat->product->alg);CHKERRQ(ierr); 8934222ddf1SHong Zhang PetscFunctionReturn(0); 8944222ddf1SHong Zhang } 8954222ddf1SHong Zhang 8964222ddf1SHong Zhang /*@ 8976718818eSStefano Zampini MatProductSetType - Sets a particular matrix product type 8984222ddf1SHong Zhang 8994222ddf1SHong Zhang Collective on Mat 9004222ddf1SHong Zhang 9014222ddf1SHong Zhang Input Parameters: 9024222ddf1SHong Zhang + mat - the matrix 9034222ddf1SHong Zhang - productype - matrix product type, e.g., MATPRODUCT_AB,MATPRODUCT_AtB,MATPRODUCT_ABt,MATPRODUCT_PtAP,MATPRODUCT_RARt,MATPRODUCT_ABC. 9044222ddf1SHong Zhang 9054222ddf1SHong Zhang Level: intermediate 9064222ddf1SHong Zhang 9076718818eSStefano Zampini .seealso: MatProductCreate(), MatProductType 9084222ddf1SHong Zhang @*/ 9094222ddf1SHong Zhang PetscErrorCode MatProductSetType(Mat mat,MatProductType productype) 9104222ddf1SHong Zhang { 9116718818eSStefano Zampini PetscErrorCode ierr; 9124222ddf1SHong Zhang 9134222ddf1SHong Zhang PetscFunctionBegin; 9144222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9156718818eSStefano Zampini MatCheckProduct(mat,1); 9167a3c3d58SStefano Zampini PetscValidLogicalCollectiveEnum(mat,productype,2); 9176718818eSStefano Zampini if (productype != mat->product->type) { 9186718818eSStefano Zampini if (mat->product->destroy) { 9196718818eSStefano Zampini ierr = (*mat->product->destroy)(mat->product->data);CHKERRQ(ierr); 9204222ddf1SHong Zhang } 9216718818eSStefano Zampini mat->product->destroy = NULL; 9226718818eSStefano Zampini mat->product->data = NULL; 9236718818eSStefano Zampini mat->ops->productsymbolic = NULL; 9246718818eSStefano Zampini mat->ops->productnumeric = NULL; 9256718818eSStefano Zampini } 9266718818eSStefano Zampini mat->product->type = productype; 9274222ddf1SHong Zhang PetscFunctionReturn(0); 9284222ddf1SHong Zhang } 9294222ddf1SHong Zhang 9304417c5e8SHong Zhang /*@ 9314417c5e8SHong Zhang MatProductClear - Clears matrix product internal structure. 9324417c5e8SHong Zhang 9334417c5e8SHong Zhang Collective on Mat 9344417c5e8SHong Zhang 9354417c5e8SHong Zhang Input Parameters: 9364417c5e8SHong Zhang . mat - the product matrix 9374417c5e8SHong Zhang 9384417c5e8SHong Zhang Level: intermediate 9396718818eSStefano Zampini 9406718818eSStefano Zampini Notes: this function should be called to remove any intermediate data used by the product 9416718818eSStefano Zampini After having called this function, MatProduct operations can no longer be used on mat 9424417c5e8SHong Zhang @*/ 9434417c5e8SHong Zhang PetscErrorCode MatProductClear(Mat mat) 9444417c5e8SHong Zhang { 9454417c5e8SHong Zhang PetscErrorCode ierr; 9464417c5e8SHong Zhang Mat_Product *product = mat->product; 9474417c5e8SHong Zhang 9484417c5e8SHong Zhang PetscFunctionBegin; 9497a3c3d58SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9504417c5e8SHong Zhang if (product) { 9514417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 9524417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 9534417c5e8SHong Zhang ierr = MatDestroy(&product->C);CHKERRQ(ierr); 9547a3c3d58SStefano Zampini ierr = PetscFree(product->alg);CHKERRQ(ierr); 9554417c5e8SHong Zhang ierr = MatDestroy(&product->Dwork);CHKERRQ(ierr); 9566718818eSStefano Zampini if (product->destroy) { 9576718818eSStefano Zampini ierr = (*product->destroy)(product->data);CHKERRQ(ierr); 9584417c5e8SHong Zhang } 9596718818eSStefano Zampini } 9606718818eSStefano Zampini ierr = PetscFree(mat->product);CHKERRQ(ierr); 9616718818eSStefano Zampini mat->ops->productsymbolic = NULL; 9626718818eSStefano Zampini mat->ops->productnumeric = NULL; 9634417c5e8SHong Zhang PetscFunctionReturn(0); 9644417c5e8SHong Zhang } 9654417c5e8SHong Zhang 9664222ddf1SHong Zhang /* Create a supporting struct and attach it to the matrix product */ 9674417c5e8SHong Zhang PetscErrorCode MatProductCreate_Private(Mat A,Mat B,Mat C,Mat D) 9684222ddf1SHong Zhang { 9694222ddf1SHong Zhang PetscErrorCode ierr; 9704222ddf1SHong Zhang Mat_Product *product=NULL; 9714222ddf1SHong Zhang 9724222ddf1SHong Zhang PetscFunctionBegin; 9736718818eSStefano Zampini PetscValidHeaderSpecific(D,MAT_CLASSID,4); 974*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(D->product,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product already present"); 9754222ddf1SHong Zhang ierr = PetscNewLog(D,&product);CHKERRQ(ierr); 9764222ddf1SHong Zhang product->A = A; 9774222ddf1SHong Zhang product->B = B; 9784222ddf1SHong Zhang product->C = C; 9796718818eSStefano Zampini product->type = MATPRODUCT_UNSPECIFIED; 9804222ddf1SHong Zhang product->Dwork = NULL; 9814222ddf1SHong Zhang product->api_user = PETSC_FALSE; 9826718818eSStefano Zampini product->clear = PETSC_FALSE; 9834222ddf1SHong Zhang D->product = product; 9844417c5e8SHong Zhang 9853e662e0bSHong Zhang ierr = MatProductSetAlgorithm(D,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 9866718818eSStefano Zampini ierr = MatProductSetFill(D,PETSC_DEFAULT);CHKERRQ(ierr); 9877a3c3d58SStefano Zampini 9884417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 9894417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 9904417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); 9914222ddf1SHong Zhang PetscFunctionReturn(0); 9924222ddf1SHong Zhang } 9934222ddf1SHong Zhang 9944222ddf1SHong Zhang /*@ 9954222ddf1SHong Zhang MatProductCreateWithMat - Setup a given matrix as a matrix product. 9964222ddf1SHong Zhang 9974222ddf1SHong Zhang Collective on Mat 9984222ddf1SHong Zhang 9994222ddf1SHong Zhang Input Parameters: 10004222ddf1SHong Zhang + A - the first matrix 10014222ddf1SHong Zhang . B - the second matrix 10024222ddf1SHong Zhang . C - the third matrix (optional) 10034222ddf1SHong Zhang - D - the matrix which will be used as a product 10044222ddf1SHong Zhang 10054222ddf1SHong Zhang Output Parameters: 10064222ddf1SHong Zhang . D - the product matrix 10074222ddf1SHong Zhang 10086718818eSStefano Zampini Notes: 10096718818eSStefano Zampini Any product data attached to D will be cleared 10106718818eSStefano Zampini 10114222ddf1SHong Zhang Level: intermediate 10124222ddf1SHong Zhang 10136718818eSStefano Zampini .seealso: MatProductCreate(), MatProductClear() 10144222ddf1SHong Zhang @*/ 10154222ddf1SHong Zhang PetscErrorCode MatProductCreateWithMat(Mat A,Mat B,Mat C,Mat D) 10164222ddf1SHong Zhang { 10174222ddf1SHong Zhang PetscErrorCode ierr; 10184222ddf1SHong Zhang 10194222ddf1SHong Zhang PetscFunctionBegin; 10204222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10214222ddf1SHong Zhang PetscValidType(A,1); 10224222ddf1SHong Zhang MatCheckPreallocated(A,1); 1023*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1024*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10254222ddf1SHong Zhang 10264222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10274222ddf1SHong Zhang PetscValidType(B,2); 10284222ddf1SHong Zhang MatCheckPreallocated(B,2); 1029*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1030*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(B->factortype,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10314222ddf1SHong Zhang 10324222ddf1SHong Zhang if (C) { 10334222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10344222ddf1SHong Zhang PetscValidType(C,3); 10354222ddf1SHong Zhang MatCheckPreallocated(C,3); 1036*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!C->assembled,PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1037*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(C->factortype,PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10384222ddf1SHong Zhang } 10394222ddf1SHong Zhang 10404222ddf1SHong Zhang PetscValidHeaderSpecific(D,MAT_CLASSID,4); 10414222ddf1SHong Zhang PetscValidType(D,4); 10424222ddf1SHong Zhang MatCheckPreallocated(D,4); 1043*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!D->assembled,PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1044*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(D->factortype,PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10454222ddf1SHong Zhang 10464222ddf1SHong Zhang /* Create a supporting struct and attach it to D */ 10476718818eSStefano Zampini ierr = MatProductClear(D);CHKERRQ(ierr); 10484222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,D);CHKERRQ(ierr); 10494222ddf1SHong Zhang PetscFunctionReturn(0); 10504222ddf1SHong Zhang } 10514222ddf1SHong Zhang 10524222ddf1SHong Zhang /*@ 10534222ddf1SHong Zhang MatProductCreate - create a matrix product object that can be used to compute various matrix times matrix operations. 10544222ddf1SHong Zhang 10554222ddf1SHong Zhang Collective on Mat 10564222ddf1SHong Zhang 10574222ddf1SHong Zhang Input Parameters: 10584222ddf1SHong Zhang + A - the first matrix 10594222ddf1SHong Zhang . B - the second matrix 10604222ddf1SHong Zhang - C - the third matrix (optional) 10614222ddf1SHong Zhang 10624222ddf1SHong Zhang Output Parameters: 10634222ddf1SHong Zhang . D - the product matrix 10644222ddf1SHong Zhang 10654222ddf1SHong Zhang Level: intermediate 10664222ddf1SHong Zhang 10674222ddf1SHong Zhang .seealso: MatProductCreateWithMat(), MatProductSetType(), MatProductSetAlgorithm() 10684222ddf1SHong Zhang @*/ 10694222ddf1SHong Zhang PetscErrorCode MatProductCreate(Mat A,Mat B,Mat C,Mat *D) 10704222ddf1SHong Zhang { 10714222ddf1SHong Zhang PetscErrorCode ierr; 10724222ddf1SHong Zhang 10734222ddf1SHong Zhang PetscFunctionBegin; 10744222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10754222ddf1SHong Zhang PetscValidType(A,1); 10764222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10774222ddf1SHong Zhang PetscValidType(B,2); 1078*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix A"); 1079*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(B->factortype,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix B"); 10804222ddf1SHong Zhang 10814222ddf1SHong Zhang if (C) { 10824222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10834222ddf1SHong Zhang PetscValidType(C,3); 1084*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(C->factortype,PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix C"); 10854222ddf1SHong Zhang } 10864222ddf1SHong Zhang 10874222ddf1SHong Zhang PetscValidPointer(D,4); 10884222ddf1SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A),D);CHKERRQ(ierr); 10894222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,*D);CHKERRQ(ierr); 10904222ddf1SHong Zhang PetscFunctionReturn(0); 10914222ddf1SHong Zhang } 10925415d71bSStefano Zampini 10935415d71bSStefano Zampini /* 10945415d71bSStefano Zampini These are safe basic implementations of ABC, RARt and PtAP 10955415d71bSStefano Zampini that do not rely on mat->ops->matmatop function pointers. 10965415d71bSStefano Zampini They only use the MatProduct API and are currently used by 10975415d71bSStefano Zampini cuSPARSE and KOKKOS-KERNELS backends 10985415d71bSStefano Zampini */ 1099ec446438SStefano Zampini typedef struct { 11005415d71bSStefano Zampini Mat BC; 11015415d71bSStefano Zampini Mat ABC; 11025415d71bSStefano Zampini } MatMatMatPrivate; 11035415d71bSStefano Zampini 11045415d71bSStefano Zampini static PetscErrorCode MatDestroy_MatMatMatPrivate(void *data) 11055415d71bSStefano Zampini { 11065415d71bSStefano Zampini PetscErrorCode ierr; 11075415d71bSStefano Zampini MatMatMatPrivate *mmdata = (MatMatMatPrivate *)data; 11085415d71bSStefano Zampini 11095415d71bSStefano Zampini PetscFunctionBegin; 11105415d71bSStefano Zampini ierr = MatDestroy(&mmdata->BC);CHKERRQ(ierr); 11115415d71bSStefano Zampini ierr = MatDestroy(&mmdata->ABC);CHKERRQ(ierr); 11125415d71bSStefano Zampini ierr = PetscFree(data);CHKERRQ(ierr); 11135415d71bSStefano Zampini PetscFunctionReturn(0); 11145415d71bSStefano Zampini } 11155415d71bSStefano Zampini 11165415d71bSStefano Zampini static PetscErrorCode MatProductNumeric_ABC_Basic(Mat mat) 11175415d71bSStefano Zampini { 11185415d71bSStefano Zampini PetscErrorCode ierr; 11195415d71bSStefano Zampini Mat_Product *product = mat->product; 11205415d71bSStefano Zampini MatMatMatPrivate *mmabc; 11215415d71bSStefano Zampini 11225415d71bSStefano Zampini PetscFunctionBegin; 11235415d71bSStefano Zampini MatCheckProduct(mat,1); 1124*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->product->data,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Product data empty"); 11255415d71bSStefano Zampini mmabc = (MatMatMatPrivate *)mat->product->data; 1126*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mmabc->BC->ops->productnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric stage"); 1127ec446438SStefano Zampini /* use function pointer directly to prevent logging */ 11285415d71bSStefano Zampini ierr = (*mmabc->BC->ops->productnumeric)(mmabc->BC);CHKERRQ(ierr); 11295415d71bSStefano Zampini /* swap ABC product stuff with that of ABC for the numeric phase on mat */ 11305415d71bSStefano Zampini mat->product = mmabc->ABC->product; 11315415d71bSStefano Zampini mat->ops->productnumeric = mmabc->ABC->ops->productnumeric; 1132*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mat->ops->productnumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric stage"); 1133ec446438SStefano Zampini /* use function pointer directly to prevent logging */ 11345415d71bSStefano Zampini ierr = (*mat->ops->productnumeric)(mat);CHKERRQ(ierr); 11355415d71bSStefano Zampini mat->ops->productnumeric = MatProductNumeric_ABC_Basic; 11365415d71bSStefano Zampini mat->product = product; 11375415d71bSStefano Zampini PetscFunctionReturn(0); 11385415d71bSStefano Zampini } 11395415d71bSStefano Zampini 11405415d71bSStefano Zampini PetscErrorCode MatProductSymbolic_ABC_Basic(Mat mat) 11415415d71bSStefano Zampini { 11425415d71bSStefano Zampini PetscErrorCode ierr; 11435415d71bSStefano Zampini Mat_Product *product = mat->product; 11445415d71bSStefano Zampini Mat A, B ,C; 11455415d71bSStefano Zampini MatProductType p1,p2; 11465415d71bSStefano Zampini MatMatMatPrivate *mmabc; 114765e4b4d4SStefano Zampini const char *prefix; 11485415d71bSStefano Zampini 11495415d71bSStefano Zampini PetscFunctionBegin; 11505415d71bSStefano Zampini MatCheckProduct(mat,1); 1151*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(mat->product->data,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Product data not empty"); 115265e4b4d4SStefano Zampini ierr = MatGetOptionsPrefix(mat,&prefix);CHKERRQ(ierr); 11535415d71bSStefano Zampini ierr = PetscNew(&mmabc);CHKERRQ(ierr); 11545415d71bSStefano Zampini product->data = mmabc; 11555415d71bSStefano Zampini product->destroy = MatDestroy_MatMatMatPrivate; 11565415d71bSStefano Zampini switch (product->type) { 11575415d71bSStefano Zampini case MATPRODUCT_PtAP: 11585415d71bSStefano Zampini p1 = MATPRODUCT_AB; 11595415d71bSStefano Zampini p2 = MATPRODUCT_AtB; 11605415d71bSStefano Zampini A = product->B; 11615415d71bSStefano Zampini B = product->A; 11625415d71bSStefano Zampini C = product->B; 11635415d71bSStefano Zampini break; 11645415d71bSStefano Zampini case MATPRODUCT_RARt: 11655415d71bSStefano Zampini p1 = MATPRODUCT_ABt; 11665415d71bSStefano Zampini p2 = MATPRODUCT_AB; 11675415d71bSStefano Zampini A = product->B; 11685415d71bSStefano Zampini B = product->A; 11695415d71bSStefano Zampini C = product->B; 11705415d71bSStefano Zampini break; 11715415d71bSStefano Zampini case MATPRODUCT_ABC: 11725415d71bSStefano Zampini p1 = MATPRODUCT_AB; 11735415d71bSStefano Zampini p2 = MATPRODUCT_AB; 11745415d71bSStefano Zampini A = product->A; 11755415d71bSStefano Zampini B = product->B; 11765415d71bSStefano Zampini C = product->C; 11775415d71bSStefano Zampini break; 11785415d71bSStefano Zampini default: 117998921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Not for ProductType %s",MatProductTypes[product->type]); 11805415d71bSStefano Zampini } 11815415d71bSStefano Zampini ierr = MatProductCreate(B,C,NULL,&mmabc->BC);CHKERRQ(ierr); 118265e4b4d4SStefano Zampini ierr = MatSetOptionsPrefix(mmabc->BC,prefix);CHKERRQ(ierr); 118365e4b4d4SStefano Zampini ierr = MatAppendOptionsPrefix(mmabc->BC,"P1_");CHKERRQ(ierr); 11845415d71bSStefano Zampini ierr = MatProductSetType(mmabc->BC,p1);CHKERRQ(ierr); 11853e662e0bSHong Zhang ierr = MatProductSetAlgorithm(mmabc->BC,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 11865415d71bSStefano Zampini ierr = MatProductSetFill(mmabc->BC,product->fill);CHKERRQ(ierr); 11875415d71bSStefano Zampini mmabc->BC->product->api_user = product->api_user; 11885415d71bSStefano Zampini ierr = MatProductSetFromOptions(mmabc->BC);CHKERRQ(ierr); 1189*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mmabc->BC->ops->productsymbolic,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Symbolic ProductType %s not supported with %s and %s",MatProductTypes[p1],((PetscObject)B)->type_name,((PetscObject)C)->type_name); 1190bfcc3627SStefano Zampini /* use function pointer directly to prevent logging */ 11915415d71bSStefano Zampini ierr = (*mmabc->BC->ops->productsymbolic)(mmabc->BC);CHKERRQ(ierr); 11925415d71bSStefano Zampini 11935415d71bSStefano Zampini ierr = MatProductCreate(A,mmabc->BC,NULL,&mmabc->ABC);CHKERRQ(ierr); 119465e4b4d4SStefano Zampini ierr = MatSetOptionsPrefix(mmabc->ABC,prefix);CHKERRQ(ierr); 119565e4b4d4SStefano Zampini ierr = MatAppendOptionsPrefix(mmabc->ABC,"P2_");CHKERRQ(ierr); 11965415d71bSStefano Zampini ierr = MatProductSetType(mmabc->ABC,p2);CHKERRQ(ierr); 11973e662e0bSHong Zhang ierr = MatProductSetAlgorithm(mmabc->ABC,MATPRODUCTALGORITHMDEFAULT);CHKERRQ(ierr); 11985415d71bSStefano Zampini ierr = MatProductSetFill(mmabc->ABC,product->fill);CHKERRQ(ierr); 11995415d71bSStefano Zampini mmabc->ABC->product->api_user = product->api_user; 12005415d71bSStefano Zampini ierr = MatProductSetFromOptions(mmabc->ABC);CHKERRQ(ierr); 1201*2c71b3e2SJacob Faibussowitsch PetscCheckFalse(!mmabc->ABC->ops->productsymbolic,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Symbolic ProductType %s not supported with %s and %s",MatProductTypes[p2],((PetscObject)A)->type_name,((PetscObject)mmabc->BC)->type_name); 12025415d71bSStefano Zampini /* swap ABC product stuff with that of ABC for the symbolic phase on mat */ 12035415d71bSStefano Zampini mat->product = mmabc->ABC->product; 12045415d71bSStefano Zampini mat->ops->productsymbolic = mmabc->ABC->ops->productsymbolic; 1205bfcc3627SStefano Zampini /* use function pointer directly to prevent logging */ 12065415d71bSStefano Zampini ierr = (*mat->ops->productsymbolic)(mat);CHKERRQ(ierr); 12075415d71bSStefano Zampini mmabc->ABC->ops->productnumeric = mat->ops->productnumeric; 12085415d71bSStefano Zampini mat->ops->productsymbolic = MatProductSymbolic_ABC_Basic; 12095415d71bSStefano Zampini mat->ops->productnumeric = MatProductNumeric_ABC_Basic; 12105415d71bSStefano Zampini mat->product = product; 12115415d71bSStefano Zampini PetscFunctionReturn(0); 12125415d71bSStefano Zampini } 1213c600787bSStefano Zampini 1214c600787bSStefano Zampini /*@ 1215c600787bSStefano Zampini MatProductGetType - Returns the type of the MatProduct. 1216c600787bSStefano Zampini 1217c600787bSStefano Zampini Not collective 1218c600787bSStefano Zampini 1219c600787bSStefano Zampini Input Parameter: 1220c600787bSStefano Zampini . mat - the matrix 1221c600787bSStefano Zampini 1222c600787bSStefano Zampini Output Parameter: 1223c600787bSStefano Zampini . mtype - the MatProduct type 1224c600787bSStefano Zampini 1225c600787bSStefano Zampini Level: intermediate 1226c600787bSStefano Zampini 1227c600787bSStefano Zampini .seealso: MatProductCreateWithMat(), MatProductSetType(), MatProductCreate() 1228c600787bSStefano Zampini @*/ 1229c600787bSStefano Zampini PetscErrorCode MatProductGetType(Mat mat, MatProductType *mtype) 1230c600787bSStefano Zampini { 1231c600787bSStefano Zampini PetscFunctionBegin; 1232c600787bSStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1233c600787bSStefano Zampini PetscValidPointer(mtype,2); 1234c600787bSStefano Zampini *mtype = MATPRODUCT_UNSPECIFIED; 1235c600787bSStefano Zampini if (mat->product) *mtype = mat->product->type; 1236c600787bSStefano Zampini PetscFunctionReturn(0); 1237c600787bSStefano Zampini } 1238c600787bSStefano Zampini 1239c600787bSStefano Zampini /*@ 1240c600787bSStefano Zampini MatProductGetMats - Returns the matrices associated with the MatProduct. 1241c600787bSStefano Zampini 1242c600787bSStefano Zampini Not collective 1243c600787bSStefano Zampini 1244c600787bSStefano Zampini Input Parameter: 1245c600787bSStefano Zampini . mat - the product matrix 1246c600787bSStefano Zampini 1247c600787bSStefano Zampini Output Parameters: 1248c600787bSStefano Zampini + A - the first matrix 1249c600787bSStefano Zampini . B - the second matrix 1250c600787bSStefano Zampini - C - the third matrix (optional) 1251c600787bSStefano Zampini 1252c600787bSStefano Zampini Level: intermediate 1253c600787bSStefano Zampini 1254c600787bSStefano Zampini .seealso: MatProductCreateWithMat(), MatProductSetType(), MatProductSetAlgorithm() 1255c600787bSStefano Zampini @*/ 1256c600787bSStefano Zampini PetscErrorCode MatProductGetMats(Mat mat, Mat *A, Mat *B, Mat *C) 1257c600787bSStefano Zampini { 1258c600787bSStefano Zampini PetscFunctionBegin; 1259c600787bSStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1260c600787bSStefano Zampini if (A) *A = mat->product ? mat->product->A : NULL; 1261c600787bSStefano Zampini if (B) *B = mat->product ? mat->product->B : NULL; 1262c600787bSStefano Zampini if (C) *C = mat->product ? mat->product->C : NULL; 1263c600787bSStefano Zampini PetscFunctionReturn(0); 1264c600787bSStefano Zampini } 1265