xref: /petsc/src/mat/tests/ex237.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
156bd94f4SPierre Jolivet static char help[] = "Mini-app to benchmark matrix--matrix multiplication\n\n";
256bd94f4SPierre Jolivet 
356bd94f4SPierre Jolivet /*
456bd94f4SPierre Jolivet   See the paper below for more information
556bd94f4SPierre Jolivet 
656bd94f4SPierre Jolivet    "KSPHPDDM and PCHPDDM: Extending PETSc with Robust Overlapping Schwarz Preconditioners and Advanced Krylov Methods",
756bd94f4SPierre Jolivet    P. Jolivet, J. E. Roman, and S. Zampini (2020).
856bd94f4SPierre Jolivet */
956bd94f4SPierre Jolivet 
1056bd94f4SPierre Jolivet #include <petsc.h>
1156bd94f4SPierre Jolivet 
12b88df2e7SBarry Smith #if defined(PETSC_HAVE_MKL_SPARSE_OPTIMIZE)
1356bd94f4SPierre Jolivet #include <mkl.h>
1456bd94f4SPierre Jolivet #define PetscStackCallMKLSparse(func, args) do {               \
1556bd94f4SPierre Jolivet     sparse_status_t __ierr;                                    \
1656bd94f4SPierre Jolivet     PetscStackPush(#func);                                     \
1756bd94f4SPierre Jolivet     __ierr = func args;                                        \
1856bd94f4SPierre Jolivet     PetscStackPop;                                             \
192c71b3e2SJacob Faibussowitsch     PetscCheckFalse(__ierr != SPARSE_STATUS_SUCCESS,PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in %s(): error code %d", #func, (int)__ierr); \
2056bd94f4SPierre Jolivet   } while (0)
2156bd94f4SPierre Jolivet #else
2256bd94f4SPierre Jolivet #define PetscStackCallMKLSparse(func, args) do {               \
2356bd94f4SPierre Jolivet     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No MKL support"); \
2456bd94f4SPierre Jolivet   } while (0)
2556bd94f4SPierre Jolivet #endif
2656bd94f4SPierre Jolivet 
27956f8c0dSBarry Smith int main(int argc, char** argv)
28956f8c0dSBarry Smith {
2956bd94f4SPierre Jolivet   Mat            A, C, D, E;
3056bd94f4SPierre Jolivet   PetscInt       nbs = 10, ntype = 10, nN = 8, m, M, trial = 5;
3156bd94f4SPierre Jolivet   PetscViewer    viewer;
3256bd94f4SPierre Jolivet   PetscInt       bs[10], N[8];
3356bd94f4SPierre Jolivet   char           *type[10];
3456bd94f4SPierre Jolivet   PetscMPIInt    size;
3556bd94f4SPierre Jolivet   PetscBool      flg, cuda, maij = PETSC_FALSE, check = PETSC_FALSE, trans = PETSC_FALSE, convert = PETSC_FALSE, mkl;
3656bd94f4SPierre Jolivet   char           file[PETSC_MAX_PATH_LEN];
3756bd94f4SPierre Jolivet   PetscErrorCode ierr;
3856bd94f4SPierre Jolivet 
392da392ccSBarry Smith   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
4056bd94f4SPierre Jolivet   if (ierr) return ierr;
41*5f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
422c71b3e2SJacob Faibussowitsch   PetscCheckFalse(size != 1,PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "This is a uniprocessor example only");
43*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetString(NULL, NULL, "-f", file, PETSC_MAX_PATH_LEN, &flg));
442c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Must indicate binary file with the -f option");
45*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL, NULL, "-trial", &trial, NULL));
46*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetIntArray(NULL, NULL, "-bs", bs, &nbs, &flg));
4756bd94f4SPierre Jolivet   if (!flg) {
4856bd94f4SPierre Jolivet     nbs = 1;
4956bd94f4SPierre Jolivet     bs[0] = 1;
5056bd94f4SPierre Jolivet   }
51*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetIntArray(NULL, NULL, "-N", N, &nN, &flg));
5256bd94f4SPierre Jolivet   if (!flg) {
5356bd94f4SPierre Jolivet     nN = 8;
5456bd94f4SPierre Jolivet     N[0] = 1;  N[1] = 2;  N[2] = 4;  N[3] = 8;
5556bd94f4SPierre Jolivet     N[4] = 16; N[5] = 32; N[6] = 64; N[7] = 128;
5656bd94f4SPierre Jolivet   }
57*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetStringArray(NULL, NULL, "-type", type, &ntype, &flg));
5856bd94f4SPierre Jolivet   if (!flg) {
5956bd94f4SPierre Jolivet     ntype = 1;
60*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrallocpy(MATSEQAIJ, &type[0]));
6156bd94f4SPierre Jolivet   }
62*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL, NULL, "-check", &check, NULL));
63*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL, NULL, "-trans", &trans, NULL));
64*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL, NULL, "-convert_aij", &convert, NULL));
6556bd94f4SPierre Jolivet   for (PetscInt j = 0; j < nbs; ++j) {
66*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file, FILE_MODE_READ, &viewer));
67*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreate(PETSC_COMM_WORLD, &A));
68*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetFromOptions(A));
69*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatLoad(A, viewer));
70*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerDestroy(&viewer));
71*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectTypeCompareAny((PetscObject)A, &flg, MATSEQAIJ, MATMPIAIJ, ""));
722c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!flg,PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Must indicate a MatAIJ input matrix");
73*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetSize(A, &m, &M));
7456bd94f4SPierre Jolivet     if (m == M) {
7556bd94f4SPierre Jolivet       Mat oA;
76*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatTranspose(A, MAT_INITIAL_MATRIX, &oA));
77*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(A, 1.0, oA, DIFFERENT_NONZERO_PATTERN));
78*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&oA));
7956bd94f4SPierre Jolivet     }
80*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetLocalSize(A, &m, NULL));
81*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetSize(A, &M, NULL));
8256bd94f4SPierre Jolivet     if (bs[j] > 1) {
8356bd94f4SPierre Jolivet       Mat               T, Tt, B;
8456bd94f4SPierre Jolivet       const PetscScalar *ptr;
8556bd94f4SPierre Jolivet       PetscScalar       *val, *Aa;
8656bd94f4SPierre Jolivet       const PetscInt    *Ai, *Aj;
8756bd94f4SPierre Jolivet       PetscInt          An, i, k;
8856bd94f4SPierre Jolivet       PetscBool         done;
8956bd94f4SPierre Jolivet 
90*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateDense(PETSC_COMM_SELF, bs[j], bs[j], bs[j], bs[j], NULL, &T));
91*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSetRandom(T, NULL));
92*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatTranspose(T, MAT_INITIAL_MATRIX, &Tt));
93*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(T, 1.0, Tt, SAME_NONZERO_PATTERN));
94*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&Tt));
95*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDenseGetArrayRead(T, &ptr));
96*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatGetRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &An, &Ai, &Aj, &done));
972c71b3e2SJacob Faibussowitsch       PetscCheckFalse(!done || An != m,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes");
98*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSeqAIJGetArray(A, &Aa));
99*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreate(PETSC_COMM_WORLD, &B));
100*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSetType(B, MATSEQBAIJ));
101*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSetSizes(B, bs[j] * An, bs[j] * An, PETSC_DECIDE, PETSC_DECIDE));
102*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscMalloc1(Ai[An] * bs[j] * bs[j], &val));
10356bd94f4SPierre Jolivet       for (i = 0; i < Ai[An]; ++i)
10456bd94f4SPierre Jolivet         for (k = 0; k < bs[j] * bs[j]; ++k)
10556bd94f4SPierre Jolivet           val[i * bs[j] * bs[j] + k] = Aa[i] * ptr[k];
106*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSetOption(B, MAT_ROW_ORIENTED, PETSC_FALSE));
107*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSeqBAIJSetPreallocationCSR(B, bs[j], Ai, Aj, val));
108*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFree(val));
109*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSeqAIJRestoreArray(A, &Aa));
110*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatRestoreRowIJ(A, 0, PETSC_FALSE, PETSC_FALSE, &An, &Ai, &Aj, &done));
111*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDenseRestoreArrayRead(T, &ptr));
112*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&T));
113*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&A));
11456bd94f4SPierre Jolivet       A    = B;
11556bd94f4SPierre Jolivet     }
11656bd94f4SPierre Jolivet     /* reconvert back to SeqAIJ before converting to the desired type later */
11756bd94f4SPierre Jolivet     if (!convert) E = A;
118*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(A, MATSEQAIJ, convert ? MAT_INITIAL_MATRIX : MAT_INPLACE_MATRIX, &E));
119*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetOption(E, MAT_SYMMETRIC, PETSC_TRUE));
12056bd94f4SPierre Jolivet     for (PetscInt i = 0; i < ntype; ++i) {
12156bd94f4SPierre Jolivet       char        *tmp;
12256bd94f4SPierre Jolivet       PetscInt    *ia_ptr, *ja_ptr, k;
12356bd94f4SPierre Jolivet       PetscScalar *a_ptr;
124b88df2e7SBarry Smith #if defined(PETSC_HAVE_MKL_SPARSE_OPTIMIZE)
12556bd94f4SPierre Jolivet       struct matrix_descr descr;
12656bd94f4SPierre Jolivet       sparse_matrix_t     spr;
12756bd94f4SPierre Jolivet       descr.type = SPARSE_MATRIX_TYPE_GENERAL;
12856bd94f4SPierre Jolivet       descr.diag = SPARSE_DIAG_NON_UNIT;
12956bd94f4SPierre Jolivet #endif
13056bd94f4SPierre Jolivet       if (convert) {
131*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatDestroy(&A));
13256bd94f4SPierre Jolivet       }
133*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscStrstr(type[i], "mkl", &tmp));
13456bd94f4SPierre Jolivet       if (tmp) {
13556bd94f4SPierre Jolivet         size_t mlen, tlen;
13656bd94f4SPierre Jolivet         char base[256];
13756bd94f4SPierre Jolivet 
13856bd94f4SPierre Jolivet         mkl  = PETSC_TRUE;
139*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscStrlen(tmp, &mlen));
140*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscStrlen(type[i], &tlen));
141*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscStrncpy(base, type[i], tlen-mlen + 1));
142*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatConvert(E, base, convert ? MAT_INITIAL_MATRIX : MAT_INPLACE_MATRIX, &A));
14356bd94f4SPierre Jolivet       } else {
14456bd94f4SPierre Jolivet         mkl  = PETSC_FALSE;
145*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscStrstr(type[i], "maij", &tmp));
14656bd94f4SPierre Jolivet         if (!tmp) {
147*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatConvert(E, type[i], convert ? MAT_INITIAL_MATRIX : MAT_INPLACE_MATRIX, &A));
14856bd94f4SPierre Jolivet         } else {
149*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatConvert(E, MATAIJ, convert ? MAT_INITIAL_MATRIX : MAT_INPLACE_MATRIX, &A));
15056bd94f4SPierre Jolivet           maij = PETSC_TRUE;
15156bd94f4SPierre Jolivet         }
15256bd94f4SPierre Jolivet       }
153*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectTypeCompareAny((PetscObject)A, &cuda, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, ""));
15456bd94f4SPierre Jolivet       if (mkl) {
15556bd94f4SPierre Jolivet         const PetscInt *Ai, *Aj;
15656bd94f4SPierre Jolivet         PetscInt       An;
15756bd94f4SPierre Jolivet         PetscBool      done;
15856bd94f4SPierre Jolivet 
159*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectTypeCompareAny((PetscObject)A, &flg, MATSEQAIJ, MATSEQBAIJ, MATSEQSBAIJ, ""));
1602c71b3e2SJacob Faibussowitsch         PetscCheckFalse(!flg,PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Not implemented");
161*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATSEQAIJ, &flg));
162*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetRowIJ(A, 0, PETSC_FALSE, flg ? PETSC_FALSE : PETSC_TRUE, &An, &Ai, &Aj, &done));
1632c71b3e2SJacob Faibussowitsch         PetscCheckFalse(!done,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Inconsistent sizes");
164*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscMalloc1(An + 1, &ia_ptr));
165*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscMalloc1(Ai[An], &ja_ptr));
16656bd94f4SPierre Jolivet         if (flg) { /* SeqAIJ */
16756bd94f4SPierre Jolivet           for (k = 0; k < An + 1; ++k) ia_ptr[k] = Ai[k];
16856bd94f4SPierre Jolivet           for (k = 0; k < Ai[An]; ++k) ja_ptr[k] = Aj[k];
169*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatSeqAIJGetArray(A, &a_ptr));
17056bd94f4SPierre Jolivet           PetscStackCallMKLSparse(mkl_sparse_d_create_csr, (&spr, SPARSE_INDEX_BASE_ZERO, An, An, ia_ptr, ia_ptr + 1, ja_ptr, a_ptr));
17156bd94f4SPierre Jolivet         } else {
172*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATSEQBAIJ, &flg));
17356bd94f4SPierre Jolivet           if (flg) {
17456bd94f4SPierre Jolivet             for (k = 0; k < An + 1; ++k) ia_ptr[k] = Ai[k] + 1; /* Fortran indexing to maximize cases covered by _mm routines */
17556bd94f4SPierre Jolivet             for (k = 0; k < Ai[An]; ++k) ja_ptr[k] = Aj[k] + 1; /* Fortran indexing to maximize cases covered by _mm routines */
176*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatSeqBAIJGetArray(A, &a_ptr));
17756bd94f4SPierre Jolivet             PetscStackCallMKLSparse(mkl_sparse_d_create_bsr, (&spr, SPARSE_INDEX_BASE_ONE, SPARSE_LAYOUT_COLUMN_MAJOR, An, An, bs[j], ia_ptr, ia_ptr + 1, ja_ptr, a_ptr));
17856bd94f4SPierre Jolivet           } else {
179*5f80ce2aSJacob Faibussowitsch             CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATSEQSBAIJ, &flg));
18056bd94f4SPierre Jolivet             if (flg) {
18156bd94f4SPierre Jolivet               for (k = 0; k < An + 1; ++k) ia_ptr[k] = Ai[k] + 1; /* Fortran indexing to maximize cases covered by _mm routines */
18256bd94f4SPierre Jolivet               for (k = 0; k < Ai[An]; ++k) ja_ptr[k] = Aj[k] + 1; /* Fortran indexing to maximize cases covered by _mm routines */
183*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatSeqSBAIJGetArray(A, &a_ptr));
18456bd94f4SPierre Jolivet               PetscStackCallMKLSparse(mkl_sparse_d_create_bsr, (&spr, SPARSE_INDEX_BASE_ONE, SPARSE_LAYOUT_COLUMN_MAJOR, An, An, bs[j], ia_ptr, ia_ptr + 1, ja_ptr, a_ptr));
185b88df2e7SBarry Smith #if defined(PETSC_HAVE_MKL_SPARSE_OPTIMIZE)
18656bd94f4SPierre Jolivet               descr.type = SPARSE_MATRIX_TYPE_SYMMETRIC;
18756bd94f4SPierre Jolivet               descr.mode = SPARSE_FILL_MODE_UPPER;
18856bd94f4SPierre Jolivet               descr.diag = SPARSE_DIAG_NON_UNIT;
18956bd94f4SPierre Jolivet #endif
19056bd94f4SPierre Jolivet             }
19156bd94f4SPierre Jolivet           }
19256bd94f4SPierre Jolivet         }
193*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscObjectTypeCompare((PetscObject)A, MATSEQAIJ, &flg));
194*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatRestoreRowIJ(A, 0, PETSC_FALSE, flg ? PETSC_FALSE : PETSC_TRUE, &An, &Ai, &Aj, &done));
19556bd94f4SPierre Jolivet       }
19656bd94f4SPierre Jolivet 
197*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatViewFromOptions(A, NULL, "-A_view"));
19856bd94f4SPierre Jolivet 
19956bd94f4SPierre Jolivet       for (k = 0; k < nN; ++k) {
20056bd94f4SPierre Jolivet         MatType       Atype, Ctype;
20156bd94f4SPierre Jolivet         PetscInt      AM, AN, CM, CN, t;
202956f8c0dSBarry Smith #if defined(PETSC_USE_LOG)
20356bd94f4SPierre Jolivet         PetscLogStage stage, tstage;
20456bd94f4SPierre Jolivet         char          stage_s[256];
205956f8c0dSBarry Smith #endif
20656bd94f4SPierre Jolivet 
207*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatCreateDense(PETSC_COMM_WORLD, bs[j] * m, PETSC_DECIDE, bs[j] * M, N[k], NULL, &C));
208*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatCreateDense(PETSC_COMM_WORLD, bs[j] * m, PETSC_DECIDE, bs[j] * M, N[k], NULL, &D));
209*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatSetRandom(C, NULL));
21056bd94f4SPierre Jolivet         if (cuda) { /* convert to GPU if needed */
211*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatConvert(C, MATDENSECUDA, MAT_INPLACE_MATRIX, &C));
212*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatConvert(D, MATDENSECUDA, MAT_INPLACE_MATRIX, &D));
21356bd94f4SPierre Jolivet         }
21456bd94f4SPierre Jolivet         if (mkl) {
21556bd94f4SPierre Jolivet           if (N[k] > 1) PetscStackCallMKLSparse(mkl_sparse_set_mm_hint, (spr, SPARSE_OPERATION_NON_TRANSPOSE, descr, SPARSE_LAYOUT_COLUMN_MAJOR, N[k], 1 + trial));
21656bd94f4SPierre Jolivet           else          PetscStackCallMKLSparse(mkl_sparse_set_mv_hint, (spr, SPARSE_OPERATION_NON_TRANSPOSE, descr, 1 + trial));
21756bd94f4SPierre Jolivet           PetscStackCallMKLSparse(mkl_sparse_set_memory_hint, (spr, SPARSE_MEMORY_AGGRESSIVE));
21856bd94f4SPierre Jolivet           PetscStackCallMKLSparse(mkl_sparse_optimize, (spr));
21956bd94f4SPierre Jolivet         }
220*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetType(A, &Atype));
221*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetType(C, &Ctype));
222*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetSize(A, &AM, &AN));
223*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetSize(C, &CM, &CN));
22456bd94f4SPierre Jolivet 
225956f8c0dSBarry Smith #if defined(PETSC_USE_LOG)
22656bd94f4SPierre Jolivet         if (!maij || N[k] > 1) {
227*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscSNPrintf(stage_s, sizeof(stage_s), "type_%s-bs_%" PetscInt_FMT "-N_%02d", type[i], bs[j], (int)N[k]));
228*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscLogStageRegister(stage_s, &stage));
22956bd94f4SPierre Jolivet         }
23056bd94f4SPierre Jolivet         if (trans && N[k] > 1) {
231*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscSNPrintf(stage_s, sizeof(stage_s), "trans_type_%s-bs_%" PetscInt_FMT "-N_%02d", type[i], bs[j], (int)N[k]));
232*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscLogStageRegister(stage_s, &tstage));
23356bd94f4SPierre Jolivet         }
234956f8c0dSBarry Smith #endif
23556bd94f4SPierre Jolivet         /* A*B */
23656bd94f4SPierre Jolivet         if (N[k] > 1) {
23756bd94f4SPierre Jolivet           if (!maij) {
238*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatProductCreateWithMat(A, C, NULL, D));
239*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatProductSetType(D, MATPRODUCT_AB));
240*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatProductSetFromOptions(D));
241*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatProductSymbolic(D));
24256bd94f4SPierre Jolivet           }
24356bd94f4SPierre Jolivet 
24456bd94f4SPierre Jolivet           if (!mkl) {
24556bd94f4SPierre Jolivet             if (!maij) {
246*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatProductNumeric(D));
247*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Benchmarking MatProduct %s: with A %s %" PetscInt_FMT "x%" PetscInt_FMT " and B %s %" PetscInt_FMT "x%" PetscInt_FMT "\n", MatProductTypes[MATPRODUCT_AB], Atype, AM, AN, Ctype, CM, CN));
248*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscLogStagePush(stage));
24956bd94f4SPierre Jolivet               for (t = 0; t < trial; ++t) {
250*5f80ce2aSJacob Faibussowitsch                 CHKERRQ(MatProductNumeric(D));
25156bd94f4SPierre Jolivet               }
252*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscLogStagePop());
25356bd94f4SPierre Jolivet             } else {
25456bd94f4SPierre Jolivet               Mat               E, Ct, Dt;
25556bd94f4SPierre Jolivet               Vec               cC, cD;
25656bd94f4SPierre Jolivet               const PetscScalar *c_ptr;
25756bd94f4SPierre Jolivet               PetscScalar       *d_ptr;
258*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatCreateMAIJ(A, N[k], &E));
259*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseGetLocalMatrix(C, &Ct));
260*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseGetLocalMatrix(D, &Dt));
261*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatTranspose(Ct, MAT_INPLACE_MATRIX, &Ct));
262*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatTranspose(Dt, MAT_INPLACE_MATRIX, &Dt));
263*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseGetArrayRead(Ct, &c_ptr));
264*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseGetArrayWrite(Dt, &d_ptr));
265*5f80ce2aSJacob Faibussowitsch               CHKERRQ(VecCreateMPIWithArray(PETSC_COMM_WORLD, 1, AM * N[k], PETSC_DECIDE, c_ptr, &cC));
266*5f80ce2aSJacob Faibussowitsch               CHKERRQ(VecCreateMPIWithArray(PETSC_COMM_WORLD, 1, AM * N[k], PETSC_DECIDE, d_ptr, &cD));
267*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatMult(E, cC, cD));
268*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Benchmarking MatMult: with A %s %" PetscInt_FMT "x%" PetscInt_FMT " and B %s %" PetscInt_FMT "x%" PetscInt_FMT "\n", MATMAIJ, AM, AN, VECMPI, AM * N[k], 1));
269*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscLogStagePush(stage));
27056bd94f4SPierre Jolivet               for (t = 0; t < trial; ++t) {
271*5f80ce2aSJacob Faibussowitsch                 CHKERRQ(MatMult(E, cC, cD));
27256bd94f4SPierre Jolivet               }
273*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscLogStagePop());
274*5f80ce2aSJacob Faibussowitsch               CHKERRQ(VecDestroy(&cD));
275*5f80ce2aSJacob Faibussowitsch               CHKERRQ(VecDestroy(&cC));
276*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDestroy(&E));
277*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseRestoreArrayWrite(Dt, &d_ptr));
278*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseRestoreArrayRead(Ct, &c_ptr));
279*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatTranspose(Ct, MAT_INPLACE_MATRIX, &Ct));
280*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatTranspose(Dt, MAT_INPLACE_MATRIX, &Dt));
28156bd94f4SPierre Jolivet             }
28256bd94f4SPierre Jolivet           } else {
28356bd94f4SPierre Jolivet             const PetscScalar *c_ptr;
28456bd94f4SPierre Jolivet             PetscScalar       *d_ptr;
28556bd94f4SPierre Jolivet 
286*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatDenseGetArrayRead(C, &c_ptr));
287*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatDenseGetArrayWrite(D, &d_ptr));
28856bd94f4SPierre Jolivet             PetscStackCallMKLSparse(mkl_sparse_d_mm,(SPARSE_OPERATION_NON_TRANSPOSE, 1.0, spr, descr, SPARSE_LAYOUT_COLUMN_MAJOR, c_ptr, CN, CM, 0.0, d_ptr, CM));
289*5f80ce2aSJacob Faibussowitsch             CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Benchmarking mkl_sparse_d_mm (COLUMN_MAJOR): with A %s %" PetscInt_FMT "x%" PetscInt_FMT " and B %s %" PetscInt_FMT "x%" PetscInt_FMT "\n", Atype, AM, AN, Ctype, CM, CN));
290*5f80ce2aSJacob Faibussowitsch             CHKERRQ(PetscLogStagePush(stage));
29156bd94f4SPierre Jolivet             for (t = 0; t < trial; ++t) {
29256bd94f4SPierre Jolivet               PetscStackCallMKLSparse(mkl_sparse_d_mm, (SPARSE_OPERATION_NON_TRANSPOSE, 1.0, spr, descr, SPARSE_LAYOUT_COLUMN_MAJOR, c_ptr, CN, CM, 0.0, d_ptr, CM));
29356bd94f4SPierre Jolivet             }
294*5f80ce2aSJacob Faibussowitsch             CHKERRQ(PetscLogStagePop());
295*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatDenseRestoreArrayWrite(D, &d_ptr));
296*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatDenseRestoreArrayRead(C, &c_ptr));
29756bd94f4SPierre Jolivet           }
29856bd94f4SPierre Jolivet         } else if (maij) {
299*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDestroy(&C));
300*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDestroy(&D));
30156bd94f4SPierre Jolivet           continue;
30256bd94f4SPierre Jolivet         } else if (!mkl) {
30356bd94f4SPierre Jolivet           Vec cC, cD;
30456bd94f4SPierre Jolivet 
305*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDenseGetColumnVecRead(C, 0, &cC));
306*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDenseGetColumnVecWrite(D, 0, &cD));
307*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatMult(A, cC, cD));
308*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Benchmarking MatMult: with A %s %" PetscInt_FMT "x%" PetscInt_FMT "\n", Atype, AM, AN));
309*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscLogStagePush(stage));
31056bd94f4SPierre Jolivet           for (t = 0; t < trial; ++t) {
311*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatMult(A, cC, cD));
31256bd94f4SPierre Jolivet           }
313*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscLogStagePop());
314*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDenseRestoreColumnVecRead(C, 0, &cC));
315*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDenseRestoreColumnVecWrite(D, 0, &cD));
31656bd94f4SPierre Jolivet         } else {
31756bd94f4SPierre Jolivet           const PetscScalar *c_ptr;
31856bd94f4SPierre Jolivet           PetscScalar       *d_ptr;
31956bd94f4SPierre Jolivet 
320*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDenseGetArrayRead(C, &c_ptr));
321*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDenseGetArrayWrite(D, &d_ptr));
322*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Benchmarking mkl_sparse_d_mv: with A %s %" PetscInt_FMT "x%" PetscInt_FMT "\n", Atype, AM, AN));
32356bd94f4SPierre Jolivet           PetscStackCallMKLSparse(mkl_sparse_d_mv, (SPARSE_OPERATION_NON_TRANSPOSE, 1.0, spr, descr, c_ptr, 0.0, d_ptr));
324*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscLogStagePush(stage));
32556bd94f4SPierre Jolivet           for (t = 0; t < trial; ++t) {
32656bd94f4SPierre Jolivet             PetscStackCallMKLSparse(mkl_sparse_d_mv, (SPARSE_OPERATION_NON_TRANSPOSE, 1.0, spr, descr, c_ptr, 0.0, d_ptr));
32756bd94f4SPierre Jolivet           }
328*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscLogStagePop());
329*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDenseRestoreArrayWrite(D, &d_ptr));
330*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatDenseRestoreArrayRead(C, &c_ptr));
33156bd94f4SPierre Jolivet         }
33256bd94f4SPierre Jolivet 
33356bd94f4SPierre Jolivet         if (check) {
334*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatMatMultEqual(A, C, D, 10, &flg));
33556bd94f4SPierre Jolivet           if (!flg) {
33656bd94f4SPierre Jolivet             MatType Dtype;
33756bd94f4SPierre Jolivet 
338*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatGetType(D, &Dtype));
339*5f80ce2aSJacob Faibussowitsch             CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Error with A %s%s, C %s, D %s, Nk %" PetscInt_FMT "\n", Atype, mkl ? "mkl" : "", Ctype, Dtype, N[k]));
34056bd94f4SPierre Jolivet           }
34156bd94f4SPierre Jolivet         }
34256bd94f4SPierre Jolivet 
34356bd94f4SPierre Jolivet         /* MKL implementation seems buggy for ABt */
34456bd94f4SPierre Jolivet         /* A*Bt */
34556bd94f4SPierre Jolivet         if (!mkl && trans && N[k] > 1) {
346*5f80ce2aSJacob Faibussowitsch           CHKERRQ(PetscObjectTypeCompareAny((PetscObject)A, &flg, MATSEQAIJ, MATMPIAIJ, ""));
34756bd94f4SPierre Jolivet           if (flg) {
348*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatTranspose(C, MAT_INPLACE_MATRIX, &C));
349*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatGetType(C, &Ctype));
35056bd94f4SPierre Jolivet             if (!mkl) {
351*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatProductCreateWithMat(A, C, NULL, D));
352*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatProductSetType(D, MATPRODUCT_ABt));
353*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatProductSetFromOptions(D));
354*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatProductSymbolic(D));
355*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatProductNumeric(D));
356*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Benchmarking MatProduct %s: with A %s %" PetscInt_FMT "x%" PetscInt_FMT " and Bt %s %" PetscInt_FMT "x%" PetscInt_FMT "\n", MatProductTypes[MATPRODUCT_ABt], Atype, AM, AN, Ctype, CM, CN));
357*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscLogStagePush(tstage));
35856bd94f4SPierre Jolivet               for (t = 0; t < trial; ++t) {
359*5f80ce2aSJacob Faibussowitsch                 CHKERRQ(MatProductNumeric(D));
36056bd94f4SPierre Jolivet               }
361*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscLogStagePop());
36256bd94f4SPierre Jolivet             } else {
36356bd94f4SPierre Jolivet               const PetscScalar *c_ptr;
36456bd94f4SPierre Jolivet               PetscScalar       *d_ptr;
36556bd94f4SPierre Jolivet 
36656bd94f4SPierre Jolivet               PetscStackCallMKLSparse(mkl_sparse_set_mm_hint, (spr, SPARSE_OPERATION_NON_TRANSPOSE, descr, SPARSE_LAYOUT_ROW_MAJOR, N[k], 1 + trial));
36756bd94f4SPierre Jolivet               PetscStackCallMKLSparse(mkl_sparse_optimize, (spr));
368*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseGetArrayRead(C, &c_ptr));
369*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseGetArrayWrite(D, &d_ptr));
370*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Benchmarking mkl_sparse_d_mm (ROW_MAJOR): with A %s %" PetscInt_FMT "x%" PetscInt_FMT " and B %s %" PetscInt_FMT "x%" PetscInt_FMT "\n", Atype, AM, AN, Ctype, CM, CN));
37156bd94f4SPierre Jolivet               PetscStackCallMKLSparse(mkl_sparse_d_mm, (SPARSE_OPERATION_NON_TRANSPOSE, 1.0, spr, descr, SPARSE_LAYOUT_ROW_MAJOR, c_ptr, CN, CM, 0.0, d_ptr, CM));
372*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscLogStagePush(stage));
37356bd94f4SPierre Jolivet               for (t = 0; t < trial; ++t) {
37456bd94f4SPierre Jolivet                 PetscStackCallMKLSparse(mkl_sparse_d_mm, (SPARSE_OPERATION_NON_TRANSPOSE, 1.0, spr, descr, SPARSE_LAYOUT_ROW_MAJOR, c_ptr, CN, CM, 0.0, d_ptr, CM));
37556bd94f4SPierre Jolivet               }
376*5f80ce2aSJacob Faibussowitsch               CHKERRQ(PetscLogStagePop());
377*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseRestoreArrayWrite(D, &d_ptr));
378*5f80ce2aSJacob Faibussowitsch               CHKERRQ(MatDenseRestoreArrayRead(C, &c_ptr));
37956bd94f4SPierre Jolivet             }
38056bd94f4SPierre Jolivet           }
38156bd94f4SPierre Jolivet         }
38256bd94f4SPierre Jolivet 
38356bd94f4SPierre Jolivet         if (!mkl && trans && N[k] > 1 && flg && check) {
384*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatMatTransposeMultEqual(A, C, D, 10, &flg));
38556bd94f4SPierre Jolivet           if (!flg) {
38656bd94f4SPierre Jolivet             MatType Dtype;
387*5f80ce2aSJacob Faibussowitsch             CHKERRQ(MatGetType(D, &Dtype));
388*5f80ce2aSJacob Faibussowitsch             CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "Error with A %s%s, C %s, D %s, Nk %" PetscInt_FMT "\n", Atype, mkl ? "mkl" : "", Ctype, Dtype, N[k]));
38956bd94f4SPierre Jolivet           }
39056bd94f4SPierre Jolivet         }
391*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatDestroy(&C));
392*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatDestroy(&D));
39356bd94f4SPierre Jolivet       }
39456bd94f4SPierre Jolivet       if (mkl) {
39556bd94f4SPierre Jolivet         PetscStackCallMKLSparse(mkl_sparse_destroy, (spr));
396*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscFree(ia_ptr));
397*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscFree(ja_ptr));
39856bd94f4SPierre Jolivet       }
39956bd94f4SPierre Jolivet       if (cuda && i != ntype - 1) {
400*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscPrintf(PETSC_COMM_WORLD, "AIJCUSPARSE must be last, otherwise MatConvert() to another MatType is too slow\n"));
40156bd94f4SPierre Jolivet         break;
40256bd94f4SPierre Jolivet       }
40356bd94f4SPierre Jolivet     }
40456bd94f4SPierre Jolivet     if (E != A) {
405*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&E));
40656bd94f4SPierre Jolivet     }
407*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&A));
40856bd94f4SPierre Jolivet   }
40956bd94f4SPierre Jolivet   for (m = 0; m < ntype; ++m) {
410*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree(type[m]));
41156bd94f4SPierre Jolivet   }
41256bd94f4SPierre Jolivet   ierr = PetscFinalize();
41356bd94f4SPierre Jolivet   return 0;
41456bd94f4SPierre Jolivet }
41556bd94f4SPierre Jolivet 
41656bd94f4SPierre Jolivet /*TEST
417b8582c7cSSatish Balay    build:
418dfd57a17SPierre Jolivet      requires: double !complex !defined(PETSC_USE_64BIT_INDICES)
41956bd94f4SPierre Jolivet 
42056bd94f4SPierre Jolivet    testset:
42156bd94f4SPierre Jolivet      nsize: 1
42256bd94f4SPierre Jolivet      filter: sed "/Benchmarking/d"
42356bd94f4SPierre Jolivet      args: -f ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int32-float64 -bs 1,2,3 -N 1,2,18 -check -trans -convert_aij {{false true}shared output}
42456bd94f4SPierre Jolivet      test:
42556bd94f4SPierre Jolivet        suffix: basic
42656bd94f4SPierre Jolivet        args: -type aij,sbaij,baij
42756bd94f4SPierre Jolivet        output_file: output/ex237.out
42856bd94f4SPierre Jolivet      test:
42956bd94f4SPierre Jolivet        suffix: maij
43056bd94f4SPierre Jolivet        args: -type aij,maij
43156bd94f4SPierre Jolivet        output_file: output/ex237.out
43256bd94f4SPierre Jolivet      test:
43356bd94f4SPierre Jolivet        suffix: cuda
43456bd94f4SPierre Jolivet        requires: cuda
43556bd94f4SPierre Jolivet        args: -type aij,aijcusparse
43656bd94f4SPierre Jolivet        output_file: output/ex237.out
43756bd94f4SPierre Jolivet      test:
43856bd94f4SPierre Jolivet        suffix: mkl
439b88df2e7SBarry Smith        requires: mkl_sparse_optimize
44056bd94f4SPierre Jolivet        args: -type aij,aijmkl,baijmkl,sbaijmkl
44156bd94f4SPierre Jolivet        output_file: output/ex237.out
44256bd94f4SPierre Jolivet 
44356bd94f4SPierre Jolivet TEST*/
444