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); 38b2566f29SBarry Smith ierr = MPIU_Allreduce(n,N,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); 39e5c89e4eSSatish Balay } else if (*n == PETSC_DECIDE) { 40e5c89e4eSSatish Balay PetscInt Nbs = *N/bs; 41e5c89e4eSSatish Balay ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 42e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(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; 830e9ea286SStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 840e9ea286SStefano Zampini ierr = MPIU_Allreduce(l,g,2,MPI_INT,MPI_SUM,comm);CHKERRQ(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; 9181863419SJunchao Zhang ierr = MPIU_Allreduce(&m,&M,1,MPIU_INT64,MPI_SUM,comm);CHKERRQ(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) { 95e5c89e4eSSatish Balay ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 96e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 97e5c89e4eSSatish Balay *n = *N/size + ((*N % size) > rank); 9876bd3646SJed Brown } else if (PetscDefined(USE_DEBUG)) { 99e5c89e4eSSatish Balay PetscInt tmp; 100b2566f29SBarry Smith ierr = MPIU_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(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 106*d24d4204SJose E. Roman 107*d24d4204SJose E. Roman /*@ 108*d24d4204SJose E. Roman PetscSplitOwnershipEqual - Given a global (or local) length determines a local 109*d24d4204SJose E. Roman (or global) length via a simple formula, trying to have all local lengths equal 110*d24d4204SJose E. Roman 111*d24d4204SJose E. Roman Collective (if n or N is PETSC_DECIDE) 112*d24d4204SJose E. Roman 113*d24d4204SJose E. Roman Input Parameters: 114*d24d4204SJose E. Roman + comm - MPI communicator that shares the object being divided 115*d24d4204SJose E. Roman . n - local length (or PETSC_DECIDE to have it set) 116*d24d4204SJose E. Roman - N - global length (or PETSC_DECIDE) 117*d24d4204SJose E. Roman 118*d24d4204SJose E. Roman Level: developer 119*d24d4204SJose E. Roman 120*d24d4204SJose E. Roman Notes: 121*d24d4204SJose E. Roman This is intended to be used with MATSCALAPACK, where the local size must 122*d24d4204SJose E. Roman be equal in all processes (except possibly the last one). For instance, 123*d24d4204SJose E. Roman the local sizes when spliting N=50 with 6 processes are 9,9,9,9,9,5 124*d24d4204SJose E. Roman 125*d24d4204SJose E. Roman n and N cannot be both PETSC_DECIDE 126*d24d4204SJose E. Roman 127*d24d4204SJose E. Roman If one processor calls this with n or N of PETSC_DECIDE then all processors 128*d24d4204SJose E. Roman must. Otherwise, an error is thrown in debug mode while the program will hang 129*d24d4204SJose E. Roman in optimized (i.e. configured --with-debugging=0) mode. 130*d24d4204SJose E. Roman 131*d24d4204SJose E. Roman .seealso: PetscSplitOwnership(), PetscSplitOwnershipBlock() 132*d24d4204SJose E. Roman 133*d24d4204SJose E. Roman @*/ 134*d24d4204SJose E. Roman PetscErrorCode PetscSplitOwnershipEqual(MPI_Comm comm,PetscInt *n,PetscInt *N) 135*d24d4204SJose E. Roman { 136*d24d4204SJose E. Roman PetscErrorCode ierr; 137*d24d4204SJose E. Roman PetscMPIInt size,rank; 138*d24d4204SJose E. Roman 139*d24d4204SJose E. Roman PetscFunctionBegin; 140*d24d4204SJose 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"); 141*d24d4204SJose E. Roman if (PetscDefined(USE_DEBUG)) { 142*d24d4204SJose E. Roman PetscMPIInt l[2],g[2]; 143*d24d4204SJose E. Roman l[0] = (*n == PETSC_DECIDE) ? 1 : 0; 144*d24d4204SJose E. Roman l[1] = (*N == PETSC_DECIDE) ? 1 : 0; 145*d24d4204SJose E. Roman ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 146*d24d4204SJose E. Roman ierr = MPIU_Allreduce(l,g,2,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 147*d24d4204SJose E. Roman if (g[0] && g[0] != size) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for local size"); 148*d24d4204SJose E. Roman if (g[1] && g[1] != size) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"All processes must supply PETSC_DECIDE for global size"); 149*d24d4204SJose E. Roman } 150*d24d4204SJose E. Roman 151*d24d4204SJose E. Roman if (*N == PETSC_DECIDE) { 152*d24d4204SJose E. Roman PetscInt64 m = *n, M; 153*d24d4204SJose E. Roman ierr = MPIU_Allreduce(&m,&M,1,MPIU_INT64,MPI_SUM,comm);CHKERRQ(ierr); 154*d24d4204SJose 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); 155*d24d4204SJose E. Roman else *N = (PetscInt)M; 156*d24d4204SJose E. Roman } else if (*n == PETSC_DECIDE) { 157*d24d4204SJose E. Roman ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 158*d24d4204SJose E. Roman ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 159*d24d4204SJose E. Roman *n = *N/size; 160*d24d4204SJose E. Roman if (*N % size) { 161*d24d4204SJose E. Roman if ((rank+1)*(*n+1)<=*N) *n = *n+1; 162*d24d4204SJose E. Roman else if (rank*(*n+1)<=*N) *n = *N-rank*(*n+1); 163*d24d4204SJose E. Roman else *n = 0; 164*d24d4204SJose E. Roman } 165*d24d4204SJose E. Roman } else if (PetscDefined(USE_DEBUG)) { 166*d24d4204SJose E. Roman PetscInt tmp; 167*d24d4204SJose E. Roman ierr = MPIU_Allreduce(n,&tmp,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); 168*d24d4204SJose 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); 169*d24d4204SJose E. Roman } 170*d24d4204SJose E. Roman PetscFunctionReturn(0); 171*d24d4204SJose E. Roman } 172*d24d4204SJose E. Roman 173