14222ddf1SHong Zhang 24222ddf1SHong Zhang /* 34222ddf1SHong Zhang Routines for matrix products. Calling procedure: 44222ddf1SHong Zhang 5*6718818eSStefano Zampini MatProductCreate(A,B,C,&D); or MatProductCreateWithMat(A,B,C,D) 6*6718818eSStefano Zampini MatProductSetType(D, MATPRODUCT_AB/AtB/ABt/PtAP/RARt/ABC) 7*6718818eSStefano Zampini MatProductSetAlgorithm(D, alg) 8*6718818eSStefano Zampini MatProductSetFill(D,fill) 9*6718818eSStefano Zampini MatProductSetFromOptions(D) 10*6718818eSStefano Zampini -> MatProductSetFromOptions_Private(D) 114222ddf1SHong Zhang # Check matrix global sizes 12*6718818eSStefano Zampini if the matrices have the same setfromoptions routine, use it 13*6718818eSStefano Zampini if not, try: 14*6718818eSStefano Zampini -> Query MatProductSetFromOptions_Atype_Btype_Ctype_C(D) from A, B and C (in order) 15*6718818eSStefano Zampini if found -> run the specific setup that must set the symbolic operation (these callbacks should never fail) 16*6718818eSStefano Zampini if callback not found or no symbolic operation set 17*6718818eSStefano Zampini -> Query MatProductSetFromOptions_anytype_C(D) from A, B and C (in order) (e.g, matrices may have inner matrices like MATTRANPOSEMAT) 18*6718818eSStefano Zampini if dispatch found but combination still not present do 19*6718818eSStefano Zampini -> check if B is dense and product type AtB or AB -> if true, basic looping of dense columns 20*6718818eSStefano Zampini -> check if triple product (PtAP, RARt or ABC) -> if true, set the Basic routines 21*6718818eSStefano Zampini 22*6718818eSStefano 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 26*6718818eSStefano Zampini # Set D->ops->productsymbolic = MatProductSymbolic_productype_Atype_Btype_Ctype if found 274222ddf1SHong Zhang 284222ddf1SHong Zhang PetscLogEventBegin() 29*6718818eSStefano Zampini MatProductSymbolic(D) 30*6718818eSStefano Zampini # Call MatProductSymbolic_productype_Atype_Btype_Ctype() 31*6718818eSStefano Zampini the callback must set the numeric phase D->ops->productnumeric = MatProductNumeric_productype_Atype_Btype_Ctype 324222ddf1SHong Zhang PetscLogEventEnd() 334222ddf1SHong Zhang 344222ddf1SHong Zhang PetscLogEventBegin() 35*6718818eSStefano Zampini MatProductNumeric(D) 36*6718818eSStefano Zampini # Call the numeric phase 374222ddf1SHong Zhang PetscLogEventEnd() 38*6718818eSStefano Zampini 39*6718818eSStefano Zampini # The symbolic phases are allowed to set extra data structures and attach those to the product 40*6718818eSStefano Zampini # this additional data can be reused between multiple numeric phases with the same matrices 41*6718818eSStefano Zampini # if not needed, call 42*6718818eSStefano Zampini MatProductClear(D) 434222ddf1SHong Zhang */ 444222ddf1SHong Zhang 454222ddf1SHong Zhang #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 464222ddf1SHong Zhang 47*6718818eSStefano Zampini const char *const MatProductTypes[] = {"UNSPECIFIED","AB","AtB","ABt","PtAP","RARt","ABC"}; 48544a5e07SHong Zhang 49*6718818eSStefano Zampini /* these are basic implementations relying on the old function pointers 50*6718818eSStefano Zampini * they are dangerous and should be removed in the future */ 514222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_PtAP_Basic(Mat C) 524222ddf1SHong Zhang { 534222ddf1SHong Zhang PetscErrorCode ierr; 544222ddf1SHong Zhang Mat_Product *product = C->product; 554222ddf1SHong Zhang Mat P = product->B,AP = product->Dwork; 564222ddf1SHong Zhang 574222ddf1SHong Zhang PetscFunctionBegin; 584222ddf1SHong Zhang /* AP = A*P */ 594222ddf1SHong Zhang ierr = MatProductNumeric(AP);CHKERRQ(ierr); 604222ddf1SHong Zhang /* C = P^T*AP */ 617a3c3d58SStefano Zampini if (!C->ops->transposematmultnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing numeric stage"); 627a3c3d58SStefano Zampini ierr = (*C->ops->transposematmultnumeric)(P,AP,C);CHKERRQ(ierr); 634222ddf1SHong Zhang PetscFunctionReturn(0); 644222ddf1SHong Zhang } 654222ddf1SHong Zhang 664222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_PtAP_Basic(Mat C) 674222ddf1SHong Zhang { 684222ddf1SHong Zhang PetscErrorCode ierr; 694222ddf1SHong Zhang Mat_Product *product = C->product; 704222ddf1SHong Zhang Mat A=product->A,P=product->B,AP; 714222ddf1SHong Zhang PetscReal fill=product->fill; 724222ddf1SHong Zhang 734222ddf1SHong Zhang PetscFunctionBegin; 74*6718818eSStefano Zampini ierr = PetscInfo2((PetscObject)C,"for A %s, P %s is used\n",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name);CHKERRQ(ierr); 754222ddf1SHong Zhang /* AP = A*P */ 764222ddf1SHong Zhang ierr = MatProductCreate(A,P,NULL,&AP);CHKERRQ(ierr); 774222ddf1SHong Zhang ierr = MatProductSetType(AP,MATPRODUCT_AB);CHKERRQ(ierr); 787a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(AP,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 794222ddf1SHong Zhang ierr = MatProductSetFill(AP,fill);CHKERRQ(ierr); 804222ddf1SHong Zhang ierr = MatProductSetFromOptions(AP);CHKERRQ(ierr); 814222ddf1SHong Zhang ierr = MatProductSymbolic(AP);CHKERRQ(ierr); 824222ddf1SHong Zhang 834222ddf1SHong Zhang /* C = P^T*AP */ 844222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_AtB);CHKERRQ(ierr); 857a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 864222ddf1SHong Zhang product->A = P; 874222ddf1SHong Zhang product->B = AP; 884222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 894222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 904222ddf1SHong Zhang 914222ddf1SHong Zhang /* resume user's original input matrix setting for A and B */ 924222ddf1SHong Zhang product->A = A; 934222ddf1SHong Zhang product->B = P; 944222ddf1SHong Zhang product->Dwork = AP; 954222ddf1SHong Zhang 964222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_PtAP_Basic; 974222ddf1SHong Zhang PetscFunctionReturn(0); 984222ddf1SHong Zhang } 994222ddf1SHong Zhang 1004222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_RARt_Basic(Mat C) 1014222ddf1SHong Zhang { 1024222ddf1SHong Zhang PetscErrorCode ierr; 1034222ddf1SHong Zhang Mat_Product *product = C->product; 1044222ddf1SHong Zhang Mat R=product->B,RA=product->Dwork; 1054222ddf1SHong Zhang 1064222ddf1SHong Zhang PetscFunctionBegin; 1074222ddf1SHong Zhang /* RA = R*A */ 1084222ddf1SHong Zhang ierr = MatProductNumeric(RA);CHKERRQ(ierr); 1094222ddf1SHong Zhang /* C = RA*R^T */ 1107a3c3d58SStefano Zampini if (!C->ops->mattransposemultnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Missing numeric stage"); 1117a3c3d58SStefano Zampini ierr = (*C->ops->mattransposemultnumeric)(RA,R,C);CHKERRQ(ierr); 1124222ddf1SHong Zhang PetscFunctionReturn(0); 1134222ddf1SHong Zhang } 1144222ddf1SHong Zhang 1154222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_RARt_Basic(Mat C) 1164222ddf1SHong Zhang { 1174222ddf1SHong Zhang PetscErrorCode ierr; 1184222ddf1SHong Zhang Mat_Product *product = C->product; 1194222ddf1SHong Zhang Mat A=product->A,R=product->B,RA; 1204222ddf1SHong Zhang PetscReal fill=product->fill; 1214222ddf1SHong Zhang 1224222ddf1SHong Zhang PetscFunctionBegin; 123*6718818eSStefano Zampini ierr = PetscInfo2((PetscObject)C,"for A %s, R %s is used\n",((PetscObject)product->A)->type_name,((PetscObject)product->B)->type_name);CHKERRQ(ierr); 1244222ddf1SHong Zhang /* RA = R*A */ 1254222ddf1SHong Zhang ierr = MatProductCreate(R,A,NULL,&RA);CHKERRQ(ierr); 1264222ddf1SHong Zhang ierr = MatProductSetType(RA,MATPRODUCT_AB);CHKERRQ(ierr); 1277a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(RA,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1284222ddf1SHong Zhang ierr = MatProductSetFill(RA,fill);CHKERRQ(ierr); 1294222ddf1SHong Zhang ierr = MatProductSetFromOptions(RA);CHKERRQ(ierr); 1304222ddf1SHong Zhang ierr = MatProductSymbolic(RA);CHKERRQ(ierr); 1314222ddf1SHong Zhang 1324222ddf1SHong Zhang /* C = RA*R^T */ 1334222ddf1SHong Zhang ierr = MatProductSetType(C,MATPRODUCT_ABt);CHKERRQ(ierr); 1347a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1354222ddf1SHong Zhang product->A = RA; 1364222ddf1SHong Zhang ierr = MatProductSetFromOptions(C);CHKERRQ(ierr); 1374222ddf1SHong Zhang ierr = MatProductSymbolic(C);CHKERRQ(ierr); 1384222ddf1SHong Zhang 1394222ddf1SHong Zhang /* resume user's original input matrix setting for A */ 1404222ddf1SHong Zhang product->A = A; 1414222ddf1SHong Zhang product->Dwork = RA; /* save here so it will be destroyed with product C */ 1424222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_Basic; 1434222ddf1SHong Zhang PetscFunctionReturn(0); 1444222ddf1SHong Zhang } 1454222ddf1SHong Zhang 1464222ddf1SHong Zhang static PetscErrorCode MatProductNumeric_ABC_Basic(Mat mat) 1474222ddf1SHong Zhang { 1484222ddf1SHong Zhang PetscErrorCode ierr; 1494222ddf1SHong Zhang Mat_Product *product = mat->product; 1504222ddf1SHong Zhang Mat A=product->A,BC=product->Dwork; 1514222ddf1SHong Zhang 1524222ddf1SHong Zhang PetscFunctionBegin; 1534222ddf1SHong Zhang /* Numeric BC = B*C */ 1544222ddf1SHong Zhang ierr = MatProductNumeric(BC);CHKERRQ(ierr); 1554222ddf1SHong Zhang /* Numeric mat = A*BC */ 1567a3c3d58SStefano Zampini if (!mat->ops->transposematmultnumeric) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric stage"); 1577a3c3d58SStefano Zampini ierr = (*mat->ops->matmultnumeric)(A,BC,mat);CHKERRQ(ierr); 1584222ddf1SHong Zhang PetscFunctionReturn(0); 1594222ddf1SHong Zhang } 1604222ddf1SHong Zhang 1614222ddf1SHong Zhang static PetscErrorCode MatProductSymbolic_ABC_Basic(Mat mat) 1624222ddf1SHong Zhang { 1634222ddf1SHong Zhang PetscErrorCode ierr; 1644222ddf1SHong Zhang Mat_Product *product = mat->product; 1654222ddf1SHong Zhang Mat B=product->B,C=product->C,BC; 1664222ddf1SHong Zhang PetscReal fill=product->fill; 1674222ddf1SHong Zhang 1684222ddf1SHong Zhang PetscFunctionBegin; 169*6718818eSStefano Zampini ierr = PetscInfo3((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); 1704222ddf1SHong Zhang /* Symbolic BC = B*C */ 1714222ddf1SHong Zhang ierr = MatProductCreate(B,C,NULL,&BC);CHKERRQ(ierr); 1724222ddf1SHong Zhang ierr = MatProductSetType(BC,MATPRODUCT_AB);CHKERRQ(ierr); 1737a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(BC,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1744222ddf1SHong Zhang ierr = MatProductSetFill(BC,fill);CHKERRQ(ierr); 1754222ddf1SHong Zhang ierr = MatProductSetFromOptions(BC);CHKERRQ(ierr); 1764222ddf1SHong Zhang ierr = MatProductSymbolic(BC);CHKERRQ(ierr); 1774222ddf1SHong Zhang 1784222ddf1SHong Zhang /* Symbolic mat = A*BC */ 1794222ddf1SHong Zhang ierr = MatProductSetType(mat,MATPRODUCT_AB);CHKERRQ(ierr); 1807a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(mat,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 1814222ddf1SHong Zhang product->B = BC; 1824222ddf1SHong Zhang product->Dwork = BC; 1834222ddf1SHong Zhang ierr = MatProductSetFromOptions(mat);CHKERRQ(ierr); 1844222ddf1SHong Zhang ierr = MatProductSymbolic(mat);CHKERRQ(ierr); 1854222ddf1SHong Zhang 1864222ddf1SHong Zhang /* resume user's original input matrix setting for B */ 1874222ddf1SHong Zhang product->B = B; 1884222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC_Basic; 1894222ddf1SHong Zhang PetscFunctionReturn(0); 1904222ddf1SHong Zhang } 1914222ddf1SHong Zhang 192*6718818eSStefano Zampini static PetscErrorCode MatProductSymbolic_Basic(Mat mat) 1934222ddf1SHong Zhang { 1944222ddf1SHong Zhang PetscErrorCode ierr; 1954222ddf1SHong Zhang Mat_Product *product = mat->product; 1964222ddf1SHong Zhang 1974222ddf1SHong Zhang PetscFunctionBegin; 1984222ddf1SHong Zhang switch (product->type) { 1994222ddf1SHong Zhang case MATPRODUCT_PtAP: 2004222ddf1SHong Zhang ierr = MatProductSymbolic_PtAP_Basic(mat);CHKERRQ(ierr); 2014222ddf1SHong Zhang break; 2024222ddf1SHong Zhang case MATPRODUCT_RARt: 2034222ddf1SHong Zhang ierr = MatProductSymbolic_RARt_Basic(mat);CHKERRQ(ierr); 2044222ddf1SHong Zhang break; 2054222ddf1SHong Zhang case MATPRODUCT_ABC: 2064222ddf1SHong Zhang ierr = MatProductSymbolic_ABC_Basic(mat);CHKERRQ(ierr); 2074222ddf1SHong Zhang break; 208*6718818eSStefano Zampini default: SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[product->type]); 2094222ddf1SHong Zhang } 2104222ddf1SHong Zhang PetscFunctionReturn(0); 2114222ddf1SHong Zhang } 2124222ddf1SHong Zhang 2134222ddf1SHong Zhang /* ----------------------------------------------- */ 2144222ddf1SHong Zhang /*@C 2154222ddf1SHong Zhang MatProductReplaceMats - Replace input matrices for a matrix product. 2164222ddf1SHong Zhang 2174222ddf1SHong Zhang Collective on Mat 2184222ddf1SHong Zhang 2194222ddf1SHong Zhang Input Parameters: 2204222ddf1SHong Zhang + A - the matrix or NULL if not being replaced 2214222ddf1SHong Zhang . B - the matrix or NULL if not being replaced 2224222ddf1SHong Zhang . C - the matrix or NULL if not being replaced 2234222ddf1SHong Zhang - D - the matrix product 2244222ddf1SHong Zhang 2254222ddf1SHong Zhang Level: intermediate 2264222ddf1SHong Zhang 2274222ddf1SHong Zhang Notes: 228*6718818eSStefano Zampini To reuse the symbolic phase, input matrices must have exactly the same data structure as the replaced one. 229*6718818eSStefano Zampini If the type of any of the input matrices is different than what previously used, the product is cleared and MatProductSetFromOptions()/MatProductSymbolic() are invoked again. 2304222ddf1SHong Zhang 231*6718818eSStefano Zampini .seealso: MatProductCreate(), MatProductSetFromOptions(), MatProductSymbolic(). MatProductClear() 2324222ddf1SHong Zhang @*/ 2334222ddf1SHong Zhang PetscErrorCode MatProductReplaceMats(Mat A,Mat B,Mat C,Mat D) 2344222ddf1SHong Zhang { 2354417c5e8SHong Zhang PetscErrorCode ierr; 236*6718818eSStefano Zampini Mat_Product *product; 237*6718818eSStefano Zampini PetscBool flgA = PETSC_TRUE,flgB = PETSC_TRUE,flgC = PETSC_TRUE; 2384222ddf1SHong Zhang 2394222ddf1SHong Zhang PetscFunctionBegin; 2407a3c3d58SStefano Zampini PetscValidHeaderSpecific(D,MAT_CLASSID,4); 241*6718818eSStefano Zampini MatCheckProduct(D,4); 242*6718818eSStefano Zampini product = D->product; 2434222ddf1SHong Zhang if (A) { 2447a3c3d58SStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 245*6718818eSStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 246*6718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)product->A,((PetscObject)A)->type_name,&flgA);CHKERRQ(ierr); 247*6718818eSStefano Zampini ierr = MatDestroy(&product->A);CHKERRQ(ierr); 2484222ddf1SHong Zhang product->A = A; 2494222ddf1SHong Zhang } 2504222ddf1SHong Zhang if (B) { 2517a3c3d58SStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,2); 252*6718818eSStefano Zampini ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 253*6718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)product->B,((PetscObject)B)->type_name,&flgB);CHKERRQ(ierr); 254*6718818eSStefano Zampini ierr = MatDestroy(&product->B);CHKERRQ(ierr); 2554222ddf1SHong Zhang product->B = B; 2564222ddf1SHong Zhang } 2574417c5e8SHong Zhang if (C) { 2587a3c3d58SStefano Zampini PetscValidHeaderSpecific(C,MAT_CLASSID,3); 259*6718818eSStefano Zampini ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); 260*6718818eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)product->C,((PetscObject)C)->type_name,&flgC);CHKERRQ(ierr); 261*6718818eSStefano Zampini ierr = MatDestroy(&product->C);CHKERRQ(ierr); 2624417c5e8SHong Zhang product->C = C; 2634417c5e8SHong Zhang } 264*6718818eSStefano Zampini /* Any of the replaced mats is of a different type, reset */ 265*6718818eSStefano Zampini if (!flgA || !flgB || !flgC) { 266*6718818eSStefano Zampini if (D->product->destroy) { 267*6718818eSStefano Zampini ierr = (*D->product->destroy)(D->product->data);CHKERRQ(ierr); 268*6718818eSStefano Zampini } 269*6718818eSStefano Zampini D->product->destroy = NULL; 270*6718818eSStefano Zampini D->product->data = NULL; 271*6718818eSStefano Zampini if (D->ops->productnumeric || D->ops->productsymbolic) { 272*6718818eSStefano Zampini ierr = MatProductSetFromOptions(D);CHKERRQ(ierr); 273*6718818eSStefano Zampini ierr = MatProductSymbolic(D);CHKERRQ(ierr); 274*6718818eSStefano Zampini } 275*6718818eSStefano Zampini } 2764222ddf1SHong Zhang PetscFunctionReturn(0); 2774222ddf1SHong Zhang } 2784222ddf1SHong Zhang 2797a3c3d58SStefano Zampini static PetscErrorCode MatProductNumeric_X_Dense(Mat C) 2807a3c3d58SStefano Zampini { 2817a3c3d58SStefano Zampini PetscErrorCode ierr; 2827a3c3d58SStefano Zampini Mat_Product *product = C->product; 2837a3c3d58SStefano Zampini Mat A = product->A, B = product->B; 2847a3c3d58SStefano Zampini PetscInt k, K = B->cmap->N; 2857a3c3d58SStefano Zampini PetscBool t = PETSC_TRUE,iscuda = PETSC_FALSE; 2867a3c3d58SStefano Zampini PetscBool Bcpu = PETSC_TRUE, Ccpu = PETSC_TRUE; 2877a3c3d58SStefano Zampini char *Btype = NULL,*Ctype = NULL; 2887a3c3d58SStefano Zampini 2897a3c3d58SStefano Zampini PetscFunctionBegin; 2907a3c3d58SStefano Zampini switch (product->type) { 2917a3c3d58SStefano Zampini case MATPRODUCT_AB: 2927a3c3d58SStefano Zampini t = PETSC_FALSE; 2937a3c3d58SStefano Zampini case MATPRODUCT_AtB: 2947a3c3d58SStefano Zampini break; 2957a3c3d58SStefano Zampini default: SETERRQ3(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProductNumeric type %s not supported for %s and %s matrices",MatProductTypes[product->type],((PetscObject)A)->type_name,((PetscObject)B)->type_name); 2967a3c3d58SStefano Zampini } 2977a3c3d58SStefano Zampini if (PetscDefined(HAVE_CUDA)) { 2987a3c3d58SStefano Zampini VecType vtype; 2997a3c3d58SStefano Zampini 3007a3c3d58SStefano Zampini ierr = MatGetVecType(A,&vtype);CHKERRQ(ierr); 3017a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECCUDA,&iscuda);CHKERRQ(ierr); 3027a3c3d58SStefano Zampini if (!iscuda) { 3037a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECSEQCUDA,&iscuda);CHKERRQ(ierr); 3047a3c3d58SStefano Zampini } 3057a3c3d58SStefano Zampini if (!iscuda) { 3067a3c3d58SStefano Zampini ierr = PetscStrcmp(vtype,VECMPICUDA,&iscuda);CHKERRQ(ierr); 3077a3c3d58SStefano Zampini } 3087a3c3d58SStefano Zampini if (iscuda) { /* Make sure we have up-to-date data on the GPU */ 3097a3c3d58SStefano Zampini ierr = PetscStrallocpy(((PetscObject)B)->type_name,&Btype);CHKERRQ(ierr); 3107a3c3d58SStefano Zampini ierr = PetscStrallocpy(((PetscObject)C)->type_name,&Ctype);CHKERRQ(ierr); 3117a3c3d58SStefano Zampini ierr = MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 3127a3c3d58SStefano Zampini if (!C->assembled) { /* need to flag the matrix as assembled, otherwise MatConvert will complain */ 3137a3c3d58SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3147a3c3d58SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3157a3c3d58SStefano Zampini } 3167a3c3d58SStefano Zampini ierr = MatConvert(C,MATDENSECUDA,MAT_INPLACE_MATRIX,&C);CHKERRQ(ierr); 3177a3c3d58SStefano Zampini } else { /* Make sure we have up-to-date data on the CPU */ 3187a3c3d58SStefano Zampini #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL) 3197a3c3d58SStefano Zampini Bcpu = B->boundtocpu; 3207a3c3d58SStefano Zampini Ccpu = C->boundtocpu; 3217a3c3d58SStefano Zampini #endif 3227a3c3d58SStefano Zampini ierr = MatBindToCPU(B,PETSC_TRUE);CHKERRQ(ierr); 3237a3c3d58SStefano Zampini ierr = MatBindToCPU(C,PETSC_TRUE);CHKERRQ(ierr); 3247a3c3d58SStefano Zampini } 3257a3c3d58SStefano Zampini } 3267a3c3d58SStefano Zampini for (k=0;k<K;k++) { 3277a3c3d58SStefano Zampini Vec x,y; 3287a3c3d58SStefano Zampini 3297a3c3d58SStefano Zampini ierr = MatDenseGetColumnVecRead(B,k,&x);CHKERRQ(ierr); 3307a3c3d58SStefano Zampini ierr = MatDenseGetColumnVecWrite(C,k,&y);CHKERRQ(ierr); 3317a3c3d58SStefano Zampini if (t) { 3327a3c3d58SStefano Zampini ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 3337a3c3d58SStefano Zampini } else { 3347a3c3d58SStefano Zampini ierr = MatMult(A,x,y);CHKERRQ(ierr); 3357a3c3d58SStefano Zampini } 3367a3c3d58SStefano Zampini ierr = MatDenseRestoreColumnVecRead(B,k,&x);CHKERRQ(ierr); 3377a3c3d58SStefano Zampini ierr = MatDenseRestoreColumnVecWrite(C,k,&y);CHKERRQ(ierr); 3387a3c3d58SStefano Zampini } 3397a3c3d58SStefano Zampini ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3407a3c3d58SStefano Zampini ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3417a3c3d58SStefano Zampini if (PetscDefined(HAVE_CUDA)) { 3427a3c3d58SStefano Zampini if (iscuda) { 3437a3c3d58SStefano Zampini ierr = MatConvert(B,Btype,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 3447a3c3d58SStefano Zampini ierr = MatConvert(C,Ctype,MAT_INPLACE_MATRIX,&C);CHKERRQ(ierr); 3457a3c3d58SStefano Zampini } else { 3467a3c3d58SStefano Zampini ierr = MatBindToCPU(B,Bcpu);CHKERRQ(ierr); 3477a3c3d58SStefano Zampini ierr = MatBindToCPU(C,Ccpu);CHKERRQ(ierr); 3487a3c3d58SStefano Zampini } 3497a3c3d58SStefano Zampini } 3507a3c3d58SStefano Zampini ierr = PetscFree(Btype);CHKERRQ(ierr); 3517a3c3d58SStefano Zampini ierr = PetscFree(Ctype);CHKERRQ(ierr); 3527a3c3d58SStefano Zampini PetscFunctionReturn(0); 3537a3c3d58SStefano Zampini } 3547a3c3d58SStefano Zampini 3557a3c3d58SStefano Zampini static PetscErrorCode MatProductSymbolic_X_Dense(Mat C) 3567a3c3d58SStefano Zampini { 3577a3c3d58SStefano Zampini PetscErrorCode ierr; 3587a3c3d58SStefano Zampini Mat_Product *product = C->product; 3597a3c3d58SStefano Zampini Mat A = product->A, B = product->B; 3607a3c3d58SStefano Zampini PetscBool isdense; 3617a3c3d58SStefano Zampini 3627a3c3d58SStefano Zampini PetscFunctionBegin; 3637a3c3d58SStefano Zampini switch (product->type) { 3647a3c3d58SStefano Zampini case MATPRODUCT_AB: 3657a3c3d58SStefano Zampini ierr = MatSetSizes(C,A->rmap->n,B->cmap->n,A->rmap->N,B->cmap->N);CHKERRQ(ierr); 3667a3c3d58SStefano Zampini break; 3677a3c3d58SStefano Zampini case MATPRODUCT_AtB: 3687a3c3d58SStefano Zampini ierr = MatSetSizes(C,A->cmap->n,B->cmap->n,A->cmap->N,B->cmap->N);CHKERRQ(ierr); 3697a3c3d58SStefano Zampini break; 3707a3c3d58SStefano Zampini default: SETERRQ3(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProductSymbolic type %s not supported for %s and %s matrices",MatProductTypes[product->type],((PetscObject)A)->type_name,((PetscObject)B)->type_name); 3717a3c3d58SStefano Zampini } 3727a3c3d58SStefano Zampini ierr = PetscObjectBaseTypeCompareAny((PetscObject)C,&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 3737a3c3d58SStefano Zampini if (!isdense) { 3747a3c3d58SStefano Zampini ierr = MatSetType(C,((PetscObject)B)->type_name);CHKERRQ(ierr); 375*6718818eSStefano Zampini /* If matrix type of C was not set or not dense, we need to reset the pointer */ 3767a3c3d58SStefano Zampini C->ops->productsymbolic = MatProductSymbolic_X_Dense; 3777a3c3d58SStefano Zampini } 378*6718818eSStefano Zampini C->ops->productnumeric = MatProductNumeric_X_Dense; 3797a3c3d58SStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 3807a3c3d58SStefano Zampini PetscFunctionReturn(0); 3817a3c3d58SStefano Zampini } 3827a3c3d58SStefano Zampini 383*6718818eSStefano Zampini /* a single driver to query the dispatching */ 384*6718818eSStefano Zampini static PetscErrorCode MatProductSetFromOptions_Private(Mat mat) 3854222ddf1SHong Zhang { 3864222ddf1SHong Zhang PetscErrorCode ierr; 3874222ddf1SHong Zhang Mat_Product *product = mat->product; 388*6718818eSStefano Zampini PetscInt Am,An,Bm,Bn,Cm,Cn; 3894222ddf1SHong Zhang Mat A = product->A,B = product->B,C = product->C; 390*6718818eSStefano Zampini const char* const Bnames[] = { "B", "R", "P" }; 391*6718818eSStefano Zampini const char* bname; 3924222ddf1SHong Zhang PetscErrorCode (*fA)(Mat); 3934222ddf1SHong Zhang PetscErrorCode (*fB)(Mat); 3944222ddf1SHong Zhang PetscErrorCode (*fC)(Mat); 3954222ddf1SHong Zhang PetscErrorCode (*f)(Mat)=NULL; 3964222ddf1SHong Zhang 3974222ddf1SHong Zhang PetscFunctionBegin; 398*6718818eSStefano Zampini mat->ops->productsymbolic = NULL; 399*6718818eSStefano Zampini mat->ops->productnumeric = NULL; 400*6718818eSStefano Zampini if (product->type == MATPRODUCT_UNSPECIFIED) PetscFunctionReturn(0); 401*6718818eSStefano Zampini if (product->type != MATPRODUCT_ABC) C = NULL; /* do not use C if not needed */ 402*6718818eSStefano Zampini if (product->type == MATPRODUCT_RARt) bname = Bnames[1]; 403*6718818eSStefano Zampini else if (product->type == MATPRODUCT_PtAP) bname = Bnames[2]; 404*6718818eSStefano Zampini else bname = Bnames[0]; 405*6718818eSStefano Zampini 406*6718818eSStefano Zampini /* Check matrices sizes */ 407*6718818eSStefano Zampini Am = A->rmap->N; 408*6718818eSStefano Zampini An = A->cmap->N; 409*6718818eSStefano Zampini Bm = B->rmap->N; 410*6718818eSStefano Zampini Bn = B->cmap->N; 411*6718818eSStefano Zampini Cm = C ? C->rmap->N : 0; 412*6718818eSStefano Zampini Cn = C ? C->cmap->N : 0; 413*6718818eSStefano Zampini if (product->type == MATPRODUCT_RARt || product->type == MATPRODUCT_ABt) { PetscInt t = Bn; Bn = Bm; Bm = t; } 414*6718818eSStefano Zampini if (product->type == MATPRODUCT_AtB) { PetscInt t = An; An = Am; Am = t; } 415*6718818eSStefano Zampini if (An != Bm) SETERRQ7(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Matrix dimensions of A and %s are incompatible for MatProductType %s: A %Dx%D, %s %Dx%D",bname,MatProductTypes[product->type],A->rmap->N,A->cmap->N,bname,B->rmap->N,B->cmap->N); 416*6718818eSStefano Zampini if (Cm && Cm != Bn) SETERRQ5(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Matrix dimensions of B and C are incompatible for MatProductType %s: B %Dx%D, C %Dx%D",MatProductTypes[product->type],B->rmap->N,B->cmap->N,Cm,Cn); 4174222ddf1SHong Zhang 4184222ddf1SHong Zhang fA = A->ops->productsetfromoptions; 4194222ddf1SHong Zhang fB = B->ops->productsetfromoptions; 420*6718818eSStefano Zampini fC = C ? C->ops->productsetfromoptions : fA; 421*6718818eSStefano Zampini if (C) { 422*6718818eSStefano Zampini ierr = PetscInfo5(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); 423*6718818eSStefano Zampini } else { 424*6718818eSStefano Zampini ierr = PetscInfo4(mat,"MatProductType %s for A %s, %s %s\n",MatProductTypes[product->type],((PetscObject)A)->type_name,bname,((PetscObject)B)->type_name);CHKERRQ(ierr); 425*6718818eSStefano Zampini } 4264222ddf1SHong Zhang if (fA == fB && fA == fC && fA) { 4276896283bSStefano Zampini ierr = PetscInfo(mat," matching op\n");CHKERRQ(ierr); 428*6718818eSStefano Zampini ierr = (*fA)(mat);CHKERRQ(ierr); 4294222ddf1SHong Zhang } else { 4304222ddf1SHong Zhang /* query MatProductSetFromOptions_Atype_Btype_Ctype */ 4314222ddf1SHong Zhang char mtypes[256]; 4324222ddf1SHong Zhang ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_",sizeof(mtypes));CHKERRQ(ierr); 4334222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)A)->type_name,sizeof(mtypes));CHKERRQ(ierr); 4344222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4354222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)B)->type_name,sizeof(mtypes));CHKERRQ(ierr); 436*6718818eSStefano Zampini if (C) { 4374222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_",sizeof(mtypes));CHKERRQ(ierr); 4384222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,((PetscObject)C)->type_name,sizeof(mtypes));CHKERRQ(ierr); 439*6718818eSStefano Zampini } 4404222ddf1SHong Zhang ierr = PetscStrlcat(mtypes,"_C",sizeof(mtypes));CHKERRQ(ierr); 4414222ddf1SHong Zhang 4424222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 443*6718818eSStefano Zampini ierr = PetscInfo2(mat," querying %s from A? %p\n",mtypes,f);CHKERRQ(ierr); 4444222ddf1SHong Zhang if (!f) { 4454222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 446*6718818eSStefano Zampini ierr = PetscInfo3(mat," querying %s from %s? %p\n",mtypes,bname,f);CHKERRQ(ierr); 4474222ddf1SHong Zhang } 448*6718818eSStefano Zampini if (!f && C) { 4494222ddf1SHong Zhang ierr = PetscObjectQueryFunction((PetscObject)C,mtypes,&f);CHKERRQ(ierr); 450*6718818eSStefano Zampini ierr = PetscInfo2(mat," querying %s from C? %p\n",mtypes,f);CHKERRQ(ierr); 4514222ddf1SHong Zhang } 452*6718818eSStefano Zampini if (f) { ierr = (*f)(mat);CHKERRQ(ierr); } 453*6718818eSStefano Zampini 454*6718818eSStefano Zampini /* We may have found f but it did not succeed */ 455*6718818eSStefano Zampini /* some matrices (i.e. MATTRANSPOSE, MATSHELL constructed from MatConvert), knows what to do with their inner matrices */ 456*6718818eSStefano Zampini if (!mat->ops->productsymbolic) { 457*6718818eSStefano Zampini ierr = PetscStrncpy(mtypes,"MatProductSetFromOptions_anytype_C",sizeof(mtypes));CHKERRQ(ierr); 458*6718818eSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)A,mtypes,&f);CHKERRQ(ierr); 459*6718818eSStefano Zampini ierr = PetscInfo2(mat," querying %s from A? %p\n",mtypes,f);CHKERRQ(ierr); 460*6718818eSStefano Zampini if (!f) { 461*6718818eSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)B,mtypes,&f);CHKERRQ(ierr); 462*6718818eSStefano Zampini ierr = PetscInfo3(mat," querying %s from %s? %p\n",mtypes,bname,f);CHKERRQ(ierr); 463*6718818eSStefano Zampini } 464*6718818eSStefano Zampini if (!f && C) { 465*6718818eSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)C,mtypes,&f);CHKERRQ(ierr); 466*6718818eSStefano Zampini ierr = PetscInfo2(mat," querying %s from C? %p\n",mtypes,f);CHKERRQ(ierr); 467*6718818eSStefano Zampini } 468*6718818eSStefano Zampini } 469*6718818eSStefano Zampini if (f) { ierr = (*f)(mat);CHKERRQ(ierr); } 4704222ddf1SHong Zhang } 4714222ddf1SHong Zhang 472*6718818eSStefano Zampini /* We may have found f but it did not succeed */ 473*6718818eSStefano Zampini if (!mat->ops->productsymbolic) { 474*6718818eSStefano Zampini /* we can still compute the product if B is of type dense */ 475*6718818eSStefano Zampini if (product->type == MATPRODUCT_AB || product->type == MATPRODUCT_AtB) { 476*6718818eSStefano Zampini PetscBool isdense; 477*6718818eSStefano Zampini 478*6718818eSStefano Zampini ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&isdense,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 479*6718818eSStefano Zampini if (isdense) { 480*6718818eSStefano Zampini 481*6718818eSStefano Zampini mat->ops->productsymbolic = MatProductSymbolic_X_Dense; 482*6718818eSStefano Zampini ierr = PetscInfo(mat," using basic looping over columns of a dense matrix\n");CHKERRQ(ierr); 483*6718818eSStefano Zampini } 484*6718818eSStefano Zampini } else if (product->type != MATPRODUCT_ABt) { /* use MatProductSymbolic/Numeric_Basic() for triple products only */ 485*6718818eSStefano Zampini /* 486*6718818eSStefano Zampini TODO: this should be changed to a proper setfromoptions, not setting the symbolic pointer here, because we do not know if 487*6718818eSStefano Zampini the compination will succeed. In order to be sure, we need MatProductGetProductType to return the type of the result 488*6718818eSStefano Zampini before computing the symbolic phase 489*6718818eSStefano Zampini */ 490*6718818eSStefano Zampini ierr = PetscInfo(mat," symbolic product not supported, using MatProductSymbolic_Basic() implementation\n");CHKERRQ(ierr); 4914222ddf1SHong Zhang mat->ops->productsymbolic = MatProductSymbolic_Basic; 4924222ddf1SHong Zhang } 493*6718818eSStefano Zampini } 494*6718818eSStefano Zampini if (!mat->ops->productsymbolic) { 495*6718818eSStefano Zampini ierr = PetscInfo(mat," symbolic product is not supported\n");CHKERRQ(ierr); 496*6718818eSStefano Zampini } 4974222ddf1SHong Zhang PetscFunctionReturn(0); 4984222ddf1SHong Zhang } 4994222ddf1SHong Zhang 5004222ddf1SHong Zhang /*@C 5014222ddf1SHong Zhang MatProductSetFromOptions - Creates a matrix product where the type, the algorithm etc are determined from the options database. 5024222ddf1SHong Zhang 5034222ddf1SHong Zhang Logically Collective on Mat 5044222ddf1SHong Zhang 5054222ddf1SHong Zhang Input Parameter: 5064222ddf1SHong Zhang . mat - the matrix 5074222ddf1SHong Zhang 508*6718818eSStefano Zampini Options Database Keys: 509*6718818eSStefano Zampini . -mat_product_clear - Clear intermediate data structures after MatProductNumeric() has been called 5104222ddf1SHong Zhang 511*6718818eSStefano Zampini Level: intermediate 512*6718818eSStefano Zampini 513*6718818eSStefano Zampini .seealso: MatSetFromOptions(), MatProductCreate(), MatProductCreateWithMat() 5144222ddf1SHong Zhang @*/ 5154222ddf1SHong Zhang PetscErrorCode MatProductSetFromOptions(Mat mat) 5164222ddf1SHong Zhang { 5174222ddf1SHong Zhang PetscErrorCode ierr; 5184222ddf1SHong Zhang 5194222ddf1SHong Zhang PetscFunctionBegin; 5204222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 521*6718818eSStefano Zampini MatCheckProduct(mat,1); 522*6718818eSStefano Zampini if (mat->product->data) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Cannot call MatProductSetFromOptions with already present data"); 523*6718818eSStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)mat);CHKERRQ(ierr); 524*6718818eSStefano 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); 525*6718818eSStefano Zampini ierr = PetscOptionsDeprecated("-mat_freeintermediatedatastructures","-mat_product_clear","3.13","Or call MatProductClear() after MatProductNumeric()");CHKERRQ(ierr); 526*6718818eSStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 527*6718818eSStefano Zampini ierr = MatProductSetFromOptions_Private(mat);CHKERRQ(ierr); 528*6718818eSStefano Zampini if (!mat->product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing product after setup phase"); 529*6718818eSStefano Zampini PetscFunctionReturn(0); 530*6718818eSStefano Zampini } 531*6718818eSStefano Zampini 532*6718818eSStefano Zampini /*@C 533*6718818eSStefano Zampini MatProductView - View a MatProduct 534*6718818eSStefano Zampini 535*6718818eSStefano Zampini Logically Collective on Mat 536*6718818eSStefano Zampini 537*6718818eSStefano Zampini Input Parameter: 538*6718818eSStefano Zampini . mat - the matrix obtained with MatProductCreate() or MatProductCreateWithMat() 539*6718818eSStefano Zampini 540*6718818eSStefano Zampini Level: intermediate 541*6718818eSStefano Zampini 542*6718818eSStefano Zampini .seealso: MatView(), MatProductCreate(), MatProductCreateWithMat() 543*6718818eSStefano Zampini @*/ 544*6718818eSStefano Zampini PetscErrorCode MatProductView(Mat mat, PetscViewer viewer) 545*6718818eSStefano Zampini { 546*6718818eSStefano Zampini PetscErrorCode ierr; 547*6718818eSStefano Zampini 548*6718818eSStefano Zampini PetscFunctionBegin; 549*6718818eSStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 550*6718818eSStefano Zampini if (!mat->product) PetscFunctionReturn(0); 551*6718818eSStefano Zampini if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr);} 552*6718818eSStefano Zampini PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 553*6718818eSStefano Zampini PetscCheckSameComm(mat,1,viewer,2); 554*6718818eSStefano Zampini if (mat->product->view) { 555*6718818eSStefano Zampini ierr = (*mat->product->view)(mat,viewer);CHKERRQ(ierr); 556*6718818eSStefano Zampini } 5574222ddf1SHong Zhang PetscFunctionReturn(0); 5584222ddf1SHong Zhang } 5594222ddf1SHong Zhang 5604222ddf1SHong Zhang /* ----------------------------------------------- */ 561*6718818eSStefano Zampini /* these are basic implementations relying on the old function pointers 562*6718818eSStefano Zampini * they are dangerous and should be removed in the future */ 5634222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AB(Mat mat) 5644222ddf1SHong Zhang { 5654222ddf1SHong Zhang PetscErrorCode ierr; 5664222ddf1SHong Zhang Mat_Product *product = mat->product; 5674222ddf1SHong Zhang Mat A=product->A,B=product->B; 5684222ddf1SHong Zhang 5694222ddf1SHong Zhang PetscFunctionBegin; 5707a3c3d58SStefano Zampini if (!mat->ops->matmultnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 5714222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 5727a3c3d58SStefano Zampini ierr = (*mat->ops->matmultnumeric)(A,B,mat);CHKERRQ(ierr); 5734222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 5744222ddf1SHong Zhang PetscFunctionReturn(0); 5754222ddf1SHong Zhang } 5764222ddf1SHong Zhang 5774222ddf1SHong Zhang PetscErrorCode MatProductNumeric_AtB(Mat mat) 5784222ddf1SHong Zhang { 5794222ddf1SHong Zhang PetscErrorCode ierr; 5804222ddf1SHong Zhang Mat_Product *product = mat->product; 5814222ddf1SHong Zhang Mat A=product->A,B=product->B; 5824222ddf1SHong Zhang 5834222ddf1SHong Zhang PetscFunctionBegin; 5847a3c3d58SStefano Zampini if (!mat->ops->transposematmultnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 5854222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 5867a3c3d58SStefano Zampini ierr = (*mat->ops->transposematmultnumeric)(A,B,mat);CHKERRQ(ierr); 5874222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 5884222ddf1SHong Zhang PetscFunctionReturn(0); 5894222ddf1SHong Zhang } 5904222ddf1SHong Zhang 5914222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABt(Mat mat) 5924222ddf1SHong Zhang { 5934222ddf1SHong Zhang PetscErrorCode ierr; 5944222ddf1SHong Zhang Mat_Product *product = mat->product; 5954222ddf1SHong Zhang Mat A=product->A,B=product->B; 5964222ddf1SHong Zhang 5974222ddf1SHong Zhang PetscFunctionBegin; 5987a3c3d58SStefano Zampini if (!mat->ops->mattransposemultnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 5994222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 6007a3c3d58SStefano Zampini ierr = (*mat->ops->mattransposemultnumeric)(A,B,mat);CHKERRQ(ierr); 6014222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 6024222ddf1SHong Zhang PetscFunctionReturn(0); 6034222ddf1SHong Zhang } 6044222ddf1SHong Zhang 6054222ddf1SHong Zhang PetscErrorCode MatProductNumeric_PtAP(Mat mat) 6064222ddf1SHong Zhang { 6074222ddf1SHong Zhang PetscErrorCode ierr; 6084222ddf1SHong Zhang Mat_Product *product = mat->product; 6094222ddf1SHong Zhang Mat A=product->A,B=product->B; 6104222ddf1SHong Zhang 6114222ddf1SHong Zhang PetscFunctionBegin; 6127a3c3d58SStefano Zampini if (!mat->ops->ptapnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 6134222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 6147a3c3d58SStefano Zampini ierr = (*mat->ops->ptapnumeric)(A,B,mat);CHKERRQ(ierr); 6154222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_PtAPNumeric,mat,0,0,0);CHKERRQ(ierr); 6164222ddf1SHong Zhang PetscFunctionReturn(0); 6174222ddf1SHong Zhang } 6184222ddf1SHong Zhang 6194222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt(Mat mat) 6204222ddf1SHong Zhang { 6214222ddf1SHong Zhang PetscErrorCode ierr; 6224222ddf1SHong Zhang Mat_Product *product = mat->product; 6234222ddf1SHong Zhang Mat A=product->A,B=product->B; 6244222ddf1SHong Zhang 6254222ddf1SHong Zhang PetscFunctionBegin; 6267a3c3d58SStefano Zampini if (!mat->ops->rartnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 6274222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 6287a3c3d58SStefano Zampini ierr = (*mat->ops->rartnumeric)(A,B,mat);CHKERRQ(ierr); 6294222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_RARtNumeric,A,B,0,0);CHKERRQ(ierr); 6304222ddf1SHong Zhang PetscFunctionReturn(0); 6314222ddf1SHong Zhang } 6324222ddf1SHong Zhang 6334222ddf1SHong Zhang PetscErrorCode MatProductNumeric_ABC(Mat mat) 6344222ddf1SHong Zhang { 6354222ddf1SHong Zhang PetscErrorCode ierr; 6364222ddf1SHong Zhang Mat_Product *product = mat->product; 6374222ddf1SHong Zhang Mat A=product->A,B=product->B,C=product->C; 6384222ddf1SHong Zhang 6394222ddf1SHong Zhang PetscFunctionBegin; 6407a3c3d58SStefano Zampini if (!mat->ops->matmatmultnumeric) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing numeric implementation of product %s for mat %s",MatProductTypes[product->type],((PetscObject)mat)->type_name); 6414222ddf1SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 6427a3c3d58SStefano Zampini ierr = (*mat->ops->matmatmultnumeric)(A,B,C,mat);CHKERRQ(ierr); 6434222ddf1SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 6444222ddf1SHong Zhang PetscFunctionReturn(0); 6454222ddf1SHong Zhang } 6464222ddf1SHong Zhang 647*6718818eSStefano Zampini /* ----------------------------------------------- */ 648*6718818eSStefano Zampini 6494222ddf1SHong Zhang /*@ 6504222ddf1SHong Zhang MatProductNumeric - Implement a matrix product with numerical values. 6514222ddf1SHong Zhang 6524222ddf1SHong Zhang Collective on Mat 6534222ddf1SHong Zhang 654*6718818eSStefano Zampini Input/Output Parameter: 655*6718818eSStefano Zampini . mat - the matrix holding the product 6564222ddf1SHong Zhang 6574222ddf1SHong Zhang Level: intermediate 6584222ddf1SHong Zhang 659*6718818eSStefano Zampini Notes: MatProductSymbolic() must have been called on mat before calling this function 660*6718818eSStefano Zampini 661*6718818eSStefano Zampini .seealso: MatProductCreate(), MatSetType(), MatProductSymbolic() 6624222ddf1SHong Zhang @*/ 6634222ddf1SHong Zhang PetscErrorCode MatProductNumeric(Mat mat) 6644222ddf1SHong Zhang { 6654222ddf1SHong Zhang PetscErrorCode ierr; 6664222ddf1SHong Zhang 6674222ddf1SHong Zhang PetscFunctionBegin; 6684222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 669*6718818eSStefano Zampini MatCheckProduct(mat,1); 6704222ddf1SHong Zhang if (mat->ops->productnumeric) { 6714222ddf1SHong Zhang ierr = (*mat->ops->productnumeric)(mat);CHKERRQ(ierr); 6727a3c3d58SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Call MatProductSymbolic() first"); 673*6718818eSStefano Zampini if (!mat->product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing product after numeric phase"); 674*6718818eSStefano Zampini if (mat->product->clear) { 675*6718818eSStefano Zampini ierr = MatProductClear(mat);CHKERRQ(ierr); 676*6718818eSStefano Zampini } 6774222ddf1SHong Zhang PetscFunctionReturn(0); 6784222ddf1SHong Zhang } 6794222ddf1SHong Zhang 6804222ddf1SHong Zhang /* ----------------------------------------------- */ 681*6718818eSStefano Zampini /* these are basic implementations relying on the old function pointers 682*6718818eSStefano Zampini * they are dangerous and should be removed in the future */ 6834222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AB(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; 6907a3c3d58SStefano Zampini if (!mat->ops->matmultsymbolic) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 6917a3c3d58SStefano Zampini ierr = (*mat->ops->matmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 6924222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AB; 6934222ddf1SHong Zhang PetscFunctionReturn(0); 6944222ddf1SHong Zhang } 6954222ddf1SHong Zhang 6964222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_AtB(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; 7037a3c3d58SStefano Zampini if (!mat->ops->transposematmultsymbolic) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 7047a3c3d58SStefano Zampini ierr = (*mat->ops->transposematmultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7054222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_AtB; 7064222ddf1SHong Zhang PetscFunctionReturn(0); 7074222ddf1SHong Zhang } 7084222ddf1SHong Zhang 7094222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_ABt(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; 7167a3c3d58SStefano Zampini if (!mat->ops->mattransposemultsymbolic) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 7177a3c3d58SStefano Zampini ierr = (*mat->ops->mattransposemultsymbolic)(A,B,product->fill,mat);CHKERRQ(ierr); 7184222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABt; 7194222ddf1SHong Zhang PetscFunctionReturn(0); 7204222ddf1SHong Zhang } 7214222ddf1SHong Zhang 7224222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_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; 7297a3c3d58SStefano Zampini if (!mat->ops->matmatmultsymbolic) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing symbolic implementation of product %s",MatProductTypes[product->type]); 7307a3c3d58SStefano Zampini ierr = (*mat->ops->matmatmultsymbolic)(A,B,C,product->fill,mat);CHKERRQ(ierr); 7314222ddf1SHong Zhang mat->ops->productnumeric = MatProductNumeric_ABC; 7324222ddf1SHong Zhang PetscFunctionReturn(0); 7334222ddf1SHong Zhang } 7344222ddf1SHong Zhang 735*6718818eSStefano Zampini /* ----------------------------------------------- */ 736*6718818eSStefano Zampini 7374222ddf1SHong Zhang /*@ 7384222ddf1SHong Zhang MatProductSymbolic - Perform the symbolic portion of a matrix product, this creates a data structure for use with the numerical produce. 7394222ddf1SHong Zhang 7404222ddf1SHong Zhang Collective on Mat 7414222ddf1SHong Zhang 742*6718818eSStefano Zampini Input/Output Parameter: 7434222ddf1SHong Zhang . mat - the matrix to hold a product 7444222ddf1SHong Zhang 7454222ddf1SHong Zhang Level: intermediate 7464222ddf1SHong Zhang 747*6718818eSStefano Zampini Notes: MatProductSetFromOptions() must have been called on mat before calling this function 748*6718818eSStefano Zampini 749*6718818eSStefano Zampini .seealso: MatProductCreate(), MatProductCreateWithMat(), MatProductSetFromOptions(), MatProductNumeric(), MatProductSetType(), MatProductSetAlgorithm() 7504222ddf1SHong Zhang @*/ 7514222ddf1SHong Zhang PetscErrorCode MatProductSymbolic(Mat mat) 7524222ddf1SHong Zhang { 7534222ddf1SHong Zhang PetscErrorCode ierr; 7544222ddf1SHong Zhang PetscLogEvent eventtype=-1; 7554222ddf1SHong Zhang 7564222ddf1SHong Zhang PetscFunctionBegin; 7574222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 758*6718818eSStefano Zampini MatCheckProduct(mat,1); 759*6718818eSStefano Zampini if (mat->product->data) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Cannot run symbolic phase. Product data not empty"); 7604222ddf1SHong Zhang 7614222ddf1SHong Zhang /* log event */ 762*6718818eSStefano Zampini switch (mat->product->type) { 7634222ddf1SHong Zhang case MATPRODUCT_AB: 7644222ddf1SHong Zhang eventtype = MAT_MatMultSymbolic; 7654222ddf1SHong Zhang break; 7664222ddf1SHong Zhang case MATPRODUCT_AtB: 7674222ddf1SHong Zhang eventtype = MAT_TransposeMatMultSymbolic; 7684222ddf1SHong Zhang break; 7694222ddf1SHong Zhang case MATPRODUCT_ABt: 7704222ddf1SHong Zhang eventtype = MAT_MatTransposeMultSymbolic; 7714222ddf1SHong Zhang break; 7724222ddf1SHong Zhang case MATPRODUCT_PtAP: 7734222ddf1SHong Zhang eventtype = MAT_PtAPSymbolic; 7744222ddf1SHong Zhang break; 7754222ddf1SHong Zhang case MATPRODUCT_RARt: 7764222ddf1SHong Zhang eventtype = MAT_RARtSymbolic; 7774222ddf1SHong Zhang break; 7784222ddf1SHong Zhang case MATPRODUCT_ABC: 7794222ddf1SHong Zhang eventtype = MAT_MatMatMultSymbolic; 7804222ddf1SHong Zhang break; 781*6718818eSStefano Zampini default: SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"ProductType %s is not supported",MatProductTypes[mat->product->type]); 7824222ddf1SHong Zhang } 7834222ddf1SHong Zhang 784*6718818eSStefano Zampini mat->ops->productnumeric = NULL; 7854222ddf1SHong Zhang if (mat->ops->productsymbolic) { 7864222ddf1SHong Zhang ierr = PetscLogEventBegin(eventtype,mat,0,0,0);CHKERRQ(ierr); 7874222ddf1SHong Zhang ierr = (*mat->ops->productsymbolic)(mat);CHKERRQ(ierr); 7884222ddf1SHong Zhang ierr = PetscLogEventEnd(eventtype,mat,0,0,0);CHKERRQ(ierr); 7897a3c3d58SStefano Zampini } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Call MatProductSetFromOptions() first"); 790*6718818eSStefano Zampini if (!mat->product) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Missing product after symbolic phase"); 791*6718818eSStefano Zampini if (!mat->ops->productnumeric) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Symbolic phase did not specify the numeric phase"); 7924222ddf1SHong Zhang PetscFunctionReturn(0); 7934222ddf1SHong Zhang } 7944222ddf1SHong Zhang 7954222ddf1SHong Zhang /*@ 7964222ddf1SHong Zhang MatProductSetFill - Set an expected fill of the matrix product. 7974222ddf1SHong Zhang 7984222ddf1SHong Zhang Collective on Mat 7994222ddf1SHong Zhang 8004222ddf1SHong Zhang Input Parameters: 8014222ddf1SHong Zhang + mat - the matrix product 8024222ddf1SHong 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. 8034222ddf1SHong Zhang 8044222ddf1SHong Zhang Level: intermediate 8054222ddf1SHong Zhang 8064222ddf1SHong Zhang .seealso: MatProductSetType(), MatProductSetAlgorithm(), MatProductCreate() 8074222ddf1SHong Zhang @*/ 8084222ddf1SHong Zhang PetscErrorCode MatProductSetFill(Mat mat,PetscReal fill) 8094222ddf1SHong Zhang { 8104222ddf1SHong Zhang PetscFunctionBegin; 8114222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 812*6718818eSStefano Zampini MatCheckProduct(mat,1); 813*6718818eSStefano Zampini if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) mat->product->fill = 2.0; 814*6718818eSStefano Zampini else mat->product->fill = fill; 8154222ddf1SHong Zhang PetscFunctionReturn(0); 8164222ddf1SHong Zhang } 8174222ddf1SHong Zhang 8184222ddf1SHong Zhang /*@ 8194222ddf1SHong Zhang MatProductSetAlgorithm - Requests a particular algorithm for a matrix product implementation. 8204222ddf1SHong Zhang 8214222ddf1SHong Zhang Collective on Mat 8224222ddf1SHong Zhang 8234222ddf1SHong Zhang Input Parameters: 8244222ddf1SHong Zhang + mat - the matrix product 8254222ddf1SHong Zhang - alg - particular implementation algorithm of the matrix product, e.g., MATPRODUCTALGORITHM_DEFAULT. 8264222ddf1SHong Zhang 8274222ddf1SHong Zhang Level: intermediate 8284222ddf1SHong Zhang 829*6718818eSStefano Zampini .seealso: MatProductSetType(), MatProductSetFill(), MatProductCreate(), MatProductAlgorithm 8304222ddf1SHong Zhang @*/ 8314222ddf1SHong Zhang PetscErrorCode MatProductSetAlgorithm(Mat mat,MatProductAlgorithm alg) 8324222ddf1SHong Zhang { 8337a3c3d58SStefano Zampini PetscErrorCode ierr; 8344222ddf1SHong Zhang 8354222ddf1SHong Zhang PetscFunctionBegin; 8364222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 837*6718818eSStefano Zampini MatCheckProduct(mat,1); 838*6718818eSStefano Zampini ierr = PetscFree(mat->product->alg);CHKERRQ(ierr); 839*6718818eSStefano Zampini ierr = PetscStrallocpy(alg,&mat->product->alg);CHKERRQ(ierr); 8404222ddf1SHong Zhang PetscFunctionReturn(0); 8414222ddf1SHong Zhang } 8424222ddf1SHong Zhang 8434222ddf1SHong Zhang /*@ 844*6718818eSStefano Zampini MatProductSetType - Sets a particular matrix product type 8454222ddf1SHong Zhang 8464222ddf1SHong Zhang Collective on Mat 8474222ddf1SHong Zhang 8484222ddf1SHong Zhang Input Parameters: 8494222ddf1SHong Zhang + mat - the matrix 8504222ddf1SHong Zhang - productype - matrix product type, e.g., MATPRODUCT_AB,MATPRODUCT_AtB,MATPRODUCT_ABt,MATPRODUCT_PtAP,MATPRODUCT_RARt,MATPRODUCT_ABC. 8514222ddf1SHong Zhang 8524222ddf1SHong Zhang Level: intermediate 8534222ddf1SHong Zhang 854*6718818eSStefano Zampini .seealso: MatProductCreate(), MatProductType 8554222ddf1SHong Zhang @*/ 8564222ddf1SHong Zhang PetscErrorCode MatProductSetType(Mat mat,MatProductType productype) 8574222ddf1SHong Zhang { 858*6718818eSStefano Zampini PetscErrorCode ierr; 8594222ddf1SHong Zhang 8604222ddf1SHong Zhang PetscFunctionBegin; 8614222ddf1SHong Zhang PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 862*6718818eSStefano Zampini MatCheckProduct(mat,1); 8637a3c3d58SStefano Zampini PetscValidLogicalCollectiveEnum(mat,productype,2); 864*6718818eSStefano Zampini if (productype != mat->product->type) { 865*6718818eSStefano Zampini if (mat->product->destroy) { 866*6718818eSStefano Zampini ierr = (*mat->product->destroy)(mat->product->data);CHKERRQ(ierr); 8674222ddf1SHong Zhang } 868*6718818eSStefano Zampini mat->product->destroy = NULL; 869*6718818eSStefano Zampini mat->product->data = NULL; 870*6718818eSStefano Zampini mat->ops->productsymbolic = NULL; 871*6718818eSStefano Zampini mat->ops->productnumeric = NULL; 872*6718818eSStefano Zampini } 873*6718818eSStefano Zampini mat->product->type = productype; 8744222ddf1SHong Zhang PetscFunctionReturn(0); 8754222ddf1SHong Zhang } 8764222ddf1SHong Zhang 8774417c5e8SHong Zhang /*@ 8784417c5e8SHong Zhang MatProductClear - Clears matrix product internal structure. 8794417c5e8SHong Zhang 8804417c5e8SHong Zhang Collective on Mat 8814417c5e8SHong Zhang 8824417c5e8SHong Zhang Input Parameters: 8834417c5e8SHong Zhang . mat - the product matrix 8844417c5e8SHong Zhang 8854417c5e8SHong Zhang Level: intermediate 886*6718818eSStefano Zampini 887*6718818eSStefano Zampini Notes: this function should be called to remove any intermediate data used by the product 888*6718818eSStefano Zampini After having called this function, MatProduct operations can no longer be used on mat 8894417c5e8SHong Zhang @*/ 8904417c5e8SHong Zhang PetscErrorCode MatProductClear(Mat mat) 8914417c5e8SHong Zhang { 8924417c5e8SHong Zhang PetscErrorCode ierr; 8934417c5e8SHong Zhang Mat_Product *product = mat->product; 8944417c5e8SHong Zhang 8954417c5e8SHong Zhang PetscFunctionBegin; 8967a3c3d58SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8974417c5e8SHong Zhang if (product) { 8984417c5e8SHong Zhang ierr = MatDestroy(&product->A);CHKERRQ(ierr); 8994417c5e8SHong Zhang ierr = MatDestroy(&product->B);CHKERRQ(ierr); 9004417c5e8SHong Zhang ierr = MatDestroy(&product->C);CHKERRQ(ierr); 9017a3c3d58SStefano Zampini ierr = PetscFree(product->alg);CHKERRQ(ierr); 9024417c5e8SHong Zhang ierr = MatDestroy(&product->Dwork);CHKERRQ(ierr); 903*6718818eSStefano Zampini if (product->destroy) { 904*6718818eSStefano Zampini ierr = (*product->destroy)(product->data);CHKERRQ(ierr); 9054417c5e8SHong Zhang } 906*6718818eSStefano Zampini } 907*6718818eSStefano Zampini ierr = PetscFree(mat->product);CHKERRQ(ierr); 908*6718818eSStefano Zampini mat->ops->productsymbolic = NULL; 909*6718818eSStefano Zampini mat->ops->productnumeric = NULL; 9104417c5e8SHong Zhang PetscFunctionReturn(0); 9114417c5e8SHong Zhang } 9124417c5e8SHong Zhang 9134222ddf1SHong Zhang /* Create a supporting struct and attach it to the matrix product */ 9144417c5e8SHong Zhang PetscErrorCode MatProductCreate_Private(Mat A,Mat B,Mat C,Mat D) 9154222ddf1SHong Zhang { 9164222ddf1SHong Zhang PetscErrorCode ierr; 9174222ddf1SHong Zhang Mat_Product *product=NULL; 9184222ddf1SHong Zhang 9194222ddf1SHong Zhang PetscFunctionBegin; 920*6718818eSStefano Zampini PetscValidHeaderSpecific(D,MAT_CLASSID,4); 921*6718818eSStefano Zampini if (D->product) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product already present"); 9224222ddf1SHong Zhang ierr = PetscNewLog(D,&product);CHKERRQ(ierr); 9234222ddf1SHong Zhang product->A = A; 9244222ddf1SHong Zhang product->B = B; 9254222ddf1SHong Zhang product->C = C; 926*6718818eSStefano Zampini product->type = MATPRODUCT_UNSPECIFIED; 9274222ddf1SHong Zhang product->Dwork = NULL; 9284222ddf1SHong Zhang product->api_user = PETSC_FALSE; 929*6718818eSStefano Zampini product->clear = PETSC_FALSE; 9304222ddf1SHong Zhang D->product = product; 9314417c5e8SHong Zhang 9327a3c3d58SStefano Zampini ierr = MatProductSetAlgorithm(D,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr); 933*6718818eSStefano Zampini ierr = MatProductSetFill(D,PETSC_DEFAULT);CHKERRQ(ierr); 9347a3c3d58SStefano Zampini 9354417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 9364417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 9374417c5e8SHong Zhang ierr = PetscObjectReference((PetscObject)C);CHKERRQ(ierr); 9384222ddf1SHong Zhang PetscFunctionReturn(0); 9394222ddf1SHong Zhang } 9404222ddf1SHong Zhang 9414222ddf1SHong Zhang /*@ 9424222ddf1SHong Zhang MatProductCreateWithMat - Setup a given matrix as a matrix product. 9434222ddf1SHong Zhang 9444222ddf1SHong Zhang Collective on Mat 9454222ddf1SHong Zhang 9464222ddf1SHong Zhang Input Parameters: 9474222ddf1SHong Zhang + A - the first matrix 9484222ddf1SHong Zhang . B - the second matrix 9494222ddf1SHong Zhang . C - the third matrix (optional) 9504222ddf1SHong Zhang - D - the matrix which will be used as a product 9514222ddf1SHong Zhang 9524222ddf1SHong Zhang Output Parameters: 9534222ddf1SHong Zhang . D - the product matrix 9544222ddf1SHong Zhang 955*6718818eSStefano Zampini Notes: 956*6718818eSStefano Zampini Any product data attached to D will be cleared 957*6718818eSStefano Zampini 9584222ddf1SHong Zhang Level: intermediate 9594222ddf1SHong Zhang 960*6718818eSStefano Zampini .seealso: MatProductCreate(), MatProductClear() 9614222ddf1SHong Zhang @*/ 9624222ddf1SHong Zhang PetscErrorCode MatProductCreateWithMat(Mat A,Mat B,Mat C,Mat D) 9634222ddf1SHong Zhang { 9644222ddf1SHong Zhang PetscErrorCode ierr; 9654222ddf1SHong Zhang 9664222ddf1SHong Zhang PetscFunctionBegin; 9674222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9684222ddf1SHong Zhang PetscValidType(A,1); 9694222ddf1SHong Zhang MatCheckPreallocated(A,1); 9704222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9714222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9724222ddf1SHong Zhang 9734222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9744222ddf1SHong Zhang PetscValidType(B,2); 9754222ddf1SHong Zhang MatCheckPreallocated(B,2); 9764222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9774222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9784222ddf1SHong Zhang 9794222ddf1SHong Zhang if (C) { 9804222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9814222ddf1SHong Zhang PetscValidType(C,3); 9824222ddf1SHong Zhang MatCheckPreallocated(C,3); 9834222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9844222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9854222ddf1SHong Zhang } 9864222ddf1SHong Zhang 9874222ddf1SHong Zhang PetscValidHeaderSpecific(D,MAT_CLASSID,4); 9884222ddf1SHong Zhang PetscValidType(D,4); 9894222ddf1SHong Zhang MatCheckPreallocated(D,4); 9904222ddf1SHong Zhang if (!D->assembled) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9914222ddf1SHong Zhang if (D->factortype) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9924222ddf1SHong Zhang 9934222ddf1SHong Zhang /* Create a supporting struct and attach it to D */ 994*6718818eSStefano Zampini ierr = MatProductClear(D);CHKERRQ(ierr); 9954222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,D);CHKERRQ(ierr); 9964222ddf1SHong Zhang PetscFunctionReturn(0); 9974222ddf1SHong Zhang } 9984222ddf1SHong Zhang 9994222ddf1SHong Zhang /*@ 10004222ddf1SHong Zhang MatProductCreate - create a matrix product object that can be used to compute various matrix times matrix operations. 10014222ddf1SHong Zhang 10024222ddf1SHong Zhang Collective on Mat 10034222ddf1SHong Zhang 10044222ddf1SHong Zhang Input Parameters: 10054222ddf1SHong Zhang + A - the first matrix 10064222ddf1SHong Zhang . B - the second matrix 10074222ddf1SHong Zhang - C - the third matrix (optional) 10084222ddf1SHong Zhang 10094222ddf1SHong Zhang Output Parameters: 10104222ddf1SHong Zhang . D - the product matrix 10114222ddf1SHong Zhang 10124222ddf1SHong Zhang Level: intermediate 10134222ddf1SHong Zhang 10144222ddf1SHong Zhang .seealso: MatProductCreateWithMat(), MatProductSetType(), MatProductSetAlgorithm() 10154222ddf1SHong Zhang @*/ 10164222ddf1SHong Zhang PetscErrorCode MatProductCreate(Mat A,Mat B,Mat C,Mat *D) 10174222ddf1SHong Zhang { 10184222ddf1SHong Zhang PetscErrorCode ierr; 10194222ddf1SHong Zhang 10204222ddf1SHong Zhang PetscFunctionBegin; 10214222ddf1SHong Zhang PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10224222ddf1SHong Zhang PetscValidType(A,1); 10234222ddf1SHong Zhang MatCheckPreallocated(A,1); 10244222ddf1SHong Zhang if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10254222ddf1SHong Zhang if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10264222ddf1SHong Zhang 10274222ddf1SHong Zhang PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10284222ddf1SHong Zhang PetscValidType(B,2); 10294222ddf1SHong Zhang MatCheckPreallocated(B,2); 10304222ddf1SHong Zhang if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10314222ddf1SHong Zhang if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10324222ddf1SHong Zhang 10334222ddf1SHong Zhang if (C) { 10344222ddf1SHong Zhang PetscValidHeaderSpecific(C,MAT_CLASSID,3); 10354222ddf1SHong Zhang PetscValidType(C,3); 10364222ddf1SHong Zhang MatCheckPreallocated(C,3); 10374222ddf1SHong Zhang if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10384222ddf1SHong Zhang if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10394222ddf1SHong Zhang } 10404222ddf1SHong Zhang 10414222ddf1SHong Zhang PetscValidPointer(D,4); 10424222ddf1SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A),D);CHKERRQ(ierr); 10434222ddf1SHong Zhang ierr = MatProductCreate_Private(A,B,C,*D);CHKERRQ(ierr); 10444222ddf1SHong Zhang PetscFunctionReturn(0); 10454222ddf1SHong Zhang } 1046