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 /*@ 11*a8643c1eSVaclav Hapla PetscLayoutCreate - Allocates PetscLayout space and sets the PetscLayout contents to the default. 1269ce434fSBarry Smith 13d083f849SBarry Smith Collective 1469ce434fSBarry Smith 1569ce434fSBarry Smith Input Parameters: 16*a8643c1eSVaclav Hapla . comm - the MPI communicator 17*a8643c1eSVaclav Hapla 18*a8643c1eSVaclav Hapla Output Parameters: 19*a8643c1eSVaclav 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 *); 27*a8643c1eSVaclav Hapla PetscLayoutSetBlockSize(PetscLayout,bs); 28*a8643c1eSVaclav Hapla PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n); 2969ce434fSBarry Smith PetscLayoutSetUp(PetscLayout); 30456fcb79SJed Brown .ve 3169ce434fSBarry Smith Optionally use any of the following: 32456fcb79SJed Brown 33456fcb79SJed Brown + PetscLayoutGetSize(PetscLayout,PetscInt *); 34456fcb79SJed Brown . PetscLayoutGetLocalSize(PetscLayout,PetscInt *); 35456fcb79SJed Brown . PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend); 36456fcb79SJed Brown . PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]); 37456fcb79SJed Brown - PetscLayoutDestroy(PetscLayout*); 3869ce434fSBarry Smith 3969ce434fSBarry Smith The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in 4069ce434fSBarry Smith user codes unless you really gain something in their use. 4169ce434fSBarry Smith 4269ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 4369ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp() 4469ce434fSBarry Smith 4569ce434fSBarry Smith @*/ 4669ce434fSBarry Smith PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map) 4769ce434fSBarry Smith { 4869ce434fSBarry Smith PetscErrorCode ierr; 4969ce434fSBarry Smith 5069ce434fSBarry Smith PetscFunctionBegin; 51b00a9115SJed Brown ierr = PetscNew(map);CHKERRQ(ierr); 5269ce434fSBarry Smith 5369ce434fSBarry Smith (*map)->comm = comm; 5469ce434fSBarry Smith (*map)->bs = -1; 5569ce434fSBarry Smith (*map)->n = -1; 5669ce434fSBarry Smith (*map)->N = -1; 57f92d6284SStefano Zampini (*map)->range = NULL; 5869ce434fSBarry Smith (*map)->rstart = 0; 5969ce434fSBarry Smith (*map)->rend = 0; 6069ce434fSBarry Smith PetscFunctionReturn(0); 6169ce434fSBarry Smith } 6269ce434fSBarry Smith 63c3002683SMatthew G. Knepley /*@ 6469ce434fSBarry Smith PetscLayoutDestroy - Frees a map object and frees its range if that exists. 6569ce434fSBarry Smith 66d083f849SBarry Smith Collective 6769ce434fSBarry Smith 6869ce434fSBarry Smith Input Parameters: 6969ce434fSBarry Smith . map - the PetscLayout 7069ce434fSBarry Smith 7169ce434fSBarry Smith Level: developer 7269ce434fSBarry Smith 73c3002683SMatthew G. Knepley Note: 7469ce434fSBarry Smith The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is 7569ce434fSBarry Smith recommended they not be used in user codes unless you really gain something in their use. 7669ce434fSBarry Smith 7769ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(), 7869ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp() 7969ce434fSBarry Smith 8069ce434fSBarry Smith @*/ 8169ce434fSBarry Smith PetscErrorCode PetscLayoutDestroy(PetscLayout *map) 8269ce434fSBarry Smith { 8369ce434fSBarry Smith PetscErrorCode ierr; 8469ce434fSBarry Smith 8569ce434fSBarry Smith PetscFunctionBegin; 8669ce434fSBarry Smith if (!*map) PetscFunctionReturn(0); 8769ce434fSBarry Smith if (!(*map)->refcnt--) { 8869ce434fSBarry Smith ierr = PetscFree((*map)->range);CHKERRQ(ierr); 8969ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr); 9069ce434fSBarry Smith ierr = PetscFree((*map));CHKERRQ(ierr); 9169ce434fSBarry Smith } 9269ce434fSBarry Smith *map = NULL; 9369ce434fSBarry Smith PetscFunctionReturn(0); 9469ce434fSBarry Smith } 9569ce434fSBarry Smith 967b659617SVaclav Hapla static PetscErrorCode PetscLayoutSetUp_SizesFromRanges_Private(PetscLayout map) 977b659617SVaclav Hapla { 987b659617SVaclav Hapla PetscMPIInt rank,size; 997b659617SVaclav Hapla PetscErrorCode ierr; 1007b659617SVaclav Hapla 1017b659617SVaclav Hapla PetscFunctionBegin; 1027b659617SVaclav Hapla ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr); 1037b659617SVaclav Hapla ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr); 1047b659617SVaclav Hapla map->rstart = map->range[rank]; 1057b659617SVaclav Hapla map->rend = map->range[rank+1]; 1067b659617SVaclav Hapla map->n = map->rend - map->rstart; 1077b659617SVaclav Hapla map->N = map->range[size]; 1087b659617SVaclav Hapla #if defined(PETSC_USE_DEBUG) 1097b659617SVaclav Hapla /* just check that n, N and bs are consistent */ 1107b659617SVaclav Hapla { 1117b659617SVaclav Hapla PetscInt tmp; 1127b659617SVaclav Hapla ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 1137b659617SVaclav 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); 1147b659617SVaclav Hapla } 1157b659617SVaclav Hapla if (map->bs > 1) { 1167b659617SVaclav 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); 1177b659617SVaclav Hapla } 1187b659617SVaclav Hapla if (map->bs > 1) { 1197b659617SVaclav 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); 1207b659617SVaclav Hapla } 1217b659617SVaclav Hapla #endif 1227b659617SVaclav Hapla PetscFunctionReturn(0); 1237b659617SVaclav Hapla } 1247b659617SVaclav Hapla 125c3002683SMatthew G. Knepley /*@ 12669ce434fSBarry Smith PetscLayoutSetUp - given a map where you have set either the global or local 12769ce434fSBarry Smith size sets up the map so that it may be used. 12869ce434fSBarry Smith 129d083f849SBarry Smith Collective 13069ce434fSBarry Smith 13169ce434fSBarry Smith Input Parameters: 13269ce434fSBarry Smith . map - pointer to the map 13369ce434fSBarry Smith 13469ce434fSBarry Smith Level: developer 13569ce434fSBarry Smith 13695452b02SPatrick Sanan Notes: 13795452b02SPatrick Sanan Typical calling sequence 138c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *); 139c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1); 140c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both 141c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout); 142c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *); 14369ce434fSBarry Smith 1447b659617SVaclav Hapla If range exists, and local size is not set, everything gets computed from the range. 14569ce434fSBarry Smith 14669ce434fSBarry Smith If the local size, global size are already set and range exists then this does nothing. 14769ce434fSBarry Smith 14869ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 14969ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate() 15069ce434fSBarry Smith @*/ 15169ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map) 15269ce434fSBarry Smith { 15369ce434fSBarry Smith PetscMPIInt rank,size; 15469ce434fSBarry Smith PetscInt p; 15569ce434fSBarry Smith PetscErrorCode ierr; 15669ce434fSBarry Smith 15769ce434fSBarry Smith PetscFunctionBegin; 15869ce434fSBarry Smith if ((map->n >= 0) && (map->N >= 0) && (map->range)) PetscFunctionReturn(0); 1597b659617SVaclav Hapla if (map->range && map->n < 0) { 1607b659617SVaclav Hapla ierr = PetscLayoutSetUp_SizesFromRanges_Private(map);CHKERRQ(ierr); 1617b659617SVaclav Hapla PetscFunctionReturn(0); 1627b659617SVaclav Hapla } 16369ce434fSBarry Smith 164b146b01cSBarry Smith if (map->n > 0 && map->bs > 1) { 165ec4d677dSStefano 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); 166b146b01cSBarry Smith } 167b146b01cSBarry Smith if (map->N > 0 && map->bs > 1) { 168ec4d677dSStefano 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); 169b146b01cSBarry Smith } 170b146b01cSBarry Smith 17169ce434fSBarry Smith ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr); 17269ce434fSBarry Smith ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr); 17333d57670SJed Brown if (map->n > 0) map->n = map->n/PetscAbs(map->bs); 17433d57670SJed Brown if (map->N > 0) map->N = map->N/PetscAbs(map->bs); 17569ce434fSBarry Smith ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr); 17633d57670SJed Brown map->n = map->n*PetscAbs(map->bs); 17733d57670SJed Brown map->N = map->N*PetscAbs(map->bs); 17869ce434fSBarry Smith if (!map->range) { 179854ce69bSBarry Smith ierr = PetscMalloc1(size+1, &map->range);CHKERRQ(ierr); 18069ce434fSBarry Smith } 18169ce434fSBarry Smith ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRQ(ierr); 18269ce434fSBarry Smith 18369ce434fSBarry Smith map->range[0] = 0; 18469ce434fSBarry Smith for (p = 2; p <= size; p++) map->range[p] += map->range[p-1]; 18569ce434fSBarry Smith 18669ce434fSBarry Smith map->rstart = map->range[rank]; 18769ce434fSBarry Smith map->rend = map->range[rank+1]; 18869ce434fSBarry Smith PetscFunctionReturn(0); 18969ce434fSBarry Smith } 19069ce434fSBarry Smith 191c3002683SMatthew G. Knepley /*@ 19269ce434fSBarry Smith PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first. 19369ce434fSBarry Smith 19469ce434fSBarry Smith Collective on PetscLayout 19569ce434fSBarry Smith 19669ce434fSBarry Smith Input Parameter: 19769ce434fSBarry Smith . in - input PetscLayout to be duplicated 19869ce434fSBarry Smith 19969ce434fSBarry Smith Output Parameter: 20069ce434fSBarry Smith . out - the copy 20169ce434fSBarry Smith 20269ce434fSBarry Smith Level: developer 20369ce434fSBarry Smith 20495452b02SPatrick Sanan Notes: 20595452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 20669ce434fSBarry Smith 20769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference() 20869ce434fSBarry Smith @*/ 20969ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out) 21069ce434fSBarry Smith { 21169ce434fSBarry Smith PetscMPIInt size; 21269ce434fSBarry Smith PetscErrorCode ierr; 21369ce434fSBarry Smith MPI_Comm comm = in->comm; 21469ce434fSBarry Smith 21569ce434fSBarry Smith PetscFunctionBegin; 21669ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 21769ce434fSBarry Smith ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr); 21869ce434fSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 21969ce434fSBarry Smith ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr); 220854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&(*out)->range);CHKERRQ(ierr); 221580bdb30SBarry Smith ierr = PetscArraycpy((*out)->range,in->range,size+1);CHKERRQ(ierr); 22269ce434fSBarry Smith 22369ce434fSBarry Smith (*out)->refcnt = 0; 22469ce434fSBarry Smith PetscFunctionReturn(0); 22569ce434fSBarry Smith } 22669ce434fSBarry Smith 227c3002683SMatthew G. Knepley /*@ 22869ce434fSBarry Smith PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 22969ce434fSBarry Smith 23069ce434fSBarry Smith Collective on PetscLayout 23169ce434fSBarry Smith 23269ce434fSBarry Smith Input Parameter: 23369ce434fSBarry Smith . in - input PetscLayout to be copied 23469ce434fSBarry Smith 23569ce434fSBarry Smith Output Parameter: 23669ce434fSBarry Smith . out - the reference location 23769ce434fSBarry Smith 23869ce434fSBarry Smith Level: developer 23969ce434fSBarry Smith 24095452b02SPatrick Sanan Notes: 24195452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 24269ce434fSBarry Smith 24369ce434fSBarry Smith If the out location already contains a PetscLayout it is destroyed 24469ce434fSBarry Smith 24569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 24669ce434fSBarry Smith @*/ 24769ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out) 24869ce434fSBarry Smith { 24969ce434fSBarry Smith PetscErrorCode ierr; 25069ce434fSBarry Smith 25169ce434fSBarry Smith PetscFunctionBegin; 25269ce434fSBarry Smith in->refcnt++; 25369ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 25469ce434fSBarry Smith *out = in; 25569ce434fSBarry Smith PetscFunctionReturn(0); 25669ce434fSBarry Smith } 25769ce434fSBarry Smith 258c3002683SMatthew G. Knepley /*@ 25969ce434fSBarry Smith PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 26069ce434fSBarry Smith 26169ce434fSBarry Smith Collective on PetscLayout 26269ce434fSBarry Smith 26369ce434fSBarry Smith Input Parameter: 26469ce434fSBarry Smith + in - input PetscLayout 26569ce434fSBarry Smith - ltog - the local to global mapping 26669ce434fSBarry Smith 26769ce434fSBarry Smith 26869ce434fSBarry Smith Level: developer 26969ce434fSBarry Smith 27095452b02SPatrick Sanan Notes: 27195452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 27269ce434fSBarry Smith 27369ce434fSBarry Smith If the ltog location already contains a PetscLayout it is destroyed 27469ce434fSBarry Smith 275a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 27669ce434fSBarry Smith @*/ 27769ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog) 27869ce434fSBarry Smith { 27969ce434fSBarry Smith PetscErrorCode ierr; 28045b6f7e9SBarry Smith PetscInt bs; 28169ce434fSBarry Smith 28269ce434fSBarry Smith PetscFunctionBegin; 28345b6f7e9SBarry Smith ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr); 28437461477SLawrence 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); 28569ce434fSBarry Smith ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 28669ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr); 28769ce434fSBarry Smith in->mapping = ltog; 28869ce434fSBarry Smith PetscFunctionReturn(0); 28969ce434fSBarry Smith } 29069ce434fSBarry Smith 291c3002683SMatthew G. Knepley /*@ 29269ce434fSBarry Smith PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 29369ce434fSBarry Smith 29469ce434fSBarry Smith Collective on PetscLayout 29569ce434fSBarry Smith 29669ce434fSBarry Smith Input Parameters: 29769ce434fSBarry Smith + map - pointer to the map 29869ce434fSBarry Smith - n - the local size 29969ce434fSBarry Smith 30069ce434fSBarry Smith Level: developer 30169ce434fSBarry Smith 30269ce434fSBarry Smith Notes: 30369ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 30469ce434fSBarry Smith 30569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 30669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 30769ce434fSBarry Smith @*/ 30869ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n) 30969ce434fSBarry Smith { 31069ce434fSBarry Smith PetscFunctionBegin; 31169ce434fSBarry 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); 31269ce434fSBarry Smith map->n = n; 31369ce434fSBarry Smith PetscFunctionReturn(0); 31469ce434fSBarry Smith } 31569ce434fSBarry Smith 31669ce434fSBarry Smith /*@C 31769ce434fSBarry Smith PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 31869ce434fSBarry Smith 31969ce434fSBarry Smith Not Collective 32069ce434fSBarry Smith 32169ce434fSBarry Smith Input Parameters: 32269ce434fSBarry Smith . map - pointer to the map 32369ce434fSBarry Smith 32469ce434fSBarry Smith Output Parameters: 32569ce434fSBarry Smith . n - the local size 32669ce434fSBarry Smith 32769ce434fSBarry Smith Level: developer 32869ce434fSBarry Smith 32969ce434fSBarry Smith Notes: 33069ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 33169ce434fSBarry Smith 33269ce434fSBarry Smith Fortran Notes: 33369ce434fSBarry Smith Not available from Fortran 33469ce434fSBarry Smith 33569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 33669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 33769ce434fSBarry Smith 33869ce434fSBarry Smith @*/ 33969ce434fSBarry Smith PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n) 34069ce434fSBarry Smith { 34169ce434fSBarry Smith PetscFunctionBegin; 34269ce434fSBarry Smith *n = map->n; 34369ce434fSBarry Smith PetscFunctionReturn(0); 34469ce434fSBarry Smith } 34569ce434fSBarry Smith 346c3002683SMatthew G. Knepley /*@ 34769ce434fSBarry Smith PetscLayoutSetSize - Sets the global size for a PetscLayout object. 34869ce434fSBarry Smith 34969ce434fSBarry Smith Logically Collective on PetscLayout 35069ce434fSBarry Smith 35169ce434fSBarry Smith Input Parameters: 35269ce434fSBarry Smith + map - pointer to the map 35369ce434fSBarry Smith - n - the global size 35469ce434fSBarry Smith 35569ce434fSBarry Smith Level: developer 35669ce434fSBarry Smith 35769ce434fSBarry Smith Notes: 35869ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 35969ce434fSBarry Smith 36069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 36169ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 36269ce434fSBarry Smith @*/ 36369ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n) 36469ce434fSBarry Smith { 36569ce434fSBarry Smith PetscFunctionBegin; 36669ce434fSBarry Smith map->N = n; 36769ce434fSBarry Smith PetscFunctionReturn(0); 36869ce434fSBarry Smith } 36969ce434fSBarry Smith 370c3002683SMatthew G. Knepley /*@ 37169ce434fSBarry Smith PetscLayoutGetSize - Gets the global size for a PetscLayout object. 37269ce434fSBarry Smith 37369ce434fSBarry Smith Not Collective 37469ce434fSBarry Smith 37569ce434fSBarry Smith Input Parameters: 37669ce434fSBarry Smith . map - pointer to the map 37769ce434fSBarry Smith 37869ce434fSBarry Smith Output Parameters: 37969ce434fSBarry Smith . n - the global size 38069ce434fSBarry Smith 38169ce434fSBarry Smith Level: developer 38269ce434fSBarry Smith 38369ce434fSBarry Smith Notes: 38469ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 38569ce434fSBarry Smith 38669ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 38769ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 38869ce434fSBarry Smith @*/ 38969ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n) 39069ce434fSBarry Smith { 39169ce434fSBarry Smith PetscFunctionBegin; 39269ce434fSBarry Smith *n = map->N; 39369ce434fSBarry Smith PetscFunctionReturn(0); 39469ce434fSBarry Smith } 39569ce434fSBarry Smith 396c3002683SMatthew G. Knepley /*@ 39769ce434fSBarry Smith PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 39869ce434fSBarry Smith 39969ce434fSBarry Smith Logically Collective on PetscLayout 40069ce434fSBarry Smith 40169ce434fSBarry Smith Input Parameters: 40269ce434fSBarry Smith + map - pointer to the map 40369ce434fSBarry Smith - bs - the size 40469ce434fSBarry Smith 40569ce434fSBarry Smith Level: developer 40669ce434fSBarry Smith 40769ce434fSBarry Smith Notes: 40869ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 40969ce434fSBarry Smith 41069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 41169ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 41269ce434fSBarry Smith @*/ 41369ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs) 41469ce434fSBarry Smith { 41569ce434fSBarry Smith PetscFunctionBegin; 41669bbac97SJed Brown if (bs < 0) PetscFunctionReturn(0); 417299e779cSStefano 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); 418565245c5SBarry Smith if (map->mapping) { 419705e6b8bSstefano_zampini PetscInt obs; 420565245c5SBarry Smith PetscErrorCode ierr; 421565245c5SBarry Smith 422705e6b8bSstefano_zampini ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr); 423705e6b8bSstefano_zampini if (obs > 1) { 42463fa5c83Sstefano_zampini ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr); 425565245c5SBarry Smith } 426705e6b8bSstefano_zampini } 42769ce434fSBarry Smith map->bs = bs; 42869ce434fSBarry Smith PetscFunctionReturn(0); 42969ce434fSBarry Smith } 43069ce434fSBarry Smith 431c3002683SMatthew G. Knepley /*@ 43269ce434fSBarry Smith PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 43369ce434fSBarry Smith 43469ce434fSBarry Smith Not Collective 43569ce434fSBarry Smith 43669ce434fSBarry Smith Input Parameters: 43769ce434fSBarry Smith . map - pointer to the map 43869ce434fSBarry Smith 43969ce434fSBarry Smith Output Parameters: 44069ce434fSBarry Smith . bs - the size 44169ce434fSBarry Smith 44269ce434fSBarry Smith Level: developer 44369ce434fSBarry Smith 44469ce434fSBarry Smith Notes: 44569ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 44669ce434fSBarry Smith 44769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 44869ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize() 44969ce434fSBarry Smith @*/ 45069ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs) 45169ce434fSBarry Smith { 45269ce434fSBarry Smith PetscFunctionBegin; 45333d57670SJed Brown *bs = PetscAbs(map->bs); 45469ce434fSBarry Smith PetscFunctionReturn(0); 45569ce434fSBarry Smith } 45669ce434fSBarry Smith 457c3002683SMatthew G. Knepley /*@ 45869ce434fSBarry Smith PetscLayoutGetRange - gets the range of values owned by this process 45969ce434fSBarry Smith 46069ce434fSBarry Smith Not Collective 46169ce434fSBarry Smith 46269ce434fSBarry Smith Input Parameters: 46369ce434fSBarry Smith . map - pointer to the map 46469ce434fSBarry Smith 46569ce434fSBarry Smith Output Parameters: 46669ce434fSBarry Smith + rstart - first index owned by this process 46769ce434fSBarry Smith - rend - one more than the last index owned by this process 46869ce434fSBarry Smith 46969ce434fSBarry Smith Level: developer 47069ce434fSBarry Smith 47169ce434fSBarry Smith Notes: 47269ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 47369ce434fSBarry Smith 47469ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 47569ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 47669ce434fSBarry Smith @*/ 47769ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend) 47869ce434fSBarry Smith { 47969ce434fSBarry Smith PetscFunctionBegin; 48069ce434fSBarry Smith if (rstart) *rstart = map->rstart; 48169ce434fSBarry Smith if (rend) *rend = map->rend; 48269ce434fSBarry Smith PetscFunctionReturn(0); 48369ce434fSBarry Smith } 48469ce434fSBarry Smith 48569ce434fSBarry Smith /*@C 48669ce434fSBarry Smith PetscLayoutGetRanges - gets the range of values owned by all processes 48769ce434fSBarry Smith 48869ce434fSBarry Smith Not Collective 48969ce434fSBarry Smith 49069ce434fSBarry Smith Input Parameters: 49169ce434fSBarry Smith . map - pointer to the map 49269ce434fSBarry Smith 49369ce434fSBarry Smith Output Parameters: 49469ce434fSBarry Smith . range - start of each processors range of indices (the final entry is one more then the 49569ce434fSBarry Smith last index on the last process) 49669ce434fSBarry Smith 49769ce434fSBarry Smith Level: developer 49869ce434fSBarry Smith 49969ce434fSBarry Smith Notes: 50069ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 50169ce434fSBarry Smith 50269ce434fSBarry Smith Fortran Notes: 50369ce434fSBarry Smith Not available from Fortran 50469ce434fSBarry Smith 50569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 50669ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 50769ce434fSBarry Smith 50869ce434fSBarry Smith @*/ 50969ce434fSBarry Smith PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[]) 51069ce434fSBarry Smith { 51169ce434fSBarry Smith PetscFunctionBegin; 51269ce434fSBarry Smith *range = map->range; 51369ce434fSBarry Smith PetscFunctionReturn(0); 51469ce434fSBarry Smith } 51569ce434fSBarry Smith 51669ce434fSBarry Smith /*@C 51769ce434fSBarry Smith PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout 51869ce434fSBarry Smith 51969ce434fSBarry Smith Collective 52069ce434fSBarry Smith 52169ce434fSBarry Smith Input Arguments: 52269ce434fSBarry Smith + sf - star forest 52369ce434fSBarry Smith . layout - PetscLayout defining the global space 52469ce434fSBarry Smith . nleaves - number of leaf vertices on the current process, each of these references a root on any process 52569ce434fSBarry Smith . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage 526cf79137fSStefano Zampini . localmode - copy mode for ilocal 52769ce434fSBarry Smith - iremote - remote locations of root vertices for each leaf on the current process 52869ce434fSBarry Smith 52969ce434fSBarry Smith Level: intermediate 53069ce434fSBarry Smith 531cf79137fSStefano Zampini Developers Note: Local indices which are the identity permutation in the range [0,nleaves) are discarded as they 532cf79137fSStefano Zampini encode contiguous storage. In such case, if localmode is PETSC_OWN_POINTER, the memory is deallocated as it is not 533cf79137fSStefano Zampini needed 534cf79137fSStefano Zampini 53569ce434fSBarry Smith .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph() 53669ce434fSBarry Smith @*/ 53769ce434fSBarry Smith PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote) 53869ce434fSBarry Smith { 53969ce434fSBarry Smith PetscErrorCode ierr; 54069ce434fSBarry Smith PetscInt i,nroots; 54169ce434fSBarry Smith PetscSFNode *remote; 54269ce434fSBarry Smith 54369ce434fSBarry Smith PetscFunctionBegin; 54469ce434fSBarry Smith ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr); 545785e854fSJed Brown ierr = PetscMalloc1(nleaves,&remote);CHKERRQ(ierr); 54669ce434fSBarry Smith for (i=0; i<nleaves; i++) { 54769ce434fSBarry Smith PetscInt owner = -1; 54869ce434fSBarry Smith ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr); 54969ce434fSBarry Smith remote[i].rank = owner; 55069ce434fSBarry Smith remote[i].index = iremote[i] - layout->range[owner]; 55169ce434fSBarry Smith } 55269ce434fSBarry Smith ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr); 55369ce434fSBarry Smith PetscFunctionReturn(0); 55469ce434fSBarry Smith } 55569ce434fSBarry Smith 556f92d6284SStefano Zampini /*@ 557f92d6284SStefano Zampini PetscLayoutCompare - Compares two layouts 558f92d6284SStefano Zampini 559f92d6284SStefano Zampini Not Collective 560f92d6284SStefano Zampini 561f92d6284SStefano Zampini Input Parameters: 562d11c674dSStefano Zampini + mapa - pointer to the first map 563f92d6284SStefano Zampini - mapb - pointer to the second map 564f92d6284SStefano Zampini 565f92d6284SStefano Zampini Output Parameters: 566f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise 567f92d6284SStefano Zampini 568f92d6284SStefano Zampini Level: beginner 569f92d6284SStefano Zampini 570f92d6284SStefano Zampini Notes: 571f92d6284SStefano Zampini 572f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 573f92d6284SStefano Zampini PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 574f92d6284SStefano Zampini @*/ 575f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent) 576f92d6284SStefano Zampini { 577f92d6284SStefano Zampini PetscErrorCode ierr; 578f92d6284SStefano Zampini PetscMPIInt sizea,sizeb; 579f92d6284SStefano Zampini 580f92d6284SStefano Zampini PetscFunctionBegin; 581f92d6284SStefano Zampini *congruent = PETSC_FALSE; 582f92d6284SStefano Zampini ierr = MPI_Comm_size(mapa->comm,&sizea);CHKERRQ(ierr); 583f92d6284SStefano Zampini ierr = MPI_Comm_size(mapb->comm,&sizeb);CHKERRQ(ierr); 584f92d6284SStefano Zampini if (mapa->N == mapb->N && mapa->range && mapb->range && sizea == sizeb) { 585580bdb30SBarry Smith ierr = PetscArraycmp(mapa->range,mapb->range,sizea+1,congruent);CHKERRQ(ierr); 586f92d6284SStefano Zampini } 587f92d6284SStefano Zampini PetscFunctionReturn(0); 588f92d6284SStefano Zampini } 589a72d46e8SStefano Zampini 590a72d46e8SStefano Zampini /* TODO: handle nooffprocentries like MatZeroRowsMapLocal_Private, since this code is the same */ 591a72d46e8SStefano Zampini PetscErrorCode PetscLayoutMapLocal(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 592a72d46e8SStefano Zampini { 593a72d46e8SStefano Zampini PetscInt *owners = map->range; 594a72d46e8SStefano Zampini PetscInt n = map->n; 595a72d46e8SStefano Zampini PetscSF sf; 596a72d46e8SStefano Zampini PetscInt *lidxs,*work = NULL; 597a72d46e8SStefano Zampini PetscSFNode *ridxs; 598a72d46e8SStefano Zampini PetscMPIInt rank; 599a72d46e8SStefano Zampini PetscInt r, p = 0, len = 0; 600a72d46e8SStefano Zampini PetscErrorCode ierr; 601a72d46e8SStefano Zampini 602a72d46e8SStefano Zampini PetscFunctionBegin; 603a72d46e8SStefano Zampini if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 604a72d46e8SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs */ 605a72d46e8SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 606a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 607a72d46e8SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 608a72d46e8SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 609a72d46e8SStefano Zampini for (r = 0; r < N; ++r) { 610a72d46e8SStefano Zampini const PetscInt idx = idxs[r]; 611a72d46e8SStefano 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); 612a72d46e8SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 613a72d46e8SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 614a72d46e8SStefano Zampini } 615a72d46e8SStefano Zampini ridxs[r].rank = p; 616a72d46e8SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 617a72d46e8SStefano Zampini } 618a72d46e8SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 619a72d46e8SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 620a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 621a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 622a72d46e8SStefano Zampini if (ogidxs) { /* communicate global idxs */ 623a72d46e8SStefano Zampini PetscInt cum = 0,start,*work2; 624a72d46e8SStefano Zampini 625a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 626a72d46e8SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 627a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 628a72d46e8SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 629a72d46e8SStefano Zampini start -= cum; 630a72d46e8SStefano Zampini cum = 0; 631a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 632a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 633a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 634a72d46e8SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 635a72d46e8SStefano Zampini } 636a72d46e8SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 637a72d46e8SStefano Zampini /* Compress and put in indices */ 638a72d46e8SStefano Zampini for (r = 0; r < n; ++r) 639a72d46e8SStefano Zampini if (lidxs[r] >= 0) { 640a72d46e8SStefano Zampini if (work) work[len] = work[r]; 641a72d46e8SStefano Zampini lidxs[len++] = r; 642a72d46e8SStefano Zampini } 643a72d46e8SStefano Zampini if (on) *on = len; 644a72d46e8SStefano Zampini if (oidxs) *oidxs = lidxs; 645a72d46e8SStefano Zampini if (ogidxs) *ogidxs = work; 646a72d46e8SStefano Zampini PetscFunctionReturn(0); 647a72d46e8SStefano Zampini } 648