169ce434fSBarry Smith /* 269ce434fSBarry Smith This file contains routines for basic map object implementation. 369ce434fSBarry Smith */ 469ce434fSBarry Smith 557e2745dSVaclav Hapla #include <petsc/private/isimpl.h> /*I "petscis.h" I*/ 65c25fcd7SBarry Smith 7c3002683SMatthew G. Knepley /*@ 8cab54364SBarry Smith PetscLayoutCreate - Allocates `PetscLayout` object 969ce434fSBarry Smith 10d083f849SBarry Smith Collective 1169ce434fSBarry Smith 122fe279fdSBarry Smith Input Parameter: 13a8643c1eSVaclav Hapla . comm - the MPI communicator 14a8643c1eSVaclav Hapla 152fe279fdSBarry Smith Output Parameter: 16cab54364SBarry Smith . map - the new `PetscLayout` 1769ce434fSBarry Smith 18456fcb79SJed Brown Level: advanced 1969ce434fSBarry Smith 20456fcb79SJed Brown Notes: 21456fcb79SJed Brown Typical calling sequence 22456fcb79SJed Brown .vb 2369ce434fSBarry Smith PetscLayoutCreate(MPI_Comm,PetscLayout *); 24a8643c1eSVaclav Hapla PetscLayoutSetBlockSize(PetscLayout,bs); 25a8643c1eSVaclav Hapla PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n); 2669ce434fSBarry Smith PetscLayoutSetUp(PetscLayout); 27456fcb79SJed Brown .ve 289621ec18SVaclav Hapla Alternatively, 29147403d9SBarry Smith .vb 30147403d9SBarry Smith PetscLayoutCreateFromSizes(comm,n,N,bs,&layout); 31147403d9SBarry Smith .ve 329621ec18SVaclav Hapla 33147403d9SBarry Smith Optionally use any of the following 34147403d9SBarry Smith .vb 35147403d9SBarry Smith PetscLayoutGetSize(PetscLayout,PetscInt *); 36147403d9SBarry Smith PetscLayoutGetLocalSize(PetscLayout,PetscInt *); 37147403d9SBarry Smith PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend); 38147403d9SBarry Smith PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]); 39147403d9SBarry Smith PetscLayoutDestroy(PetscLayout*); 40147403d9SBarry Smith .ve 4169ce434fSBarry Smith 42cab54364SBarry Smith The `PetscLayout` object and methods are intended to be used in the PETSc `Vec` and `Mat` implementations; it is often not needed in 4369ce434fSBarry Smith user codes unless you really gain something in their use. 4469ce434fSBarry Smith 45cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, 46cab54364SBarry Smith `PetscLayout`, `PetscLayoutDestroy()`, 47db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, 48db781477SPatrick Sanan `PetscLayoutCreateFromSizes()` 4969ce434fSBarry Smith @*/ 50d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreate(MPI_Comm comm, PetscLayout *map) 51d71ae5a4SJacob Faibussowitsch { 5269ce434fSBarry Smith PetscFunctionBegin; 539566063dSJacob Faibussowitsch PetscCall(PetscNew(map)); 549566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &(*map)->size)); 5569ce434fSBarry Smith (*map)->comm = comm; 5658b7e2c1SStefano Zampini (*map)->bs = 1; 5769ce434fSBarry Smith (*map)->n = -1; 5869ce434fSBarry Smith (*map)->N = -1; 59f92d6284SStefano Zampini (*map)->range = NULL; 609621ec18SVaclav Hapla (*map)->range_alloc = PETSC_TRUE; 6169ce434fSBarry Smith (*map)->rstart = 0; 6269ce434fSBarry Smith (*map)->rend = 0; 63ca5434daSLawrence Mitchell (*map)->setupcalled = PETSC_FALSE; 64ca5434daSLawrence Mitchell (*map)->oldn = -1; 65ca5434daSLawrence Mitchell (*map)->oldN = -1; 66ca5434daSLawrence Mitchell (*map)->oldbs = -1; 673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6869ce434fSBarry Smith } 6969ce434fSBarry Smith 70c3002683SMatthew G. Knepley /*@ 71cab54364SBarry Smith PetscLayoutCreateFromSizes - Allocates `PetscLayout` object and sets the layout sizes, and sets the layout up. 729621ec18SVaclav Hapla 739621ec18SVaclav Hapla Collective 749621ec18SVaclav Hapla 759621ec18SVaclav Hapla Input Parameters: 769621ec18SVaclav Hapla + comm - the MPI communicator 77cab54364SBarry Smith . n - the local size (or `PETSC_DECIDE`) 78cab54364SBarry Smith . N - the global size (or `PETSC_DECIDE`) 79cab54364SBarry Smith - bs - the block size (or `PETSC_DECIDE`) 809621ec18SVaclav Hapla 812fe279fdSBarry Smith Output Parameter: 82cab54364SBarry Smith . map - the new `PetscLayout` 839621ec18SVaclav Hapla 849621ec18SVaclav Hapla Level: advanced 859621ec18SVaclav Hapla 86cab54364SBarry Smith Note: 87b44f4de4SBarry Smith .vb 88b44f4de4SBarry Smith PetscLayoutCreateFromSizes(comm, n, N, bs, &layout); 89b44f4de4SBarry Smith .ve 909621ec18SVaclav Hapla is a shorthand for 919621ec18SVaclav Hapla .vb 929621ec18SVaclav Hapla PetscLayoutCreate(comm, &layout); 939621ec18SVaclav Hapla PetscLayoutSetLocalSize(layout, n); 949621ec18SVaclav Hapla PetscLayoutSetSize(layout, N); 959621ec18SVaclav Hapla PetscLayoutSetBlockSize(layout, bs); 969621ec18SVaclav Hapla PetscLayoutSetUp(layout); 979621ec18SVaclav Hapla .ve 989621ec18SVaclav Hapla 99cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`, 100db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromRanges()` 1019621ec18SVaclav Hapla @*/ 102d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt bs, PetscLayout *map) 103d71ae5a4SJacob Faibussowitsch { 1049621ec18SVaclav Hapla PetscFunctionBegin; 1059566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, map)); 1069566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(*map, n)); 1079566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetSize(*map, N)); 1089566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(*map, bs)); 1099566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(*map)); 1103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1119621ec18SVaclav Hapla } 1129621ec18SVaclav Hapla 1139621ec18SVaclav Hapla /*@ 114cab54364SBarry Smith PetscLayoutDestroy - Frees a `PetscLayout` object and frees its range if that exists. 11569ce434fSBarry Smith 116d083f849SBarry Smith Collective 11769ce434fSBarry Smith 1182fe279fdSBarry Smith Input Parameter: 119cab54364SBarry Smith . map - the `PetscLayout` 12069ce434fSBarry Smith 12169ce434fSBarry Smith Level: developer 12269ce434fSBarry Smith 123cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, 124cab54364SBarry Smith `PetscLayout`, `PetscLayoutCreate()`, 125db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()` 12669ce434fSBarry Smith @*/ 127d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutDestroy(PetscLayout *map) 128d71ae5a4SJacob Faibussowitsch { 12969ce434fSBarry Smith PetscFunctionBegin; 1303ba16761SJacob Faibussowitsch if (!*map) PetscFunctionReturn(PETSC_SUCCESS); 13169ce434fSBarry Smith if (!(*map)->refcnt--) { 1329566063dSJacob Faibussowitsch if ((*map)->range_alloc) PetscCall(PetscFree((*map)->range)); 1339566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&(*map)->mapping)); 134f4f49eeaSPierre Jolivet PetscCall(PetscFree(*map)); 13569ce434fSBarry Smith } 13669ce434fSBarry Smith *map = NULL; 1373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13869ce434fSBarry Smith } 13969ce434fSBarry Smith 1409621ec18SVaclav Hapla /*@ 141cab54364SBarry Smith PetscLayoutCreateFromRanges - Creates a new `PetscLayout` with the given ownership ranges and sets it up. 1429621ec18SVaclav Hapla 1439621ec18SVaclav Hapla Collective 1449621ec18SVaclav Hapla 1459621ec18SVaclav Hapla Input Parameters: 1469621ec18SVaclav Hapla + comm - the MPI communicator 1479621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1 1489621ec18SVaclav Hapla . mode - the copy mode for range 149cab54364SBarry Smith - bs - the block size (or `PETSC_DECIDE`) 1509621ec18SVaclav Hapla 1512fe279fdSBarry Smith Output Parameter: 152cab54364SBarry Smith . newmap - the new `PetscLayout` 1539621ec18SVaclav Hapla 1549621ec18SVaclav Hapla Level: developer 1559621ec18SVaclav Hapla 156cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, 157cab54364SBarry Smith `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`, 158db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromSizes()` 1599621ec18SVaclav Hapla @*/ 160d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm, const PetscInt range[], PetscCopyMode mode, PetscInt bs, PetscLayout *newmap) 161d71ae5a4SJacob Faibussowitsch { 1629621ec18SVaclav Hapla PetscLayout map; 16338a25198SStefano Zampini PetscMPIInt rank; 1647b659617SVaclav Hapla 1657b659617SVaclav Hapla PetscFunctionBegin; 1669566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1679566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &map)); 1689566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(map, bs)); 1699621ec18SVaclav Hapla switch (mode) { 1709621ec18SVaclav Hapla case PETSC_COPY_VALUES: 1719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(map->size + 1, &map->range)); 1729566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(map->range, range, map->size + 1)); 1739621ec18SVaclav Hapla break; 174d71ae5a4SJacob Faibussowitsch case PETSC_USE_POINTER: 175d71ae5a4SJacob Faibussowitsch map->range_alloc = PETSC_FALSE; 176d71ae5a4SJacob Faibussowitsch break; 177d71ae5a4SJacob Faibussowitsch default: 178d71ae5a4SJacob Faibussowitsch map->range = (PetscInt *)range; 179d71ae5a4SJacob Faibussowitsch break; 1809621ec18SVaclav Hapla } 1817b659617SVaclav Hapla map->rstart = map->range[rank]; 1827b659617SVaclav Hapla map->rend = map->range[rank + 1]; 1837b659617SVaclav Hapla map->n = map->rend - map->rstart; 18438a25198SStefano Zampini map->N = map->range[map->size]; 18576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */ 1867b659617SVaclav Hapla PetscInt tmp; 187462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&map->n, &tmp, 1, MPIU_INT, MPI_SUM, map->comm)); 18800045ab3SPierre Jolivet PetscCheck(tmp == map->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 ". The provided PetscLayout is wrong.", tmp, map->N, map->n); 18958b7e2c1SStefano Zampini PetscCheck(map->n % map->bs == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->n, map->bs); 19058b7e2c1SStefano Zampini PetscCheck(map->N % map->bs == 0, map->comm, PETSC_ERR_PLIB, "Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->N, map->bs); 19176bd3646SJed Brown } 192ca5434daSLawrence Mitchell /* lock the layout */ 193ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE; 194ca5434daSLawrence Mitchell map->oldn = map->n; 195ca5434daSLawrence Mitchell map->oldN = map->N; 196ca5434daSLawrence Mitchell map->oldbs = map->bs; 1979621ec18SVaclav Hapla *newmap = map; 1983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1997b659617SVaclav Hapla } 2007b659617SVaclav Hapla 201c3002683SMatthew G. Knepley /*@ 20269ce434fSBarry Smith PetscLayoutSetUp - given a map where you have set either the global or local 20369ce434fSBarry Smith size sets up the map so that it may be used. 20469ce434fSBarry Smith 205d083f849SBarry Smith Collective 20669ce434fSBarry Smith 2072fe279fdSBarry Smith Input Parameter: 20869ce434fSBarry Smith . map - pointer to the map 20969ce434fSBarry Smith 21069ce434fSBarry Smith Level: developer 21169ce434fSBarry Smith 21295452b02SPatrick Sanan Notes: 21395452b02SPatrick Sanan Typical calling sequence 214cab54364SBarry Smith .vb 215cab54364SBarry Smith PetscLayoutCreate(MPI_Comm,PetscLayout *); 216cab54364SBarry Smith PetscLayoutSetBlockSize(PetscLayout,1); 217cab54364SBarry Smith PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both 218cab54364SBarry Smith PetscLayoutSetUp(PetscLayout); 219cab54364SBarry Smith PetscLayoutGetSize(PetscLayout,PetscInt *); 220cab54364SBarry Smith .ve 22169ce434fSBarry Smith 2227b659617SVaclav Hapla If range exists, and local size is not set, everything gets computed from the range. 22369ce434fSBarry Smith 22469ce434fSBarry Smith If the local size, global size are already set and range exists then this does nothing. 22569ce434fSBarry Smith 226cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, 227cab54364SBarry Smith `PetscLayout`, `PetscLayoutDestroy()`, 228f1f2ae84SBarry Smith `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutCreate()`, `PetscSplitOwnership()` 22969ce434fSBarry Smith @*/ 230d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetUp(PetscLayout map) 231d71ae5a4SJacob Faibussowitsch { 23238a25198SStefano Zampini PetscMPIInt rank; 23369ce434fSBarry Smith PetscInt p; 23469ce434fSBarry Smith 23569ce434fSBarry Smith PetscFunctionBegin; 2369371c9d4SSatish Balay PetscCheck(!map->setupcalled || !(map->n != map->oldn || map->N != map->oldN), map->comm, PETSC_ERR_ARG_WRONGSTATE, "Layout is already setup with (local=%" PetscInt_FMT ",global=%" PetscInt_FMT "), cannot call setup again with (local=%" PetscInt_FMT ",global=%" PetscInt_FMT ")", 2379371c9d4SSatish Balay map->oldn, map->oldN, map->n, map->N); 2383ba16761SJacob Faibussowitsch if (map->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 23969ce434fSBarry Smith 24058b7e2c1SStefano Zampini PetscCheck(map->n < 0 || map->n % map->bs == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->n, map->bs); 24158b7e2c1SStefano Zampini PetscCheck(map->N < 0 || map->N % map->bs == 0, map->comm, PETSC_ERR_PLIB, "Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->N, map->bs); 242b146b01cSBarry Smith 2439566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(map->comm, &rank)); 24458b7e2c1SStefano Zampini if (map->n > 0) map->n = map->n / map->bs; 24558b7e2c1SStefano Zampini if (map->N > 0) map->N = map->N / map->bs; 2469566063dSJacob Faibussowitsch PetscCall(PetscSplitOwnership(map->comm, &map->n, &map->N)); 24758b7e2c1SStefano Zampini map->n = map->n * map->bs; 24858b7e2c1SStefano Zampini map->N = map->N * map->bs; 24948a46eb9SPierre Jolivet if (!map->range) PetscCall(PetscMalloc1(map->size + 1, &map->range)); 2509566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allgather(&map->n, 1, MPIU_INT, map->range + 1, 1, MPIU_INT, map->comm)); 25169ce434fSBarry Smith 25269ce434fSBarry Smith map->range[0] = 0; 25338a25198SStefano Zampini for (p = 2; p <= map->size; p++) map->range[p] += map->range[p - 1]; 25469ce434fSBarry Smith 25569ce434fSBarry Smith map->rstart = map->range[rank]; 25669ce434fSBarry Smith map->rend = map->range[rank + 1]; 257ca5434daSLawrence Mitchell 258ca5434daSLawrence Mitchell /* lock the layout */ 259ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE; 260ca5434daSLawrence Mitchell map->oldn = map->n; 261ca5434daSLawrence Mitchell map->oldN = map->N; 262ca5434daSLawrence Mitchell map->oldbs = map->bs; 2633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26469ce434fSBarry Smith } 26569ce434fSBarry Smith 266c3002683SMatthew G. Knepley /*@ 267cab54364SBarry Smith PetscLayoutDuplicate - creates a new `PetscLayout` with the same information as a given one. If the `PetscLayout` already exists it is destroyed first. 26869ce434fSBarry Smith 269c3339decSBarry Smith Collective 27069ce434fSBarry Smith 27169ce434fSBarry Smith Input Parameter: 272cab54364SBarry Smith . in - input `PetscLayout` to be duplicated 27369ce434fSBarry Smith 27469ce434fSBarry Smith Output Parameter: 27569ce434fSBarry Smith . out - the copy 27669ce434fSBarry Smith 27769ce434fSBarry Smith Level: developer 27869ce434fSBarry Smith 279cab54364SBarry Smith Note: 280cab54364SBarry Smith `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout` 28169ce434fSBarry Smith 282cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutReference()` 28369ce434fSBarry Smith @*/ 284d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutDuplicate(PetscLayout in, PetscLayout *out) 285d71ae5a4SJacob Faibussowitsch { 28669ce434fSBarry Smith MPI_Comm comm = in->comm; 28769ce434fSBarry Smith 28869ce434fSBarry Smith PetscFunctionBegin; 2899566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(out)); 2909566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, out)); 2919566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(*out, in, sizeof(struct _n_PetscLayout))); 292c168f6d8SVaclav Hapla if (in->range) { 2939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*out)->size + 1, &(*out)->range)); 2949566063dSJacob Faibussowitsch PetscCall(PetscArraycpy((*out)->range, in->range, (*out)->size + 1)); 295c168f6d8SVaclav Hapla } 29669ce434fSBarry Smith (*out)->refcnt = 0; 2973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29869ce434fSBarry Smith } 29969ce434fSBarry Smith 300c3002683SMatthew G. Knepley /*@ 301cab54364SBarry Smith PetscLayoutReference - Causes a PETSc `Vec` or `Mat` to share a `PetscLayout` with one that already exists. 30269ce434fSBarry Smith 303c3339decSBarry Smith Collective 30469ce434fSBarry Smith 30569ce434fSBarry Smith Input Parameter: 306cab54364SBarry Smith . in - input `PetscLayout` to be copied 30769ce434fSBarry Smith 30869ce434fSBarry Smith Output Parameter: 30969ce434fSBarry Smith . out - the reference location 31069ce434fSBarry Smith 31169ce434fSBarry Smith Level: developer 31269ce434fSBarry Smith 31395452b02SPatrick Sanan Notes: 314cab54364SBarry Smith `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout` 31569ce434fSBarry Smith 316cab54364SBarry Smith If the out location already contains a `PetscLayout` it is destroyed 31769ce434fSBarry Smith 318cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()` 31969ce434fSBarry Smith @*/ 320d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutReference(PetscLayout in, PetscLayout *out) 321d71ae5a4SJacob Faibussowitsch { 32269ce434fSBarry Smith PetscFunctionBegin; 32369ce434fSBarry Smith in->refcnt++; 3249566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(out)); 32569ce434fSBarry Smith *out = in; 3263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32769ce434fSBarry Smith } 32869ce434fSBarry Smith 329c3002683SMatthew G. Knepley /*@ 330cab54364SBarry Smith PetscLayoutSetISLocalToGlobalMapping - sets a `ISLocalGlobalMapping` into a `PetscLayout` 33169ce434fSBarry Smith 332c3339decSBarry Smith Collective 33369ce434fSBarry Smith 334d8d19677SJose E. Roman Input Parameters: 335cab54364SBarry Smith + in - input `PetscLayout` 33669ce434fSBarry Smith - ltog - the local to global mapping 33769ce434fSBarry Smith 33869ce434fSBarry Smith Level: developer 33969ce434fSBarry Smith 34095452b02SPatrick Sanan Notes: 341cab54364SBarry Smith `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout` 34269ce434fSBarry Smith 343cab54364SBarry Smith If the `PetscLayout` already contains a `ISLocalGlobalMapping` it is destroyed 34469ce434fSBarry Smith 345cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()` 34669ce434fSBarry Smith @*/ 347d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in, ISLocalToGlobalMapping ltog) 348d71ae5a4SJacob Faibussowitsch { 34969ce434fSBarry Smith PetscFunctionBegin; 350fc989267SStefano Zampini if (ltog) { 351fc989267SStefano Zampini PetscInt bs; 352fc989267SStefano Zampini 3539566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetBlockSize(ltog, &bs)); 35458b7e2c1SStefano Zampini PetscCheck(in->bs == 1 || bs == 1 || in->bs == bs, in->comm, PETSC_ERR_PLIB, "Blocksize of layout %" PetscInt_FMT " must match that of mapping %" PetscInt_FMT " (or the latter must be 1)", in->bs, bs); 355fc989267SStefano Zampini } 356da0802e2SStefano Zampini PetscCall(PetscObjectReference((PetscObject)ltog)); 3579566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&in->mapping)); 35869ce434fSBarry Smith in->mapping = ltog; 3593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36069ce434fSBarry Smith } 36169ce434fSBarry Smith 362c3002683SMatthew G. Knepley /*@ 363cab54364SBarry Smith PetscLayoutSetLocalSize - Sets the local size for a `PetscLayout` object. 36469ce434fSBarry Smith 365c3339decSBarry Smith Collective 36669ce434fSBarry Smith 36769ce434fSBarry Smith Input Parameters: 36869ce434fSBarry Smith + map - pointer to the map 369*e1b2f275SBarry Smith - n - the local size, pass `PETSC_DECIDE` (the default) to have this value determined by the global size set with `PetscLayoutSetSize()` 37069ce434fSBarry Smith 37169ce434fSBarry Smith Level: developer 37269ce434fSBarry Smith 373cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()` 374db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 37569ce434fSBarry Smith @*/ 376d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map, PetscInt n) 377d71ae5a4SJacob Faibussowitsch { 37869ce434fSBarry Smith PetscFunctionBegin; 37958b7e2c1SStefano Zampini PetscCheck(n % map->bs == 0, map->comm, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, n, map->bs); 38069ce434fSBarry Smith map->n = n; 3813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38269ce434fSBarry Smith } 38369ce434fSBarry Smith 3844ffacfe2SAlexis Marboeuf /*@ 385cab54364SBarry Smith PetscLayoutGetLocalSize - Gets the local size for a `PetscLayout` object. 38669ce434fSBarry Smith 38769ce434fSBarry Smith Not Collective 38869ce434fSBarry Smith 3892fe279fdSBarry Smith Input Parameter: 39069ce434fSBarry Smith . map - pointer to the map 39169ce434fSBarry Smith 3922fe279fdSBarry Smith Output Parameter: 39369ce434fSBarry Smith . n - the local size 39469ce434fSBarry Smith 39569ce434fSBarry Smith Level: developer 39669ce434fSBarry Smith 397cab54364SBarry Smith Note: 398cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()` 39969ce434fSBarry Smith 40042747ad1SJacob Faibussowitsch .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 401db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 40269ce434fSBarry Smith @*/ 403d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map, PetscInt *n) 404d71ae5a4SJacob Faibussowitsch { 40569ce434fSBarry Smith PetscFunctionBegin; 40669ce434fSBarry Smith *n = map->n; 4073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40869ce434fSBarry Smith } 40969ce434fSBarry Smith 410c3002683SMatthew G. Knepley /*@ 411cab54364SBarry Smith PetscLayoutSetSize - Sets the global size for a `PetscLayout` object. 41269ce434fSBarry Smith 413c3339decSBarry Smith Logically Collective 41469ce434fSBarry Smith 41569ce434fSBarry Smith Input Parameters: 41669ce434fSBarry Smith + map - pointer to the map 417*e1b2f275SBarry Smith - n - the global size, use `PETSC_DETERMINE` (the default) to have this value computed as the sum of the local sizes set with `PetscLayoutSetLocalSize()` 41869ce434fSBarry Smith 41969ce434fSBarry Smith Level: developer 42069ce434fSBarry Smith 421cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 422db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 42369ce434fSBarry Smith @*/ 424d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetSize(PetscLayout map, PetscInt n) 425d71ae5a4SJacob Faibussowitsch { 42669ce434fSBarry Smith PetscFunctionBegin; 42769ce434fSBarry Smith map->N = n; 4283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42969ce434fSBarry Smith } 43069ce434fSBarry Smith 431c3002683SMatthew G. Knepley /*@ 432cab54364SBarry Smith PetscLayoutGetSize - Gets the global size for a `PetscLayout` object. 43369ce434fSBarry Smith 43469ce434fSBarry Smith Not Collective 43569ce434fSBarry Smith 4362fe279fdSBarry Smith Input Parameter: 43769ce434fSBarry Smith . map - pointer to the map 43869ce434fSBarry Smith 4392fe279fdSBarry Smith Output Parameter: 44069ce434fSBarry Smith . n - the global size 44169ce434fSBarry Smith 44269ce434fSBarry Smith Level: developer 44369ce434fSBarry Smith 444cab54364SBarry Smith Note: 445cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()` 44669ce434fSBarry Smith 447cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()` 448db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 44969ce434fSBarry Smith @*/ 450d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetSize(PetscLayout map, PetscInt *n) 451d71ae5a4SJacob Faibussowitsch { 45269ce434fSBarry Smith PetscFunctionBegin; 45369ce434fSBarry Smith *n = map->N; 4543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45569ce434fSBarry Smith } 45669ce434fSBarry Smith 457c3002683SMatthew G. Knepley /*@ 458cab54364SBarry Smith PetscLayoutSetBlockSize - Sets the block size for a `PetscLayout` object. 45969ce434fSBarry Smith 460c3339decSBarry Smith Logically Collective 46169ce434fSBarry Smith 46269ce434fSBarry Smith Input Parameters: 46369ce434fSBarry Smith + map - pointer to the map 46469ce434fSBarry Smith - bs - the size 46569ce434fSBarry Smith 46669ce434fSBarry Smith Level: developer 46769ce434fSBarry Smith 468cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`, 469db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 47069ce434fSBarry Smith @*/ 471d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map, PetscInt bs) 472d71ae5a4SJacob Faibussowitsch { 47369ce434fSBarry Smith PetscFunctionBegin; 47458b7e2c1SStefano Zampini PetscCheck(bs > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Block size %" PetscInt_FMT " must be positive", bs); 475c9cc58a2SBarry Smith PetscCheck(map->n <= 0 || (map->n % bs) == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, map->n, bs); 476565245c5SBarry Smith if (map->mapping) { 477705e6b8bSstefano_zampini PetscInt obs; 478565245c5SBarry Smith 4799566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetBlockSize(map->mapping, &obs)); 48048a46eb9SPierre Jolivet if (obs > 1) PetscCall(ISLocalToGlobalMappingSetBlockSize(map->mapping, bs)); 481705e6b8bSstefano_zampini } 48269ce434fSBarry Smith map->bs = bs; 4833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48469ce434fSBarry Smith } 48569ce434fSBarry Smith 486c3002683SMatthew G. Knepley /*@ 487cab54364SBarry Smith PetscLayoutGetBlockSize - Gets the block size for a `PetscLayout` object. 48869ce434fSBarry Smith 48969ce434fSBarry Smith Not Collective 49069ce434fSBarry Smith 4912fe279fdSBarry Smith Input Parameter: 49269ce434fSBarry Smith . map - pointer to the map 49369ce434fSBarry Smith 4942fe279fdSBarry Smith Output Parameter: 49569ce434fSBarry Smith . bs - the size 49669ce434fSBarry Smith 49769ce434fSBarry Smith Level: developer 49869ce434fSBarry Smith 49969ce434fSBarry Smith Notes: 500cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()` 50169ce434fSBarry Smith 502cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()` 503db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()` 50469ce434fSBarry Smith @*/ 505d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map, PetscInt *bs) 506d71ae5a4SJacob Faibussowitsch { 50769ce434fSBarry Smith PetscFunctionBegin; 50858b7e2c1SStefano Zampini *bs = map->bs; 5093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 51069ce434fSBarry Smith } 51169ce434fSBarry Smith 512c3002683SMatthew G. Knepley /*@ 51369ce434fSBarry Smith PetscLayoutGetRange - gets the range of values owned by this process 51469ce434fSBarry Smith 51569ce434fSBarry Smith Not Collective 51669ce434fSBarry Smith 517f899ff85SJose E. Roman Input Parameter: 51869ce434fSBarry Smith . map - pointer to the map 51969ce434fSBarry Smith 52069ce434fSBarry Smith Output Parameters: 52169ce434fSBarry Smith + rstart - first index owned by this process 52269ce434fSBarry Smith - rend - one more than the last index owned by this process 52369ce434fSBarry Smith 52469ce434fSBarry Smith Level: developer 52569ce434fSBarry Smith 526cab54364SBarry Smith Note: 527cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()` 52869ce434fSBarry Smith 529cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, 53038b5cf2dSJacob Faibussowitsch `PetscLayoutGetSize()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutSetUp()` 53169ce434fSBarry Smith @*/ 532d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetRange(PetscLayout map, PetscInt *rstart, PetscInt *rend) 533d71ae5a4SJacob Faibussowitsch { 53469ce434fSBarry Smith PetscFunctionBegin; 53569ce434fSBarry Smith if (rstart) *rstart = map->rstart; 53669ce434fSBarry Smith if (rend) *rend = map->rend; 5373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 53869ce434fSBarry Smith } 53969ce434fSBarry Smith 54069ce434fSBarry Smith /*@C 541cab54364SBarry Smith PetscLayoutGetRanges - gets the ranges of values owned by all processes 54269ce434fSBarry Smith 54369ce434fSBarry Smith Not Collective 54469ce434fSBarry Smith 5452fe279fdSBarry Smith Input Parameter: 54669ce434fSBarry Smith . map - pointer to the map 54769ce434fSBarry Smith 5482fe279fdSBarry Smith Output Parameter: 549c3b5f7baSPierre Jolivet . range - start of each processors range of indices (the final entry is one more than the 5502c9a7b26SBarry Smith last index on the last process). The length of the array is one more than the number of processes in the MPI 5512c9a7b26SBarry Smith communicator owned by `map` 55269ce434fSBarry Smith 55369ce434fSBarry Smith Level: developer 55469ce434fSBarry Smith 555cab54364SBarry Smith Note: 556cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()` 55769ce434fSBarry Smith 55838b5cf2dSJacob Faibussowitsch Fortran Notes: 559ce78bad3SBarry Smith .vb 560ce78bad3SBarry Smith PetscInt, pointer :: range(:) 561ce78bad3SBarry Smith .ve 562ce78bad3SBarry Smith 563ce78bad3SBarry Smith Call `PetscLayoutRestoreRanges()` when no longer needed. 56469ce434fSBarry Smith 565cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, 56638b5cf2dSJacob Faibussowitsch `PetscLayoutGetSize()`, `PetscLayoutGetRange()`, `PetscLayoutSetBlockSize()`, `PetscLayoutSetUp()` 56769ce434fSBarry Smith @*/ 568d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetRanges(PetscLayout map, const PetscInt *range[]) 569d71ae5a4SJacob Faibussowitsch { 57069ce434fSBarry Smith PetscFunctionBegin; 57169ce434fSBarry Smith *range = map->range; 5723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57369ce434fSBarry Smith } 57469ce434fSBarry Smith 575f92d6284SStefano Zampini /*@ 576f92d6284SStefano Zampini PetscLayoutCompare - Compares two layouts 577f92d6284SStefano Zampini 578f92d6284SStefano Zampini Not Collective 579f92d6284SStefano Zampini 580f92d6284SStefano Zampini Input Parameters: 581d11c674dSStefano Zampini + mapa - pointer to the first map 582f92d6284SStefano Zampini - mapb - pointer to the second map 583f92d6284SStefano Zampini 5842fe279fdSBarry Smith Output Parameter: 585cab54364SBarry Smith . congruent - `PETSC_TRUE` if the two layouts are congruent, `PETSC_FALSE` otherwise 586f92d6284SStefano Zampini 587f92d6284SStefano Zampini Level: beginner 588f92d6284SStefano Zampini 589cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`, 590db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 591f92d6284SStefano Zampini @*/ 592d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCompare(PetscLayout mapa, PetscLayout mapb, PetscBool *congruent) 593d71ae5a4SJacob Faibussowitsch { 594f92d6284SStefano Zampini PetscFunctionBegin; 595f92d6284SStefano Zampini *congruent = PETSC_FALSE; 59648a46eb9SPierre Jolivet if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) PetscCall(PetscArraycmp(mapa->range, mapb->range, mapa->size + 1, congruent)); 5973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 598f92d6284SStefano Zampini } 5995d83a8b1SBarry Smith 6005d83a8b1SBarry Smith /*@ 6015d83a8b1SBarry Smith PetscLayoutFindOwner - Find the owning MPI process for a global index 6025d83a8b1SBarry Smith 6035d83a8b1SBarry Smith Not Collective; No Fortran Support 6045d83a8b1SBarry Smith 6055d83a8b1SBarry Smith Input Parameters: 6065d83a8b1SBarry Smith + map - the layout 6075d83a8b1SBarry Smith - idx - global index to find the owner of 6085d83a8b1SBarry Smith 6095d83a8b1SBarry Smith Output Parameter: 6105d83a8b1SBarry Smith . owner - the owning rank 6115d83a8b1SBarry Smith 6125d83a8b1SBarry Smith Level: developer 6135d83a8b1SBarry Smith 6145d83a8b1SBarry Smith .seealso: `PetscLayout`, `PetscLayoutFindOwnerIndex()` 6155d83a8b1SBarry Smith @*/ 6165d83a8b1SBarry Smith PetscErrorCode PetscLayoutFindOwner(PetscLayout map, PetscInt idx, PetscMPIInt *owner) 6175d83a8b1SBarry Smith { 6185d83a8b1SBarry Smith PetscMPIInt lo = 0, hi, t; 6195d83a8b1SBarry Smith 6205d83a8b1SBarry Smith PetscFunctionBegin; 6215d83a8b1SBarry Smith *owner = -1; /* GCC erroneously issues warning about possibly uninitialized use when error condition */ 6225d83a8b1SBarry Smith PetscAssert((map->n >= 0) && (map->N >= 0) && (map->range), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscLayoutSetUp() must be called first"); 6235d83a8b1SBarry Smith PetscAssert(idx >= 0 && idx <= map->N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is out of range", idx); 6245d83a8b1SBarry Smith hi = map->size; 6255d83a8b1SBarry Smith while (hi - lo > 1) { 6265d83a8b1SBarry Smith t = lo + (hi - lo) / 2; 6275d83a8b1SBarry Smith if (idx < map->range[t]) hi = t; 6285d83a8b1SBarry Smith else lo = t; 6295d83a8b1SBarry Smith } 6305d83a8b1SBarry Smith *owner = lo; 6315d83a8b1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 6325d83a8b1SBarry Smith } 6335d83a8b1SBarry Smith 6345d83a8b1SBarry Smith /*@ 6355d83a8b1SBarry Smith PetscLayoutFindOwnerIndex - Find the owning MPI process and the local index on that process for a global index 6365d83a8b1SBarry Smith 6375d83a8b1SBarry Smith Not Collective; No Fortran Support 6385d83a8b1SBarry Smith 6395d83a8b1SBarry Smith Input Parameters: 6405d83a8b1SBarry Smith + map - the layout 6415d83a8b1SBarry Smith - idx - global index to find the owner of 6425d83a8b1SBarry Smith 6435d83a8b1SBarry Smith Output Parameters: 6445d83a8b1SBarry Smith + owner - the owning rank 6455d83a8b1SBarry Smith - lidx - local index used by the owner for `idx` 6465d83a8b1SBarry Smith 6475d83a8b1SBarry Smith Level: developer 6485d83a8b1SBarry Smith 6495d83a8b1SBarry Smith .seealso: `PetscLayout`, `PetscLayoutFindOwner()` 6505d83a8b1SBarry Smith @*/ 6515d83a8b1SBarry Smith PetscErrorCode PetscLayoutFindOwnerIndex(PetscLayout map, PetscInt idx, PetscMPIInt *owner, PetscInt *lidx) 6525d83a8b1SBarry Smith { 6535d83a8b1SBarry Smith PetscMPIInt lo = 0, hi, t; 6545d83a8b1SBarry Smith 6555d83a8b1SBarry Smith PetscFunctionBegin; 6565d83a8b1SBarry Smith PetscAssert((map->n >= 0) && (map->N >= 0) && (map->range), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscLayoutSetUp() must be called first"); 6575d83a8b1SBarry Smith PetscAssert(idx >= 0 && idx <= map->N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is out of range", idx); 6585d83a8b1SBarry Smith hi = map->size; 6595d83a8b1SBarry Smith while (hi - lo > 1) { 6605d83a8b1SBarry Smith t = lo + (hi - lo) / 2; 6615d83a8b1SBarry Smith if (idx < map->range[t]) hi = t; 6625d83a8b1SBarry Smith else lo = t; 6635d83a8b1SBarry Smith } 6645d83a8b1SBarry Smith if (owner) *owner = lo; 6655d83a8b1SBarry Smith if (lidx) *lidx = idx - map->range[lo]; 6665d83a8b1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 6675d83a8b1SBarry Smith } 668