Actual source code: ex36.c

  1: static char help[] = "Parallel vector layout.\n\n";

  3: /*
  4:   Include "petscvec.h" so that we can use vectors.  Note that this file
  5:   automatically includes:
  6:      petscsys.h       - base PETSc routines   petscis.h     - index sets
  7:      petscviewer.h - viewers
  8: */
  9: #include <petscvec.h>

 11: int main(int argc, char **argv)
 12: {
 13:   PetscMPIInt  rank;
 14:   PetscInt     i, istart, iend, n = 6, m, *indices;
 15:   PetscScalar *values;
 16:   Vec          x;
 17:   PetscBool    set_option_negidx = PETSC_FALSE, set_values_negidx = PETSC_FALSE, get_values_negidx = PETSC_FALSE;

 19:   PetscFunctionBeginUser;
 20:   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
 21:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));

 23:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL));
 24:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-set_option_negidx", &set_option_negidx, NULL));
 25:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-set_values_negidx", &set_values_negidx, NULL));
 26:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-get_values_negidx", &get_values_negidx, NULL));

 28:   PetscCall(VecCreate(PETSC_COMM_WORLD, &x));
 29:   PetscCall(VecSetSizes(x, PETSC_DECIDE, n));
 30:   PetscCall(VecSetFromOptions(x));

 32:   /* If we want to use negative indices, set the option */
 33:   PetscCall(VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES, set_option_negidx));

 35:   PetscCall(VecGetOwnershipRange(x, &istart, &iend));
 36:   m = iend - istart;

 38:   PetscCall(PetscMalloc1(n, &values));
 39:   PetscCall(PetscMalloc1(n, &indices));

 41:   for (i = istart; i < iend; i++) {
 42:     values[i - istart] = (rank + 1) * i * 2;
 43:     if (set_values_negidx) indices[i - istart] = (-1 + 2 * (i % 2)) * i;
 44:     else indices[i - istart] = i;
 45:   }

 47:   PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%d: Setting values...\n", rank));
 48:   for (i = 0; i < m; i++) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%d: idx[%" PetscInt_FMT "] == %" PetscInt_FMT "; val[%" PetscInt_FMT "] == %f\n", rank, i, indices[i], i, (double)PetscRealPart(values[i])));
 49:   PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT));

 51:   PetscCall(VecSetValues(x, m, indices, values, INSERT_VALUES));

 53:   /*
 54:      Assemble vector.
 55:   */

 57:   PetscCall(VecAssemblyBegin(x));
 58:   PetscCall(VecAssemblyEnd(x));

 60:   /*
 61:      Extract values from the vector.
 62:   */

 64:   for (i = 0; i < m; i++) {
 65:     values[i] = -1.0;
 66:     if (get_values_negidx) indices[i] = (-1 + 2 * ((istart + i) % 2)) * (istart + i);
 67:     else indices[i] = istart + i;
 68:   }

 70:   PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%d: Fetching these values from vector...\n", rank));
 71:   for (i = 0; i < m; i++) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%d: idx[%" PetscInt_FMT "] == %" PetscInt_FMT "\n", rank, i, indices[i]));
 72:   PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT));

 74:   PetscCall(VecGetValues(x, m, indices, values));

 76:   PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%d: Fetched values:\n", rank));
 77:   for (i = 0; i < m; i++) PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "%d: idx[%" PetscInt_FMT "] == %" PetscInt_FMT "; val[%" PetscInt_FMT "] == %f\n", rank, i, indices[i], i, (double)PetscRealPart(values[i])));
 78:   PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT));

 80:   /*
 81:      Free work space.
 82:   */

 84:   PetscCall(VecDestroy(&x));
 85:   PetscCall(PetscFree(values));
 86:   PetscCall(PetscFree(indices));

 88:   PetscCall(PetscFinalize());
 89:   return 0;
 90: }

 92: /*TEST

 94:    test:
 95:       nsize: 2
 96:       args: -set_option_negidx -set_values_negidx -get_values_negidx

 98: TEST*/