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: }