Actual source code: ex310.c
1: static char help[] = "Tests block sparse-dense matrix products.\n\n";
3: #include <petscmat.h>
5: static PetscErrorCode CheckEqual(Mat A, Mat B)
6: {
7: Mat D;
8: PetscReal norm;
10: PetscFunctionBegin;
11: PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &D));
12: PetscCall(MatAXPY(D, -1.0, B, SAME_NONZERO_PATTERN));
13: PetscCall(MatNorm(D, NORM_FROBENIUS, &norm));
14: PetscCheck(norm <= 100.0 * PETSC_MACHINE_EPSILON, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Matrix product error %g", (double)norm);
15: PetscCall(MatDestroy(&D));
16: PetscFunctionReturn(PETSC_SUCCESS);
17: }
19: int main(int argc, char **argv)
20: {
21: Mat A, Alibxsmm = NULL, AlibxsmmDuplicate = NULL, Aref, B, Cbaij, Clibxsmm = NULL, Cref;
22: MatType type, actual;
23: PetscInt rstart, rend, M, ncols = 5, bs = 2;
24: PetscMPIInt size;
25: PetscBool match, testlibxsmm = PETSC_FALSE;
26: PetscScalar value;
28: PetscFunctionBeginUser;
29: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
30: PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_libxsmm", &testlibxsmm, NULL));
31: PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
32: M = 4 * size;
33: PetscCall(MatCreateBAIJ(PETSC_COMM_WORLD, bs, PETSC_DECIDE, PETSC_DECIDE, M, M, 3, NULL, 3, NULL, &A));
34: PetscCall(MatGetOwnershipRange(A, &rstart, &rend));
35: for (PetscInt i = rstart; i < rend; i++) {
36: PetscInt brow = i / bs;
38: for (PetscInt bcol = PetscMax(brow - 1, 0); bcol <= PetscMin(brow + 1, M / bs - 1); bcol++) {
39: for (PetscInt j = bcol * bs; j < (bcol + 1) * bs; j++) {
40: value = 1.0 + i + 0.25 * j;
41: PetscCall(MatSetValue(A, i, j, value, INSERT_VALUES));
42: }
43: }
44: }
45: PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
46: PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
48: PetscCall(MatCreateDense(PETSC_COMM_WORLD, PETSC_DECIDE, PETSC_DECIDE, M, ncols, NULL, &B));
49: PetscCall(MatGetOwnershipRange(B, &rstart, &rend));
50: for (PetscInt i = rstart; i < rend; i++) {
51: for (PetscInt j = 0; j < ncols; j++) {
52: value = 0.5 + 0.125 * i - 0.25 * j;
53: PetscCall(MatSetValue(B, i, j, value, INSERT_VALUES));
54: }
55: }
56: PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
57: PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
59: type = size == 1 ? MATSEQBAIJ : MATMPIBAIJ;
60: PetscCall(PetscObjectTypeCompare((PetscObject)A, type, &match));
61: PetscCall(MatGetType(A, &actual));
62: PetscCheck(match, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Unexpected BAIJ matrix type %s", actual);
63: PetscCall(MatConvert(A, MATAIJ, MAT_INITIAL_MATRIX, &Aref));
64: if (testlibxsmm) {
65: PetscCall(MatConvert(A, MATBAIJLIBXSMM, MAT_INITIAL_MATRIX, &Alibxsmm));
66: type = size == 1 ? MATSEQBAIJLIBXSMM : MATMPIBAIJLIBXSMM;
67: PetscCall(PetscObjectTypeCompare((PetscObject)Alibxsmm, type, &match));
68: PetscCall(MatGetType(Alibxsmm, &actual));
69: PetscCheck(match, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Unexpected converted matrix type %s", actual);
70: PetscCall(MatDuplicate(Alibxsmm, MAT_COPY_VALUES, &AlibxsmmDuplicate));
71: PetscCall(PetscObjectTypeCompare((PetscObject)AlibxsmmDuplicate, type, &match));
72: PetscCall(MatGetType(AlibxsmmDuplicate, &actual));
73: PetscCheck(match, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Unexpected duplicated matrix type %s", actual);
74: }
76: PetscCall(MatMatMult(Aref, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &Cref));
77: PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &Cbaij));
78: PetscCall(CheckEqual(Cbaij, Cref));
79: if (testlibxsmm) {
80: PetscCall(MatMatMult(AlibxsmmDuplicate, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &Clibxsmm));
81: PetscCall(CheckEqual(Clibxsmm, Cref));
82: }
83: PetscCall(MatScale(B, -0.5));
84: PetscCall(MatMatMult(Aref, B, MAT_REUSE_MATRIX, PETSC_DETERMINE, &Cref));
85: PetscCall(MatMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DETERMINE, &Cbaij));
86: PetscCall(CheckEqual(Cbaij, Cref));
87: if (testlibxsmm) {
88: PetscCall(MatMatMult(AlibxsmmDuplicate, B, MAT_REUSE_MATRIX, PETSC_DETERMINE, &Clibxsmm));
89: PetscCall(CheckEqual(Clibxsmm, Cref));
90: }
92: if (testlibxsmm) {
93: type = size == 1 ? MATSEQBAIJ : MATMPIBAIJ;
94: PetscCall(MatConvert(Alibxsmm, type, MAT_INPLACE_MATRIX, &Alibxsmm));
95: PetscCall(PetscObjectTypeCompare((PetscObject)Alibxsmm, type, &match));
96: PetscCall(MatGetType(Alibxsmm, &actual));
97: PetscCheck(match, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Unexpected reverted matrix type %s", actual);
98: }
100: PetscCall(MatDestroy(&Clibxsmm));
101: PetscCall(MatDestroy(&Cbaij));
102: PetscCall(MatDestroy(&Cref));
103: PetscCall(MatDestroy(&B));
104: PetscCall(MatDestroy(&Aref));
105: PetscCall(MatDestroy(&AlibxsmmDuplicate));
106: PetscCall(MatDestroy(&Alibxsmm));
107: PetscCall(MatDestroy(&A));
108: PetscCall(PetscFinalize());
109: return 0;
110: }
112: /*TEST
114: testset:
115: output_file: output/empty.out
117: test:
118: suffix: baij_seq
120: test:
121: suffix: baij_mpi
122: nsize: 2
124: test:
125: suffix: baij_mpi_batch
126: nsize: 2
127: args: -matproduct_batch_size 3
129: testset:
130: requires: libxsmm !complex
131: args: -test_libxsmm
132: output_file: output/empty.out
134: test:
135: suffix: libxsmm_seq
137: test:
138: suffix: libxsmm_mpi
139: nsize: 2
141: test:
142: suffix: libxsmm_mpi_batch
143: nsize: 2
144: args: -matproduct_batch_size 3
146: TEST*/