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) 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; 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]; 19576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */ 1967b659617SVaclav Hapla PetscInt tmp; 1977b659617SVaclav Hapla ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 1987b659617SVaclav 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); 1997b659617SVaclav Hapla if (map->bs > 1) { 2007b659617SVaclav 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); 2017b659617SVaclav Hapla } 2027b659617SVaclav Hapla if (map->bs > 1) { 2037b659617SVaclav 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); 2047b659617SVaclav Hapla } 20576bd3646SJed Brown } 206ca5434daSLawrence Mitchell /* lock the layout */ 207ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE; 208ca5434daSLawrence Mitchell map->oldn = map->n; 209ca5434daSLawrence Mitchell map->oldN = map->N; 210ca5434daSLawrence Mitchell map->oldbs = map->bs; 2119621ec18SVaclav Hapla *newmap = map; 2127b659617SVaclav Hapla PetscFunctionReturn(0); 2137b659617SVaclav Hapla } 2147b659617SVaclav Hapla 215c3002683SMatthew G. Knepley /*@ 21669ce434fSBarry Smith PetscLayoutSetUp - given a map where you have set either the global or local 21769ce434fSBarry Smith size sets up the map so that it may be used. 21869ce434fSBarry Smith 219d083f849SBarry Smith Collective 22069ce434fSBarry Smith 22169ce434fSBarry Smith Input Parameters: 22269ce434fSBarry Smith . map - pointer to the map 22369ce434fSBarry Smith 22469ce434fSBarry Smith Level: developer 22569ce434fSBarry Smith 22695452b02SPatrick Sanan Notes: 22795452b02SPatrick Sanan Typical calling sequence 228c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *); 229c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1); 230c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both 231c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout); 232c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *); 23369ce434fSBarry Smith 2347b659617SVaclav Hapla If range exists, and local size is not set, everything gets computed from the range. 23569ce434fSBarry Smith 23669ce434fSBarry Smith If the local size, global size are already set and range exists then this does nothing. 23769ce434fSBarry Smith 23869ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 23969ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate() 24069ce434fSBarry Smith @*/ 24169ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map) 24269ce434fSBarry Smith { 24369ce434fSBarry Smith PetscMPIInt rank,size; 24469ce434fSBarry Smith PetscInt p; 24569ce434fSBarry Smith PetscErrorCode ierr; 24669ce434fSBarry Smith 24769ce434fSBarry Smith PetscFunctionBegin; 248ca5434daSLawrence 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); 249ca5434daSLawrence Mitchell if (map->setupcalled) PetscFunctionReturn(0); 25069ce434fSBarry Smith 251b146b01cSBarry Smith if (map->n > 0 && map->bs > 1) { 252ec4d677dSStefano 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); 253b146b01cSBarry Smith } 254b146b01cSBarry Smith if (map->N > 0 && map->bs > 1) { 255ec4d677dSStefano 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); 256b146b01cSBarry Smith } 257b146b01cSBarry Smith 25869ce434fSBarry Smith ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr); 25969ce434fSBarry Smith ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr); 26033d57670SJed Brown if (map->n > 0) map->n = map->n/PetscAbs(map->bs); 26133d57670SJed Brown if (map->N > 0) map->N = map->N/PetscAbs(map->bs); 26269ce434fSBarry Smith ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr); 26333d57670SJed Brown map->n = map->n*PetscAbs(map->bs); 26433d57670SJed Brown map->N = map->N*PetscAbs(map->bs); 26569ce434fSBarry Smith if (!map->range) { 266854ce69bSBarry Smith ierr = PetscMalloc1(size+1, &map->range);CHKERRQ(ierr); 26769ce434fSBarry Smith } 26869ce434fSBarry Smith ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRQ(ierr); 26969ce434fSBarry Smith 27069ce434fSBarry Smith map->range[0] = 0; 27169ce434fSBarry Smith for (p = 2; p <= size; p++) map->range[p] += map->range[p-1]; 27269ce434fSBarry Smith 27369ce434fSBarry Smith map->rstart = map->range[rank]; 27469ce434fSBarry Smith map->rend = map->range[rank+1]; 275ca5434daSLawrence Mitchell 276ca5434daSLawrence Mitchell /* lock the layout */ 277ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE; 278ca5434daSLawrence Mitchell map->oldn = map->n; 279ca5434daSLawrence Mitchell map->oldN = map->N; 280ca5434daSLawrence Mitchell map->oldbs = map->bs; 28169ce434fSBarry Smith PetscFunctionReturn(0); 28269ce434fSBarry Smith } 28369ce434fSBarry Smith 284c3002683SMatthew G. Knepley /*@ 28569ce434fSBarry Smith PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first. 28669ce434fSBarry Smith 28769ce434fSBarry Smith Collective on PetscLayout 28869ce434fSBarry Smith 28969ce434fSBarry Smith Input Parameter: 29069ce434fSBarry Smith . in - input PetscLayout to be duplicated 29169ce434fSBarry Smith 29269ce434fSBarry Smith Output Parameter: 29369ce434fSBarry Smith . out - the copy 29469ce434fSBarry Smith 29569ce434fSBarry Smith Level: developer 29669ce434fSBarry Smith 29795452b02SPatrick Sanan Notes: 29895452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 29969ce434fSBarry Smith 30069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference() 30169ce434fSBarry Smith @*/ 30269ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out) 30369ce434fSBarry Smith { 30469ce434fSBarry Smith PetscMPIInt size; 30569ce434fSBarry Smith PetscErrorCode ierr; 30669ce434fSBarry Smith MPI_Comm comm = in->comm; 30769ce434fSBarry Smith 30869ce434fSBarry Smith PetscFunctionBegin; 30969ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 31069ce434fSBarry Smith ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr); 31169ce434fSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 31269ce434fSBarry Smith ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr); 313c168f6d8SVaclav Hapla if (in->range) { 314854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&(*out)->range);CHKERRQ(ierr); 315580bdb30SBarry Smith ierr = PetscArraycpy((*out)->range,in->range,size+1);CHKERRQ(ierr); 316c168f6d8SVaclav Hapla } 31769ce434fSBarry Smith 31869ce434fSBarry Smith (*out)->refcnt = 0; 31969ce434fSBarry Smith PetscFunctionReturn(0); 32069ce434fSBarry Smith } 32169ce434fSBarry Smith 322c3002683SMatthew G. Knepley /*@ 32369ce434fSBarry Smith PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 32469ce434fSBarry Smith 32569ce434fSBarry Smith Collective on PetscLayout 32669ce434fSBarry Smith 32769ce434fSBarry Smith Input Parameter: 32869ce434fSBarry Smith . in - input PetscLayout to be copied 32969ce434fSBarry Smith 33069ce434fSBarry Smith Output Parameter: 33169ce434fSBarry Smith . out - the reference location 33269ce434fSBarry Smith 33369ce434fSBarry Smith Level: developer 33469ce434fSBarry Smith 33595452b02SPatrick Sanan Notes: 33695452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 33769ce434fSBarry Smith 33869ce434fSBarry Smith If the out location already contains a PetscLayout it is destroyed 33969ce434fSBarry Smith 34069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 34169ce434fSBarry Smith @*/ 34269ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out) 34369ce434fSBarry Smith { 34469ce434fSBarry Smith PetscErrorCode ierr; 34569ce434fSBarry Smith 34669ce434fSBarry Smith PetscFunctionBegin; 34769ce434fSBarry Smith in->refcnt++; 34869ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 34969ce434fSBarry Smith *out = in; 35069ce434fSBarry Smith PetscFunctionReturn(0); 35169ce434fSBarry Smith } 35269ce434fSBarry Smith 353c3002683SMatthew G. Knepley /*@ 35469ce434fSBarry Smith PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 35569ce434fSBarry Smith 35669ce434fSBarry Smith Collective on PetscLayout 35769ce434fSBarry Smith 35869ce434fSBarry Smith Input Parameter: 35969ce434fSBarry Smith + in - input PetscLayout 36069ce434fSBarry Smith - ltog - the local to global mapping 36169ce434fSBarry Smith 36269ce434fSBarry Smith 36369ce434fSBarry Smith Level: developer 36469ce434fSBarry Smith 36595452b02SPatrick Sanan Notes: 36695452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 36769ce434fSBarry Smith 36869ce434fSBarry Smith If the ltog location already contains a PetscLayout it is destroyed 36969ce434fSBarry Smith 370a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 37169ce434fSBarry Smith @*/ 37269ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog) 37369ce434fSBarry Smith { 37469ce434fSBarry Smith PetscErrorCode ierr; 37545b6f7e9SBarry Smith PetscInt bs; 37669ce434fSBarry Smith 37769ce434fSBarry Smith PetscFunctionBegin; 37845b6f7e9SBarry Smith ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr); 37937461477SLawrence 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); 38069ce434fSBarry Smith ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 38169ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr); 38269ce434fSBarry Smith in->mapping = ltog; 38369ce434fSBarry Smith PetscFunctionReturn(0); 38469ce434fSBarry Smith } 38569ce434fSBarry Smith 386c3002683SMatthew G. Knepley /*@ 38769ce434fSBarry Smith PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 38869ce434fSBarry Smith 38969ce434fSBarry Smith Collective on PetscLayout 39069ce434fSBarry Smith 39169ce434fSBarry Smith Input Parameters: 39269ce434fSBarry Smith + map - pointer to the map 39369ce434fSBarry Smith - n - the local size 39469ce434fSBarry Smith 39569ce434fSBarry Smith Level: developer 39669ce434fSBarry Smith 39769ce434fSBarry Smith Notes: 39869ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 39969ce434fSBarry Smith 40069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 40169ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 40269ce434fSBarry Smith @*/ 40369ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n) 40469ce434fSBarry Smith { 40569ce434fSBarry Smith PetscFunctionBegin; 40669ce434fSBarry 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); 40769ce434fSBarry Smith map->n = n; 40869ce434fSBarry Smith PetscFunctionReturn(0); 40969ce434fSBarry Smith } 41069ce434fSBarry Smith 41169ce434fSBarry Smith /*@C 41269ce434fSBarry Smith PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 41369ce434fSBarry Smith 41469ce434fSBarry Smith Not Collective 41569ce434fSBarry Smith 41669ce434fSBarry Smith Input Parameters: 41769ce434fSBarry Smith . map - pointer to the map 41869ce434fSBarry Smith 41969ce434fSBarry Smith Output Parameters: 42069ce434fSBarry Smith . n - the local size 42169ce434fSBarry Smith 42269ce434fSBarry Smith Level: developer 42369ce434fSBarry Smith 42469ce434fSBarry Smith Notes: 42569ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 42669ce434fSBarry Smith 42769ce434fSBarry Smith Fortran Notes: 42869ce434fSBarry Smith Not available from Fortran 42969ce434fSBarry Smith 43069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 43169ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 43269ce434fSBarry Smith 43369ce434fSBarry Smith @*/ 43469ce434fSBarry Smith PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n) 43569ce434fSBarry Smith { 43669ce434fSBarry Smith PetscFunctionBegin; 43769ce434fSBarry Smith *n = map->n; 43869ce434fSBarry Smith PetscFunctionReturn(0); 43969ce434fSBarry Smith } 44069ce434fSBarry Smith 441c3002683SMatthew G. Knepley /*@ 44269ce434fSBarry Smith PetscLayoutSetSize - Sets the global size for a PetscLayout object. 44369ce434fSBarry Smith 44469ce434fSBarry Smith Logically Collective on PetscLayout 44569ce434fSBarry Smith 44669ce434fSBarry Smith Input Parameters: 44769ce434fSBarry Smith + map - pointer to the map 44869ce434fSBarry Smith - n - the global size 44969ce434fSBarry Smith 45069ce434fSBarry Smith Level: developer 45169ce434fSBarry Smith 45269ce434fSBarry Smith Notes: 45369ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 45469ce434fSBarry Smith 45569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 45669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 45769ce434fSBarry Smith @*/ 45869ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n) 45969ce434fSBarry Smith { 46069ce434fSBarry Smith PetscFunctionBegin; 46169ce434fSBarry Smith map->N = n; 46269ce434fSBarry Smith PetscFunctionReturn(0); 46369ce434fSBarry Smith } 46469ce434fSBarry Smith 465c3002683SMatthew G. Knepley /*@ 46669ce434fSBarry Smith PetscLayoutGetSize - Gets the global size for a PetscLayout object. 46769ce434fSBarry Smith 46869ce434fSBarry Smith Not Collective 46969ce434fSBarry Smith 47069ce434fSBarry Smith Input Parameters: 47169ce434fSBarry Smith . map - pointer to the map 47269ce434fSBarry Smith 47369ce434fSBarry Smith Output Parameters: 47469ce434fSBarry Smith . n - the global size 47569ce434fSBarry Smith 47669ce434fSBarry Smith Level: developer 47769ce434fSBarry Smith 47869ce434fSBarry Smith Notes: 47969ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 48069ce434fSBarry Smith 48169ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 48269ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 48369ce434fSBarry Smith @*/ 48469ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n) 48569ce434fSBarry Smith { 48669ce434fSBarry Smith PetscFunctionBegin; 48769ce434fSBarry Smith *n = map->N; 48869ce434fSBarry Smith PetscFunctionReturn(0); 48969ce434fSBarry Smith } 49069ce434fSBarry Smith 491c3002683SMatthew G. Knepley /*@ 49269ce434fSBarry Smith PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 49369ce434fSBarry Smith 49469ce434fSBarry Smith Logically Collective on PetscLayout 49569ce434fSBarry Smith 49669ce434fSBarry Smith Input Parameters: 49769ce434fSBarry Smith + map - pointer to the map 49869ce434fSBarry Smith - bs - the size 49969ce434fSBarry Smith 50069ce434fSBarry Smith Level: developer 50169ce434fSBarry Smith 50269ce434fSBarry Smith Notes: 50369ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 50469ce434fSBarry Smith 50569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 50669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 50769ce434fSBarry Smith @*/ 50869ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs) 50969ce434fSBarry Smith { 51069ce434fSBarry Smith PetscFunctionBegin; 51169bbac97SJed Brown if (bs < 0) PetscFunctionReturn(0); 512299e779cSStefano 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); 513565245c5SBarry Smith if (map->mapping) { 514705e6b8bSstefano_zampini PetscInt obs; 515565245c5SBarry Smith PetscErrorCode ierr; 516565245c5SBarry Smith 517705e6b8bSstefano_zampini ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr); 518705e6b8bSstefano_zampini if (obs > 1) { 51963fa5c83Sstefano_zampini ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr); 520565245c5SBarry Smith } 521705e6b8bSstefano_zampini } 52269ce434fSBarry Smith map->bs = bs; 52369ce434fSBarry Smith PetscFunctionReturn(0); 52469ce434fSBarry Smith } 52569ce434fSBarry Smith 526c3002683SMatthew G. Knepley /*@ 52769ce434fSBarry Smith PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 52869ce434fSBarry Smith 52969ce434fSBarry Smith Not Collective 53069ce434fSBarry Smith 53169ce434fSBarry Smith Input Parameters: 53269ce434fSBarry Smith . map - pointer to the map 53369ce434fSBarry Smith 53469ce434fSBarry Smith Output Parameters: 53569ce434fSBarry Smith . bs - the size 53669ce434fSBarry Smith 53769ce434fSBarry Smith Level: developer 53869ce434fSBarry Smith 53969ce434fSBarry Smith Notes: 54069ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 54169ce434fSBarry Smith 54269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 54369ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize() 54469ce434fSBarry Smith @*/ 54569ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs) 54669ce434fSBarry Smith { 54769ce434fSBarry Smith PetscFunctionBegin; 54833d57670SJed Brown *bs = PetscAbs(map->bs); 54969ce434fSBarry Smith PetscFunctionReturn(0); 55069ce434fSBarry Smith } 55169ce434fSBarry Smith 552c3002683SMatthew G. Knepley /*@ 55369ce434fSBarry Smith PetscLayoutGetRange - gets the range of values owned by this process 55469ce434fSBarry Smith 55569ce434fSBarry Smith Not Collective 55669ce434fSBarry Smith 55769ce434fSBarry Smith Input Parameters: 55869ce434fSBarry Smith . map - pointer to the map 55969ce434fSBarry Smith 56069ce434fSBarry Smith Output Parameters: 56169ce434fSBarry Smith + rstart - first index owned by this process 56269ce434fSBarry Smith - rend - one more than the last index owned by this process 56369ce434fSBarry Smith 56469ce434fSBarry Smith Level: developer 56569ce434fSBarry Smith 56669ce434fSBarry Smith Notes: 56769ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 56869ce434fSBarry Smith 56969ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 57069ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 57169ce434fSBarry Smith @*/ 57269ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend) 57369ce434fSBarry Smith { 57469ce434fSBarry Smith PetscFunctionBegin; 57569ce434fSBarry Smith if (rstart) *rstart = map->rstart; 57669ce434fSBarry Smith if (rend) *rend = map->rend; 57769ce434fSBarry Smith PetscFunctionReturn(0); 57869ce434fSBarry Smith } 57969ce434fSBarry Smith 58069ce434fSBarry Smith /*@C 58169ce434fSBarry Smith PetscLayoutGetRanges - gets the range of values owned by all processes 58269ce434fSBarry Smith 58369ce434fSBarry Smith Not Collective 58469ce434fSBarry Smith 58569ce434fSBarry Smith Input Parameters: 58669ce434fSBarry Smith . map - pointer to the map 58769ce434fSBarry Smith 58869ce434fSBarry Smith Output Parameters: 58969ce434fSBarry Smith . range - start of each processors range of indices (the final entry is one more then the 59069ce434fSBarry Smith last index on the last process) 59169ce434fSBarry Smith 59269ce434fSBarry Smith Level: developer 59369ce434fSBarry Smith 59469ce434fSBarry Smith Notes: 59569ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 59669ce434fSBarry Smith 59769ce434fSBarry Smith Fortran Notes: 59869ce434fSBarry Smith Not available from Fortran 59969ce434fSBarry Smith 60069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 60169ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 60269ce434fSBarry Smith 60369ce434fSBarry Smith @*/ 60469ce434fSBarry Smith PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[]) 60569ce434fSBarry Smith { 60669ce434fSBarry Smith PetscFunctionBegin; 60769ce434fSBarry Smith *range = map->range; 60869ce434fSBarry Smith PetscFunctionReturn(0); 60969ce434fSBarry Smith } 61069ce434fSBarry Smith 61169ce434fSBarry Smith /*@C 612*f26271d2SStefano Zampini PetscLayoutsCreateSF - Creates a parallel star forest mapping two PetscLayout objects 613*f26271d2SStefano Zampini 614*f26271d2SStefano Zampini Collective 615*f26271d2SStefano Zampini 616*f26271d2SStefano Zampini Input Arguments: 617*f26271d2SStefano Zampini + rmap - PetscLayout defining the global root space 618*f26271d2SStefano Zampini - lmap - PetscLayout defining the global leaf space 619*f26271d2SStefano Zampini 620*f26271d2SStefano Zampini Output Arguments: 621*f26271d2SStefano Zampini . sf - The parallel star forest 622*f26271d2SStefano Zampini 623*f26271d2SStefano Zampini Level: intermediate 624*f26271d2SStefano Zampini 625*f26271d2SStefano Zampini .seealso: PetscSFCreate(), PetscLayoutCreate(), PetscSFSetGraphLayout() 626*f26271d2SStefano Zampini @*/ 627*f26271d2SStefano Zampini PetscErrorCode PetscLayoutsCreateSF(PetscLayout rmap, PetscLayout lmap, PetscSF* sf) 628*f26271d2SStefano Zampini { 629*f26271d2SStefano Zampini PetscErrorCode ierr; 630*f26271d2SStefano Zampini PetscInt i,nroots,nleaves = 0; 631*f26271d2SStefano Zampini PetscInt rN, lst, len; 632*f26271d2SStefano Zampini PetscMPIInt owner = -1; 633*f26271d2SStefano Zampini PetscSFNode *remote; 634*f26271d2SStefano Zampini MPI_Comm rcomm = rmap->comm; 635*f26271d2SStefano Zampini MPI_Comm lcomm = lmap->comm; 636*f26271d2SStefano Zampini PetscMPIInt flg; 637*f26271d2SStefano Zampini 638*f26271d2SStefano Zampini PetscFunctionBegin; 639*f26271d2SStefano Zampini PetscValidPointer(sf,3); 640*f26271d2SStefano Zampini if (!rmap->setupcalled) SETERRQ(rcomm,PETSC_ERR_ARG_WRONGSTATE,"Root layout not setup"); 641*f26271d2SStefano Zampini if (!lmap->setupcalled) SETERRQ(lcomm,PETSC_ERR_ARG_WRONGSTATE,"Leaf layout not setup"); 642*f26271d2SStefano Zampini ierr = MPI_Comm_compare(rcomm,lcomm,&flg);CHKERRQ(ierr); 643*f26271d2SStefano Zampini if (flg != MPI_CONGRUENT && flg != MPI_IDENT) SETERRQ(rcomm,PETSC_ERR_SUP,"cannot map two layouts with non-matching communicators"); 644*f26271d2SStefano Zampini ierr = PetscSFCreate(rcomm,sf);CHKERRQ(ierr); 645*f26271d2SStefano Zampini ierr = PetscLayoutGetLocalSize(rmap,&nroots);CHKERRQ(ierr); 646*f26271d2SStefano Zampini ierr = PetscLayoutGetSize(rmap,&rN);CHKERRQ(ierr); 647*f26271d2SStefano Zampini ierr = PetscLayoutGetRange(lmap,&lst,&len);CHKERRQ(ierr); 648*f26271d2SStefano Zampini ierr = PetscMalloc1(len-lst,&remote);CHKERRQ(ierr); 649*f26271d2SStefano Zampini for (i = lst; i < len && i < rN; i++) { 650*f26271d2SStefano Zampini if (owner < -1 || i >= rmap->range[owner+1]) { 651*f26271d2SStefano Zampini ierr = PetscLayoutFindOwner(rmap,i,&owner);CHKERRQ(ierr); 652*f26271d2SStefano Zampini } 653*f26271d2SStefano Zampini remote[nleaves].rank = owner; 654*f26271d2SStefano Zampini remote[nleaves].index = i - rmap->range[owner]; 655*f26271d2SStefano Zampini nleaves++; 656*f26271d2SStefano Zampini } 657*f26271d2SStefano Zampini ierr = PetscSFSetGraph(*sf,nroots,nleaves,NULL,PETSC_OWN_POINTER,remote,PETSC_COPY_VALUES);CHKERRQ(ierr); 658*f26271d2SStefano Zampini ierr = PetscFree(remote);CHKERRQ(ierr); 659*f26271d2SStefano Zampini PetscFunctionReturn(0); 660*f26271d2SStefano Zampini } 661*f26271d2SStefano Zampini 662*f26271d2SStefano Zampini /*@C 66369ce434fSBarry Smith PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout 66469ce434fSBarry Smith 66569ce434fSBarry Smith Collective 66669ce434fSBarry Smith 66769ce434fSBarry Smith Input Arguments: 66869ce434fSBarry Smith + sf - star forest 66969ce434fSBarry Smith . layout - PetscLayout defining the global space 67069ce434fSBarry Smith . nleaves - number of leaf vertices on the current process, each of these references a root on any process 67169ce434fSBarry Smith . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage 672cf79137fSStefano Zampini . localmode - copy mode for ilocal 67369ce434fSBarry Smith - iremote - remote locations of root vertices for each leaf on the current process 67469ce434fSBarry Smith 67569ce434fSBarry Smith Level: intermediate 67669ce434fSBarry Smith 677cf79137fSStefano Zampini Developers Note: Local indices which are the identity permutation in the range [0,nleaves) are discarded as they 678cf79137fSStefano Zampini encode contiguous storage. In such case, if localmode is PETSC_OWN_POINTER, the memory is deallocated as it is not 679cf79137fSStefano Zampini needed 680cf79137fSStefano Zampini 68169ce434fSBarry Smith .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph() 68269ce434fSBarry Smith @*/ 68369ce434fSBarry Smith PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote) 68469ce434fSBarry Smith { 68569ce434fSBarry Smith PetscErrorCode ierr; 68669ce434fSBarry Smith PetscInt i,nroots; 68769ce434fSBarry Smith PetscSFNode *remote; 68869ce434fSBarry Smith 68969ce434fSBarry Smith PetscFunctionBegin; 69069ce434fSBarry Smith ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr); 691785e854fSJed Brown ierr = PetscMalloc1(nleaves,&remote);CHKERRQ(ierr); 69269ce434fSBarry Smith for (i=0; i<nleaves; i++) { 693131c27b5Sprj- PetscMPIInt owner = -1; 69469ce434fSBarry Smith ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr); 69569ce434fSBarry Smith remote[i].rank = owner; 69669ce434fSBarry Smith remote[i].index = iremote[i] - layout->range[owner]; 69769ce434fSBarry Smith } 69869ce434fSBarry Smith ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr); 69969ce434fSBarry Smith PetscFunctionReturn(0); 70069ce434fSBarry Smith } 70169ce434fSBarry Smith 702f92d6284SStefano Zampini /*@ 703f92d6284SStefano Zampini PetscLayoutCompare - Compares two layouts 704f92d6284SStefano Zampini 705f92d6284SStefano Zampini Not Collective 706f92d6284SStefano Zampini 707f92d6284SStefano Zampini Input Parameters: 708d11c674dSStefano Zampini + mapa - pointer to the first map 709f92d6284SStefano Zampini - mapb - pointer to the second map 710f92d6284SStefano Zampini 711f92d6284SStefano Zampini Output Parameters: 712f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise 713f92d6284SStefano Zampini 714f92d6284SStefano Zampini Level: beginner 715f92d6284SStefano Zampini 716f92d6284SStefano Zampini Notes: 717f92d6284SStefano Zampini 718f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 719f92d6284SStefano Zampini PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 720f92d6284SStefano Zampini @*/ 721f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent) 722f92d6284SStefano Zampini { 723f92d6284SStefano Zampini PetscErrorCode ierr; 724f92d6284SStefano Zampini PetscMPIInt sizea,sizeb; 725f92d6284SStefano Zampini 726f92d6284SStefano Zampini PetscFunctionBegin; 727f92d6284SStefano Zampini *congruent = PETSC_FALSE; 728f92d6284SStefano Zampini ierr = MPI_Comm_size(mapa->comm,&sizea);CHKERRQ(ierr); 729f92d6284SStefano Zampini ierr = MPI_Comm_size(mapb->comm,&sizeb);CHKERRQ(ierr); 730f92d6284SStefano Zampini if (mapa->N == mapb->N && mapa->range && mapb->range && sizea == sizeb) { 731580bdb30SBarry Smith ierr = PetscArraycmp(mapa->range,mapb->range,sizea+1,congruent);CHKERRQ(ierr); 732f92d6284SStefano Zampini } 733f92d6284SStefano Zampini PetscFunctionReturn(0); 734f92d6284SStefano Zampini } 735a72d46e8SStefano Zampini 736a72d46e8SStefano Zampini /* TODO: handle nooffprocentries like MatZeroRowsMapLocal_Private, since this code is the same */ 737a72d46e8SStefano Zampini PetscErrorCode PetscLayoutMapLocal(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 738a72d46e8SStefano Zampini { 739a72d46e8SStefano Zampini PetscInt *owners = map->range; 740a72d46e8SStefano Zampini PetscInt n = map->n; 741a72d46e8SStefano Zampini PetscSF sf; 742a72d46e8SStefano Zampini PetscInt *lidxs,*work = NULL; 743a72d46e8SStefano Zampini PetscSFNode *ridxs; 744131c27b5Sprj- PetscMPIInt rank, p = 0; 745131c27b5Sprj- PetscInt r, len = 0; 746a72d46e8SStefano Zampini PetscErrorCode ierr; 747a72d46e8SStefano Zampini 748a72d46e8SStefano Zampini PetscFunctionBegin; 749a72d46e8SStefano Zampini if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 750a72d46e8SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs */ 751a72d46e8SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 752a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 753a72d46e8SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 754a72d46e8SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 755a72d46e8SStefano Zampini for (r = 0; r < N; ++r) { 756a72d46e8SStefano Zampini const PetscInt idx = idxs[r]; 757a72d46e8SStefano 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); 758a72d46e8SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 759a72d46e8SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 760a72d46e8SStefano Zampini } 761a72d46e8SStefano Zampini ridxs[r].rank = p; 762a72d46e8SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 763a72d46e8SStefano Zampini } 764a72d46e8SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 765a72d46e8SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 766a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 767a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 768a72d46e8SStefano Zampini if (ogidxs) { /* communicate global idxs */ 769a72d46e8SStefano Zampini PetscInt cum = 0,start,*work2; 770a72d46e8SStefano Zampini 771a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 772a72d46e8SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 773a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 774a72d46e8SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 775a72d46e8SStefano Zampini start -= cum; 776a72d46e8SStefano Zampini cum = 0; 777a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 778a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 779a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 780a72d46e8SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 781a72d46e8SStefano Zampini } 782a72d46e8SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 783a72d46e8SStefano Zampini /* Compress and put in indices */ 784a72d46e8SStefano Zampini for (r = 0; r < n; ++r) 785a72d46e8SStefano Zampini if (lidxs[r] >= 0) { 786a72d46e8SStefano Zampini if (work) work[len] = work[r]; 787a72d46e8SStefano Zampini lidxs[len++] = r; 788a72d46e8SStefano Zampini } 789a72d46e8SStefano Zampini if (on) *on = len; 790a72d46e8SStefano Zampini if (oidxs) *oidxs = lidxs; 791a72d46e8SStefano Zampini if (ogidxs) *ogidxs = work; 792a72d46e8SStefano Zampini PetscFunctionReturn(0); 793a72d46e8SStefano Zampini } 794