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); 40e5c89e4eSSatish Balay ierr = MPI_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; 81*f08646a8SSatish 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) { 84e5c89e4eSSatish Balay ierr = MPI_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; 92e5c89e4eSSatish Balay ierr = MPI_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); 93*f08646a8SSatish 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