[J3] Getting c_ptr for type(*), dimension(..)

Jeff Hammond jehammond at nvidia.com
Wed Nov 16 14:43:37 UTC 2022

Thanks, Vipul.  Adding TARGET solves the problem.

Sorry for the dumb question.


On 16Nov 2022, at 5:34 AM, Vipul Parekh <parekhvs at gmail.com<mailto:parekhvs at gmail.com>> wrote:

External email: Use caution opening links or attachments

On Tue, Nov 15, 2022 at 6:00 AM Jeff Hammond via J3 <j3 at mailman.j3-fortran.org<mailto:j3 at mailman.j3-fortran.org>> wrote:
Am I missing something or is it not possible to obtain a Fortran pointer for a type(*), dimension(..) argument without going through C?

I am trying to write a generic interface for a callback, i.e. one that has type(*), dimension(..) arguments.  Inside of my callback, I know what the type and shape are going to be, and therefore can assign them to an appropriate pointer, which I can then operate on appropriately.

This is easily done with a C function that reads the base address from the CFI_cdesc_t, but I cannot figure out how to do it entirely within Fortran.  Did I miss something or is it impossible?

Hi Jeff,

Apologies if I am misunderstanding your inquiry.

You will know the Fortran standard has under the TYPE specifier section, "C715 An assumed-type variable name shall not appear in a designator or expression except as an actual argument corresponding to a dummy argument that is assumed-type, or as the first argument to the intrinsic function IS_CONTIGUOUS, LBOUND, PRESENT, RANK, SHAPE, SIZE, or UBOUND, or the function C_LOC from the intrinsic module ISO_C_BINDING."

Given above, have you tried employing the C_LOC function along with the TARGET attribute on your assumed-type (TYPE(*)) argument?  If yes, did that not work, or is that not what you're after?

Based on the description in your email, here is a small reproducer of a program I envisioned and it works as I expect: perhaps you will take a look at it and see if that you're after, or let me know if I misunderstood your question altogether:  In the example below, you will note the code makes use of what you write, " Inside of my callback, I know what the type and shape are going to be, and therefore can assign them to an appropriate pointer, which I can then operate on appropriately."  So you can see the "px" pointer in the Fcallback procedure gets you the object you describe.

! Fortran program in p.f90 file
module m
   use, intrinsic :: iso_c_binding, only : c_int, c_loc, c_f_pointer
      subroutine Csub( a ) bind(C, name="Csub")
         import :: c_int
         ! Argument list
         integer(c_int), intent(inout) :: a(:,:)
      end subroutine
   end interface
   integer(c_int) :: x(2,3)
   subroutine Fcallback( a ) bind(C, name="Fcallback")
      ! Argument list
      type(*), intent(inout), target :: a(..)
      integer(c_int), pointer :: px(:,:)
      print *, "In Fortran callback:"
      call c_f_pointer( cptr=c_loc(a), fptr=px, shape=shape(x) )
      print *, "x = ", px
   end subroutine
end module
   use m
   call Csub( x )

// C "library" function; it doesn't have it to be in C; in c.c file
#include <stdio.h>
#include "ISO_Fortran_binding.h"

extern void Fcallback(CFI_cdesc_t *);

void Csub(CFI_cdesc_t * d) {

   // Presume Fortran descriptor is for rank-2 object
   CFI_index_t extents[2];
   int i, j, n;
   int *x;

   x = (int *)d->base_addr;
   extents[0] = d->dim[0].extent;
   extents[1] = d->dim[1].extent;

   n = 0;
   for (i = 0; i < extents[1]; i++)
      for (j = 0; j < extents[0]; j++)
         *(x + n - 1) = n;

Running the above on Windows OS with Intel Fortran oneAPI compiler and Microsoft C/C++ companion processor, I get the following:
C:\temp>ifort /c /standard-semantics p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.7.0 Build 20220726_000000
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.

C:\temp>cl /c /W3 /EHsc c.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.33.31630 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.


C:\temp>link p.obj c.obj /subsystem:console /out:p.exe
Microsoft (R) Incremental Linker Version 14.33.31630.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 In Fortran callback:
 x =  1 2 3 4 5 6

Hope this is of some help to you.

Vipul Parekh

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20221116/22f6de4b/attachment-0003.htm>

More information about the J3 mailing list