Date: 2013-07-02T14:39:11+00:00

Actual source code: psplit.c
petsc-3.4.2 2013-07-02

      2: #include <petscsys.h>           /*I    "petscsys.h" I*/

      6: /*@
      7:     PetscSplitOwnershipBlock - Given a global (or local) length determines a local
      8:         (or global) length via a simple formula. Splits so each processors local size
      9:         is divisible by the block size.

     11:    Collective on MPI_Comm (if N is PETSC_DECIDE)

     13:    Input Parameters:
     14: +    comm - MPI communicator that shares the object being divided
     15: .    bs - block size
     16: .    n - local length (or PETSC_DECIDE to have it set)
     17: -    N - global length (or PETSC_DECIDE)

     19:   Level: developer

     21:    Notes:
     22:      n and N cannot be both PETSC_DECIDE

     24:      If one processor calls this with N of PETSC_DECIDE then all processors
     25:      must, otherwise the program will hang.

     27: .seealso: PetscSplitOwnership()

     29: @*/
     30: PetscErrorCode  PetscSplitOwnershipBlock(MPI_Comm comm,PetscInt bs,PetscInt *n,PetscInt *N)
     31: {
     33:   PetscMPIInt    size,rank;

     36:   if (*N == PETSC_DECIDE && *n == PETSC_DECIDE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE");

     38:   if (*N == PETSC_DECIDE) {
     39:     if (*n % bs != 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"local size %D not divisible by block size %D",*n,bs);
     40:     MPI_Allreduce(n,N,1,MPIU_INT,MPI_SUM,comm);
     41:   } else if (*n == PETSC_DECIDE) {
     42:     PetscInt Nbs = *N/bs;
     43:     MPI_Comm_size(comm,&size);
     44:     MPI_Comm_rank(comm,&rank);
     45:     *n   = bs*(Nbs/size + ((Nbs % size) > rank));
     46:   }
     47:   return(0);
     48: }

     53: /*@
     54:     PetscSplitOwnership - Given a global (or local) length determines a local
     55:         (or global) length via a simple formula

     57:    Collective on MPI_Comm (if N is PETSC_DECIDE)

     59:    Input Parameters:
     60: +    comm - MPI communicator that shares the object being divided
     61: .    n - local length (or PETSC_DECIDE to have it set)
     62: -    N - global length (or PETSC_DECIDE)

     64:   Level: developer

     66:    Notes:
     67:      n and N cannot be both PETSC_DECIDE

     69:      If one processor calls this with N of PETSC_DECIDE then all processors
     70:      must, otherwise the program will hang.

     72: .seealso: PetscSplitOwnershipBlock()

     74: @*/
     75: PetscErrorCode  PetscSplitOwnership(MPI_Comm comm,PetscInt *n,PetscInt *N)
     76: {
     78:   PetscMPIInt    size,rank;

     81:   if (*N == PETSC_DECIDE && *n == PETSC_DECIDE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE\n  likely a call to VecSetSizes() or MatSetSizes() is wrong.\nSee http://www.mcs.anl.gov/petsc/documentation/faq.html#split");

     83:   if (*N == PETSC_DECIDE) {
     84:     MPI_Allreduce(n,N,1,MPIU_INT,MPI_SUM,comm);
     85:   } else if (*n == PETSC_DECIDE) {
     86:     MPI_Comm_size(comm,&size);
     87:     MPI_Comm_rank(comm,&rank);
     88:     *n   = *N/size + ((*N % size) > rank);
     89: #if defined(PETSC_USE_DEBUG)
     90:   } else {
     91:     PetscInt tmp;
     92:     MPI_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm);
     93:     if (tmp != *N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local lengths %D does not equal global length %D, my local length %D\n  likely a call to VecSetSizes() or MatSetSizes() is wrong.\nSee http://www.mcs.anl.gov/petsc/documentation/faq.html#split",tmp,*N,*n);
     94: #endif
     95:   }
     96:   return(0);
     97: }