# PetscSFCreateByMatchingIndices
Create `PetscSF` by matching root and leaf indices 
## Synopsis
```
#include "petscsf.h"   
PetscErrorCode PetscSFCreateByMatchingIndices(PetscLayout layout, PetscInt numRootIndices, const PetscInt *rootIndices, const PetscInt *rootLocalIndices, PetscInt rootLocalOffset, PetscInt numLeafIndices, const PetscInt *leafIndices, const PetscInt *leafLocalIndices, PetscInt leafLocalOffset, PetscSF *sfA, PetscSF *sf)
```
Collective


## Input Parameters

- ***layout -*** `PetscLayout` defining the global index space and the rank that brokers each index
- ***numRootIndices -*** size of rootIndices
- ***rootIndices -*** `PetscInt` array of global indices of which this process requests ownership
- ***rootLocalIndices -*** root local index permutation (NULL if no permutation)
- ***rootLocalOffset -*** offset to be added to root local indices
- ***numLeafIndices -*** size of leafIndices
- ***leafIndices -*** `PetscInt` array of global indices with which this process requires data associated
- ***leafLocalIndices -*** leaf local index permutation (NULL if no permutation)
- ***leafLocalOffset -*** offset to be added to leaf local indices



## Output Parameters

- ***sfA -*** star forest representing the communication pattern from the layout space to the leaf space (NULL if not needed)
- ***sf -*** star forest representing the communication pattern from the root space to the leaf space





## Example 1
```none
  rank             : 0            1            2
  rootIndices      : [1 0 2]      [3]          [3]
  rootLocalOffset  : 100          200          300
  layout           : [0 1]        [2]          [3]
  leafIndices      : [0]          [2]          [0 3]
  leafLocalOffset  : 400          500          600

would build the following PetscSF

  [0] 400 <- (0,101)
  [1] 500 <- (0,102)
  [2] 600 <- (0,101)
  [2] 601 <- (2,300)
```



## Example 2
```none
  rank             : 0               1               2
  rootIndices      : [1 0 2]         [3]             [3]
  rootLocalOffset  : 100             200             300
  layout           : [0 1]           [2]             [3]
  leafIndices      : rootIndices     rootIndices     rootIndices
  leafLocalOffset  : rootLocalOffset rootLocalOffset rootLocalOffset

would build the following PetscSF

  [1] 200 <- (2,300)
```



## Example 3
```none
  No process requests ownership of global index 1, but no process needs it.

  rank             : 0            1            2
  numRootIndices   : 2            1            1
  rootIndices      : [0 2]        [3]          [3]
  rootLocalOffset  : 100          200          300
  layout           : [0 1]        [2]          [3]
  numLeafIndices   : 1            1            2
  leafIndices      : [0]          [2]          [0 3]
  leafLocalOffset  : 400          500          600

would build the following PetscSF

  [0] 400 <- (0,100)
  [1] 500 <- (0,101)
  [2] 600 <- (0,100)
  [2] 601 <- (2,300)
```



## Notes
The layout parameter represents any partitioning of [0, N), where N is the total number of global indices, and its
local size can be set to `PETSC_DECIDE`.

If a global index x lies in the partition owned by process i, each process whose rootIndices contains x requests
ownership of x and sends its own rank and the local index of x to process i.
If multiple processes request ownership of x, the one with the highest rank is to own x.
Process i then broadcasts the ownership information, so that each process whose leafIndices contains x knows the
ownership information of x.
The output sf is constructed by associating each leaf point to a root point in this way.

Suppose there is point data ordered according to the global indices and partitioned according to the given layout.
The optional output `PetscSF` object sfA can be used to push such data to leaf points.

All indices in rootIndices and leafIndices must lie in the layout range. The union (over all processes) of rootIndices
must cover that of leafIndices, but need not cover the entire layout.

If (leafIndices, leafLocalIndices, leafLocalOffset) == (rootIndices, rootLocalIndices, rootLocalOffset), the output
star forest is almost identity, so will only include non-trivial part of the map.


## Developer Note
Current approach of a process of the highest rank gaining the ownership may cause load imbalance; consider using
hash(rank, root_local_index) as the bid for the ownership determination.


## See Also
 `PetscSF`, `PetscSFCreate()`

## Level
advanced

## Location
<A HREF="PETSC_DOC_OUT_ROOT_PLACEHOLDER/src/vec/is/sf/utils/sfutils.c.html#PetscSFCreateByMatchingIndices">src/vec/is/sf/utils/sfutils.c</A>


---
[Edit on GitLab](https://gitlab.com/petsc/petsc/-/edit/release/src/vec/is/sf/utils/sfutils.c)


[Index of all PetscSF routines](index.md)  
[Table of Contents for all manual pages](/docs/manualpages/index.md)  
[Index of all manual pages](/docs/manualpages/singleindex.md)  
