Jed, Matt, Junchao, Lawrence,

   I need some expert advice with this 
https://gitlab.com/petsc/petsc/-/merge_requests/4542 
<https://gitlab.com/petsc/petsc/-/merge_requests/4542>. I was able to translate 
the cython to PETSc C for moving the ghost points to the end in the local 
section.

 But I don't know 

   * the best way to generate the ghosts list needed by VecCreateGhost()?   or 
should I not use VecCreateGhost() 

   * but somehow instead use the existing DMGetSectionSF() to be able to 
PetscSF between the owned part and the ghosted part of a hybrid vector (that 
is, don't use VecCreateGhost() but create an equivalent somehow using the sf 
that already exists?)

   Thanks

  Barry




> On Oct 28, 2021, at 6:37 PM, Jed Brown <j...@jedbrown.org> wrote:
> 
> Yeah, I think that's about true. Should the interface for this be to set a 
> flag before creating fields (and perhaps that flag can become true by default 
> at some point)?
> 
> Barry Smith <bsm...@petsc.dev> writes:
> 
>>  Seems like it should be possible to simply "rewrite" the cython code into 
>> PETSc C.
>> 
>>  Barry
>> 
>> 
>>> On Oct 28, 2021, at 12:36 PM, Matthew Knepley <knep...@gmail.com> wrote:
>>> 
>>> I agree it is.
>>> 
>>>  Matt
>>> 
>>> On Thu, Oct 28, 2021 at 11:53 AM Barry Smith <bsm...@petsc.dev 
>>> <mailto:bsm...@petsc.dev>> wrote:
>>> 
>>>  Thanks, sounds like something DMPLEX should be automatically optionally 
>>> doing directly.
>>> 
>>>> On Oct 28, 2021, at 10:58 AM, Lawrence Mitchell <we...@gmx.li 
>>>> <mailto:we...@gmx.li>> wrote:
>>>> 
>>>> Hi Barry et al.,
>>>> 
>>>>> On 28 Oct 2021, at 15:37, Barry Smith <bsm...@petsc.dev 
>>>>> <mailto:bsm...@petsc.dev>> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>>> On Oct 28, 2021, at 10:31 AM, Matthew Knepley <knep...@gmail.com 
>>>>>> <mailto:knep...@gmail.com>> wrote:
>>>>>> 
>>>>>> On Thu, Oct 28, 2021 at 9:37 AM Barry Smith <bsm...@petsc.dev 
>>>>>> <mailto:bsm...@petsc.dev>> wrote:
>>>>>> 
>>>>>> Matt,
>>>>>> 
>>>>>>   How difficult would it be to rework DMPLEX to allow the use of 
>>>>>> VecGhost? We have performance problems with GPUs with simple DMNETWORK 
>>>>>> models because the code spends more time uselessly copying the local 
>>>>>> part of the vector to another vector in global to local and local to 
>>>>>> global;  more than 1/2 the time of the total simulation.
>>>>>> 
>>>>>> Firedrake already does this because they "vec ghost" their vectors by 
>>>>>> default. Here is what you need:
>>>>>> 
>>>>>> When you create the PetscSection, by default it orders the unknowns 
>>>>>> according to the default point numbering. This
>>>>>> is what causes the ghost unknowns to be mixed in with the local 
>>>>>> unknowns. However, PetscSection allows you to set
>>>>>> a point permutation
>>>>>> 
>>>>>>   
>>>>>> https://petsc.org/main/docs/manualpages/PetscSection/PetscSectionSetPermutation.html
>>>>>>  
>>>>>> <https://petsc.org/main/docs/manualpages/PetscSection/PetscSectionSetPermutation.html>
>>>>>> 
>>>>>> This determines the order of dogs by iterating through points in this 
>>>>>> permutation, and you can put all shared points at the end.
>>>>> 
>>>>> How do I know what are shared points to put at the end? Couldn't DMPLEX 
>>>>> do this automatically with an option? Where is the Firedrake code that 
>>>>> does this with DMPLEX so I can see it?
>>>> 
>>>> The DM's "point sf" indicates shared points. To label them, do something 
>>>> like:
>>>> 
>>>> DMCreateLabel(dm, "ghost_points");
>>>> DMGetPointSF(dm, &pointsf);
>>>> PetscSFGetGraph(pointsf, NULL, &nleaves, &ilocal, NULL);
>>>> for (PetscInt p = 0; p < nleaves; p++) {
>>>>  DMSetLabelValue(dm, "ghost_points", p, 1);
>>>> }
>>>> 
>>>> Then you do something like (this is more pseudo-codey):
>>>> 
>>>> PetscInt *permutation;
>>>> DMPlexGetChart(dm, &pStart, &pEnd);
>>>> PetscMalloc1(pEnd - pStart, &permutation);
>>>> PetscInt offsets[2] = {0, pEnd - pStart - nleaves};
>>>> DMGetLabel(dm, &ghosts);
>>>> DMLabelCreateIndex(ghosts, pStart, pEnd);
>>>> for (PetscInt p = pStart, p < pEnd; p++) {
>>>>  DMLabelHasPoint(ghosts, p, &has);
>>>>  if (has) {
>>>>     // this point is ghost point
>>>>     permutation[offsets[1]++] = p;
>>>>  } else {
>>>>     permutation[offsets[0]++] = p;
>>>>  }
>>>> }
>>>> DMLabelDestroyIndex(ghosts, pStart, pEnd);
>>>> ISCreateGeneral(..., permutation, &isperm);
>>>> 
>>>> // Now whenever your do PetscSectionCreate, do
>>>> PetscSectionSetPermutation(..., isperm);
>>>> 
>>>> And now ghost point dofs will appear after local ones.
>>>> 
>>>> Note that this is probably more complicated for multi-field setups, 
>>>> depending whether you are point major or field major.
>>>> 
>>>> You can see what we actually do (if you like reading Cython) here: 
>>>> https://github.com/firedrakeproject/firedrake/blob/master/firedrake/cython/dmcommon.pyx#L1734
>>>>  
>>>> <https://github.com/firedrakeproject/firedrake/blob/master/firedrake/cython/dmcommon.pyx#L1734>
>>>> 
>>>> It's more complicated because here we are doing some additional things:
>>>> 
>>>> 1. We compute an RCM-order traversal for cells with DMPlexGetOrdering;
>>>> 2. Rather than ordering all plex points in the permutation, we walk the 
>>>> cells in the RCM order and then greedily number points in the transitive 
>>>> closure (so that in a section cell and vertex dofs from the same cell will 
>>>> be "close" to each other in the final Vec).
>>>> 
>>>> Thanks,
>>>> 
>>>> Lawrence
>>> 
>>> 
>>> 
>>> -- 
>>> What most experimenters take for granted before they begin their 
>>> experiments is infinitely more interesting than any results to which their 
>>> experiments lead.
>>> -- Norbert Wiener
>>> 
>>> https://www.cse.buffalo.edu/~knepley/ <http://www.cse.buffalo.edu/~knepley/>

Reply via email to