Actual source code: psplit.c

  1: /*$Id: psplit.c,v 1.16 2001/03/23 23:20:45 balay Exp $*/

 3:  #include petsc.h

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

 12:    Collective on MPI_Comm (if N is PETSC_DECIDE)

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

 20:   Level: developer

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

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

 28: .seealso: PetscSplitOwnership()

 30: @*/
 31: int PetscSplitOwnershipBlock(MPI_Comm comm,int bs,int *n,int *N)
 32: {
 33:   int ierr,size,rank;

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

 38:   if (*N == PETSC_DECIDE) {
 39:     if (*n % bs != 0) SETERRQ2(1,"local size %d not divisible by block size %d",*n,bs);
 40:     MPI_Allreduce(n,N,1,MPI_INT,MPI_SUM,comm);
 41:   } else if (*n == PETSC_DECIDE) {
 42:     int 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: }


 51: #undef __FUNCT__  
 53: /*@C
 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: int PetscSplitOwnership(MPI_Comm comm,int *n,int *N)
 76: {
 77:   int ierr,size,rank;

 80:   if (*N == PETSC_DECIDE && *n == PETSC_DECIDE) SETERRQ(1,"Both n and N cannot be PETSC_DECIDE");

 82:   if (*N == PETSC_DECIDE) {
 83:     MPI_Allreduce(n,N,1,MPI_INT,MPI_SUM,comm);
 84:   } else if (*n == PETSC_DECIDE) {
 85:     MPI_Comm_size(comm,&size);
 86:     MPI_Comm_rank(comm,&rank);
 87:     *n = *N/size + ((*N % size) > rank);
 88: #if defined(PETSC_USE_BOPT_g)
 89:   } else {
 90:     int tmp;
 91:     MPI_Allreduce(n,&tmp,1,MPI_INT,MPI_SUM,comm);
 92:     if (tmp != *N) SETERRQ3(1,"Sum of local lengths %d does not equal global length %d, my local length %d",tmp,*N,*n);
 93: #endif
 94:   }

 96:   return(0);
 97: }