169ce434fSBarry Smith 269ce434fSBarry Smith /* 369ce434fSBarry Smith This file contains routines for basic map object implementation. 469ce434fSBarry Smith */ 569ce434fSBarry Smith 6c3002683SMatthew G. Knepley #include <petscis.h> /*I "petscis.h" I*/ 70c312b8eSJed Brown #include <petscsf.h> 807acc2aeSBarry Smith #include <petsc/private/isimpl.h> 95c25fcd7SBarry Smith 10c3002683SMatthew G. Knepley /*@ 11a8643c1eSVaclav Hapla PetscLayoutCreate - Allocates PetscLayout space and sets the PetscLayout contents to the default. 1269ce434fSBarry Smith 13d083f849SBarry Smith Collective 1469ce434fSBarry Smith 1569ce434fSBarry Smith Input Parameters: 16a8643c1eSVaclav Hapla . comm - the MPI communicator 17a8643c1eSVaclav Hapla 18a8643c1eSVaclav Hapla Output Parameters: 19a8643c1eSVaclav Hapla . map - the new PetscLayout 2069ce434fSBarry Smith 21456fcb79SJed Brown Level: advanced 2269ce434fSBarry Smith 23456fcb79SJed Brown Notes: 24456fcb79SJed Brown Typical calling sequence 25456fcb79SJed Brown .vb 2669ce434fSBarry Smith PetscLayoutCreate(MPI_Comm,PetscLayout *); 27a8643c1eSVaclav Hapla PetscLayoutSetBlockSize(PetscLayout,bs); 28a8643c1eSVaclav Hapla PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n); 2969ce434fSBarry Smith PetscLayoutSetUp(PetscLayout); 30456fcb79SJed Brown .ve 319621ec18SVaclav Hapla Alternatively, 329621ec18SVaclav Hapla $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout); 339621ec18SVaclav Hapla 3469ce434fSBarry Smith Optionally use any of the following: 35456fcb79SJed Brown 36456fcb79SJed Brown + PetscLayoutGetSize(PetscLayout,PetscInt *); 37456fcb79SJed Brown . PetscLayoutGetLocalSize(PetscLayout,PetscInt *); 38456fcb79SJed Brown . PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend); 39456fcb79SJed Brown . PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]); 40456fcb79SJed Brown - PetscLayoutDestroy(PetscLayout*); 4169ce434fSBarry Smith 4269ce434fSBarry Smith The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in 4369ce434fSBarry Smith user codes unless you really gain something in their use. 4469ce434fSBarry Smith 4569ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 469621ec18SVaclav Hapla PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), 479621ec18SVaclav Hapla PetscLayoutCreateFromSizes() 4869ce434fSBarry Smith 4969ce434fSBarry Smith @*/ 5069ce434fSBarry Smith PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map) 5169ce434fSBarry Smith { 5269ce434fSBarry Smith PetscErrorCode ierr; 5369ce434fSBarry Smith 5469ce434fSBarry Smith PetscFunctionBegin; 55b00a9115SJed Brown ierr = PetscNew(map);CHKERRQ(ierr); 56*38a25198SStefano Zampini ierr = MPI_Comm_size(comm, &(*map)->size);CHKERRQ(ierr); 5769ce434fSBarry Smith (*map)->comm = comm; 5869ce434fSBarry Smith (*map)->bs = -1; 5969ce434fSBarry Smith (*map)->n = -1; 6069ce434fSBarry Smith (*map)->N = -1; 61f92d6284SStefano Zampini (*map)->range = NULL; 629621ec18SVaclav Hapla (*map)->range_alloc = PETSC_TRUE; 6369ce434fSBarry Smith (*map)->rstart = 0; 6469ce434fSBarry Smith (*map)->rend = 0; 65ca5434daSLawrence Mitchell (*map)->setupcalled = PETSC_FALSE; 66ca5434daSLawrence Mitchell (*map)->oldn = -1; 67ca5434daSLawrence Mitchell (*map)->oldN = -1; 68ca5434daSLawrence Mitchell (*map)->oldbs = -1; 6969ce434fSBarry Smith PetscFunctionReturn(0); 7069ce434fSBarry Smith } 7169ce434fSBarry Smith 72c3002683SMatthew G. Knepley /*@ 739621ec18SVaclav Hapla PetscLayoutCreateFromSizes - Allocates PetscLayout space, sets the layout sizes, and sets the layout up. 749621ec18SVaclav Hapla 759621ec18SVaclav Hapla Collective 769621ec18SVaclav Hapla 779621ec18SVaclav Hapla Input Parameters: 789621ec18SVaclav Hapla + comm - the MPI communicator 799621ec18SVaclav Hapla . n - the local size (or PETSC_DECIDE) 809621ec18SVaclav Hapla . N - the global size (or PETSC_DECIDE) 81f0fc11ceSJed Brown - bs - the block size (or PETSC_DECIDE) 829621ec18SVaclav Hapla 839621ec18SVaclav Hapla Output Parameters: 849621ec18SVaclav Hapla . map - the new PetscLayout 859621ec18SVaclav Hapla 869621ec18SVaclav Hapla Level: advanced 879621ec18SVaclav Hapla 889621ec18SVaclav Hapla Notes: 899621ec18SVaclav Hapla $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout); 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 999621ec18SVaclav Hapla .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 1009621ec18SVaclav Hapla PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromRanges() 1019621ec18SVaclav Hapla 1029621ec18SVaclav Hapla @*/ 1039621ec18SVaclav Hapla PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm,PetscInt n,PetscInt N,PetscInt bs,PetscLayout *map) 1049621ec18SVaclav Hapla { 1059621ec18SVaclav Hapla PetscErrorCode ierr; 1069621ec18SVaclav Hapla 1079621ec18SVaclav Hapla PetscFunctionBegin; 1089621ec18SVaclav Hapla ierr = PetscLayoutCreate(comm, map);CHKERRQ(ierr); 1099621ec18SVaclav Hapla ierr = PetscLayoutSetLocalSize(*map, n);CHKERRQ(ierr); 1109621ec18SVaclav Hapla ierr = PetscLayoutSetSize(*map, N);CHKERRQ(ierr); 1119621ec18SVaclav Hapla ierr = PetscLayoutSetBlockSize(*map, bs);CHKERRQ(ierr); 1129621ec18SVaclav Hapla ierr = PetscLayoutSetUp(*map);CHKERRQ(ierr); 1139621ec18SVaclav Hapla PetscFunctionReturn(0); 1149621ec18SVaclav Hapla } 1159621ec18SVaclav Hapla 1169621ec18SVaclav Hapla /*@ 11769ce434fSBarry Smith PetscLayoutDestroy - Frees a map object and frees its range if that exists. 11869ce434fSBarry Smith 119d083f849SBarry Smith Collective 12069ce434fSBarry Smith 12169ce434fSBarry Smith Input Parameters: 12269ce434fSBarry Smith . map - the PetscLayout 12369ce434fSBarry Smith 12469ce434fSBarry Smith Level: developer 12569ce434fSBarry Smith 126c3002683SMatthew G. Knepley Note: 12769ce434fSBarry Smith The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is 12869ce434fSBarry Smith recommended they not be used in user codes unless you really gain something in their use. 12969ce434fSBarry Smith 13069ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(), 13169ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp() 13269ce434fSBarry Smith 13369ce434fSBarry Smith @*/ 13469ce434fSBarry Smith PetscErrorCode PetscLayoutDestroy(PetscLayout *map) 13569ce434fSBarry Smith { 13669ce434fSBarry Smith PetscErrorCode ierr; 13769ce434fSBarry Smith 13869ce434fSBarry Smith PetscFunctionBegin; 13969ce434fSBarry Smith if (!*map) PetscFunctionReturn(0); 14069ce434fSBarry Smith if (!(*map)->refcnt--) { 1419621ec18SVaclav Hapla if ((*map)->range_alloc) {ierr = PetscFree((*map)->range);CHKERRQ(ierr);} 14269ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr); 14369ce434fSBarry Smith ierr = PetscFree((*map));CHKERRQ(ierr); 14469ce434fSBarry Smith } 14569ce434fSBarry Smith *map = NULL; 14669ce434fSBarry Smith PetscFunctionReturn(0); 14769ce434fSBarry Smith } 14869ce434fSBarry Smith 1499621ec18SVaclav Hapla /*@ 1509621ec18SVaclav Hapla PetscLayoutCreateFromRanges - Creates a new PetscLayout with the given ownership ranges and sets it up. 1519621ec18SVaclav Hapla 1529621ec18SVaclav Hapla Collective 1539621ec18SVaclav Hapla 1549621ec18SVaclav Hapla Input Parameters: 1559621ec18SVaclav Hapla + comm - the MPI communicator 1569621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1 1579621ec18SVaclav Hapla . mode - the copy mode for range 1589621ec18SVaclav Hapla - bs - the block size (or PETSC_DECIDE) 1599621ec18SVaclav Hapla 1609621ec18SVaclav Hapla Output Parameters: 1619621ec18SVaclav Hapla . newmap - the new PetscLayout 1629621ec18SVaclav Hapla 1639621ec18SVaclav Hapla Level: developer 1649621ec18SVaclav Hapla 1659621ec18SVaclav Hapla .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 1669621ec18SVaclav Hapla PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromSizes() 1679621ec18SVaclav Hapla 1689621ec18SVaclav Hapla @*/ 1699621ec18SVaclav Hapla PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm,const PetscInt range[],PetscCopyMode mode,PetscInt bs,PetscLayout *newmap) 1707b659617SVaclav Hapla { 1719621ec18SVaclav Hapla PetscLayout map; 172*38a25198SStefano Zampini PetscMPIInt rank; 1737b659617SVaclav Hapla PetscErrorCode ierr; 1747b659617SVaclav Hapla 1757b659617SVaclav Hapla PetscFunctionBegin; 176ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1779621ec18SVaclav Hapla ierr = PetscLayoutCreate(comm, &map);CHKERRQ(ierr); 1789621ec18SVaclav Hapla ierr = PetscLayoutSetBlockSize(map, bs);CHKERRQ(ierr); 1799621ec18SVaclav Hapla switch (mode) { 1809621ec18SVaclav Hapla case PETSC_COPY_VALUES: 181*38a25198SStefano Zampini ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr); 182*38a25198SStefano Zampini ierr = PetscArraycpy(map->range, range, map->size+1);CHKERRQ(ierr); 1839621ec18SVaclav Hapla break; 1849621ec18SVaclav Hapla case PETSC_USE_POINTER: 1859621ec18SVaclav Hapla map->range_alloc = PETSC_FALSE; 1869621ec18SVaclav Hapla default: 1879621ec18SVaclav Hapla map->range = (PetscInt*) range; 1889621ec18SVaclav Hapla break; 1899621ec18SVaclav Hapla } 1907b659617SVaclav Hapla map->rstart = map->range[rank]; 1917b659617SVaclav Hapla map->rend = map->range[rank+1]; 1927b659617SVaclav Hapla map->n = map->rend - map->rstart; 193*38a25198SStefano Zampini map->N = map->range[map->size]; 19476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */ 1957b659617SVaclav Hapla PetscInt tmp; 1967b659617SVaclav Hapla ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 1977b659617SVaclav Hapla if (tmp != map->N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local lengths %D does not equal global length %D, my local length %D.\nThe provided PetscLayout is wrong.",tmp,map->N,map->n); 1987b659617SVaclav Hapla if (map->bs > 1) { 1997b659617SVaclav Hapla if (map->n % map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local size %D must be divisible by blocksize %D",map->n,map->bs); 2007b659617SVaclav Hapla } 2017b659617SVaclav Hapla if (map->bs > 1) { 2027b659617SVaclav Hapla if (map->N % map->bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Global size %D must be divisible by blocksize %D",map->N,map->bs); 2037b659617SVaclav Hapla } 20476bd3646SJed Brown } 205ca5434daSLawrence Mitchell /* lock the layout */ 206ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE; 207ca5434daSLawrence Mitchell map->oldn = map->n; 208ca5434daSLawrence Mitchell map->oldN = map->N; 209ca5434daSLawrence Mitchell map->oldbs = map->bs; 2109621ec18SVaclav Hapla *newmap = map; 2117b659617SVaclav Hapla PetscFunctionReturn(0); 2127b659617SVaclav Hapla } 2137b659617SVaclav Hapla 214c3002683SMatthew G. Knepley /*@ 21569ce434fSBarry Smith PetscLayoutSetUp - given a map where you have set either the global or local 21669ce434fSBarry Smith size sets up the map so that it may be used. 21769ce434fSBarry Smith 218d083f849SBarry Smith Collective 21969ce434fSBarry Smith 22069ce434fSBarry Smith Input Parameters: 22169ce434fSBarry Smith . map - pointer to the map 22269ce434fSBarry Smith 22369ce434fSBarry Smith Level: developer 22469ce434fSBarry Smith 22595452b02SPatrick Sanan Notes: 22695452b02SPatrick Sanan Typical calling sequence 227c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *); 228c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1); 229c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both 230c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout); 231c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *); 23269ce434fSBarry Smith 2337b659617SVaclav Hapla If range exists, and local size is not set, everything gets computed from the range. 23469ce434fSBarry Smith 23569ce434fSBarry Smith If the local size, global size are already set and range exists then this does nothing. 23669ce434fSBarry Smith 23769ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 23869ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate() 23969ce434fSBarry Smith @*/ 24069ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map) 24169ce434fSBarry Smith { 242*38a25198SStefano Zampini PetscMPIInt rank; 24369ce434fSBarry Smith PetscInt p; 24469ce434fSBarry Smith PetscErrorCode ierr; 24569ce434fSBarry Smith 24669ce434fSBarry Smith PetscFunctionBegin; 247ca5434daSLawrence Mitchell if (map->setupcalled && (map->n != map->oldn || map->N != map->oldN)) SETERRQ4(map->comm,PETSC_ERR_ARG_WRONGSTATE,"Layout is already setup with (local=%D,global=%D), cannot call setup again with (local=%D,global=%D)", map->oldn, map->oldN, map->n, map->N); 248ca5434daSLawrence Mitchell if (map->setupcalled) PetscFunctionReturn(0); 24969ce434fSBarry Smith 250b146b01cSBarry Smith if (map->n > 0 && map->bs > 1) { 251ec4d677dSStefano Zampini if (map->n % map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local size %D must be divisible by blocksize %D",map->n,map->bs); 252b146b01cSBarry Smith } 253b146b01cSBarry Smith if (map->N > 0 && map->bs > 1) { 254ec4d677dSStefano Zampini if (map->N % map->bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Global size %D must be divisible by blocksize %D",map->N,map->bs); 255b146b01cSBarry Smith } 256b146b01cSBarry Smith 257ffc4695bSBarry Smith ierr = MPI_Comm_rank(map->comm, &rank);CHKERRMPI(ierr); 25833d57670SJed Brown if (map->n > 0) map->n = map->n/PetscAbs(map->bs); 25933d57670SJed Brown if (map->N > 0) map->N = map->N/PetscAbs(map->bs); 26069ce434fSBarry Smith ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr); 26133d57670SJed Brown map->n = map->n*PetscAbs(map->bs); 26233d57670SJed Brown map->N = map->N*PetscAbs(map->bs); 26369ce434fSBarry Smith if (!map->range) { 264*38a25198SStefano Zampini ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr); 26569ce434fSBarry Smith } 266ffc4695bSBarry Smith ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRMPI(ierr); 26769ce434fSBarry Smith 26869ce434fSBarry Smith map->range[0] = 0; 269*38a25198SStefano Zampini for (p = 2; p <= map->size; p++) map->range[p] += map->range[p-1]; 27069ce434fSBarry Smith 27169ce434fSBarry Smith map->rstart = map->range[rank]; 27269ce434fSBarry Smith map->rend = map->range[rank+1]; 273ca5434daSLawrence Mitchell 274ca5434daSLawrence Mitchell /* lock the layout */ 275ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE; 276ca5434daSLawrence Mitchell map->oldn = map->n; 277ca5434daSLawrence Mitchell map->oldN = map->N; 278ca5434daSLawrence Mitchell map->oldbs = map->bs; 27969ce434fSBarry Smith PetscFunctionReturn(0); 28069ce434fSBarry Smith } 28169ce434fSBarry Smith 282c3002683SMatthew G. Knepley /*@ 28369ce434fSBarry Smith PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first. 28469ce434fSBarry Smith 28569ce434fSBarry Smith Collective on PetscLayout 28669ce434fSBarry Smith 28769ce434fSBarry Smith Input Parameter: 28869ce434fSBarry Smith . in - input PetscLayout to be duplicated 28969ce434fSBarry Smith 29069ce434fSBarry Smith Output Parameter: 29169ce434fSBarry Smith . out - the copy 29269ce434fSBarry Smith 29369ce434fSBarry Smith Level: developer 29469ce434fSBarry Smith 29595452b02SPatrick Sanan Notes: 29695452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 29769ce434fSBarry Smith 29869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference() 29969ce434fSBarry Smith @*/ 30069ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out) 30169ce434fSBarry Smith { 30269ce434fSBarry Smith PetscErrorCode ierr; 30369ce434fSBarry Smith MPI_Comm comm = in->comm; 30469ce434fSBarry Smith 30569ce434fSBarry Smith PetscFunctionBegin; 30669ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 30769ce434fSBarry Smith ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr); 30869ce434fSBarry Smith ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr); 309c168f6d8SVaclav Hapla if (in->range) { 310*38a25198SStefano Zampini ierr = PetscMalloc1((*out)->size+1,&(*out)->range);CHKERRQ(ierr); 311*38a25198SStefano Zampini ierr = PetscArraycpy((*out)->range,in->range,(*out)->size+1);CHKERRQ(ierr); 312c168f6d8SVaclav Hapla } 31369ce434fSBarry Smith (*out)->refcnt = 0; 31469ce434fSBarry Smith PetscFunctionReturn(0); 31569ce434fSBarry Smith } 31669ce434fSBarry Smith 317c3002683SMatthew G. Knepley /*@ 31869ce434fSBarry Smith PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 31969ce434fSBarry Smith 32069ce434fSBarry Smith Collective on PetscLayout 32169ce434fSBarry Smith 32269ce434fSBarry Smith Input Parameter: 32369ce434fSBarry Smith . in - input PetscLayout to be copied 32469ce434fSBarry Smith 32569ce434fSBarry Smith Output Parameter: 32669ce434fSBarry Smith . out - the reference location 32769ce434fSBarry Smith 32869ce434fSBarry Smith Level: developer 32969ce434fSBarry Smith 33095452b02SPatrick Sanan Notes: 33195452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 33269ce434fSBarry Smith 33369ce434fSBarry Smith If the out location already contains a PetscLayout it is destroyed 33469ce434fSBarry Smith 33569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 33669ce434fSBarry Smith @*/ 33769ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out) 33869ce434fSBarry Smith { 33969ce434fSBarry Smith PetscErrorCode ierr; 34069ce434fSBarry Smith 34169ce434fSBarry Smith PetscFunctionBegin; 34269ce434fSBarry Smith in->refcnt++; 34369ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 34469ce434fSBarry Smith *out = in; 34569ce434fSBarry Smith PetscFunctionReturn(0); 34669ce434fSBarry Smith } 34769ce434fSBarry Smith 348c3002683SMatthew G. Knepley /*@ 34969ce434fSBarry Smith PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 35069ce434fSBarry Smith 35169ce434fSBarry Smith Collective on PetscLayout 35269ce434fSBarry Smith 35369ce434fSBarry Smith Input Parameter: 35469ce434fSBarry Smith + in - input PetscLayout 35569ce434fSBarry Smith - ltog - the local to global mapping 35669ce434fSBarry Smith 35769ce434fSBarry Smith 35869ce434fSBarry Smith Level: developer 35969ce434fSBarry Smith 36095452b02SPatrick Sanan Notes: 36195452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 36269ce434fSBarry Smith 36369ce434fSBarry Smith If the ltog location already contains a PetscLayout it is destroyed 36469ce434fSBarry Smith 365a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 36669ce434fSBarry Smith @*/ 36769ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog) 36869ce434fSBarry Smith { 36969ce434fSBarry Smith PetscErrorCode ierr; 37045b6f7e9SBarry Smith PetscInt bs; 37169ce434fSBarry Smith 37269ce434fSBarry Smith PetscFunctionBegin; 37345b6f7e9SBarry Smith ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr); 37437461477SLawrence Mitchell if (in->bs > 0 && (bs != 1) && in->bs != bs) SETERRQ2(in->comm,PETSC_ERR_PLIB,"Blocksize of layout %D must match that of mapping %D (or the latter must be 1)",in->bs,bs); 37569ce434fSBarry Smith ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 37669ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr); 37769ce434fSBarry Smith in->mapping = ltog; 37869ce434fSBarry Smith PetscFunctionReturn(0); 37969ce434fSBarry Smith } 38069ce434fSBarry Smith 381c3002683SMatthew G. Knepley /*@ 38269ce434fSBarry Smith PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 38369ce434fSBarry Smith 38469ce434fSBarry Smith Collective on PetscLayout 38569ce434fSBarry Smith 38669ce434fSBarry Smith Input Parameters: 38769ce434fSBarry Smith + map - pointer to the map 38869ce434fSBarry Smith - n - the local size 38969ce434fSBarry Smith 39069ce434fSBarry Smith Level: developer 39169ce434fSBarry Smith 39269ce434fSBarry Smith Notes: 39369ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 39469ce434fSBarry Smith 39569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 39669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 39769ce434fSBarry Smith @*/ 39869ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n) 39969ce434fSBarry Smith { 40069ce434fSBarry Smith PetscFunctionBegin; 40169ce434fSBarry Smith if (map->bs > 1 && n % map->bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",n,map->bs); 40269ce434fSBarry Smith map->n = n; 40369ce434fSBarry Smith PetscFunctionReturn(0); 40469ce434fSBarry Smith } 40569ce434fSBarry Smith 40669ce434fSBarry Smith /*@C 40769ce434fSBarry Smith PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 40869ce434fSBarry Smith 40969ce434fSBarry Smith Not Collective 41069ce434fSBarry Smith 41169ce434fSBarry Smith Input Parameters: 41269ce434fSBarry Smith . map - pointer to the map 41369ce434fSBarry Smith 41469ce434fSBarry Smith Output Parameters: 41569ce434fSBarry Smith . n - the local size 41669ce434fSBarry Smith 41769ce434fSBarry Smith Level: developer 41869ce434fSBarry Smith 41969ce434fSBarry Smith Notes: 42069ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 42169ce434fSBarry Smith 42269ce434fSBarry Smith Fortran Notes: 42369ce434fSBarry Smith Not available from Fortran 42469ce434fSBarry Smith 42569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 42669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 42769ce434fSBarry Smith 42869ce434fSBarry Smith @*/ 42969ce434fSBarry Smith PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n) 43069ce434fSBarry Smith { 43169ce434fSBarry Smith PetscFunctionBegin; 43269ce434fSBarry Smith *n = map->n; 43369ce434fSBarry Smith PetscFunctionReturn(0); 43469ce434fSBarry Smith } 43569ce434fSBarry Smith 436c3002683SMatthew G. Knepley /*@ 43769ce434fSBarry Smith PetscLayoutSetSize - Sets the global size for a PetscLayout object. 43869ce434fSBarry Smith 43969ce434fSBarry Smith Logically Collective on PetscLayout 44069ce434fSBarry Smith 44169ce434fSBarry Smith Input Parameters: 44269ce434fSBarry Smith + map - pointer to the map 44369ce434fSBarry Smith - n - the global size 44469ce434fSBarry Smith 44569ce434fSBarry Smith Level: developer 44669ce434fSBarry Smith 44769ce434fSBarry Smith Notes: 44869ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 44969ce434fSBarry Smith 45069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 45169ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 45269ce434fSBarry Smith @*/ 45369ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n) 45469ce434fSBarry Smith { 45569ce434fSBarry Smith PetscFunctionBegin; 45669ce434fSBarry Smith map->N = n; 45769ce434fSBarry Smith PetscFunctionReturn(0); 45869ce434fSBarry Smith } 45969ce434fSBarry Smith 460c3002683SMatthew G. Knepley /*@ 46169ce434fSBarry Smith PetscLayoutGetSize - Gets the global size for a PetscLayout object. 46269ce434fSBarry Smith 46369ce434fSBarry Smith Not Collective 46469ce434fSBarry Smith 46569ce434fSBarry Smith Input Parameters: 46669ce434fSBarry Smith . map - pointer to the map 46769ce434fSBarry Smith 46869ce434fSBarry Smith Output Parameters: 46969ce434fSBarry Smith . n - the global size 47069ce434fSBarry Smith 47169ce434fSBarry Smith Level: developer 47269ce434fSBarry Smith 47369ce434fSBarry Smith Notes: 47469ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 47569ce434fSBarry Smith 47669ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 47769ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 47869ce434fSBarry Smith @*/ 47969ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n) 48069ce434fSBarry Smith { 48169ce434fSBarry Smith PetscFunctionBegin; 48269ce434fSBarry Smith *n = map->N; 48369ce434fSBarry Smith PetscFunctionReturn(0); 48469ce434fSBarry Smith } 48569ce434fSBarry Smith 486c3002683SMatthew G. Knepley /*@ 48769ce434fSBarry Smith PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 48869ce434fSBarry Smith 48969ce434fSBarry Smith Logically Collective on PetscLayout 49069ce434fSBarry Smith 49169ce434fSBarry Smith Input Parameters: 49269ce434fSBarry Smith + map - pointer to the map 49369ce434fSBarry Smith - bs - the size 49469ce434fSBarry Smith 49569ce434fSBarry Smith Level: developer 49669ce434fSBarry Smith 49769ce434fSBarry Smith Notes: 49869ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 49969ce434fSBarry Smith 50069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 50169ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 50269ce434fSBarry Smith @*/ 50369ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs) 50469ce434fSBarry Smith { 50569ce434fSBarry Smith PetscFunctionBegin; 50669bbac97SJed Brown if (bs < 0) PetscFunctionReturn(0); 507299e779cSStefano Zampini if (map->n > 0 && map->n % bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",map->n,bs); 508565245c5SBarry Smith if (map->mapping) { 509705e6b8bSstefano_zampini PetscInt obs; 510565245c5SBarry Smith PetscErrorCode ierr; 511565245c5SBarry Smith 512705e6b8bSstefano_zampini ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr); 513705e6b8bSstefano_zampini if (obs > 1) { 51463fa5c83Sstefano_zampini ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr); 515565245c5SBarry Smith } 516705e6b8bSstefano_zampini } 51769ce434fSBarry Smith map->bs = bs; 51869ce434fSBarry Smith PetscFunctionReturn(0); 51969ce434fSBarry Smith } 52069ce434fSBarry Smith 521c3002683SMatthew G. Knepley /*@ 52269ce434fSBarry Smith PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 52369ce434fSBarry Smith 52469ce434fSBarry Smith Not Collective 52569ce434fSBarry Smith 52669ce434fSBarry Smith Input Parameters: 52769ce434fSBarry Smith . map - pointer to the map 52869ce434fSBarry Smith 52969ce434fSBarry Smith Output Parameters: 53069ce434fSBarry Smith . bs - the size 53169ce434fSBarry Smith 53269ce434fSBarry Smith Level: developer 53369ce434fSBarry Smith 53469ce434fSBarry Smith Notes: 53569ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 53669ce434fSBarry Smith 53769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 53869ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize() 53969ce434fSBarry Smith @*/ 54069ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs) 54169ce434fSBarry Smith { 54269ce434fSBarry Smith PetscFunctionBegin; 54333d57670SJed Brown *bs = PetscAbs(map->bs); 54469ce434fSBarry Smith PetscFunctionReturn(0); 54569ce434fSBarry Smith } 54669ce434fSBarry Smith 547c3002683SMatthew G. Knepley /*@ 54869ce434fSBarry Smith PetscLayoutGetRange - gets the range of values owned by this process 54969ce434fSBarry Smith 55069ce434fSBarry Smith Not Collective 55169ce434fSBarry Smith 55269ce434fSBarry Smith Input Parameters: 55369ce434fSBarry Smith . map - pointer to the map 55469ce434fSBarry Smith 55569ce434fSBarry Smith Output Parameters: 55669ce434fSBarry Smith + rstart - first index owned by this process 55769ce434fSBarry Smith - rend - one more than the last index owned by this process 55869ce434fSBarry Smith 55969ce434fSBarry Smith Level: developer 56069ce434fSBarry Smith 56169ce434fSBarry Smith Notes: 56269ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 56369ce434fSBarry Smith 56469ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 56569ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 56669ce434fSBarry Smith @*/ 56769ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend) 56869ce434fSBarry Smith { 56969ce434fSBarry Smith PetscFunctionBegin; 57069ce434fSBarry Smith if (rstart) *rstart = map->rstart; 57169ce434fSBarry Smith if (rend) *rend = map->rend; 57269ce434fSBarry Smith PetscFunctionReturn(0); 57369ce434fSBarry Smith } 57469ce434fSBarry Smith 57569ce434fSBarry Smith /*@C 57669ce434fSBarry Smith PetscLayoutGetRanges - gets the range of values owned by all processes 57769ce434fSBarry Smith 57869ce434fSBarry Smith Not Collective 57969ce434fSBarry Smith 58069ce434fSBarry Smith Input Parameters: 58169ce434fSBarry Smith . map - pointer to the map 58269ce434fSBarry Smith 58369ce434fSBarry Smith Output Parameters: 58469ce434fSBarry Smith . range - start of each processors range of indices (the final entry is one more then the 58569ce434fSBarry Smith last index on the last process) 58669ce434fSBarry Smith 58769ce434fSBarry Smith Level: developer 58869ce434fSBarry Smith 58969ce434fSBarry Smith Notes: 59069ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 59169ce434fSBarry Smith 59269ce434fSBarry Smith Fortran Notes: 59369ce434fSBarry Smith Not available from Fortran 59469ce434fSBarry Smith 59569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 59669ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 59769ce434fSBarry Smith 59869ce434fSBarry Smith @*/ 59969ce434fSBarry Smith PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[]) 60069ce434fSBarry Smith { 60169ce434fSBarry Smith PetscFunctionBegin; 60269ce434fSBarry Smith *range = map->range; 60369ce434fSBarry Smith PetscFunctionReturn(0); 60469ce434fSBarry Smith } 60569ce434fSBarry Smith 60669ce434fSBarry Smith /*@C 607f26271d2SStefano Zampini PetscLayoutsCreateSF - Creates a parallel star forest mapping two PetscLayout objects 608f26271d2SStefano Zampini 609f26271d2SStefano Zampini Collective 610f26271d2SStefano Zampini 611f26271d2SStefano Zampini Input Arguments: 612f26271d2SStefano Zampini + rmap - PetscLayout defining the global root space 613f26271d2SStefano Zampini - lmap - PetscLayout defining the global leaf space 614f26271d2SStefano Zampini 615f26271d2SStefano Zampini Output Arguments: 616f26271d2SStefano Zampini . sf - The parallel star forest 617f26271d2SStefano Zampini 618f26271d2SStefano Zampini Level: intermediate 619f26271d2SStefano Zampini 620f26271d2SStefano Zampini .seealso: PetscSFCreate(), PetscLayoutCreate(), PetscSFSetGraphLayout() 621f26271d2SStefano Zampini @*/ 622f26271d2SStefano Zampini PetscErrorCode PetscLayoutsCreateSF(PetscLayout rmap, PetscLayout lmap, PetscSF* sf) 623f26271d2SStefano Zampini { 624f26271d2SStefano Zampini PetscErrorCode ierr; 625f26271d2SStefano Zampini PetscInt i,nroots,nleaves = 0; 626f26271d2SStefano Zampini PetscInt rN, lst, len; 627f26271d2SStefano Zampini PetscMPIInt owner = -1; 628f26271d2SStefano Zampini PetscSFNode *remote; 629f26271d2SStefano Zampini MPI_Comm rcomm = rmap->comm; 630f26271d2SStefano Zampini MPI_Comm lcomm = lmap->comm; 631f26271d2SStefano Zampini PetscMPIInt flg; 632f26271d2SStefano Zampini 633f26271d2SStefano Zampini PetscFunctionBegin; 634f26271d2SStefano Zampini PetscValidPointer(sf,3); 635f26271d2SStefano Zampini if (!rmap->setupcalled) SETERRQ(rcomm,PETSC_ERR_ARG_WRONGSTATE,"Root layout not setup"); 636f26271d2SStefano Zampini if (!lmap->setupcalled) SETERRQ(lcomm,PETSC_ERR_ARG_WRONGSTATE,"Leaf layout not setup"); 637ffc4695bSBarry Smith ierr = MPI_Comm_compare(rcomm,lcomm,&flg);CHKERRMPI(ierr); 638f26271d2SStefano Zampini if (flg != MPI_CONGRUENT && flg != MPI_IDENT) SETERRQ(rcomm,PETSC_ERR_SUP,"cannot map two layouts with non-matching communicators"); 639f26271d2SStefano Zampini ierr = PetscSFCreate(rcomm,sf);CHKERRQ(ierr); 640f26271d2SStefano Zampini ierr = PetscLayoutGetLocalSize(rmap,&nroots);CHKERRQ(ierr); 641f26271d2SStefano Zampini ierr = PetscLayoutGetSize(rmap,&rN);CHKERRQ(ierr); 642f26271d2SStefano Zampini ierr = PetscLayoutGetRange(lmap,&lst,&len);CHKERRQ(ierr); 643f26271d2SStefano Zampini ierr = PetscMalloc1(len-lst,&remote);CHKERRQ(ierr); 644f26271d2SStefano Zampini for (i = lst; i < len && i < rN; i++) { 645f26271d2SStefano Zampini if (owner < -1 || i >= rmap->range[owner+1]) { 646f26271d2SStefano Zampini ierr = PetscLayoutFindOwner(rmap,i,&owner);CHKERRQ(ierr); 647f26271d2SStefano Zampini } 648f26271d2SStefano Zampini remote[nleaves].rank = owner; 649f26271d2SStefano Zampini remote[nleaves].index = i - rmap->range[owner]; 650f26271d2SStefano Zampini nleaves++; 651f26271d2SStefano Zampini } 652f26271d2SStefano Zampini ierr = PetscSFSetGraph(*sf,nroots,nleaves,NULL,PETSC_OWN_POINTER,remote,PETSC_COPY_VALUES);CHKERRQ(ierr); 653f26271d2SStefano Zampini ierr = PetscFree(remote);CHKERRQ(ierr); 654f26271d2SStefano Zampini PetscFunctionReturn(0); 655f26271d2SStefano Zampini } 656f26271d2SStefano Zampini 657f92d6284SStefano Zampini /*@ 658f92d6284SStefano Zampini PetscLayoutCompare - Compares two layouts 659f92d6284SStefano Zampini 660f92d6284SStefano Zampini Not Collective 661f92d6284SStefano Zampini 662f92d6284SStefano Zampini Input Parameters: 663d11c674dSStefano Zampini + mapa - pointer to the first map 664f92d6284SStefano Zampini - mapb - pointer to the second map 665f92d6284SStefano Zampini 666f92d6284SStefano Zampini Output Parameters: 667f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise 668f92d6284SStefano Zampini 669f92d6284SStefano Zampini Level: beginner 670f92d6284SStefano Zampini 671f92d6284SStefano Zampini Notes: 672f92d6284SStefano Zampini 673f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 674f92d6284SStefano Zampini PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 675f92d6284SStefano Zampini @*/ 676f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent) 677f92d6284SStefano Zampini { 678f92d6284SStefano Zampini PetscErrorCode ierr; 679f92d6284SStefano Zampini 680f92d6284SStefano Zampini PetscFunctionBegin; 681f92d6284SStefano Zampini *congruent = PETSC_FALSE; 682*38a25198SStefano Zampini if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) { 683*38a25198SStefano Zampini ierr = PetscArraycmp(mapa->range,mapb->range,mapa->size+1,congruent);CHKERRQ(ierr); 684f92d6284SStefano Zampini } 685f92d6284SStefano Zampini PetscFunctionReturn(0); 686f92d6284SStefano Zampini } 687a72d46e8SStefano Zampini 688a72d46e8SStefano Zampini /* TODO: handle nooffprocentries like MatZeroRowsMapLocal_Private, since this code is the same */ 689a72d46e8SStefano Zampini PetscErrorCode PetscLayoutMapLocal(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 690a72d46e8SStefano Zampini { 691a72d46e8SStefano Zampini PetscInt *owners = map->range; 692a72d46e8SStefano Zampini PetscInt n = map->n; 693a72d46e8SStefano Zampini PetscSF sf; 694a72d46e8SStefano Zampini PetscInt *lidxs,*work = NULL; 695a72d46e8SStefano Zampini PetscSFNode *ridxs; 696131c27b5Sprj- PetscMPIInt rank, p = 0; 697131c27b5Sprj- PetscInt r, len = 0; 698a72d46e8SStefano Zampini PetscErrorCode ierr; 699a72d46e8SStefano Zampini 700a72d46e8SStefano Zampini PetscFunctionBegin; 701a72d46e8SStefano Zampini if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 702a72d46e8SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs */ 703ffc4695bSBarry Smith ierr = MPI_Comm_rank(map->comm,&rank);CHKERRMPI(ierr); 704a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 705a72d46e8SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 706a72d46e8SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 707a72d46e8SStefano Zampini for (r = 0; r < N; ++r) { 708a72d46e8SStefano Zampini const PetscInt idx = idxs[r]; 709a72d46e8SStefano Zampini if (idx < 0 || map->N <= idx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Index %D out of range [0,%D)",idx,map->N); 710a72d46e8SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 711a72d46e8SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 712a72d46e8SStefano Zampini } 713a72d46e8SStefano Zampini ridxs[r].rank = p; 714a72d46e8SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 715a72d46e8SStefano Zampini } 716a72d46e8SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 717a72d46e8SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 718a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 719a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 720a72d46e8SStefano Zampini if (ogidxs) { /* communicate global idxs */ 721a72d46e8SStefano Zampini PetscInt cum = 0,start,*work2; 722a72d46e8SStefano Zampini 723a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 724a72d46e8SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 725a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 726ffc4695bSBarry Smith ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRMPI(ierr); 727a72d46e8SStefano Zampini start -= cum; 728a72d46e8SStefano Zampini cum = 0; 729a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 730a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 731a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 732a72d46e8SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 733a72d46e8SStefano Zampini } 734a72d46e8SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 735a72d46e8SStefano Zampini /* Compress and put in indices */ 736a72d46e8SStefano Zampini for (r = 0; r < n; ++r) 737a72d46e8SStefano Zampini if (lidxs[r] >= 0) { 738a72d46e8SStefano Zampini if (work) work[len] = work[r]; 739a72d46e8SStefano Zampini lidxs[len++] = r; 740a72d46e8SStefano Zampini } 741a72d46e8SStefano Zampini if (on) *on = len; 742a72d46e8SStefano Zampini if (oidxs) *oidxs = lidxs; 743a72d46e8SStefano Zampini if (ogidxs) *ogidxs = work; 744a72d46e8SStefano Zampini PetscFunctionReturn(0); 745a72d46e8SStefano Zampini } 746