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 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); 220*c168f6d8SVaclav Hapla if (in->range) { 221854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&(*out)->range);CHKERRQ(ierr); 222580bdb30SBarry Smith ierr = PetscArraycpy((*out)->range,in->range,size+1);CHKERRQ(ierr); 223*c168f6d8SVaclav Hapla } 22469ce434fSBarry Smith 22569ce434fSBarry Smith (*out)->refcnt = 0; 22669ce434fSBarry Smith PetscFunctionReturn(0); 22769ce434fSBarry Smith } 22869ce434fSBarry Smith 229c3002683SMatthew G. Knepley /*@ 23069ce434fSBarry Smith PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 23169ce434fSBarry Smith 23269ce434fSBarry Smith Collective on PetscLayout 23369ce434fSBarry Smith 23469ce434fSBarry Smith Input Parameter: 23569ce434fSBarry Smith . in - input PetscLayout to be copied 23669ce434fSBarry Smith 23769ce434fSBarry Smith Output Parameter: 23869ce434fSBarry Smith . out - the reference location 23969ce434fSBarry Smith 24069ce434fSBarry Smith Level: developer 24169ce434fSBarry Smith 24295452b02SPatrick Sanan Notes: 24395452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 24469ce434fSBarry Smith 24569ce434fSBarry Smith If the out location already contains a PetscLayout it is destroyed 24669ce434fSBarry Smith 24769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 24869ce434fSBarry Smith @*/ 24969ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out) 25069ce434fSBarry Smith { 25169ce434fSBarry Smith PetscErrorCode ierr; 25269ce434fSBarry Smith 25369ce434fSBarry Smith PetscFunctionBegin; 25469ce434fSBarry Smith in->refcnt++; 25569ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 25669ce434fSBarry Smith *out = in; 25769ce434fSBarry Smith PetscFunctionReturn(0); 25869ce434fSBarry Smith } 25969ce434fSBarry Smith 260c3002683SMatthew G. Knepley /*@ 26169ce434fSBarry Smith PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 26269ce434fSBarry Smith 26369ce434fSBarry Smith Collective on PetscLayout 26469ce434fSBarry Smith 26569ce434fSBarry Smith Input Parameter: 26669ce434fSBarry Smith + in - input PetscLayout 26769ce434fSBarry Smith - ltog - the local to global mapping 26869ce434fSBarry Smith 26969ce434fSBarry Smith 27069ce434fSBarry Smith Level: developer 27169ce434fSBarry Smith 27295452b02SPatrick Sanan Notes: 27395452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 27469ce434fSBarry Smith 27569ce434fSBarry Smith If the ltog location already contains a PetscLayout it is destroyed 27669ce434fSBarry Smith 277a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 27869ce434fSBarry Smith @*/ 27969ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog) 28069ce434fSBarry Smith { 28169ce434fSBarry Smith PetscErrorCode ierr; 28245b6f7e9SBarry Smith PetscInt bs; 28369ce434fSBarry Smith 28469ce434fSBarry Smith PetscFunctionBegin; 28545b6f7e9SBarry Smith ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr); 28637461477SLawrence 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); 28769ce434fSBarry Smith ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 28869ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr); 28969ce434fSBarry Smith in->mapping = ltog; 29069ce434fSBarry Smith PetscFunctionReturn(0); 29169ce434fSBarry Smith } 29269ce434fSBarry Smith 293c3002683SMatthew G. Knepley /*@ 29469ce434fSBarry Smith PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 29569ce434fSBarry Smith 29669ce434fSBarry Smith Collective on PetscLayout 29769ce434fSBarry Smith 29869ce434fSBarry Smith Input Parameters: 29969ce434fSBarry Smith + map - pointer to the map 30069ce434fSBarry Smith - n - the local size 30169ce434fSBarry Smith 30269ce434fSBarry Smith Level: developer 30369ce434fSBarry Smith 30469ce434fSBarry Smith Notes: 30569ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 30669ce434fSBarry Smith 30769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 30869ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 30969ce434fSBarry Smith @*/ 31069ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n) 31169ce434fSBarry Smith { 31269ce434fSBarry Smith PetscFunctionBegin; 31369ce434fSBarry 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); 31469ce434fSBarry Smith map->n = n; 31569ce434fSBarry Smith PetscFunctionReturn(0); 31669ce434fSBarry Smith } 31769ce434fSBarry Smith 31869ce434fSBarry Smith /*@C 31969ce434fSBarry Smith PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 32069ce434fSBarry Smith 32169ce434fSBarry Smith Not Collective 32269ce434fSBarry Smith 32369ce434fSBarry Smith Input Parameters: 32469ce434fSBarry Smith . map - pointer to the map 32569ce434fSBarry Smith 32669ce434fSBarry Smith Output Parameters: 32769ce434fSBarry Smith . n - the local size 32869ce434fSBarry Smith 32969ce434fSBarry Smith Level: developer 33069ce434fSBarry Smith 33169ce434fSBarry Smith Notes: 33269ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 33369ce434fSBarry Smith 33469ce434fSBarry Smith Fortran Notes: 33569ce434fSBarry Smith Not available from Fortran 33669ce434fSBarry Smith 33769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 33869ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 33969ce434fSBarry Smith 34069ce434fSBarry Smith @*/ 34169ce434fSBarry Smith PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n) 34269ce434fSBarry Smith { 34369ce434fSBarry Smith PetscFunctionBegin; 34469ce434fSBarry Smith *n = map->n; 34569ce434fSBarry Smith PetscFunctionReturn(0); 34669ce434fSBarry Smith } 34769ce434fSBarry Smith 348c3002683SMatthew G. Knepley /*@ 34969ce434fSBarry Smith PetscLayoutSetSize - Sets the global size for a PetscLayout object. 35069ce434fSBarry Smith 35169ce434fSBarry Smith Logically Collective on PetscLayout 35269ce434fSBarry Smith 35369ce434fSBarry Smith Input Parameters: 35469ce434fSBarry Smith + map - pointer to the map 35569ce434fSBarry Smith - n - the global size 35669ce434fSBarry Smith 35769ce434fSBarry Smith Level: developer 35869ce434fSBarry Smith 35969ce434fSBarry Smith Notes: 36069ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 36169ce434fSBarry Smith 36269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 36369ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 36469ce434fSBarry Smith @*/ 36569ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n) 36669ce434fSBarry Smith { 36769ce434fSBarry Smith PetscFunctionBegin; 36869ce434fSBarry Smith map->N = n; 36969ce434fSBarry Smith PetscFunctionReturn(0); 37069ce434fSBarry Smith } 37169ce434fSBarry Smith 372c3002683SMatthew G. Knepley /*@ 37369ce434fSBarry Smith PetscLayoutGetSize - Gets the global size for a PetscLayout object. 37469ce434fSBarry Smith 37569ce434fSBarry Smith Not Collective 37669ce434fSBarry Smith 37769ce434fSBarry Smith Input Parameters: 37869ce434fSBarry Smith . map - pointer to the map 37969ce434fSBarry Smith 38069ce434fSBarry Smith Output Parameters: 38169ce434fSBarry Smith . n - the global size 38269ce434fSBarry Smith 38369ce434fSBarry Smith Level: developer 38469ce434fSBarry Smith 38569ce434fSBarry Smith Notes: 38669ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 38769ce434fSBarry Smith 38869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 38969ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 39069ce434fSBarry Smith @*/ 39169ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n) 39269ce434fSBarry Smith { 39369ce434fSBarry Smith PetscFunctionBegin; 39469ce434fSBarry Smith *n = map->N; 39569ce434fSBarry Smith PetscFunctionReturn(0); 39669ce434fSBarry Smith } 39769ce434fSBarry Smith 398c3002683SMatthew G. Knepley /*@ 39969ce434fSBarry Smith PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 40069ce434fSBarry Smith 40169ce434fSBarry Smith Logically Collective on PetscLayout 40269ce434fSBarry Smith 40369ce434fSBarry Smith Input Parameters: 40469ce434fSBarry Smith + map - pointer to the map 40569ce434fSBarry Smith - bs - the size 40669ce434fSBarry Smith 40769ce434fSBarry Smith Level: developer 40869ce434fSBarry Smith 40969ce434fSBarry Smith Notes: 41069ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 41169ce434fSBarry Smith 41269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 41369ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 41469ce434fSBarry Smith @*/ 41569ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs) 41669ce434fSBarry Smith { 41769ce434fSBarry Smith PetscFunctionBegin; 41869bbac97SJed Brown if (bs < 0) PetscFunctionReturn(0); 419299e779cSStefano 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); 420565245c5SBarry Smith if (map->mapping) { 421705e6b8bSstefano_zampini PetscInt obs; 422565245c5SBarry Smith PetscErrorCode ierr; 423565245c5SBarry Smith 424705e6b8bSstefano_zampini ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr); 425705e6b8bSstefano_zampini if (obs > 1) { 42663fa5c83Sstefano_zampini ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr); 427565245c5SBarry Smith } 428705e6b8bSstefano_zampini } 42969ce434fSBarry Smith map->bs = bs; 43069ce434fSBarry Smith PetscFunctionReturn(0); 43169ce434fSBarry Smith } 43269ce434fSBarry Smith 433c3002683SMatthew G. Knepley /*@ 43469ce434fSBarry Smith PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 43569ce434fSBarry Smith 43669ce434fSBarry Smith Not Collective 43769ce434fSBarry Smith 43869ce434fSBarry Smith Input Parameters: 43969ce434fSBarry Smith . map - pointer to the map 44069ce434fSBarry Smith 44169ce434fSBarry Smith Output Parameters: 44269ce434fSBarry Smith . bs - the size 44369ce434fSBarry Smith 44469ce434fSBarry Smith Level: developer 44569ce434fSBarry Smith 44669ce434fSBarry Smith Notes: 44769ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 44869ce434fSBarry Smith 44969ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 45069ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize() 45169ce434fSBarry Smith @*/ 45269ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs) 45369ce434fSBarry Smith { 45469ce434fSBarry Smith PetscFunctionBegin; 45533d57670SJed Brown *bs = PetscAbs(map->bs); 45669ce434fSBarry Smith PetscFunctionReturn(0); 45769ce434fSBarry Smith } 45869ce434fSBarry Smith 459c3002683SMatthew G. Knepley /*@ 46069ce434fSBarry Smith PetscLayoutGetRange - gets the range of values owned by this process 46169ce434fSBarry Smith 46269ce434fSBarry Smith Not Collective 46369ce434fSBarry Smith 46469ce434fSBarry Smith Input Parameters: 46569ce434fSBarry Smith . map - pointer to the map 46669ce434fSBarry Smith 46769ce434fSBarry Smith Output Parameters: 46869ce434fSBarry Smith + rstart - first index owned by this process 46969ce434fSBarry Smith - rend - one more than the last index owned by this process 47069ce434fSBarry Smith 47169ce434fSBarry Smith Level: developer 47269ce434fSBarry Smith 47369ce434fSBarry Smith Notes: 47469ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 47569ce434fSBarry Smith 47669ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 47769ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 47869ce434fSBarry Smith @*/ 47969ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend) 48069ce434fSBarry Smith { 48169ce434fSBarry Smith PetscFunctionBegin; 48269ce434fSBarry Smith if (rstart) *rstart = map->rstart; 48369ce434fSBarry Smith if (rend) *rend = map->rend; 48469ce434fSBarry Smith PetscFunctionReturn(0); 48569ce434fSBarry Smith } 48669ce434fSBarry Smith 48769ce434fSBarry Smith /*@C 48869ce434fSBarry Smith PetscLayoutGetRanges - gets the range of values owned by all processes 48969ce434fSBarry Smith 49069ce434fSBarry Smith Not Collective 49169ce434fSBarry Smith 49269ce434fSBarry Smith Input Parameters: 49369ce434fSBarry Smith . map - pointer to the map 49469ce434fSBarry Smith 49569ce434fSBarry Smith Output Parameters: 49669ce434fSBarry Smith . range - start of each processors range of indices (the final entry is one more then the 49769ce434fSBarry Smith last index on the last process) 49869ce434fSBarry Smith 49969ce434fSBarry Smith Level: developer 50069ce434fSBarry Smith 50169ce434fSBarry Smith Notes: 50269ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 50369ce434fSBarry Smith 50469ce434fSBarry Smith Fortran Notes: 50569ce434fSBarry Smith Not available from Fortran 50669ce434fSBarry Smith 50769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 50869ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 50969ce434fSBarry Smith 51069ce434fSBarry Smith @*/ 51169ce434fSBarry Smith PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[]) 51269ce434fSBarry Smith { 51369ce434fSBarry Smith PetscFunctionBegin; 51469ce434fSBarry Smith *range = map->range; 51569ce434fSBarry Smith PetscFunctionReturn(0); 51669ce434fSBarry Smith } 51769ce434fSBarry Smith 51869ce434fSBarry Smith /*@C 51969ce434fSBarry Smith PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout 52069ce434fSBarry Smith 52169ce434fSBarry Smith Collective 52269ce434fSBarry Smith 52369ce434fSBarry Smith Input Arguments: 52469ce434fSBarry Smith + sf - star forest 52569ce434fSBarry Smith . layout - PetscLayout defining the global space 52669ce434fSBarry Smith . nleaves - number of leaf vertices on the current process, each of these references a root on any process 52769ce434fSBarry Smith . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage 528cf79137fSStefano Zampini . localmode - copy mode for ilocal 52969ce434fSBarry Smith - iremote - remote locations of root vertices for each leaf on the current process 53069ce434fSBarry Smith 53169ce434fSBarry Smith Level: intermediate 53269ce434fSBarry Smith 533cf79137fSStefano Zampini Developers Note: Local indices which are the identity permutation in the range [0,nleaves) are discarded as they 534cf79137fSStefano Zampini encode contiguous storage. In such case, if localmode is PETSC_OWN_POINTER, the memory is deallocated as it is not 535cf79137fSStefano Zampini needed 536cf79137fSStefano Zampini 53769ce434fSBarry Smith .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph() 53869ce434fSBarry Smith @*/ 53969ce434fSBarry Smith PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote) 54069ce434fSBarry Smith { 54169ce434fSBarry Smith PetscErrorCode ierr; 54269ce434fSBarry Smith PetscInt i,nroots; 54369ce434fSBarry Smith PetscSFNode *remote; 54469ce434fSBarry Smith 54569ce434fSBarry Smith PetscFunctionBegin; 54669ce434fSBarry Smith ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr); 547785e854fSJed Brown ierr = PetscMalloc1(nleaves,&remote);CHKERRQ(ierr); 54869ce434fSBarry Smith for (i=0; i<nleaves; i++) { 54969ce434fSBarry Smith PetscInt owner = -1; 55069ce434fSBarry Smith ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr); 55169ce434fSBarry Smith remote[i].rank = owner; 55269ce434fSBarry Smith remote[i].index = iremote[i] - layout->range[owner]; 55369ce434fSBarry Smith } 55469ce434fSBarry Smith ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr); 55569ce434fSBarry Smith PetscFunctionReturn(0); 55669ce434fSBarry Smith } 55769ce434fSBarry Smith 558f92d6284SStefano Zampini /*@ 559f92d6284SStefano Zampini PetscLayoutCompare - Compares two layouts 560f92d6284SStefano Zampini 561f92d6284SStefano Zampini Not Collective 562f92d6284SStefano Zampini 563f92d6284SStefano Zampini Input Parameters: 564d11c674dSStefano Zampini + mapa - pointer to the first map 565f92d6284SStefano Zampini - mapb - pointer to the second map 566f92d6284SStefano Zampini 567f92d6284SStefano Zampini Output Parameters: 568f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise 569f92d6284SStefano Zampini 570f92d6284SStefano Zampini Level: beginner 571f92d6284SStefano Zampini 572f92d6284SStefano Zampini Notes: 573f92d6284SStefano Zampini 574f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 575f92d6284SStefano Zampini PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 576f92d6284SStefano Zampini @*/ 577f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent) 578f92d6284SStefano Zampini { 579f92d6284SStefano Zampini PetscErrorCode ierr; 580f92d6284SStefano Zampini PetscMPIInt sizea,sizeb; 581f92d6284SStefano Zampini 582f92d6284SStefano Zampini PetscFunctionBegin; 583f92d6284SStefano Zampini *congruent = PETSC_FALSE; 584f92d6284SStefano Zampini ierr = MPI_Comm_size(mapa->comm,&sizea);CHKERRQ(ierr); 585f92d6284SStefano Zampini ierr = MPI_Comm_size(mapb->comm,&sizeb);CHKERRQ(ierr); 586f92d6284SStefano Zampini if (mapa->N == mapb->N && mapa->range && mapb->range && sizea == sizeb) { 587580bdb30SBarry Smith ierr = PetscArraycmp(mapa->range,mapb->range,sizea+1,congruent);CHKERRQ(ierr); 588f92d6284SStefano Zampini } 589f92d6284SStefano Zampini PetscFunctionReturn(0); 590f92d6284SStefano Zampini } 591a72d46e8SStefano Zampini 592a72d46e8SStefano Zampini /* TODO: handle nooffprocentries like MatZeroRowsMapLocal_Private, since this code is the same */ 593a72d46e8SStefano Zampini PetscErrorCode PetscLayoutMapLocal(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 594a72d46e8SStefano Zampini { 595a72d46e8SStefano Zampini PetscInt *owners = map->range; 596a72d46e8SStefano Zampini PetscInt n = map->n; 597a72d46e8SStefano Zampini PetscSF sf; 598a72d46e8SStefano Zampini PetscInt *lidxs,*work = NULL; 599a72d46e8SStefano Zampini PetscSFNode *ridxs; 600a72d46e8SStefano Zampini PetscMPIInt rank; 601a72d46e8SStefano Zampini PetscInt r, p = 0, len = 0; 602a72d46e8SStefano Zampini PetscErrorCode ierr; 603a72d46e8SStefano Zampini 604a72d46e8SStefano Zampini PetscFunctionBegin; 605a72d46e8SStefano Zampini if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 606a72d46e8SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs */ 607a72d46e8SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 608a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 609a72d46e8SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 610a72d46e8SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 611a72d46e8SStefano Zampini for (r = 0; r < N; ++r) { 612a72d46e8SStefano Zampini const PetscInt idx = idxs[r]; 613a72d46e8SStefano 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); 614a72d46e8SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 615a72d46e8SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 616a72d46e8SStefano Zampini } 617a72d46e8SStefano Zampini ridxs[r].rank = p; 618a72d46e8SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 619a72d46e8SStefano Zampini } 620a72d46e8SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 621a72d46e8SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 622a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 623a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 624a72d46e8SStefano Zampini if (ogidxs) { /* communicate global idxs */ 625a72d46e8SStefano Zampini PetscInt cum = 0,start,*work2; 626a72d46e8SStefano Zampini 627a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 628a72d46e8SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 629a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 630a72d46e8SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 631a72d46e8SStefano Zampini start -= cum; 632a72d46e8SStefano Zampini cum = 0; 633a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 634a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 635a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 636a72d46e8SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 637a72d46e8SStefano Zampini } 638a72d46e8SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 639a72d46e8SStefano Zampini /* Compress and put in indices */ 640a72d46e8SStefano Zampini for (r = 0; r < n; ++r) 641a72d46e8SStefano Zampini if (lidxs[r] >= 0) { 642a72d46e8SStefano Zampini if (work) work[len] = work[r]; 643a72d46e8SStefano Zampini lidxs[len++] = r; 644a72d46e8SStefano Zampini } 645a72d46e8SStefano Zampini if (on) *on = len; 646a72d46e8SStefano Zampini if (oidxs) *oidxs = lidxs; 647a72d46e8SStefano Zampini if (ogidxs) *ogidxs = work; 648a72d46e8SStefano Zampini PetscFunctionReturn(0); 649a72d46e8SStefano Zampini } 650