<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>