Actual source code: iscomp.c

      1: #include <petsc/private/isimpl.h>
      2: #include <petscviewer.h>

      4: /*@
      5:   ISEqual  - Compares if two index sets have the same set of indices.

      7:   Collective

      9:   Input Parameters:
     10: + is1 - first index set to compare
     11: - is2 - second index set to compare

     13:   Output Parameter:
     14: . flg - output flag, either `PETSC_TRUE` (if both index sets have the
     15:          same indices), or `PETSC_FALSE` if the index sets differ by size
     16:          or by the set of indices)

     18:   Level: intermediate

     20:   Note:
     21:   Unlike `ISEqualUnsorted()`, this routine sorts the contents of the index sets (only within each MPI rank) before
     22:   the comparison is made, so the order of the indices on a processor is immaterial.

     24:   Each processor has to have the same indices in the two sets, for example,
     25: .vb
     26:            Processor
     27:              0      1
     28:     is1 = {0, 1} {2, 3}
     29:     is2 = {2, 3} {0, 1}
     30: .ve
     31:   will return false.

     33: .seealso: [](sec_scatter), `IS`, `ISEqualUnsorted()`
     34: @*/
     35: PetscErrorCode ISEqual(IS is1, IS is2, PetscBool *flg)
     36: {
     37:   PetscInt        sz1, sz2, *a1, *a2;
     38:   const PetscInt *ptr1, *ptr2;
     39:   PetscBool       flag;
     40:   MPI_Comm        comm;
     41:   PetscMPIInt     mflg;

     43:   PetscFunctionBegin;
     46:   PetscAssertPointer(flg, 3);

     48:   if (is1 == is2) {
     49:     *flg = PETSC_TRUE;
     50:     PetscFunctionReturn(PETSC_SUCCESS);
     51:   }

     53:   PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)is1), PetscObjectComm((PetscObject)is2), &mflg));
     54:   if (mflg != MPI_CONGRUENT && mflg != MPI_IDENT) {
     55:     *flg = PETSC_FALSE;
     56:     PetscFunctionReturn(PETSC_SUCCESS);
     57:   }

     59:   PetscCall(ISGetSize(is1, &sz1));
     60:   PetscCall(ISGetSize(is2, &sz2));
     61:   if (sz1 != sz2) *flg = PETSC_FALSE;
     62:   else {
     63:     PetscCall(ISGetLocalSize(is1, &sz1));
     64:     PetscCall(ISGetLocalSize(is2, &sz2));

     66:     if (sz1 != sz2) flag = PETSC_FALSE;
     67:     else {
     68:       PetscCall(ISGetIndices(is1, &ptr1));
     69:       PetscCall(ISGetIndices(is2, &ptr2));

     71:       PetscCall(PetscMalloc1(sz1, &a1));
     72:       PetscCall(PetscMalloc1(sz2, &a2));

     74:       PetscCall(PetscArraycpy(a1, ptr1, sz1));
     75:       PetscCall(PetscArraycpy(a2, ptr2, sz2));

     77:       PetscCall(PetscIntSortSemiOrdered(sz1, a1));
     78:       PetscCall(PetscIntSortSemiOrdered(sz2, a2));
     79:       PetscCall(PetscArraycmp(a1, a2, sz1, &flag));

     81:       PetscCall(ISRestoreIndices(is1, &ptr1));
     82:       PetscCall(ISRestoreIndices(is2, &ptr2));

     84:       PetscCall(PetscFree(a1));
     85:       PetscCall(PetscFree(a2));
     86:     }
     87:     PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
     88:     PetscCallMPI(MPIU_Allreduce(&flag, flg, 1, MPI_C_BOOL, MPI_LAND, comm));
     89:   }
     90:   PetscFunctionReturn(PETSC_SUCCESS);
     91: }

     93: /*@
     94:   ISEqualUnsorted  - Compares if two index sets have the same indices.

     96:   Collective

     98:   Input Parameters:
     99: + is1 - first index set to compare
    100: - is2 - second index set to compare

    102:   Output Parameter:
    103: . flg - output flag, either `PETSC_TRUE` (if both index sets have the
    104:          same indices), or `PETSC_FALSE` if the index sets differ by size
    105:          or by the set of indices)

    107:   Level: intermediate

    109:   Note:
    110:   Unlike `ISEqual()`, this routine does NOT sort the contents of the index sets before
    111:   the comparison is made, i.e., the order of indices is important.

    113:   Each MPI rank must have the same indices.

    115: .seealso: [](sec_scatter), `IS`, `ISEqual()`
    116: @*/
    117: PetscErrorCode ISEqualUnsorted(IS is1, IS is2, PetscBool *flg)
    118: {
    119:   PetscInt        sz1, sz2;
    120:   const PetscInt *ptr1, *ptr2;
    121:   PetscBool       flag;
    122:   MPI_Comm        comm;
    123:   PetscMPIInt     mflg;

    125:   PetscFunctionBegin;
    128:   PetscAssertPointer(flg, 3);

    130:   if (is1 == is2) {
    131:     *flg = PETSC_TRUE;
    132:     PetscFunctionReturn(PETSC_SUCCESS);
    133:   }

    135:   PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)is1), PetscObjectComm((PetscObject)is2), &mflg));
    136:   if (mflg != MPI_CONGRUENT && mflg != MPI_IDENT) {
    137:     *flg = PETSC_FALSE;
    138:     PetscFunctionReturn(PETSC_SUCCESS);
    139:   }

    141:   PetscCall(ISGetSize(is1, &sz1));
    142:   PetscCall(ISGetSize(is2, &sz2));
    143:   if (sz1 != sz2) *flg = PETSC_FALSE;
    144:   else {
    145:     PetscCall(ISGetLocalSize(is1, &sz1));
    146:     PetscCall(ISGetLocalSize(is2, &sz2));

    148:     if (sz1 != sz2) flag = PETSC_FALSE;
    149:     else {
    150:       PetscCall(ISGetIndices(is1, &ptr1));
    151:       PetscCall(ISGetIndices(is2, &ptr2));

    153:       PetscCall(PetscArraycmp(ptr1, ptr2, sz1, &flag));

    155:       PetscCall(ISRestoreIndices(is1, &ptr1));
    156:       PetscCall(ISRestoreIndices(is2, &ptr2));
    157:     }
    158:     PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
    159:     PetscCallMPI(MPIU_Allreduce(&flag, flg, 1, MPI_C_BOOL, MPI_LAND, comm));
    160:   }
    161:   PetscFunctionReturn(PETSC_SUCCESS);
    162: }