1e5c89e4eSSatish Balay 2c6db04a5SJed Brown #include <petscsys.h> /*I "petscsys.h" I*/ 3e5c89e4eSSatish Balay 4e30d2299SSatish Balay /*@ 5e5c89e4eSSatish Balay PetscSplitOwnershipBlock - Given a global (or local) length determines a local 6e5c89e4eSSatish Balay (or global) length via a simple formula. Splits so each processors local size 7e5c89e4eSSatish Balay is divisible by the block size. 8e5c89e4eSSatish Balay 9d083f849SBarry Smith Collective (if N is PETSC_DECIDE) 10e5c89e4eSSatish Balay 11e5c89e4eSSatish Balay Input Parameters: 12e5c89e4eSSatish Balay + comm - MPI communicator that shares the object being divided 13e5c89e4eSSatish Balay . bs - block size 14e5c89e4eSSatish Balay . n - local length (or PETSC_DECIDE to have it set) 15e5c89e4eSSatish Balay - N - global length (or PETSC_DECIDE) 16e5c89e4eSSatish Balay 17e5c89e4eSSatish Balay Level: developer 18e5c89e4eSSatish Balay 19e5c89e4eSSatish Balay Notes: 20e5c89e4eSSatish Balay n and N cannot be both PETSC_DECIDE 21e5c89e4eSSatish Balay 22e5c89e4eSSatish Balay If one processor calls this with N of PETSC_DECIDE then all processors 23e5c89e4eSSatish Balay must, otherwise the program will hang. 24e5c89e4eSSatish Balay 25e5c89e4eSSatish Balay .seealso: PetscSplitOwnership() 26e5c89e4eSSatish Balay 27e5c89e4eSSatish Balay @*/ 287087cfbeSBarry Smith PetscErrorCode PetscSplitOwnershipBlock(MPI_Comm comm,PetscInt bs,PetscInt *n,PetscInt *N) 29e5c89e4eSSatish Balay { 30e5c89e4eSSatish Balay PetscErrorCode ierr; 31e5c89e4eSSatish Balay PetscMPIInt size,rank; 32e5c89e4eSSatish Balay 33e5c89e4eSSatish Balay PetscFunctionBegin; 34e32f2f54SBarry Smith if (*N == PETSC_DECIDE && *n == PETSC_DECIDE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE"); 35e5c89e4eSSatish Balay 36e5c89e4eSSatish Balay if (*N == PETSC_DECIDE) { 37e32f2f54SBarry Smith if (*n % bs != 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"local size %D not divisible by block size %D",*n,bs); 38*820f2d46SBarry Smith ierr = MPIU_Allreduce(n,N,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 39e5c89e4eSSatish Balay } else if (*n == PETSC_DECIDE) { 40e5c89e4eSSatish Balay PetscInt Nbs = *N/bs; 41ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 42ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 43e5c89e4eSSatish Balay *n = bs*(Nbs/size + ((Nbs % size) > rank)); 44e5c89e4eSSatish Balay } 45e5c89e4eSSatish Balay PetscFunctionReturn(0); 46e5c89e4eSSatish Balay } 47e5c89e4eSSatish Balay 48e5c89e4eSSatish Balay 49e30d2299SSatish Balay /*@ 50e5c89e4eSSatish Balay PetscSplitOwnership - Given a global (or local) length determines a local 51e5c89e4eSSatish Balay (or global) length via a simple formula 52e5c89e4eSSatish Balay 53d083f849SBarry Smith Collective (if n or N is PETSC_DECIDE) 54e5c89e4eSSatish Balay 55e5c89e4eSSatish Balay Input Parameters: 56e5c89e4eSSatish Balay + comm - MPI communicator that shares the object being divided 57e5c89e4eSSatish Balay . n - local length (or PETSC_DECIDE to have it set) 58e5c89e4eSSatish Balay - N - global length (or PETSC_DECIDE) 59e5c89e4eSSatish Balay 60e5c89e4eSSatish Balay Level: developer 61e5c89e4eSSatish Balay 62e5c89e4eSSatish Balay Notes: 63e5c89e4eSSatish Balay n and N cannot be both PETSC_DECIDE 64e5c89e4eSSatish Balay 650e9ea286SStefano Zampini If one processor calls this with n or N of PETSC_DECIDE then all processors 660e9ea286SStefano Zampini must. Otherwise, an error is thrown in debug mode while the program will hang 670e9ea286SStefano Zampini in optimized (i.e. configured --with-debugging=0) mode. 68e5c89e4eSSatish Balay 69e5c89e4eSSatish Balay .seealso: PetscSplitOwnershipBlock() 70e5c89e4eSSatish Balay 71e5c89e4eSSatish Balay @*/ 727087cfbeSBarry Smith PetscErrorCode PetscSplitOwnership(MPI_Comm comm,PetscInt *n,PetscInt *N) 73e5c89e4eSSatish Balay { 74e5c89e4eSSatish Balay PetscErrorCode ierr; 75e5c89e4eSSatish Balay PetscMPIInt size,rank; 76e5c89e4eSSatish Balay 77e5c89e4eSSatish Balay PetscFunctionBegin; 78a8d69d7bSBarry 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 https://www.mcs.anl.gov/petsc/documentation/faq.html#split"); 7976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 800e9ea286SStefano Zampini PetscMPIInt l[2],g[2]; 810e9ea286SStefano Zampini l[0] = (*n == PETSC_DECIDE) ? 1 : 0; 820e9ea286SStefano Zampini l[1] = (*N == PETSC_DECIDE) ? 1 : 0; 83ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 84*820f2d46SBarry Smith ierr = MPIU_Allreduce(l,g,2,MPI_INT,MPI_SUM,comm);CHKERRMPI(ierr); 850e9ea286SStefano Zampini if (g[0] && g[0] != size) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for local size"); 860e9ea286SStefano Zampini if (g[1] && g[1] != size) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for global size"); 870e9ea286SStefano Zampini } 88e5c89e4eSSatish Balay 89e5c89e4eSSatish Balay if (*N == PETSC_DECIDE) { 9081863419SJunchao Zhang PetscInt64 m = *n, M; 91*820f2d46SBarry Smith ierr = MPIU_Allreduce(&m,&M,1,MPIU_INT64,MPI_SUM,comm);CHKERRMPI(ierr); 9281863419SJunchao Zhang if (M > PETSC_MAX_INT) SETERRQ1(comm,PETSC_ERR_INT_OVERFLOW,"Global size overflow %" PetscInt64_FMT ". You may consider ./configure PETSc with --with-64-bit-indices for the case you are running", M); 9381863419SJunchao Zhang else *N = (PetscInt)M; 94e5c89e4eSSatish Balay } else if (*n == PETSC_DECIDE) { 95ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 96ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 97e5c89e4eSSatish Balay *n = *N/size + ((*N % size) > rank); 9876bd3646SJed Brown } else if (PetscDefined(USE_DEBUG)) { 99e5c89e4eSSatish Balay PetscInt tmp; 100*820f2d46SBarry Smith ierr = MPIU_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 101a8d69d7bSBarry 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 https://www.mcs.anl.gov/petsc/documentation/faq.html#split",tmp,*N,*n); 102e5c89e4eSSatish Balay } 103e5c89e4eSSatish Balay PetscFunctionReturn(0); 104e5c89e4eSSatish Balay } 105e5c89e4eSSatish Balay 106d24d4204SJose E. Roman 107d24d4204SJose E. Roman /*@ 108d24d4204SJose E. Roman PetscSplitOwnershipEqual - Given a global (or local) length determines a local 109d24d4204SJose E. Roman (or global) length via a simple formula, trying to have all local lengths equal 110d24d4204SJose E. Roman 111d24d4204SJose E. Roman Collective (if n or N is PETSC_DECIDE) 112d24d4204SJose E. Roman 113d24d4204SJose E. Roman Input Parameters: 114d24d4204SJose E. Roman + comm - MPI communicator that shares the object being divided 115d24d4204SJose E. Roman . n - local length (or PETSC_DECIDE to have it set) 116d24d4204SJose E. Roman - N - global length (or PETSC_DECIDE) 117d24d4204SJose E. Roman 118d24d4204SJose E. Roman Level: developer 119d24d4204SJose E. Roman 120d24d4204SJose E. Roman Notes: 121d24d4204SJose E. Roman This is intended to be used with MATSCALAPACK, where the local size must 122d24d4204SJose E. Roman be equal in all processes (except possibly the last one). For instance, 123d24d4204SJose E. Roman the local sizes when spliting N=50 with 6 processes are 9,9,9,9,9,5 124d24d4204SJose E. Roman 125d24d4204SJose E. Roman n and N cannot be both PETSC_DECIDE 126d24d4204SJose E. Roman 127d24d4204SJose E. Roman If one processor calls this with n or N of PETSC_DECIDE then all processors 128d24d4204SJose E. Roman must. Otherwise, an error is thrown in debug mode while the program will hang 129d24d4204SJose E. Roman in optimized (i.e. configured --with-debugging=0) mode. 130d24d4204SJose E. Roman 131d24d4204SJose E. Roman .seealso: PetscSplitOwnership(), PetscSplitOwnershipBlock() 132d24d4204SJose E. Roman 133d24d4204SJose E. Roman @*/ 134d24d4204SJose E. Roman PetscErrorCode PetscSplitOwnershipEqual(MPI_Comm comm,PetscInt *n,PetscInt *N) 135d24d4204SJose E. Roman { 136d24d4204SJose E. Roman PetscErrorCode ierr; 137d24d4204SJose E. Roman PetscMPIInt size,rank; 138d24d4204SJose E. Roman 139d24d4204SJose E. Roman PetscFunctionBegin; 140d24d4204SJose E. Roman if (*N == PETSC_DECIDE && *n == PETSC_DECIDE) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE"); 141d24d4204SJose E. Roman if (PetscDefined(USE_DEBUG)) { 142d24d4204SJose E. Roman PetscMPIInt l[2],g[2]; 143d24d4204SJose E. Roman l[0] = (*n == PETSC_DECIDE) ? 1 : 0; 144d24d4204SJose E. Roman l[1] = (*N == PETSC_DECIDE) ? 1 : 0; 145ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 146*820f2d46SBarry Smith ierr = MPIU_Allreduce(l,g,2,MPI_INT,MPI_SUM,comm);CHKERRMPI(ierr); 147d24d4204SJose E. Roman if (g[0] && g[0] != size) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for local size"); 148d24d4204SJose E. Roman if (g[1] && g[1] != size) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for global size"); 149d24d4204SJose E. Roman } 150d24d4204SJose E. Roman 151d24d4204SJose E. Roman if (*N == PETSC_DECIDE) { 152d24d4204SJose E. Roman PetscInt64 m = *n, M; 153*820f2d46SBarry Smith ierr = MPIU_Allreduce(&m,&M,1,MPIU_INT64,MPI_SUM,comm);CHKERRMPI(ierr); 154d24d4204SJose E. Roman if (M > PETSC_MAX_INT) SETERRQ1(comm,PETSC_ERR_INT_OVERFLOW,"Global size overflow %" PetscInt64_FMT ". You may consider ./configure PETSc with --with-64-bit-indices for the case you are running", M); 155d24d4204SJose E. Roman else *N = (PetscInt)M; 156d24d4204SJose E. Roman } else if (*n == PETSC_DECIDE) { 157ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 158ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 159d24d4204SJose E. Roman *n = *N/size; 160d24d4204SJose E. Roman if (*N % size) { 161d24d4204SJose E. Roman if ((rank+1)*(*n+1)<=*N) *n = *n+1; 162d24d4204SJose E. Roman else if (rank*(*n+1)<=*N) *n = *N-rank*(*n+1); 163d24d4204SJose E. Roman else *n = 0; 164d24d4204SJose E. Roman } 165d24d4204SJose E. Roman } else if (PetscDefined(USE_DEBUG)) { 166d24d4204SJose E. Roman PetscInt tmp; 167*820f2d46SBarry Smith ierr = MPIU_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 168d24d4204SJose E. Roman 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",tmp,*N,*n); 169d24d4204SJose E. Roman } 170d24d4204SJose E. Roman PetscFunctionReturn(0); 171d24d4204SJose E. Roman } 172d24d4204SJose E. Roman 173