Actual source code: ex303.c

  1: static char help[] = "Testing MatCreateMPIAIJWithSeqAIJ().\n\n";

  3: #include <petscmat.h>

  5: int main(int argc, char **argv)
  6: {
  7:   Mat                mat, mat2;
  8:   Mat                A, B;   // diag, offdiag of mat
  9:   Mat                A2, B2; // diag, offdiag of mat2
 10:   PetscInt           M, N, m = 5, n = 6, d_nz = 3, o_nz = 4;
 11:   PetscInt          *bi, *bj, nd;
 12:   const PetscScalar *ba;
 13:   const PetscInt    *garray;
 14:   PetscInt          *garray_h;
 15:   PetscBool          equal, done;
 16:   PetscMPIInt        size;
 17:   char               mat_type[PETSC_MAX_PATH_LEN];
 18:   PetscBool          flg;

 20:   PetscFunctionBeginUser;
 21:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
 22:   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
 23:   PetscCheck(size > 1, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 2 or more processes");

 25:   // Create a MATMPIAIJ matrix for checking against
 26:   PetscCall(MatCreateAIJ(PETSC_COMM_WORLD, m, n, PETSC_DECIDE, PETSC_DECIDE, d_nz, NULL, o_nz, NULL, &mat));
 27:   PetscCall(MatSetRandom(mat, NULL));
 28:   PetscCall(MatGetSize(mat, &M, &N));
 29:   PetscCall(MatGetLocalSize(mat, &m, &n));
 30:   PetscCall(MatMPIAIJGetSeqAIJ(mat, &A, &B, &garray));

 32:   PetscCall(PetscOptionsGetString(NULL, NULL, "-mat_type", mat_type, sizeof(mat_type), &flg));
 33:   if (!flg) PetscCall(PetscStrncpy(mat_type, MATSEQAIJ, sizeof(mat_type))); // Default to MATAIJ
 34:   PetscCall(MatConvert(A, mat_type, MAT_INITIAL_MATRIX, &A2));              // Copy A, B to A2, B2 but in the given mat_type
 35:   PetscCall(MatConvert(B, mat_type, MAT_INITIAL_MATRIX, &B2));

 37:   // The garray passed in has to be on the host, but it can be created on device and copied to the host.
 38:   // We're just going to copy the existing host values here.
 39:   PetscInt nonlocalCols;
 40:   PetscCall(MatGetLocalSize(B, NULL, &nonlocalCols));
 41:   PetscCall(PetscMalloc1(nonlocalCols, &garray_h));
 42:   for (int i = 0; i < nonlocalCols; i++) garray_h[i] = garray[i];

 44:   // 1) Test MatCreateMPIAIJWithSeqAIJ with compressed off-diag.
 45:   PetscCall(MatCreateMPIAIJWithSeqAIJ(PETSC_COMM_WORLD, M, N, A2, B2, garray_h, &mat2));
 46:   PetscCall(MatEqual(mat, mat2, &equal));                   // might directly compare value arrays
 47:   if (equal) PetscCall(MatMultEqual(mat, mat2, 2, &equal)); // compare via MatMult()
 48:   PetscCheck(equal, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Likely a bug in MatCreateMPIAIJWithSeqAIJ()");
 49:   PetscCall(MatDestroy(&mat2)); // A2 and B2 are also destroyed

 51:   // 2) Test MatCreateMPIAIJWithSeqAIJ with non-compressed off-diag.
 52:   PetscCall(MatConvert(A, mat_type, MAT_INITIAL_MATRIX, &A2));

 54:   // Create a version of B2 of size N with global indices
 55:   PetscCall(MatGetRowIJ(B, 0, PETSC_FALSE, PETSC_FALSE, &nd, (const PetscInt **)&bi, (const PetscInt **)&bj, &done));
 56:   PetscCall(MatSeqAIJGetArrayRead(B, &ba));
 57:   PetscCall(MatCreate(PETSC_COMM_SELF, &B2));
 58:   PetscCall(MatSetSizes(B2, m, N, m, N));
 59:   PetscCall(MatSetType(B2, mat_type));
 60:   PetscCall(MatSeqAIJSetPreallocation(B2, o_nz, NULL));
 61:   for (int i = 0; i < m; i++) { // Fill B2 with values from B
 62:     for (int j = 0; j < bi[i + 1] - bi[i]; j++) PetscCall(MatSetValue(B2, i, garray[bj[bi[i] + j]], ba[bi[i] + j], INSERT_VALUES));
 63:   }
 64:   PetscCall(MatAssemblyBegin(B2, MAT_FINAL_ASSEMBLY));
 65:   PetscCall(MatAssemblyEnd(B2, MAT_FINAL_ASSEMBLY));

 67:   PetscCall(MatRestoreRowIJ(B, 0, PETSC_FALSE, PETSC_FALSE, &nd, (const PetscInt **)&bi, (const PetscInt **)&bj, &done));
 68:   PetscCall(MatSeqAIJRestoreArrayRead(B, &ba));

 70:   PetscCall(MatCreateMPIAIJWithSeqAIJ(PETSC_COMM_WORLD, M, N, A2, B2, NULL, &mat2));
 71:   PetscCall(MatEqual(mat, mat2, &equal));
 72:   if (equal) PetscCall(MatMultEqual(mat, mat2, 2, &equal));
 73:   PetscCheck(equal, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Likely a bug in MatCreateMPIAIJWithSeqAIJ()");

 75:   PetscCall(MatDestroy(&mat));
 76:   PetscCall(MatDestroy(&mat2));
 77:   PetscCall(PetscFinalize());
 78:   return 0;
 79: }

 81: /*TEST

 83:   testset:
 84:     nsize: 2
 85:     output_file: output/empty.out

 87:     test:
 88:       suffix: 1
 89:       args: -mat_type aij

 91:     test:
 92:       suffix: 2
 93:       args: -mat_type aijkokkos
 94:       requires: kokkos_kernels

 96:     test:
 97:       suffix: 3
 98:       args: -mat_type aijcusparse
 99:       requires: cuda

101:     test:
102:       suffix: 4
103:       args: -mat_type aijhipsparse
104:       requires: hip

106: TEST*/