1c6db04a5SJed Brown #include <petscsys.h> /*I "petscsys.h" I*/
2e5c89e4eSSatish Balay
3e30d2299SSatish Balay /*@
4e5c89e4eSSatish Balay PetscSplitOwnershipBlock - Given a global (or local) length determines a local
5e5c89e4eSSatish Balay (or global) length via a simple formula. Splits so each processors local size
6e5c89e4eSSatish Balay is divisible by the block size.
7e5c89e4eSSatish Balay
8667f096bSBarry Smith Collective (if `N` is `PETSC_DECIDE`)
9e5c89e4eSSatish Balay
10e5c89e4eSSatish Balay Input Parameters:
11e5c89e4eSSatish Balay + comm - MPI communicator that shares the object being divided
12e5c89e4eSSatish Balay . bs - block size
13811af0c4SBarry Smith . n - local length (or `PETSC_DECIDE` to have it set)
14811af0c4SBarry Smith - N - global length (or `PETSC_DECIDE`)
15e5c89e4eSSatish Balay
16e5c89e4eSSatish Balay Level: developer
17e5c89e4eSSatish Balay
18e5c89e4eSSatish Balay Notes:
19667f096bSBarry Smith `n` and `N` cannot be both `PETSC_DECIDE`
20e5c89e4eSSatish Balay
21667f096bSBarry Smith If one processor calls this with `N` of `PETSC_DECIDE` then all processors
22e5c89e4eSSatish Balay must, otherwise the program will hang.
23e5c89e4eSSatish Balay
24811af0c4SBarry Smith .seealso: `PetscSplitOwnership()`, `PetscSplitOwnershipEqual()`
25e5c89e4eSSatish Balay @*/
PetscSplitOwnershipBlock(MPI_Comm comm,PetscInt bs,PetscInt * n,PetscInt * N)26d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSplitOwnershipBlock(MPI_Comm comm, PetscInt bs, PetscInt *n, PetscInt *N)
27d71ae5a4SJacob Faibussowitsch {
28e5c89e4eSSatish Balay PetscMPIInt size, rank;
29e5c89e4eSSatish Balay
30e5c89e4eSSatish Balay PetscFunctionBegin;
31cc73adaaSBarry Smith PetscCheck(*N != PETSC_DECIDE || *n != PETSC_DECIDE, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Both n and N cannot be PETSC_DECIDE");
32e5c89e4eSSatish Balay
33e5c89e4eSSatish Balay if (*N == PETSC_DECIDE) {
3408401ef6SPierre Jolivet PetscCheck(*n % bs == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "local size %" PetscInt_FMT " not divisible by block size %" PetscInt_FMT, *n, bs);
35*462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(n, N, 1, MPIU_INT, MPI_SUM, comm));
36e5c89e4eSSatish Balay } else if (*n == PETSC_DECIDE) {
37e5c89e4eSSatish Balay PetscInt Nbs = *N / bs;
389566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size));
399566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank));
40e5c89e4eSSatish Balay *n = bs * (Nbs / size + ((Nbs % size) > rank));
41e5c89e4eSSatish Balay }
423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
43e5c89e4eSSatish Balay }
44e5c89e4eSSatish Balay
45e30d2299SSatish Balay /*@
46e5c89e4eSSatish Balay PetscSplitOwnership - Given a global (or local) length determines a local
47e5c89e4eSSatish Balay (or global) length via a simple formula
48e5c89e4eSSatish Balay
49b3480c81SBarry Smith Collective (if `n` or `N` is `PETSC_DECIDE` or `PETSC_DETERMINE`)
50e5c89e4eSSatish Balay
51e5c89e4eSSatish Balay Input Parameters:
52e5c89e4eSSatish Balay + comm - MPI communicator that shares the object being divided
53811af0c4SBarry Smith . n - local length (or `PETSC_DECIDE` to have it set)
54b3480c81SBarry Smith - N - global length (or `PETSC_DETERMINE` to have it set)
55e5c89e4eSSatish Balay
56e5c89e4eSSatish Balay Level: developer
57e5c89e4eSSatish Balay
58e5c89e4eSSatish Balay Notes:
59b3480c81SBarry Smith `n` and `N` cannot be both `PETSC_DECIDE` and `PETSC_DETERMINE`
60e5c89e4eSSatish Balay
61b3480c81SBarry Smith If one processor calls this with `n` of `PETSC_DECIDE` (or with `N` `PETSC_DETERMINE`) then all processors
620e9ea286SStefano Zampini must. Otherwise, an error is thrown in debug mode while the program will hang
630e9ea286SStefano Zampini in optimized (i.e. configured --with-debugging=0) mode.
64e5c89e4eSSatish Balay
65b3480c81SBarry Smith .seealso: `PetscSplitOwnershipBlock()`, `PetscSplitOwnershipEqual()`, `PETSC_DECIDE`, `PETSC_DETERMINE`
66e5c89e4eSSatish Balay @*/
PetscSplitOwnership(MPI_Comm comm,PetscInt * n,PetscInt * N)67d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
68d71ae5a4SJacob Faibussowitsch {
69e5c89e4eSSatish Balay PetscMPIInt size, rank;
70e5c89e4eSSatish Balay
71e5c89e4eSSatish Balay PetscFunctionBegin;
7200045ab3SPierre Jolivet PetscCheck(*N != PETSC_DECIDE || *n != PETSC_DECIDE, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Both n and N cannot be PETSC_DECIDE, likely a call to VecSetSizes() or MatSetSizes() is wrong. See https://petsc.org/release/faq/#split-ownership");
7376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) {
740e9ea286SStefano Zampini PetscMPIInt l[2], g[2];
750e9ea286SStefano Zampini l[0] = (*n == PETSC_DECIDE) ? 1 : 0;
760e9ea286SStefano Zampini l[1] = (*N == PETSC_DECIDE) ? 1 : 0;
779566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size));
78*462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(l, g, 2, MPI_INT, MPI_SUM, comm));
79cc73adaaSBarry Smith PetscCheck(!g[0] || g[0] == size, comm, PETSC_ERR_ARG_INCOMP, "All processes must supply PETSC_DECIDE for local size");
80cc73adaaSBarry Smith PetscCheck(!g[1] || g[1] == size, comm, PETSC_ERR_ARG_INCOMP, "All processes must supply PETSC_DECIDE for global size");
810e9ea286SStefano Zampini }
82e5c89e4eSSatish Balay
83e5c89e4eSSatish Balay if (*N == PETSC_DECIDE) {
84*462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(n, N, 1, MPIU_INT, MPI_SUM, comm));
85e5c89e4eSSatish Balay } else if (*n == PETSC_DECIDE) {
869566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size));
879566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank));
88e5c89e4eSSatish Balay *n = *N / size + ((*N % size) > rank);
8976bd3646SJed Brown } else if (PetscDefined(USE_DEBUG)) {
90e5c89e4eSSatish Balay PetscInt tmp;
91*462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(n, &tmp, 1, MPIU_INT, MPI_SUM, comm));
9200045ab3SPierre Jolivet PetscCheck(tmp == *N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Sum of local lengths %" PetscInt_FMT " does not equal global length %" PetscInt_FMT ", my local length %" PetscInt_FMT ", likely a call to VecSetSizes() or MatSetSizes() is wrong. See https://petsc.org/release/faq/#split-ownership", tmp, *N, *n);
93e5c89e4eSSatish Balay }
943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
95e5c89e4eSSatish Balay }
96e5c89e4eSSatish Balay
97d24d4204SJose E. Roman /*@
98d24d4204SJose E. Roman PetscSplitOwnershipEqual - Given a global (or local) length determines a local
99d24d4204SJose E. Roman (or global) length via a simple formula, trying to have all local lengths equal
100d24d4204SJose E. Roman
101667f096bSBarry Smith Collective (if `n` or `N` is `PETSC_DECIDE`)
102d24d4204SJose E. Roman
103d24d4204SJose E. Roman Input Parameters:
104d24d4204SJose E. Roman + comm - MPI communicator that shares the object being divided
105811af0c4SBarry Smith . n - local length (or `PETSC_DECIDE` to have it set)
106811af0c4SBarry Smith - N - global length (or `PETSC_DECIDE`)
107d24d4204SJose E. Roman
108d24d4204SJose E. Roman Level: developer
109d24d4204SJose E. Roman
110d24d4204SJose E. Roman Notes:
111811af0c4SBarry Smith This is intended to be used with `MATSCALAPACK`, where the local size must
112d24d4204SJose E. Roman be equal in all processes (except possibly the last one). For instance,
113667f096bSBarry Smith the local sizes when splitting `N`=50 with 6 processes are 9,9,9,9,9,5
114d24d4204SJose E. Roman
115811af0c4SBarry Smith n and N cannot be both `PETSC_DECIDE`
116d24d4204SJose E. Roman
117667f096bSBarry Smith If one processor calls this with `n` or `N` of `PETSC_DECIDE` then all processors
118d24d4204SJose E. Roman must. Otherwise, an error is thrown in debug mode while the program will hang
119d24d4204SJose E. Roman in optimized (i.e. configured --with-debugging=0) mode.
120d24d4204SJose E. Roman
121db781477SPatrick Sanan .seealso: `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`
122d24d4204SJose E. Roman @*/
PetscSplitOwnershipEqual(MPI_Comm comm,PetscInt * n,PetscInt * N)123d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSplitOwnershipEqual(MPI_Comm comm, PetscInt *n, PetscInt *N)
124d71ae5a4SJacob Faibussowitsch {
125d24d4204SJose E. Roman PetscMPIInt size, rank;
126d24d4204SJose E. Roman
127d24d4204SJose E. Roman PetscFunctionBegin;
128cc73adaaSBarry Smith PetscCheck(*N != PETSC_DECIDE || *n != PETSC_DECIDE, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Both n and N cannot be PETSC_DECIDE");
129d24d4204SJose E. Roman if (PetscDefined(USE_DEBUG)) {
130d24d4204SJose E. Roman PetscMPIInt l[2], g[2];
131d24d4204SJose E. Roman l[0] = (*n == PETSC_DECIDE) ? 1 : 0;
132d24d4204SJose E. Roman l[1] = (*N == PETSC_DECIDE) ? 1 : 0;
1339566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size));
134*462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(l, g, 2, MPI_INT, MPI_SUM, comm));
135cc73adaaSBarry Smith PetscCheck(!g[0] || g[0] == size, comm, PETSC_ERR_ARG_INCOMP, "All processes must supply PETSC_DECIDE for local size");
136cc73adaaSBarry Smith PetscCheck(!g[1] || g[1] == size, comm, PETSC_ERR_ARG_INCOMP, "All processes must supply PETSC_DECIDE for global size");
137d24d4204SJose E. Roman }
138d24d4204SJose E. Roman
139d24d4204SJose E. Roman if (*N == PETSC_DECIDE) {
140*462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(n, N, 1, MPIU_INT, MPI_SUM, comm));
141d24d4204SJose E. Roman } else if (*n == PETSC_DECIDE) {
1429566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size));
1439566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank));
144d24d4204SJose E. Roman *n = *N / size;
145d24d4204SJose E. Roman if (*N % size) {
146d24d4204SJose E. Roman if ((rank + 1) * (*n + 1) <= *N) *n = *n + 1;
147d24d4204SJose E. Roman else if (rank * (*n + 1) <= *N) *n = *N - rank * (*n + 1);
148d24d4204SJose E. Roman else *n = 0;
149d24d4204SJose E. Roman }
150d24d4204SJose E. Roman } else if (PetscDefined(USE_DEBUG)) {
151d24d4204SJose E. Roman PetscInt tmp;
152*462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(n, &tmp, 1, MPIU_INT, MPI_SUM, comm));
15308401ef6SPierre Jolivet PetscCheck(tmp == *N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Sum of local lengths %" PetscInt_FMT " does not equal global length %" PetscInt_FMT ", my local length %" PetscInt_FMT, tmp, *N, *n);
154d24d4204SJose E. Roman }
1553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
156d24d4204SJose E. Roman }
157