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