xref: /petsc/src/sys/utils/psplit.c (revision e30d229923a696673d75fd4bbec7dc9405e48f2f)
1e5c89e4eSSatish Balay #define PETSC_DLL
2e5c89e4eSSatish Balay 
3e5c89e4eSSatish Balay #include "petsc.h"           /*I    "petsc.h" I*/
4e5c89e4eSSatish Balay 
5e5c89e4eSSatish Balay #undef __FUNCT__
6e5c89e4eSSatish Balay #define __FUNCT__ "PetscSplitOwnershipBlock"
7*e30d2299SSatish Balay /*@
8e5c89e4eSSatish Balay     PetscSplitOwnershipBlock - Given a global (or local) length determines a local
9e5c89e4eSSatish Balay         (or global) length via a simple formula. Splits so each processors local size
10e5c89e4eSSatish Balay         is divisible by the block size.
11e5c89e4eSSatish Balay 
12e5c89e4eSSatish Balay    Collective on MPI_Comm (if N is PETSC_DECIDE)
13e5c89e4eSSatish Balay 
14e5c89e4eSSatish Balay    Input Parameters:
15e5c89e4eSSatish Balay +    comm - MPI communicator that shares the object being divided
16e5c89e4eSSatish Balay .    bs - block size
17e5c89e4eSSatish Balay .    n - local length (or PETSC_DECIDE to have it set)
18e5c89e4eSSatish Balay -    N - global length (or PETSC_DECIDE)
19e5c89e4eSSatish Balay 
20e5c89e4eSSatish Balay   Level: developer
21e5c89e4eSSatish Balay 
22e5c89e4eSSatish Balay    Notes:
23e5c89e4eSSatish Balay      n and N cannot be both PETSC_DECIDE
24e5c89e4eSSatish Balay 
25e5c89e4eSSatish Balay      If one processor calls this with N of PETSC_DECIDE then all processors
26e5c89e4eSSatish Balay      must, otherwise the program will hang.
27e5c89e4eSSatish Balay 
28e5c89e4eSSatish Balay .seealso: PetscSplitOwnership()
29e5c89e4eSSatish Balay 
30e5c89e4eSSatish Balay @*/
31e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscSplitOwnershipBlock(MPI_Comm comm,PetscInt bs,PetscInt *n,PetscInt *N)
32e5c89e4eSSatish Balay {
33e5c89e4eSSatish Balay   PetscErrorCode ierr;
34e5c89e4eSSatish Balay   PetscMPIInt    size,rank;
35e5c89e4eSSatish Balay 
36e5c89e4eSSatish Balay   PetscFunctionBegin;
37e5c89e4eSSatish Balay   if (*N == PETSC_DECIDE && *n == PETSC_DECIDE) SETERRQ(PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE");
38e5c89e4eSSatish Balay 
39e5c89e4eSSatish Balay   if (*N == PETSC_DECIDE) {
40e5c89e4eSSatish Balay     if (*n % bs != 0) SETERRQ2(PETSC_ERR_ARG_INCOMP,"local size %D not divisible by block size %D",*n,bs);
41e5c89e4eSSatish Balay     ierr = MPI_Allreduce(n,N,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr);
42e5c89e4eSSatish Balay   } else if (*n == PETSC_DECIDE) {
43e5c89e4eSSatish Balay     PetscInt Nbs = *N/bs;
44e5c89e4eSSatish Balay     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
45e5c89e4eSSatish Balay     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
46e5c89e4eSSatish Balay     *n = bs*(Nbs/size + ((Nbs % size) > rank));
47e5c89e4eSSatish Balay   }
48e5c89e4eSSatish Balay   PetscFunctionReturn(0);
49e5c89e4eSSatish Balay }
50e5c89e4eSSatish Balay 
51e5c89e4eSSatish Balay 
52e5c89e4eSSatish Balay #undef __FUNCT__
53e5c89e4eSSatish Balay #define __FUNCT__ "PetscSplitOwnership"
54*e30d2299SSatish Balay /*@
55e5c89e4eSSatish Balay     PetscSplitOwnership - Given a global (or local) length determines a local
56e5c89e4eSSatish Balay         (or global) length via a simple formula
57e5c89e4eSSatish Balay 
58e5c89e4eSSatish Balay    Collective on MPI_Comm (if N is PETSC_DECIDE)
59e5c89e4eSSatish Balay 
60e5c89e4eSSatish Balay    Input Parameters:
61e5c89e4eSSatish Balay +    comm - MPI communicator that shares the object being divided
62e5c89e4eSSatish Balay .    n - local length (or PETSC_DECIDE to have it set)
63e5c89e4eSSatish Balay -    N - global length (or PETSC_DECIDE)
64e5c89e4eSSatish Balay 
65e5c89e4eSSatish Balay   Level: developer
66e5c89e4eSSatish Balay 
67e5c89e4eSSatish Balay    Notes:
68e5c89e4eSSatish Balay      n and N cannot be both PETSC_DECIDE
69e5c89e4eSSatish Balay 
70e5c89e4eSSatish Balay      If one processor calls this with N of PETSC_DECIDE then all processors
71e5c89e4eSSatish Balay      must, otherwise the program will hang.
72e5c89e4eSSatish Balay 
73e5c89e4eSSatish Balay .seealso: PetscSplitOwnershipBlock()
74e5c89e4eSSatish Balay 
75e5c89e4eSSatish Balay @*/
76e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscSplitOwnership(MPI_Comm comm,PetscInt *n,PetscInt *N)
77e5c89e4eSSatish Balay {
78e5c89e4eSSatish Balay   PetscErrorCode ierr;
79e5c89e4eSSatish Balay   PetscMPIInt    size,rank;
80e5c89e4eSSatish Balay 
81e5c89e4eSSatish Balay   PetscFunctionBegin;
82e5c89e4eSSatish Balay   if (*N == PETSC_DECIDE && *n == PETSC_DECIDE) SETERRQ(PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE");
83e5c89e4eSSatish Balay 
84e5c89e4eSSatish Balay   if (*N == PETSC_DECIDE) {
85e5c89e4eSSatish Balay     ierr = MPI_Allreduce(n,N,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr);
86e5c89e4eSSatish Balay   } else if (*n == PETSC_DECIDE) {
87e5c89e4eSSatish Balay     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
88e5c89e4eSSatish Balay     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
89e5c89e4eSSatish Balay     *n = *N/size + ((*N % size) > rank);
90e5c89e4eSSatish Balay #if defined(PETSC_USE_DEBUG)
91e5c89e4eSSatish Balay   } else {
92e5c89e4eSSatish Balay     PetscInt tmp;
93e5c89e4eSSatish Balay     ierr = MPI_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr);
94e5c89e4eSSatish Balay     if (tmp != *N) SETERRQ3(PETSC_ERR_ARG_SIZ,"Sum of local lengths %D does not equal global length %D, my local length %D",tmp,*N,*n);
95e5c89e4eSSatish Balay #endif
96e5c89e4eSSatish Balay   }
97e5c89e4eSSatish Balay 
98e5c89e4eSSatish Balay   PetscFunctionReturn(0);
99e5c89e4eSSatish Balay }
100e5c89e4eSSatish Balay 
101