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