1e5c89e4eSSatish Balay #define PETSC_DLL 2e5c89e4eSSatish Balay 3d382aafbSBarry Smith #include "petscsys.h" /*I "petscsys.h" I*/ 4e5c89e4eSSatish Balay 5e5c89e4eSSatish Balay #undef __FUNCT__ 6e5c89e4eSSatish Balay #define __FUNCT__ "PetscSplitOwnershipBlock" 7e30d2299SSatish 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; 37*e32f2f54SBarry Smith if (*N == PETSC_DECIDE && *n == PETSC_DECIDE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE"); 38e5c89e4eSSatish Balay 39e5c89e4eSSatish Balay if (*N == PETSC_DECIDE) { 40*e32f2f54SBarry Smith if (*n % bs != 0) SETERRQ2(PETSC_COMM_SELF,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" 54e30d2299SSatish 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; 82*e32f2f54SBarry Smith 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/petsc-as/documentation/faq.html#split"); 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); 94*e32f2f54SBarry Smith 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/petsc-as/documentation/faq.html#split",tmp,*N,*n); 95e5c89e4eSSatish Balay #endif 96e5c89e4eSSatish Balay } 97e5c89e4eSSatish Balay PetscFunctionReturn(0); 98e5c89e4eSSatish Balay } 99e5c89e4eSSatish Balay 100