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> 8*07acc2aeSBarry Smith #include <petsc/private/isimpl.h> 95c25fcd7SBarry Smith 10c3002683SMatthew G. Knepley /*@ 1169ce434fSBarry Smith PetscLayoutCreate - Allocates PetscLayout space and sets the map contents to the default. 1269ce434fSBarry Smith 1369ce434fSBarry Smith Collective on MPI_Comm 1469ce434fSBarry Smith 1569ce434fSBarry Smith Input Parameters: 1669ce434fSBarry Smith + comm - the MPI communicator 1769ce434fSBarry Smith - map - pointer to the map 1869ce434fSBarry Smith 19456fcb79SJed Brown Level: advanced 2069ce434fSBarry Smith 21456fcb79SJed Brown Notes: 22456fcb79SJed Brown Typical calling sequence 23456fcb79SJed Brown .vb 2469ce434fSBarry Smith PetscLayoutCreate(MPI_Comm,PetscLayout *); 2569ce434fSBarry Smith PetscLayoutSetBlockSize(PetscLayout,1); 26456fcb79SJed Brown PetscLayoutSetSize(PetscLayout,N) // or PetscLayoutSetLocalSize(PetscLayout,n); 2769ce434fSBarry Smith PetscLayoutSetUp(PetscLayout); 28456fcb79SJed Brown .ve 2969ce434fSBarry Smith Optionally use any of the following: 30456fcb79SJed Brown 31456fcb79SJed Brown + PetscLayoutGetSize(PetscLayout,PetscInt *); 32456fcb79SJed Brown . PetscLayoutGetLocalSize(PetscLayout,PetscInt *); 33456fcb79SJed Brown . PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend); 34456fcb79SJed Brown . PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]); 35456fcb79SJed Brown - PetscLayoutDestroy(PetscLayout*); 3669ce434fSBarry Smith 3769ce434fSBarry Smith The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in 3869ce434fSBarry Smith user codes unless you really gain something in their use. 3969ce434fSBarry Smith 4069ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 4169ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp() 4269ce434fSBarry Smith 4369ce434fSBarry Smith @*/ 4469ce434fSBarry Smith PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map) 4569ce434fSBarry Smith { 4669ce434fSBarry Smith PetscErrorCode ierr; 4769ce434fSBarry Smith 4869ce434fSBarry Smith PetscFunctionBegin; 49b00a9115SJed Brown ierr = PetscNew(map);CHKERRQ(ierr); 5069ce434fSBarry Smith 5169ce434fSBarry Smith (*map)->comm = comm; 5269ce434fSBarry Smith (*map)->bs = -1; 5369ce434fSBarry Smith (*map)->n = -1; 5469ce434fSBarry Smith (*map)->N = -1; 55f92d6284SStefano Zampini (*map)->range = NULL; 5669ce434fSBarry Smith (*map)->rstart = 0; 5769ce434fSBarry Smith (*map)->rend = 0; 5869ce434fSBarry Smith PetscFunctionReturn(0); 5969ce434fSBarry Smith } 6069ce434fSBarry Smith 61c3002683SMatthew G. Knepley /*@ 6269ce434fSBarry Smith PetscLayoutDestroy - Frees a map object and frees its range if that exists. 6369ce434fSBarry Smith 6469ce434fSBarry Smith Collective on MPI_Comm 6569ce434fSBarry Smith 6669ce434fSBarry Smith Input Parameters: 6769ce434fSBarry Smith . map - the PetscLayout 6869ce434fSBarry Smith 6969ce434fSBarry Smith Level: developer 7069ce434fSBarry Smith 71c3002683SMatthew G. Knepley Note: 7269ce434fSBarry Smith The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is 7369ce434fSBarry Smith recommended they not be used in user codes unless you really gain something in their use. 7469ce434fSBarry Smith 7569ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(), 7669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp() 7769ce434fSBarry Smith 7869ce434fSBarry Smith @*/ 7969ce434fSBarry Smith PetscErrorCode PetscLayoutDestroy(PetscLayout *map) 8069ce434fSBarry Smith { 8169ce434fSBarry Smith PetscErrorCode ierr; 8269ce434fSBarry Smith 8369ce434fSBarry Smith PetscFunctionBegin; 8469ce434fSBarry Smith if (!*map) PetscFunctionReturn(0); 8569ce434fSBarry Smith if (!(*map)->refcnt--) { 8669ce434fSBarry Smith ierr = PetscFree((*map)->range);CHKERRQ(ierr); 8769ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr); 8869ce434fSBarry Smith ierr = PetscFree((*map));CHKERRQ(ierr); 8969ce434fSBarry Smith } 9069ce434fSBarry Smith *map = NULL; 9169ce434fSBarry Smith PetscFunctionReturn(0); 9269ce434fSBarry Smith } 9369ce434fSBarry Smith 947b659617SVaclav Hapla static PetscErrorCode PetscLayoutSetUp_SizesFromRanges_Private(PetscLayout map) 957b659617SVaclav Hapla { 967b659617SVaclav Hapla PetscMPIInt rank,size; 977b659617SVaclav Hapla PetscErrorCode ierr; 987b659617SVaclav Hapla 997b659617SVaclav Hapla PetscFunctionBegin; 1007b659617SVaclav Hapla ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr); 1017b659617SVaclav Hapla ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr); 1027b659617SVaclav Hapla map->rstart = map->range[rank]; 1037b659617SVaclav Hapla map->rend = map->range[rank+1]; 1047b659617SVaclav Hapla map->n = map->rend - map->rstart; 1057b659617SVaclav Hapla map->N = map->range[size]; 1067b659617SVaclav Hapla #if defined(PETSC_USE_DEBUG) 1077b659617SVaclav Hapla /* just check that n, N and bs are consistent */ 1087b659617SVaclav Hapla { 1097b659617SVaclav Hapla PetscInt tmp; 1107b659617SVaclav Hapla ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 1117b659617SVaclav 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); 1127b659617SVaclav Hapla } 1137b659617SVaclav Hapla if (map->bs > 1) { 1147b659617SVaclav 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); 1157b659617SVaclav Hapla } 1167b659617SVaclav Hapla if (map->bs > 1) { 1177b659617SVaclav 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); 1187b659617SVaclav Hapla } 1197b659617SVaclav Hapla #endif 1207b659617SVaclav Hapla PetscFunctionReturn(0); 1217b659617SVaclav Hapla } 1227b659617SVaclav Hapla 123c3002683SMatthew G. Knepley /*@ 12469ce434fSBarry Smith PetscLayoutSetUp - given a map where you have set either the global or local 12569ce434fSBarry Smith size sets up the map so that it may be used. 12669ce434fSBarry Smith 12769ce434fSBarry Smith Collective on MPI_Comm 12869ce434fSBarry Smith 12969ce434fSBarry Smith Input Parameters: 13069ce434fSBarry Smith . map - pointer to the map 13169ce434fSBarry Smith 13269ce434fSBarry Smith Level: developer 13369ce434fSBarry Smith 13495452b02SPatrick Sanan Notes: 13595452b02SPatrick Sanan Typical calling sequence 136c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *); 137c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1); 138c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both 139c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout); 140c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *); 14169ce434fSBarry Smith 1427b659617SVaclav Hapla If range exists, and local size is not set, everything gets computed from the range. 14369ce434fSBarry Smith 14469ce434fSBarry Smith If the local size, global size are already set and range exists then this does nothing. 14569ce434fSBarry Smith 14669ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(), 14769ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate() 14869ce434fSBarry Smith @*/ 14969ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map) 15069ce434fSBarry Smith { 15169ce434fSBarry Smith PetscMPIInt rank,size; 15269ce434fSBarry Smith PetscInt p; 15369ce434fSBarry Smith PetscErrorCode ierr; 15469ce434fSBarry Smith 15569ce434fSBarry Smith PetscFunctionBegin; 15669ce434fSBarry Smith if ((map->n >= 0) && (map->N >= 0) && (map->range)) PetscFunctionReturn(0); 1577b659617SVaclav Hapla if (map->range && map->n < 0) { 1587b659617SVaclav Hapla ierr = PetscLayoutSetUp_SizesFromRanges_Private(map);CHKERRQ(ierr); 1597b659617SVaclav Hapla PetscFunctionReturn(0); 1607b659617SVaclav Hapla } 16169ce434fSBarry Smith 162b146b01cSBarry Smith if (map->n > 0 && map->bs > 1) { 163ec4d677dSStefano 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); 164b146b01cSBarry Smith } 165b146b01cSBarry Smith if (map->N > 0 && map->bs > 1) { 166ec4d677dSStefano 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); 167b146b01cSBarry Smith } 168b146b01cSBarry Smith 16969ce434fSBarry Smith ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr); 17069ce434fSBarry Smith ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr); 17133d57670SJed Brown if (map->n > 0) map->n = map->n/PetscAbs(map->bs); 17233d57670SJed Brown if (map->N > 0) map->N = map->N/PetscAbs(map->bs); 17369ce434fSBarry Smith ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr); 17433d57670SJed Brown map->n = map->n*PetscAbs(map->bs); 17533d57670SJed Brown map->N = map->N*PetscAbs(map->bs); 17669ce434fSBarry Smith if (!map->range) { 177854ce69bSBarry Smith ierr = PetscMalloc1(size+1, &map->range);CHKERRQ(ierr); 17869ce434fSBarry Smith } 17969ce434fSBarry Smith ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRQ(ierr); 18069ce434fSBarry Smith 18169ce434fSBarry Smith map->range[0] = 0; 18269ce434fSBarry Smith for (p = 2; p <= size; p++) map->range[p] += map->range[p-1]; 18369ce434fSBarry Smith 18469ce434fSBarry Smith map->rstart = map->range[rank]; 18569ce434fSBarry Smith map->rend = map->range[rank+1]; 18669ce434fSBarry Smith PetscFunctionReturn(0); 18769ce434fSBarry Smith } 18869ce434fSBarry Smith 189c3002683SMatthew G. Knepley /*@ 19069ce434fSBarry Smith PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first. 19169ce434fSBarry Smith 19269ce434fSBarry Smith Collective on PetscLayout 19369ce434fSBarry Smith 19469ce434fSBarry Smith Input Parameter: 19569ce434fSBarry Smith . in - input PetscLayout to be duplicated 19669ce434fSBarry Smith 19769ce434fSBarry Smith Output Parameter: 19869ce434fSBarry Smith . out - the copy 19969ce434fSBarry Smith 20069ce434fSBarry Smith Level: developer 20169ce434fSBarry Smith 20295452b02SPatrick Sanan Notes: 20395452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 20469ce434fSBarry Smith 20569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference() 20669ce434fSBarry Smith @*/ 20769ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out) 20869ce434fSBarry Smith { 20969ce434fSBarry Smith PetscMPIInt size; 21069ce434fSBarry Smith PetscErrorCode ierr; 21169ce434fSBarry Smith MPI_Comm comm = in->comm; 21269ce434fSBarry Smith 21369ce434fSBarry Smith PetscFunctionBegin; 21469ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 21569ce434fSBarry Smith ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr); 21669ce434fSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 21769ce434fSBarry Smith ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr); 218854ce69bSBarry Smith ierr = PetscMalloc1(size+1,&(*out)->range);CHKERRQ(ierr); 21969ce434fSBarry Smith ierr = PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));CHKERRQ(ierr); 22069ce434fSBarry Smith 22169ce434fSBarry Smith (*out)->refcnt = 0; 22269ce434fSBarry Smith PetscFunctionReturn(0); 22369ce434fSBarry Smith } 22469ce434fSBarry Smith 225c3002683SMatthew G. Knepley /*@ 22669ce434fSBarry Smith PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 22769ce434fSBarry Smith 22869ce434fSBarry Smith Collective on PetscLayout 22969ce434fSBarry Smith 23069ce434fSBarry Smith Input Parameter: 23169ce434fSBarry Smith . in - input PetscLayout to be copied 23269ce434fSBarry Smith 23369ce434fSBarry Smith Output Parameter: 23469ce434fSBarry Smith . out - the reference location 23569ce434fSBarry Smith 23669ce434fSBarry Smith Level: developer 23769ce434fSBarry Smith 23895452b02SPatrick Sanan Notes: 23995452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 24069ce434fSBarry Smith 24169ce434fSBarry Smith If the out location already contains a PetscLayout it is destroyed 24269ce434fSBarry Smith 24369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 24469ce434fSBarry Smith @*/ 24569ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out) 24669ce434fSBarry Smith { 24769ce434fSBarry Smith PetscErrorCode ierr; 24869ce434fSBarry Smith 24969ce434fSBarry Smith PetscFunctionBegin; 25069ce434fSBarry Smith in->refcnt++; 25169ce434fSBarry Smith ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 25269ce434fSBarry Smith *out = in; 25369ce434fSBarry Smith PetscFunctionReturn(0); 25469ce434fSBarry Smith } 25569ce434fSBarry Smith 256c3002683SMatthew G. Knepley /*@ 25769ce434fSBarry Smith PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 25869ce434fSBarry Smith 25969ce434fSBarry Smith Collective on PetscLayout 26069ce434fSBarry Smith 26169ce434fSBarry Smith Input Parameter: 26269ce434fSBarry Smith + in - input PetscLayout 26369ce434fSBarry Smith - ltog - the local to global mapping 26469ce434fSBarry Smith 26569ce434fSBarry Smith 26669ce434fSBarry Smith Level: developer 26769ce434fSBarry Smith 26895452b02SPatrick Sanan Notes: 26995452b02SPatrick Sanan PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 27069ce434fSBarry Smith 27169ce434fSBarry Smith If the ltog location already contains a PetscLayout it is destroyed 27269ce434fSBarry Smith 273a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 27469ce434fSBarry Smith @*/ 27569ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog) 27669ce434fSBarry Smith { 27769ce434fSBarry Smith PetscErrorCode ierr; 27845b6f7e9SBarry Smith PetscInt bs; 27969ce434fSBarry Smith 28069ce434fSBarry Smith PetscFunctionBegin; 28145b6f7e9SBarry Smith ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr); 28237461477SLawrence 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); 28369ce434fSBarry Smith ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 28469ce434fSBarry Smith ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr); 28569ce434fSBarry Smith in->mapping = ltog; 28669ce434fSBarry Smith PetscFunctionReturn(0); 28769ce434fSBarry Smith } 28869ce434fSBarry Smith 289c3002683SMatthew G. Knepley /*@ 29069ce434fSBarry Smith PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 29169ce434fSBarry Smith 29269ce434fSBarry Smith Collective on PetscLayout 29369ce434fSBarry Smith 29469ce434fSBarry Smith Input Parameters: 29569ce434fSBarry Smith + map - pointer to the map 29669ce434fSBarry Smith - n - the local size 29769ce434fSBarry Smith 29869ce434fSBarry Smith Level: developer 29969ce434fSBarry Smith 30069ce434fSBarry Smith Notes: 30169ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 30269ce434fSBarry Smith 30369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 30469ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 30569ce434fSBarry Smith @*/ 30669ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n) 30769ce434fSBarry Smith { 30869ce434fSBarry Smith PetscFunctionBegin; 30969ce434fSBarry 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); 31069ce434fSBarry Smith map->n = n; 31169ce434fSBarry Smith PetscFunctionReturn(0); 31269ce434fSBarry Smith } 31369ce434fSBarry Smith 31469ce434fSBarry Smith /*@C 31569ce434fSBarry Smith PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 31669ce434fSBarry Smith 31769ce434fSBarry Smith Not Collective 31869ce434fSBarry Smith 31969ce434fSBarry Smith Input Parameters: 32069ce434fSBarry Smith . map - pointer to the map 32169ce434fSBarry Smith 32269ce434fSBarry Smith Output Parameters: 32369ce434fSBarry Smith . n - the local size 32469ce434fSBarry Smith 32569ce434fSBarry Smith Level: developer 32669ce434fSBarry Smith 32769ce434fSBarry Smith Notes: 32869ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 32969ce434fSBarry Smith 33069ce434fSBarry Smith Fortran Notes: 33169ce434fSBarry Smith Not available from Fortran 33269ce434fSBarry Smith 33369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 33469ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 33569ce434fSBarry Smith 33669ce434fSBarry Smith @*/ 33769ce434fSBarry Smith PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n) 33869ce434fSBarry Smith { 33969ce434fSBarry Smith PetscFunctionBegin; 34069ce434fSBarry Smith *n = map->n; 34169ce434fSBarry Smith PetscFunctionReturn(0); 34269ce434fSBarry Smith } 34369ce434fSBarry Smith 344c3002683SMatthew G. Knepley /*@ 34569ce434fSBarry Smith PetscLayoutSetSize - Sets the global size for a PetscLayout object. 34669ce434fSBarry Smith 34769ce434fSBarry Smith Logically Collective on PetscLayout 34869ce434fSBarry Smith 34969ce434fSBarry Smith Input Parameters: 35069ce434fSBarry Smith + map - pointer to the map 35169ce434fSBarry Smith - n - the global size 35269ce434fSBarry Smith 35369ce434fSBarry Smith Level: developer 35469ce434fSBarry Smith 35569ce434fSBarry Smith Notes: 35669ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 35769ce434fSBarry Smith 35869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 35969ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 36069ce434fSBarry Smith @*/ 36169ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n) 36269ce434fSBarry Smith { 36369ce434fSBarry Smith PetscFunctionBegin; 36469ce434fSBarry Smith map->N = n; 36569ce434fSBarry Smith PetscFunctionReturn(0); 36669ce434fSBarry Smith } 36769ce434fSBarry Smith 368c3002683SMatthew G. Knepley /*@ 36969ce434fSBarry Smith PetscLayoutGetSize - Gets the global size for a PetscLayout object. 37069ce434fSBarry Smith 37169ce434fSBarry Smith Not Collective 37269ce434fSBarry Smith 37369ce434fSBarry Smith Input Parameters: 37469ce434fSBarry Smith . map - pointer to the map 37569ce434fSBarry Smith 37669ce434fSBarry Smith Output Parameters: 37769ce434fSBarry Smith . n - the global size 37869ce434fSBarry Smith 37969ce434fSBarry Smith Level: developer 38069ce434fSBarry Smith 38169ce434fSBarry Smith Notes: 38269ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 38369ce434fSBarry Smith 38469ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 38569ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 38669ce434fSBarry Smith @*/ 38769ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n) 38869ce434fSBarry Smith { 38969ce434fSBarry Smith PetscFunctionBegin; 39069ce434fSBarry Smith *n = map->N; 39169ce434fSBarry Smith PetscFunctionReturn(0); 39269ce434fSBarry Smith } 39369ce434fSBarry Smith 394c3002683SMatthew G. Knepley /*@ 39569ce434fSBarry Smith PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 39669ce434fSBarry Smith 39769ce434fSBarry Smith Logically Collective on PetscLayout 39869ce434fSBarry Smith 39969ce434fSBarry Smith Input Parameters: 40069ce434fSBarry Smith + map - pointer to the map 40169ce434fSBarry Smith - bs - the size 40269ce434fSBarry Smith 40369ce434fSBarry Smith Level: developer 40469ce434fSBarry Smith 40569ce434fSBarry Smith Notes: 40669ce434fSBarry Smith Call this after the call to PetscLayoutCreate() 40769ce434fSBarry Smith 40869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 40969ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 41069ce434fSBarry Smith @*/ 41169ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs) 41269ce434fSBarry Smith { 41369ce434fSBarry Smith PetscFunctionBegin; 41469bbac97SJed Brown if (bs < 0) PetscFunctionReturn(0); 415299e779cSStefano 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); 416565245c5SBarry Smith if (map->mapping) { 417705e6b8bSstefano_zampini PetscInt obs; 418565245c5SBarry Smith PetscErrorCode ierr; 419565245c5SBarry Smith 420705e6b8bSstefano_zampini ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr); 421705e6b8bSstefano_zampini if (obs > 1) { 42263fa5c83Sstefano_zampini ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr); 423565245c5SBarry Smith } 424705e6b8bSstefano_zampini } 42569ce434fSBarry Smith map->bs = bs; 42669ce434fSBarry Smith PetscFunctionReturn(0); 42769ce434fSBarry Smith } 42869ce434fSBarry Smith 429c3002683SMatthew G. Knepley /*@ 43069ce434fSBarry Smith PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 43169ce434fSBarry Smith 43269ce434fSBarry Smith Not Collective 43369ce434fSBarry Smith 43469ce434fSBarry Smith Input Parameters: 43569ce434fSBarry Smith . map - pointer to the map 43669ce434fSBarry Smith 43769ce434fSBarry Smith Output Parameters: 43869ce434fSBarry Smith . bs - the size 43969ce434fSBarry Smith 44069ce434fSBarry Smith Level: developer 44169ce434fSBarry Smith 44269ce434fSBarry Smith Notes: 44369ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 44469ce434fSBarry Smith 44569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 44669ce434fSBarry Smith PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize() 44769ce434fSBarry Smith @*/ 44869ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs) 44969ce434fSBarry Smith { 45069ce434fSBarry Smith PetscFunctionBegin; 45133d57670SJed Brown *bs = PetscAbs(map->bs); 45269ce434fSBarry Smith PetscFunctionReturn(0); 45369ce434fSBarry Smith } 45469ce434fSBarry Smith 455c3002683SMatthew G. Knepley /*@ 45669ce434fSBarry Smith PetscLayoutGetRange - gets the range of values owned by this process 45769ce434fSBarry Smith 45869ce434fSBarry Smith Not Collective 45969ce434fSBarry Smith 46069ce434fSBarry Smith Input Parameters: 46169ce434fSBarry Smith . map - pointer to the map 46269ce434fSBarry Smith 46369ce434fSBarry Smith Output Parameters: 46469ce434fSBarry Smith + rstart - first index owned by this process 46569ce434fSBarry Smith - rend - one more than the last index owned by this process 46669ce434fSBarry Smith 46769ce434fSBarry Smith Level: developer 46869ce434fSBarry Smith 46969ce434fSBarry Smith Notes: 47069ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 47169ce434fSBarry Smith 47269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 47369ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 47469ce434fSBarry Smith @*/ 47569ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend) 47669ce434fSBarry Smith { 47769ce434fSBarry Smith PetscFunctionBegin; 47869ce434fSBarry Smith if (rstart) *rstart = map->rstart; 47969ce434fSBarry Smith if (rend) *rend = map->rend; 48069ce434fSBarry Smith PetscFunctionReturn(0); 48169ce434fSBarry Smith } 48269ce434fSBarry Smith 48369ce434fSBarry Smith /*@C 48469ce434fSBarry Smith PetscLayoutGetRanges - gets the range of values owned by all processes 48569ce434fSBarry Smith 48669ce434fSBarry Smith Not Collective 48769ce434fSBarry Smith 48869ce434fSBarry Smith Input Parameters: 48969ce434fSBarry Smith . map - pointer to the map 49069ce434fSBarry Smith 49169ce434fSBarry Smith Output Parameters: 49269ce434fSBarry Smith . range - start of each processors range of indices (the final entry is one more then the 49369ce434fSBarry Smith last index on the last process) 49469ce434fSBarry Smith 49569ce434fSBarry Smith Level: developer 49669ce434fSBarry Smith 49769ce434fSBarry Smith Notes: 49869ce434fSBarry Smith Call this after the call to PetscLayoutSetUp() 49969ce434fSBarry Smith 50069ce434fSBarry Smith Fortran Notes: 50169ce434fSBarry Smith Not available from Fortran 50269ce434fSBarry Smith 50369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 50469ce434fSBarry Smith PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 50569ce434fSBarry Smith 50669ce434fSBarry Smith @*/ 50769ce434fSBarry Smith PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[]) 50869ce434fSBarry Smith { 50969ce434fSBarry Smith PetscFunctionBegin; 51069ce434fSBarry Smith *range = map->range; 51169ce434fSBarry Smith PetscFunctionReturn(0); 51269ce434fSBarry Smith } 51369ce434fSBarry Smith 51469ce434fSBarry Smith /*@C 51569ce434fSBarry Smith PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout 51669ce434fSBarry Smith 51769ce434fSBarry Smith Collective 51869ce434fSBarry Smith 51969ce434fSBarry Smith Input Arguments: 52069ce434fSBarry Smith + sf - star forest 52169ce434fSBarry Smith . layout - PetscLayout defining the global space 52269ce434fSBarry Smith . nleaves - number of leaf vertices on the current process, each of these references a root on any process 52369ce434fSBarry Smith . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage 524cf79137fSStefano Zampini . localmode - copy mode for ilocal 52569ce434fSBarry Smith - iremote - remote locations of root vertices for each leaf on the current process 52669ce434fSBarry Smith 52769ce434fSBarry Smith Level: intermediate 52869ce434fSBarry Smith 529cf79137fSStefano Zampini Developers Note: Local indices which are the identity permutation in the range [0,nleaves) are discarded as they 530cf79137fSStefano Zampini encode contiguous storage. In such case, if localmode is PETSC_OWN_POINTER, the memory is deallocated as it is not 531cf79137fSStefano Zampini needed 532cf79137fSStefano Zampini 53369ce434fSBarry Smith .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph() 53469ce434fSBarry Smith @*/ 53569ce434fSBarry Smith PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote) 53669ce434fSBarry Smith { 53769ce434fSBarry Smith PetscErrorCode ierr; 53869ce434fSBarry Smith PetscInt i,nroots; 53969ce434fSBarry Smith PetscSFNode *remote; 54069ce434fSBarry Smith 54169ce434fSBarry Smith PetscFunctionBegin; 54269ce434fSBarry Smith ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr); 543785e854fSJed Brown ierr = PetscMalloc1(nleaves,&remote);CHKERRQ(ierr); 54469ce434fSBarry Smith for (i=0; i<nleaves; i++) { 54569ce434fSBarry Smith PetscInt owner = -1; 54669ce434fSBarry Smith ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr); 54769ce434fSBarry Smith remote[i].rank = owner; 54869ce434fSBarry Smith remote[i].index = iremote[i] - layout->range[owner]; 54969ce434fSBarry Smith } 55069ce434fSBarry Smith ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr); 55169ce434fSBarry Smith PetscFunctionReturn(0); 55269ce434fSBarry Smith } 55369ce434fSBarry Smith 554f92d6284SStefano Zampini /*@ 555f92d6284SStefano Zampini PetscLayoutCompare - Compares two layouts 556f92d6284SStefano Zampini 557f92d6284SStefano Zampini Not Collective 558f92d6284SStefano Zampini 559f92d6284SStefano Zampini Input Parameters: 560d11c674dSStefano Zampini + mapa - pointer to the first map 561f92d6284SStefano Zampini - mapb - pointer to the second map 562f92d6284SStefano Zampini 563f92d6284SStefano Zampini Output Parameters: 564f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise 565f92d6284SStefano Zampini 566f92d6284SStefano Zampini Level: beginner 567f92d6284SStefano Zampini 568f92d6284SStefano Zampini Notes: 569f92d6284SStefano Zampini 570f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 571f92d6284SStefano Zampini PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 572f92d6284SStefano Zampini @*/ 573f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent) 574f92d6284SStefano Zampini { 575f92d6284SStefano Zampini PetscErrorCode ierr; 576f92d6284SStefano Zampini PetscMPIInt sizea,sizeb; 577f92d6284SStefano Zampini 578f92d6284SStefano Zampini PetscFunctionBegin; 579f92d6284SStefano Zampini *congruent = PETSC_FALSE; 580f92d6284SStefano Zampini ierr = MPI_Comm_size(mapa->comm,&sizea);CHKERRQ(ierr); 581f92d6284SStefano Zampini ierr = MPI_Comm_size(mapb->comm,&sizeb);CHKERRQ(ierr); 582f92d6284SStefano Zampini if (mapa->N == mapb->N && mapa->range && mapb->range && sizea == sizeb) { 583f92d6284SStefano Zampini ierr = PetscMemcmp(mapa->range,mapb->range,(sizea+1)*sizeof(PetscInt),congruent);CHKERRQ(ierr); 584f92d6284SStefano Zampini } 585f92d6284SStefano Zampini PetscFunctionReturn(0); 586f92d6284SStefano Zampini } 587a72d46e8SStefano Zampini 588a72d46e8SStefano Zampini /* TODO: handle nooffprocentries like MatZeroRowsMapLocal_Private, since this code is the same */ 589a72d46e8SStefano Zampini PetscErrorCode PetscLayoutMapLocal(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs) 590a72d46e8SStefano Zampini { 591a72d46e8SStefano Zampini PetscInt *owners = map->range; 592a72d46e8SStefano Zampini PetscInt n = map->n; 593a72d46e8SStefano Zampini PetscSF sf; 594a72d46e8SStefano Zampini PetscInt *lidxs,*work = NULL; 595a72d46e8SStefano Zampini PetscSFNode *ridxs; 596a72d46e8SStefano Zampini PetscMPIInt rank; 597a72d46e8SStefano Zampini PetscInt r, p = 0, len = 0; 598a72d46e8SStefano Zampini PetscErrorCode ierr; 599a72d46e8SStefano Zampini 600a72d46e8SStefano Zampini PetscFunctionBegin; 601a72d46e8SStefano Zampini if (on) *on = 0; /* squelch -Wmaybe-uninitialized */ 602a72d46e8SStefano Zampini /* Create SF where leaves are input idxs and roots are owned idxs */ 603a72d46e8SStefano Zampini ierr = MPI_Comm_rank(map->comm,&rank);CHKERRQ(ierr); 604a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr); 605a72d46e8SStefano Zampini for (r = 0; r < n; ++r) lidxs[r] = -1; 606a72d46e8SStefano Zampini ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr); 607a72d46e8SStefano Zampini for (r = 0; r < N; ++r) { 608a72d46e8SStefano Zampini const PetscInt idx = idxs[r]; 609a72d46e8SStefano 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); 610a72d46e8SStefano Zampini if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */ 611a72d46e8SStefano Zampini ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr); 612a72d46e8SStefano Zampini } 613a72d46e8SStefano Zampini ridxs[r].rank = p; 614a72d46e8SStefano Zampini ridxs[r].index = idxs[r] - owners[p]; 615a72d46e8SStefano Zampini } 616a72d46e8SStefano Zampini ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr); 617a72d46e8SStefano Zampini ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr); 618a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 619a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr); 620a72d46e8SStefano Zampini if (ogidxs) { /* communicate global idxs */ 621a72d46e8SStefano Zampini PetscInt cum = 0,start,*work2; 622a72d46e8SStefano Zampini 623a72d46e8SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 624a72d46e8SStefano Zampini ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr); 625a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++; 626a72d46e8SStefano Zampini ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr); 627a72d46e8SStefano Zampini start -= cum; 628a72d46e8SStefano Zampini cum = 0; 629a72d46e8SStefano Zampini for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++; 630a72d46e8SStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 631a72d46e8SStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr); 632a72d46e8SStefano Zampini ierr = PetscFree(work2);CHKERRQ(ierr); 633a72d46e8SStefano Zampini } 634a72d46e8SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 635a72d46e8SStefano Zampini /* Compress and put in indices */ 636a72d46e8SStefano Zampini for (r = 0; r < n; ++r) 637a72d46e8SStefano Zampini if (lidxs[r] >= 0) { 638a72d46e8SStefano Zampini if (work) work[len] = work[r]; 639a72d46e8SStefano Zampini lidxs[len++] = r; 640a72d46e8SStefano Zampini } 641a72d46e8SStefano Zampini if (on) *on = len; 642a72d46e8SStefano Zampini if (oidxs) *oidxs = lidxs; 643a72d46e8SStefano Zampini if (ogidxs) *ogidxs = work; 644a72d46e8SStefano Zampini PetscFunctionReturn(0); 645a72d46e8SStefano Zampini } 646