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 PetscMPIInt size,rank; 31e5c89e4eSSatish Balay 32e5c89e4eSSatish Balay PetscFunctionBegin; 332c71b3e2SJacob Faibussowitsch PetscCheckFalse(*N == PETSC_DECIDE && *n == PETSC_DECIDE,PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE"); 34e5c89e4eSSatish Balay 35e5c89e4eSSatish Balay if (*N == PETSC_DECIDE) { 36*08401ef6SPierre Jolivet PetscCheck(*n % bs == 0,PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"local size %" PetscInt_FMT " not divisible by block size %" PetscInt_FMT,*n,bs); 371c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(n,N,1,MPIU_INT,MPI_SUM,comm)); 38e5c89e4eSSatish Balay } else if (*n == PETSC_DECIDE) { 39e5c89e4eSSatish Balay PetscInt Nbs = *N/bs; 409566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&size)); 419566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 42e5c89e4eSSatish Balay *n = bs*(Nbs/size + ((Nbs % size) > rank)); 43e5c89e4eSSatish Balay } 44e5c89e4eSSatish Balay PetscFunctionReturn(0); 45e5c89e4eSSatish Balay } 46e5c89e4eSSatish Balay 47e30d2299SSatish Balay /*@ 48e5c89e4eSSatish Balay PetscSplitOwnership - Given a global (or local) length determines a local 49e5c89e4eSSatish Balay (or global) length via a simple formula 50e5c89e4eSSatish Balay 51d083f849SBarry Smith Collective (if n or N is PETSC_DECIDE) 52e5c89e4eSSatish Balay 53e5c89e4eSSatish Balay Input Parameters: 54e5c89e4eSSatish Balay + comm - MPI communicator that shares the object being divided 55e5c89e4eSSatish Balay . n - local length (or PETSC_DECIDE to have it set) 56e5c89e4eSSatish Balay - N - global length (or PETSC_DECIDE) 57e5c89e4eSSatish Balay 58e5c89e4eSSatish Balay Level: developer 59e5c89e4eSSatish Balay 60e5c89e4eSSatish Balay Notes: 61e5c89e4eSSatish Balay n and N cannot be both PETSC_DECIDE 62e5c89e4eSSatish Balay 630e9ea286SStefano Zampini If one processor calls this with n or N of PETSC_DECIDE then all processors 640e9ea286SStefano Zampini must. Otherwise, an error is thrown in debug mode while the program will hang 650e9ea286SStefano Zampini in optimized (i.e. configured --with-debugging=0) mode. 66e5c89e4eSSatish Balay 67e5c89e4eSSatish Balay .seealso: PetscSplitOwnershipBlock() 68e5c89e4eSSatish Balay 69e5c89e4eSSatish Balay @*/ 707087cfbeSBarry Smith PetscErrorCode PetscSplitOwnership(MPI_Comm comm,PetscInt *n,PetscInt *N) 71e5c89e4eSSatish Balay { 72e5c89e4eSSatish Balay PetscMPIInt size,rank; 73e5c89e4eSSatish Balay 74e5c89e4eSSatish Balay PetscFunctionBegin; 752c71b3e2SJacob Faibussowitsch PetscCheckFalse(*N == PETSC_DECIDE && *n == PETSC_DECIDE,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://petsc.org/release/faq/#split-ownership"); 7676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 770e9ea286SStefano Zampini PetscMPIInt l[2],g[2]; 780e9ea286SStefano Zampini l[0] = (*n == PETSC_DECIDE) ? 1 : 0; 790e9ea286SStefano Zampini l[1] = (*N == PETSC_DECIDE) ? 1 : 0; 809566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&size)); 811c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(l,g,2,MPI_INT,MPI_SUM,comm)); 822c71b3e2SJacob Faibussowitsch PetscCheckFalse(g[0] && g[0] != size,comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for local size"); 832c71b3e2SJacob Faibussowitsch PetscCheckFalse(g[1] && g[1] != size,comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for global size"); 840e9ea286SStefano Zampini } 85e5c89e4eSSatish Balay 86e5c89e4eSSatish Balay if (*N == PETSC_DECIDE) { 8781863419SJunchao Zhang PetscInt64 m = *n, M; 881c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&m,&M,1,MPIU_INT64,MPI_SUM,comm)); 89*08401ef6SPierre Jolivet PetscCheck(M <= PETSC_MAX_INT,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); 9081863419SJunchao Zhang else *N = (PetscInt)M; 91e5c89e4eSSatish Balay } else if (*n == PETSC_DECIDE) { 929566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&size)); 939566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 94e5c89e4eSSatish Balay *n = *N/size + ((*N % size) > rank); 9576bd3646SJed Brown } else if (PetscDefined(USE_DEBUG)) { 96e5c89e4eSSatish Balay PetscInt tmp; 971c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm)); 98*08401ef6SPierre Jolivet PetscCheck(tmp == *N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local lengths %" PetscInt_FMT " does not equal global length %" PetscInt_FMT ", my local length %" PetscInt_FMT "\n likely a call to VecSetSizes() or MatSetSizes() is wrong.\nSee https://petsc.org/release/faq/#split-ownership",tmp,*N,*n); 99e5c89e4eSSatish Balay } 100e5c89e4eSSatish Balay PetscFunctionReturn(0); 101e5c89e4eSSatish Balay } 102e5c89e4eSSatish Balay 103d24d4204SJose E. Roman /*@ 104d24d4204SJose E. Roman PetscSplitOwnershipEqual - Given a global (or local) length determines a local 105d24d4204SJose E. Roman (or global) length via a simple formula, trying to have all local lengths equal 106d24d4204SJose E. Roman 107d24d4204SJose E. Roman Collective (if n or N is PETSC_DECIDE) 108d24d4204SJose E. Roman 109d24d4204SJose E. Roman Input Parameters: 110d24d4204SJose E. Roman + comm - MPI communicator that shares the object being divided 111d24d4204SJose E. Roman . n - local length (or PETSC_DECIDE to have it set) 112d24d4204SJose E. Roman - N - global length (or PETSC_DECIDE) 113d24d4204SJose E. Roman 114d24d4204SJose E. Roman Level: developer 115d24d4204SJose E. Roman 116d24d4204SJose E. Roman Notes: 117d24d4204SJose E. Roman This is intended to be used with MATSCALAPACK, where the local size must 118d24d4204SJose E. Roman be equal in all processes (except possibly the last one). For instance, 119d24d4204SJose E. Roman the local sizes when spliting N=50 with 6 processes are 9,9,9,9,9,5 120d24d4204SJose E. Roman 121d24d4204SJose E. Roman n and N cannot be both PETSC_DECIDE 122d24d4204SJose E. Roman 123d24d4204SJose E. Roman If one processor calls this with n or N of PETSC_DECIDE then all processors 124d24d4204SJose E. Roman must. Otherwise, an error is thrown in debug mode while the program will hang 125d24d4204SJose E. Roman in optimized (i.e. configured --with-debugging=0) mode. 126d24d4204SJose E. Roman 127d24d4204SJose E. Roman .seealso: PetscSplitOwnership(), PetscSplitOwnershipBlock() 128d24d4204SJose E. Roman 129d24d4204SJose E. Roman @*/ 130d24d4204SJose E. Roman PetscErrorCode PetscSplitOwnershipEqual(MPI_Comm comm,PetscInt *n,PetscInt *N) 131d24d4204SJose E. Roman { 132d24d4204SJose E. Roman PetscMPIInt size,rank; 133d24d4204SJose E. Roman 134d24d4204SJose E. Roman PetscFunctionBegin; 1352c71b3e2SJacob Faibussowitsch PetscCheckFalse(*N == PETSC_DECIDE && *n == PETSC_DECIDE,PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Both n and N cannot be PETSC_DECIDE"); 136d24d4204SJose E. Roman if (PetscDefined(USE_DEBUG)) { 137d24d4204SJose E. Roman PetscMPIInt l[2],g[2]; 138d24d4204SJose E. Roman l[0] = (*n == PETSC_DECIDE) ? 1 : 0; 139d24d4204SJose E. Roman l[1] = (*N == PETSC_DECIDE) ? 1 : 0; 1409566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&size)); 1411c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(l,g,2,MPI_INT,MPI_SUM,comm)); 1422c71b3e2SJacob Faibussowitsch PetscCheckFalse(g[0] && g[0] != size,comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for local size"); 1432c71b3e2SJacob Faibussowitsch PetscCheckFalse(g[1] && g[1] != size,comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for global size"); 144d24d4204SJose E. Roman } 145d24d4204SJose E. Roman 146d24d4204SJose E. Roman if (*N == PETSC_DECIDE) { 147d24d4204SJose E. Roman PetscInt64 m = *n, M; 1481c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(&m,&M,1,MPIU_INT64,MPI_SUM,comm)); 149*08401ef6SPierre Jolivet PetscCheck(M <= PETSC_MAX_INT,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); 150d24d4204SJose E. Roman else *N = (PetscInt)M; 151d24d4204SJose E. Roman } else if (*n == PETSC_DECIDE) { 1529566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&size)); 1539566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 154d24d4204SJose E. Roman *n = *N/size; 155d24d4204SJose E. Roman if (*N % size) { 156d24d4204SJose E. Roman if ((rank+1)*(*n+1)<=*N) *n = *n+1; 157d24d4204SJose E. Roman else if (rank*(*n+1)<=*N) *n = *N-rank*(*n+1); 158d24d4204SJose E. Roman else *n = 0; 159d24d4204SJose E. Roman } 160d24d4204SJose E. Roman } else if (PetscDefined(USE_DEBUG)) { 161d24d4204SJose E. Roman PetscInt tmp; 1621c2dc1cbSBarry Smith PetscCall(MPIU_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm)); 163*08401ef6SPierre Jolivet PetscCheck(tmp == *N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local lengths %" PetscInt_FMT " does not equal global length %" PetscInt_FMT ", my local length %" PetscInt_FMT,tmp,*N,*n); 164d24d4204SJose E. Roman } 165d24d4204SJose E. Roman PetscFunctionReturn(0); 166d24d4204SJose E. Roman } 167