<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>hi<br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 19/10/17 06:45, Matthew Knepley
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAMYG4GkrcMKr=S+1jjtpAboqYTvjshBQj1H-87wU-zKtbcJnVg@mail.gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">On Tue, Oct 17, 2017 at 11:35 PM,
            Adrian Croucher <span dir="ltr"><<a
                href="mailto:a.croucher@auckland.ac.nz" target="_blank"
                moz-do-not-send="true">a.croucher@auckland.ac.nz</a>></span>
            wrote:<br>
            <br>
            <blockquote class="gmail_quote" style="margin:0px 0px 0px
              0.8ex;border-left:1px solid
              rgb(204,204,204);padding-left:1ex"><br>
              So, now I'm trying to add Fortran bindings for
              PetscSFBcastBegin() and PetscSFBcastEnd().<br>
              <br>
              From the C side I have added the following into
              src/vec/is/sf/interface/f90-cu<wbr>stom/zsff90.c:<br>
              <br>
              PETSC_EXTERN void PETSC_STDCALL petscsfbcastbegin_(PetscSF
              *sf, MPI_Datatype *unit, F90Array1d *rptr, F90Array1d
              *lptr , int *ierr PETSC_F90_2PTR_PROTO(rptrd)
              PETSC_F90_2PTR_PROTO(lptrd))<br>
              {<br>
                PetscDataType ptype;<br>
                const void* rootdata;<br>
                void* leafdata;<br>
              <br>
                *ierr = PetscMPIDataTypeToPetscDataTyp<wbr>e(*unit,
              &ptype);if (*ierr) return;<br>
                *ierr = F90Array1dAccess(rptr, ptype, (void**)
              &rootdata PETSC_F90_2PTR_PARAM(rptrd));i<wbr>f (*ierr)
              return;<br>
                *ierr = F90Array1dAccess(lptr, ptype, (void**)
              &leafdata PETSC_F90_2PTR_PARAM(lptrd));i<wbr>f (*ierr)
              return;<br>
              <br>
                *ierr = PetscSFBcastBegin(*sf, *unit, rootdata,
              leafdata);<br>
              <br>
              }<br>
              <br>
              and similarly for petscsfbcastend_(). Does this look
              plausible?<br>
              <br>
              Then some wrappers need to be added to
              src/vec/f90-mod/petscis.h90. I am not sure how to do
              those.<br>
              <br>
              The difficulty is in declaring the arrays that are passed
              in, which can be of various types. In C they are declared
              as void*, but I'm not sure what to do with that in
              Fortran. I can't seem to find any other example wrappers
              in PETSc to model it on either. Any suggestions?</blockquote>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    I think this is working now by just declaring those void* C
    variables as type(*) in the Fortran interface, e.g.:<br>
    <br>
    <tt>      Interface</tt><tt><br>
    </tt><tt>         Subroutine PetscSFBcastBegin(sf,unit,rarray,</tt><tt><br>
    </tt><tt>     &       larray,ierr)</tt><tt><br>
    </tt><tt>           use petscisdef</tt><tt><br>
    </tt><tt>           PetscSF :: sf</tt><tt><br>
    </tt><tt>           PetscInt :: unit</tt><tt><br>
    </tt><tt>           type(*) :: rarray(:)</tt><tt><br>
    </tt><tt>           type(*) :: larray(:)</tt><tt><br>
    </tt><tt>           PetscErrorCode :: ierr</tt><tt><br>
    </tt><tt>         End Subroutine PetscSFBcastBegin</tt><tt><br>
    </tt><tt>      End Interface</tt><tt><br>
    </tt><tt><br>
    </tt>The only difficulty I have left with this is in the
    MPI_Datatype variable. I'd forgotten that these datatypes are all
    different in C and Fortran as well.<br>
    <br>
    I amended the C interface code to the following, to convert the
    Fortran MPI datatype (actually an integer) to a C MPI_Datatype:<br>
    <br>
    <tt>PETSC_EXTERN void PETSC_STDCALL petscsfbcastbegin_(PetscSF *sf,
      MPI_Fint *unit, F90Array1d *rptr, F90Array1d *lptr , int *ierr
      PETSC_F90_2PTR_PROTO(rptrd) PETSC_F90_2PTR_PROTO(lptrd))</tt><tt><br>
    </tt><tt>{</tt><tt><br>
    </tt><tt>  PetscDataType pdtype;</tt><tt><br>
    </tt><tt>  MPI_Datatype dtype;</tt><tt><br>
    </tt><tt>  const void* rootdata;</tt><tt><br>
    </tt><tt>  void* leafdata;</tt><tt><br>
    </tt><tt><br>
    </tt><tt>  dtype = MPI_Type_f2c(*unit);</tt><tt><br>
    </tt><tt>  *ierr = PetscMPIDataTypeToPetscDataType(dtype,
      &pdtype);if (*ierr) return;</tt><tt><br>
    </tt><tt>  *ierr = F90Array1dAccess(rptr, pdtype, (void**)
      &rootdata PETSC_F90_2PTR_PARAM(rptrd));if (*ierr) return;</tt><tt><br>
    </tt><tt>  *ierr = F90Array1dAccess(lptr, pdtype, (void**)
      &leafdata PETSC_F90_2PTR_PARAM(lptrd));if (*ierr) return;</tt><tt><br>
    </tt><tt><br>
    </tt><tt>  *ierr = PetscSFBcastBegin(*sf, dtype, rootdata,
      leafdata);</tt><tt><br>
    </tt><tt><br>
    </tt><tt>}</tt><tt><br>
    </tt><br>
    The problem is this only seems to work if I declare the datatype in
    the calling Fortran code to be of the appropriate C MPI datatype,
    e.g. MPI_INT, rather than the corresponding Fortran datatype, e.g.
    MPI_INTEGER (which causes PetscMPIDataTypeToPetscDataType() to fail,
    as something weird gets passed in for dtype).<br>
    <br>
    I was expecting the opposite to be true. It doesn't seem right to
    have to use the C datatypes in Fortran code (confusing if the
    Fortran datatypes are used elsewhere). So I suspect I've messed
    something up. Anyone have any ideas?<br>
    <br>
    - Adrian<br>
    <pre class="moz-signature" cols="72">-- 
Dr Adrian Croucher
Senior Research Fellow
Department of Engineering Science
University of Auckland, New Zealand
email: <a class="moz-txt-link-abbreviated" href="mailto:a.croucher@auckland.ac.nz">a.croucher@auckland.ac.nz</a>
tel: +64 (0)9 923 4611
</pre>
  </body>
</html>