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); 5669ce434fSBarry Smith 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) 81*f0fc11ceSJed 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; 1727b659617SVaclav Hapla PetscMPIInt rank,size; 1737b659617SVaclav Hapla PetscErrorCode ierr; 1747b659617SVaclav Hapla 1757b659617SVaclav Hapla PetscFunctionBegin; 1769621ec18SVaclav Hapla ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1779621ec18SVaclav Hapla ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 1789621ec18SVaclav Hapla ierr = PetscLayoutCreate(comm, &map);CHKERRQ(ierr); 1799621ec18SVaclav Hapla ierr = PetscLayoutSetBlockSize(map, bs);CHKERRQ(ierr); 1809621ec18SVaclav Hapla switch (mode) { 1819621ec18SVaclav Hapla case PETSC_COPY_VALUES: 1829621ec18SVaclav Hapla ierr = PetscMalloc1(size+1, &map->range);CHKERRQ(ierr); 1839621ec18SVaclav Hapla ierr = PetscArraycpy(map->range, range, size+1);CHKERRQ(ierr); 1849621ec18SVaclav Hapla break; 1859621ec18SVaclav Hapla case PETSC_USE_POINTER: 1869621ec18SVaclav Hapla map->range_alloc = PETSC_FALSE; 1879621ec18SVaclav Hapla default: 1889621ec18SVaclav Hapla map->range = (PetscInt*) range; 1899621ec18SVaclav Hapla break; 1909621ec18SVaclav Hapla } 1917b659617SVaclav Hapla map->rstart = map->range[rank]; 1927b659617SVaclav Hapla map->rend = map->range[rank+1]; 1937b659617SVaclav Hapla map->n = map->rend - map->rstart; 1947b659617SVaclav Hapla map->N = map->range[size]; 1957b659617SVaclav Hapla #if defined(PETSC_USE_DEBUG) 1967b659617SVaclav Hapla /* just check that n, N and bs are consistent */ 1977b659617SVaclav Hapla { 1987b659617SVaclav Hapla PetscInt tmp; 1997b659617SVaclav Hapla ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 2007b659617SVaclav 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); 2017b659617SVaclav Hapla } 2027b659617SVaclav Hapla if (map->bs > 1) { 2037b659617SVaclav 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); 2047b659617SVaclav Hapla } 2057b659617SVaclav Hapla if (map->bs > 1) { 2067b659617SVaclav 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); 2077b659617SVaclav Hapla } 2087b659617SVaclav Hapla #endif 209ca5434daSLawrence Mitchell /* lock the layout */ 210ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE; 211ca5434daSLawrence Mitchell map->oldn = map->n; 212ca5434daSLawrence Mitchell map->oldN = map->N; 213ca5434daSLawrence Mitchell map->oldbs = map->bs; 2149621ec18SVaclav Hapla *newmap = map; 2157b659617SVaclav Hapla PetscFunctionReturn(0); 2167b659617SVaclav Hapla } 2177b659617SVaclav Hapla 218c3002683SMatthew G. Knepley /*@ 21969ce434fSBarry Smith PetscLayoutSetUp - given a map where you have set either the global or local 22069ce434fSBarry Smith size sets up the map so that it may be used. 22169ce434fSBarry Smith 222d083f849SBarry Smith Collective 22369ce434fSBarry Smith 22469ce434fSBarry Smith Input Parameters: 22569ce434fSBarry Smith . map - pointer to the map 22669ce434fSBarry Smith 22769ce434fSBarry Smith Level: developer 22869ce434fSBarry Smith 22995452b02SPatrick Sanan Notes: 23095452b02SPatrick Sanan Typical calling sequence 231c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *); 232c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1); 233c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both 234c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout); 235c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *); 23669ce434fSBarry Smith 2377b659617SVaclav Hapla If range exists, and local size is not set, everything gets computed from the range. 23869ce434fSBarry Smith 23969ce434fSBarry Smith If the local size, global size are already set and range exists then this does nothing. 24069ce434fSBarry Smith 24169ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 24269ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate() 24369ce434fSBarry Smith @*/ 24469ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map) 24569ce434fSBarry Smith { 24669ce434fSBarry Smith PetscMPIInt rank,size; 24769ce434fSBarry Smith PetscInt p; 24869ce434fSBarry Smith PetscErrorCode ierr; 24969ce434fSBarry Smith 25069ce434fSBarry Smith PetscFunctionBegin; 251ca5434daSLawrence 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); 252ca5434daSLawrence Mitchell if (map->setupcalled) PetscFunctionReturn(0); 25369ce434fSBarry Smith 254b146b01cSBarry Smith if (map->n > 0 && map->bs > 1) { 255ec4d677dSStefano 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); 256b146b01cSBarry Smith } 257b146b01cSBarry Smith if (map->N > 0 && map->bs > 1) { 258ec4d677dSStefano 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); 259b146b01cSBarry Smith } 260b146b01cSBarry Smith 26169ce434fSBarry Smith ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr); 26269ce434fSBarry Smith ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr); 26333d57670SJed Brown if (map->n > 0) map->n = map->n/PetscAbs(map->bs); 26433d57670SJed Brown if (map->N > 0) map->N = map->N/PetscAbs(map->bs); 26569ce434fSBarry Smith ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr); 26633d57670SJed Brown map->n = map->n*PetscAbs(map->bs); 26733d57670SJed Brown map->N = map->N*PetscAbs(map->bs); 26869ce434fSBarry Smith if (!map->range) { 269854ce69bSBarry Smith ierr = PetscMalloc1(size+1, &map->range);CHKERRQ(ierr); 27069ce434fSBarry Smith } 27169ce434fSBarry Smith ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRQ(ierr); 27269ce434fSBarry Smith 27369ce434fSBarry Smith map->range[0] = 0; 27469ce434fSBarry Smith for (p = 2; p <= size; p++) map->range[p] += map->range[p-1]; 27569ce434fSBarry Smith 27669ce434fSBarry Smith map->rstart = map->range[rank]; 27769ce434fSBarry Smith map->rend = map->range[rank+1]; 278ca5434daSLawrence Mitchell 279ca5434daSLawrence Mitchell /* lock the layout */ 280ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE; 281ca5434daSLawrence Mitchell map->oldn = map->n; 282ca5434daSLawrence Mitchell map->oldN = map->N; 283ca5434daSLawrence Mitchell map->oldbs = map->bs; 28469ce434fSBarry Smith PetscFunctionReturn(0); 28569ce434fSBarry Smith } 28669ce434fSBarry Smith 287c3002683SMatthew G. Knepley /*@ 28869ce434fSBarry Smith PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first. 28969ce434fSBarry Smith 29069ce434fSBarry Smith Collective on PetscLayout 29169ce434fSBarry Smith 29269ce434fSBarry Smith Input Parameter: 29369ce434fSBarry Smith . in - input PetscLayout to be duplicated 29469ce434fSBarry Smith 29569ce434fSBarry Smith Output Parameter: 29669ce434fSBarry Smith . out - the copy 29769ce434fSBarry Smith 29869ce434fSBarry Smith Level: developer 29969ce434fSBarry Smith 30095452b02SPatrick Sanan Notes: 30195452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 30269ce434fSBarry Smith 30369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference() 30469ce434fSBarry Smith @*/ 30569ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out) 30669ce434fSBarry Smith { 30769ce434fSBarry Smith PetscMPIInt size; 30869ce434fSBarry Smith PetscErrorCode ierr; 30969ce434fSBarry Smith MPI_Comm comm = in->comm; 31069ce434fSBarry Smith 31169ce434fSBarry Smith PetscFunctionBegin; 31269ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 31369ce434fSBarry Smith ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr); 31469ce434fSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 31569ce434fSBarry Smith ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr); 316c168f6d8SVaclav Hapla if (in->range) { 317854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&(*out)->range);CHKERRQ(ierr); 318580bdb30SBarry Smith ierr = PetscArraycpy((*out)->range,in->range,size+1);CHKERRQ(ierr); 319c168f6d8SVaclav Hapla } 32069ce434fSBarry Smith 32169ce434fSBarry Smith (*out)->refcnt = 0; 32269ce434fSBarry Smith PetscFunctionReturn(0); 32369ce434fSBarry Smith } 32469ce434fSBarry Smith 325c3002683SMatthew G. Knepley /*@ 32669ce434fSBarry Smith PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 32769ce434fSBarry Smith 32869ce434fSBarry Smith Collective on PetscLayout 32969ce434fSBarry Smith 33069ce434fSBarry Smith Input Parameter: 33169ce434fSBarry Smith . in - input PetscLayout to be copied 33269ce434fSBarry Smith 33369ce434fSBarry Smith Output Parameter: 33469ce434fSBarry Smith . out - the reference location 33569ce434fSBarry Smith 33669ce434fSBarry Smith Level: developer 33769ce434fSBarry Smith 33895452b02SPatrick Sanan Notes: 33995452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 34069ce434fSBarry Smith 34169ce434fSBarry Smith If the out location already contains a PetscLayout it is destroyed 34269ce434fSBarry Smith 34369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 34469ce434fSBarry Smith @*/ 34569ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out) 34669ce434fSBarry Smith { 34769ce434fSBarry Smith PetscErrorCode ierr; 34869ce434fSBarry Smith 34969ce434fSBarry Smith PetscFunctionBegin; 35069ce434fSBarry Smith in->refcnt++; 35169ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 35269ce434fSBarry Smith *out = in; 35369ce434fSBarry Smith PetscFunctionReturn(0); 35469ce434fSBarry Smith } 35569ce434fSBarry Smith 356c3002683SMatthew G. Knepley /*@ 35769ce434fSBarry Smith PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 35869ce434fSBarry Smith 35969ce434fSBarry Smith Collective on PetscLayout 36069ce434fSBarry Smith 36169ce434fSBarry Smith Input Parameter: 36269ce434fSBarry Smith + in - input PetscLayout 36369ce434fSBarry Smith - ltog - the local to global mapping 36469ce434fSBarry Smith 36569ce434fSBarry Smith 36669ce434fSBarry Smith Level: developer 36769ce434fSBarry Smith 36895452b02SPatrick Sanan Notes: 36995452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 37069ce434fSBarry Smith 37169ce434fSBarry Smith If the ltog location already contains a PetscLayout it is destroyed 37269ce434fSBarry Smith 373a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 37469ce434fSBarry Smith @*/ 37569ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog) 37669ce434fSBarry Smith { 37769ce434fSBarry Smith PetscErrorCode ierr; 37845b6f7e9SBarry Smith PetscInt bs; 37969ce434fSBarry Smith 38069ce434fSBarry Smith PetscFunctionBegin; 38145b6f7e9SBarry Smith ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr); 38237461477SLawrence 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); 38369ce434fSBarry Smith ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 38469ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr); 38569ce434fSBarry Smith in->mapping = ltog; 38669ce434fSBarry Smith PetscFunctionReturn(0); 38769ce434fSBarry Smith } 38869ce434fSBarry Smith 389c3002683SMatthew G. Knepley /*@ 39069ce434fSBarry Smith PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 39169ce434fSBarry Smith 39269ce434fSBarry Smith Collective on PetscLayout 39369ce434fSBarry Smith 39469ce434fSBarry Smith Input Parameters: 39569ce434fSBarry Smith + map - pointer to the map 39669ce434fSBarry Smith - n - the local size 39769ce434fSBarry Smith 39869ce434fSBarry Smith Level: developer 39969ce434fSBarry Smith 40069ce434fSBarry Smith Notes: 40169ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 40269ce434fSBarry Smith 40369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 40469ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 40569ce434fSBarry Smith @*/ 40669ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n) 40769ce434fSBarry Smith { 40869ce434fSBarry Smith PetscFunctionBegin; 40969ce434fSBarry 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); 41069ce434fSBarry Smith map->n = n; 41169ce434fSBarry Smith PetscFunctionReturn(0); 41269ce434fSBarry Smith } 41369ce434fSBarry Smith 41469ce434fSBarry Smith /*@C 41569ce434fSBarry Smith PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 41669ce434fSBarry Smith 41769ce434fSBarry Smith Not Collective 41869ce434fSBarry Smith 41969ce434fSBarry Smith Input Parameters: 42069ce434fSBarry Smith . map - pointer to the map 42169ce434fSBarry Smith 42269ce434fSBarry Smith Output Parameters: 42369ce434fSBarry Smith . n - the local size 42469ce434fSBarry Smith 42569ce434fSBarry Smith Level: developer 42669ce434fSBarry Smith 42769ce434fSBarry Smith Notes: 42869ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 42969ce434fSBarry Smith 43069ce434fSBarry Smith Fortran Notes: 43169ce434fSBarry Smith Not available from Fortran 43269ce434fSBarry Smith 43369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 43469ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 43569ce434fSBarry Smith 43669ce434fSBarry Smith @*/ 43769ce434fSBarry Smith PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n) 43869ce434fSBarry Smith { 43969ce434fSBarry Smith PetscFunctionBegin; 44069ce434fSBarry Smith *n = map->n; 44169ce434fSBarry Smith PetscFunctionReturn(0); 44269ce434fSBarry Smith } 44369ce434fSBarry Smith 444c3002683SMatthew G. Knepley /*@ 44569ce434fSBarry Smith PetscLayoutSetSize - Sets the global size for a PetscLayout object. 44669ce434fSBarry Smith 44769ce434fSBarry Smith Logically Collective on PetscLayout 44869ce434fSBarry Smith 44969ce434fSBarry Smith Input Parameters: 45069ce434fSBarry Smith + map - pointer to the map 45169ce434fSBarry Smith - n - the global size 45269ce434fSBarry Smith 45369ce434fSBarry Smith Level: developer 45469ce434fSBarry Smith 45569ce434fSBarry Smith Notes: 45669ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 45769ce434fSBarry Smith 45869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 45969ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 46069ce434fSBarry Smith @*/ 46169ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n) 46269ce434fSBarry Smith { 46369ce434fSBarry Smith PetscFunctionBegin; 46469ce434fSBarry Smith map->N = n; 46569ce434fSBarry Smith PetscFunctionReturn(0); 46669ce434fSBarry Smith } 46769ce434fSBarry Smith 468c3002683SMatthew G. Knepley /*@ 46969ce434fSBarry Smith PetscLayoutGetSize - Gets the global size for a PetscLayout object. 47069ce434fSBarry Smith 47169ce434fSBarry Smith Not Collective 47269ce434fSBarry Smith 47369ce434fSBarry Smith Input Parameters: 47469ce434fSBarry Smith . map - pointer to the map 47569ce434fSBarry Smith 47669ce434fSBarry Smith Output Parameters: 47769ce434fSBarry Smith . n - the global size 47869ce434fSBarry Smith 47969ce434fSBarry Smith Level: developer 48069ce434fSBarry Smith 48169ce434fSBarry Smith Notes: 48269ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 48369ce434fSBarry Smith 48469ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 48569ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 48669ce434fSBarry Smith @*/ 48769ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n) 48869ce434fSBarry Smith { 48969ce434fSBarry Smith PetscFunctionBegin; 49069ce434fSBarry Smith *n = map->N; 49169ce434fSBarry Smith PetscFunctionReturn(0); 49269ce434fSBarry Smith } 49369ce434fSBarry Smith 494c3002683SMatthew G. Knepley /*@ 49569ce434fSBarry Smith PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 49669ce434fSBarry Smith 49769ce434fSBarry Smith Logically Collective on PetscLayout 49869ce434fSBarry Smith 49969ce434fSBarry Smith Input Parameters: 50069ce434fSBarry Smith + map - pointer to the map 50169ce434fSBarry Smith - bs - the size 50269ce434fSBarry Smith 50369ce434fSBarry Smith Level: developer 50469ce434fSBarry Smith 50569ce434fSBarry Smith Notes: 50669ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 50769ce434fSBarry Smith 50869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 50969ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 51069ce434fSBarry Smith @*/ 51169ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs) 51269ce434fSBarry Smith { 51369ce434fSBarry Smith PetscFunctionBegin; 51469bbac97SJed Brown if (bs < 0) PetscFunctionReturn(0); 515299e779cSStefano 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); 516565245c5SBarry Smith if (map->mapping) { 517705e6b8bSstefano_zampini PetscInt obs; 518565245c5SBarry Smith PetscErrorCode ierr; 519565245c5SBarry Smith 520705e6b8bSstefano_zampini ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr); 521705e6b8bSstefano_zampini if (obs > 1) { 52263fa5c83Sstefano_zampini ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr); 523565245c5SBarry Smith } 524705e6b8bSstefano_zampini } 52569ce434fSBarry Smith map->bs = bs; 52669ce434fSBarry Smith PetscFunctionReturn(0); 52769ce434fSBarry Smith } 52869ce434fSBarry Smith 529c3002683SMatthew G. Knepley /*@ 53069ce434fSBarry Smith PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 53169ce434fSBarry Smith 53269ce434fSBarry Smith Not Collective 53369ce434fSBarry Smith 53469ce434fSBarry Smith Input Parameters: 53569ce434fSBarry Smith . map - pointer to the map 53669ce434fSBarry Smith 53769ce434fSBarry Smith Output Parameters: 53869ce434fSBarry Smith . bs - the size 53969ce434fSBarry Smith 54069ce434fSBarry Smith Level: developer 54169ce434fSBarry Smith 54269ce434fSBarry Smith Notes: 54369ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 54469ce434fSBarry Smith 54569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 54669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize() 54769ce434fSBarry Smith @*/ 54869ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs) 54969ce434fSBarry Smith { 55069ce434fSBarry Smith PetscFunctionBegin; 55133d57670SJed Brown *bs = PetscAbs(map->bs); 55269ce434fSBarry Smith PetscFunctionReturn(0); 55369ce434fSBarry Smith } 55469ce434fSBarry Smith 555c3002683SMatthew G. Knepley /*@ 55669ce434fSBarry Smith PetscLayoutGetRange - gets the range of values owned by this process 55769ce434fSBarry Smith 55869ce434fSBarry Smith Not Collective 55969ce434fSBarry Smith 56069ce434fSBarry Smith Input Parameters: 56169ce434fSBarry Smith . map - pointer to the map 56269ce434fSBarry Smith 56369ce434fSBarry Smith Output Parameters: 56469ce434fSBarry Smith + rstart - first index owned by this process 56569ce434fSBarry Smith - rend - one more than the last index owned by this process 56669ce434fSBarry Smith 56769ce434fSBarry Smith Level: developer 56869ce434fSBarry Smith 56969ce434fSBarry Smith Notes: 57069ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 57169ce434fSBarry Smith 57269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 57369ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 57469ce434fSBarry Smith @*/ 57569ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend) 57669ce434fSBarry Smith { 57769ce434fSBarry Smith PetscFunctionBegin; 57869ce434fSBarry Smith if (rstart) *rstart = map->rstart; 57969ce434fSBarry Smith if (rend) *rend = map->rend; 58069ce434fSBarry Smith PetscFunctionReturn(0); 58169ce434fSBarry Smith } 58269ce434fSBarry Smith 58369ce434fSBarry Smith /*@C 58469ce434fSBarry Smith PetscLayoutGetRanges - gets the range of values owned by all processes 58569ce434fSBarry Smith 58669ce434fSBarry Smith Not Collective 58769ce434fSBarry Smith 58869ce434fSBarry Smith Input Parameters: 58969ce434fSBarry Smith . map - pointer to the map 59069ce434fSBarry Smith 59169ce434fSBarry Smith Output Parameters: 59269ce434fSBarry Smith . range - start of each processors range of indices (the final entry is one more then the 59369ce434fSBarry Smith last index on the last process) 59469ce434fSBarry Smith 59569ce434fSBarry Smith Level: developer 59669ce434fSBarry Smith 59769ce434fSBarry Smith Notes: 59869ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 59969ce434fSBarry Smith 60069ce434fSBarry Smith Fortran Notes: 60169ce434fSBarry Smith Not available from Fortran 60269ce434fSBarry Smith 60369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 60469ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 60569ce434fSBarry Smith 60669ce434fSBarry Smith @*/ 60769ce434fSBarry Smith PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[]) 60869ce434fSBarry Smith { 60969ce434fSBarry Smith PetscFunctionBegin; 61069ce434fSBarry Smith *range = map->range; 61169ce434fSBarry Smith PetscFunctionReturn(0); 61269ce434fSBarry Smith } 61369ce434fSBarry Smith 61469ce434fSBarry Smith /*@C 61569ce434fSBarry Smith PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout 61669ce434fSBarry Smith 61769ce434fSBarry Smith Collective 61869ce434fSBarry Smith 61969ce434fSBarry Smith Input Arguments: 62069ce434fSBarry Smith + sf - star forest 62169ce434fSBarry Smith . layout - PetscLayout defining the global space 62269ce434fSBarry Smith . nleaves - number of leaf vertices on the current process, each of these references a root on any process 62369ce434fSBarry Smith . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage 624cf79137fSStefano Zampini . localmode - copy mode for ilocal 62569ce434fSBarry Smith - iremote - remote locations of root vertices for each leaf on the current process 62669ce434fSBarry Smith 62769ce434fSBarry Smith Level: intermediate 62869ce434fSBarry Smith 629cf79137fSStefano Zampini Developers Note: Local indices which are the identity permutation in the range [0,nleaves) are discarded as they 630cf79137fSStefano Zampini encode contiguous storage. In such case, if localmode is PETSC_OWN_POINTER, the memory is deallocated as it is not 631cf79137fSStefano Zampini needed 632cf79137fSStefano Zampini 63369ce434fSBarry Smith .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph() 63469ce434fSBarry Smith @*/ 63569ce434fSBarry Smith PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote) 63669ce434fSBarry Smith { 63769ce434fSBarry Smith PetscErrorCode ierr; 63869ce434fSBarry Smith PetscInt i,nroots; 63969ce434fSBarry Smith PetscSFNode *remote; 64069ce434fSBarry Smith 64169ce434fSBarry Smith PetscFunctionBegin; 64269ce434fSBarry Smith ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr); 643785e854fSJed Brown ierr = PetscMalloc1(nleaves,&remote);CHKERRQ(ierr); 64469ce434fSBarry Smith for (i=0; i<nleaves; i++) { 645131c27b5Sprj- PetscMPIInt owner = -1; 64669ce434fSBarry Smith ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr); 64769ce434fSBarry Smith remote[i].rank = owner; 64869ce434fSBarry Smith remote[i].index = iremote[i] - layout->range[owner]; 64969ce434fSBarry Smith } 65069ce434fSBarry Smith ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr); 65169ce434fSBarry Smith PetscFunctionReturn(0); 65269ce434fSBarry Smith } 65369ce434fSBarry Smith 654f92d6284SStefano Zampini /*@ 655f92d6284SStefano Zampini PetscLayoutCompare - Compares two layouts 656f92d6284SStefano Zampini 657f92d6284SStefano Zampini Not Collective 658f92d6284SStefano Zampini 659f92d6284SStefano Zampini Input Parameters: 660d11c674dSStefano Zampini + mapa - pointer to the first map 661f92d6284SStefano Zampini - mapb - pointer to the second map 662f92d6284SStefano Zampini 663f92d6284SStefano Zampini Output Parameters: 664f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise 665f92d6284SStefano Zampini 666f92d6284SStefano Zampini Level: beginner 667f92d6284SStefano Zampini 668f92d6284SStefano Zampini Notes: 669f92d6284SStefano Zampini 670f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 671f92d6284SStefano Zampini PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 672f92d6284SStefano Zampini @*/ 673f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent) 674f92d6284SStefano Zampini { 675f92d6284SStefano Zampini PetscErrorCode ierr; 676f92d6284SStefano Zampini PetscMPIInt sizea,sizeb; 677f92d6284SStefano Zampini 678f92d6284SStefano Zampini PetscFunctionBegin; 679f92d6284SStefano Zampini *congruent = PETSC_FALSE; 680f92d6284SStefano Zampini ierr = MPI_Comm_size(mapa->comm,&sizea);CHKERRQ(ierr); 681f92d6284SStefano Zampini ierr = MPI_Comm_size(mapb->comm,&sizeb);CHKERRQ(ierr); 682f92d6284SStefano Zampini if (mapa->N == mapb->N && mapa->range && mapb->range && sizea == sizeb) { 683580bdb30SBarry Smith ierr = PetscArraycmp(mapa->range,mapb->range,sizea+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 */ 703a72d46e8SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(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++; 726a72d46e8SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(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