[petsc-dev] PetscSF in Fortran
Jed Brown
jed at jedbrown.org
Fri Oct 20 12:31:39 CDT 2017
Barry Smith <bsmith at mcs.anl.gov> writes:
> Adrian,
>
> You should not use F90Array1d *rptr as arguments in the Fortran interface. You should just use a regular Fortran one dimensional array of real/scalar.
> Fortran doesn't handle polymorphism in this way at all. You have to have multiple f90 interfaces, one for each type and provide a C stub for real, int, or whatever else you want to send.
Barry, look at the "use mpi_f08" way of calling MPI from Fortran.
> What types do you need to send? It is probably easier if we just write the Fortran interfaces for you.
>
> If you can send a simple Fortran PETS code that uses PetscSFBcastBegin() and PetscSFBcastEnd() that I can use for testing then I will write them. Do a bcast with int and another with real/scalar.
>
>
> Barry
>
>
>
>> On Oct 19, 2017, at 8:59 PM, Adrian Croucher <a.croucher at auckland.ac.nz> wrote:
>>
>> hi
>>
>> On 19/10/17 06:45, Matthew Knepley wrote:
>>> On Tue, Oct 17, 2017 at 11:35 PM, Adrian Croucher <a.croucher at auckland.ac.nz> wrote:
>>>
>>>
>>> So, now I'm trying to add Fortran bindings for PetscSFBcastBegin() and PetscSFBcastEnd().
>>>
>>> From the C side I have added the following into src/vec/is/sf/interface/f90-custom/zsff90.c:
>>>
>>> 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))
>>> {
>>> PetscDataType ptype;
>>> const void* rootdata;
>>> void* leafdata;
>>>
>>> *ierr = PetscMPIDataTypeToPetscDataType(*unit, &ptype);if (*ierr) return;
>>> *ierr = F90Array1dAccess(rptr, ptype, (void**) &rootdata PETSC_F90_2PTR_PARAM(rptrd));if (*ierr) return;
>>> *ierr = F90Array1dAccess(lptr, ptype, (void**) &leafdata PETSC_F90_2PTR_PARAM(lptrd));if (*ierr) return;
>>>
>>> *ierr = PetscSFBcastBegin(*sf, *unit, rootdata, leafdata);
>>>
>>> }
>>>
>>> and similarly for petscsfbcastend_(). Does this look plausible?
>>>
>>> Then some wrappers need to be added to src/vec/f90-mod/petscis.h90. I am not sure how to do those.
>>>
>>> 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?
>>
>>
>> I think this is working now by just declaring those void* C variables as type(*) in the Fortran interface, e.g.:
>>
>> Interface
>> Subroutine PetscSFBcastBegin(sf,unit,rarray,
>> & larray,ierr)
>> use petscisdef
>> PetscSF :: sf
>> PetscInt :: unit
>> type(*) :: rarray(:)
>> type(*) :: larray(:)
>> PetscErrorCode :: ierr
>> End Subroutine PetscSFBcastBegin
>> End Interface
>>
>> 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.
>>
>> I amended the C interface code to the following, to convert the Fortran MPI datatype (actually an integer) to a C MPI_Datatype:
>>
>> 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))
>> {
>> PetscDataType pdtype;
>> MPI_Datatype dtype;
>> const void* rootdata;
>> void* leafdata;
>>
>> dtype = MPI_Type_f2c(*unit);
>> *ierr = PetscMPIDataTypeToPetscDataType(dtype, &pdtype);if (*ierr) return;
>> *ierr = F90Array1dAccess(rptr, pdtype, (void**) &rootdata PETSC_F90_2PTR_PARAM(rptrd));if (*ierr) return;
>> *ierr = F90Array1dAccess(lptr, pdtype, (void**) &leafdata PETSC_F90_2PTR_PARAM(lptrd));if (*ierr) return;
>>
>> *ierr = PetscSFBcastBegin(*sf, dtype, rootdata, leafdata);
>>
>> }
>>
>> 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).
>>
>> 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?
>>
>> - Adrian
>> --
>> Dr Adrian Croucher
>> Senior Research Fellow
>> Department of Engineering Science
>> University of Auckland, New Zealand
>> email:
>> a.croucher at auckland.ac.nz
>>
>> tel: +64 (0)9 923 4611
>>
More information about the petsc-dev
mailing list