Re: GSoC Fortran – 2018/202x – Inquiry About Project Scope

2025-03-24 Thread Steve Kargl
I've already written a prototype of the half-cycle trig
functions.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113152

There are two issues that need to be address.  First, some
operating systems provide half-cycle trig functions in their
libm.  The initial patch tries to use libm functions if 
found, but in hindsight I think gfortran should simply 
provide its own implementations.  Second, the patch needs
to be cleaned up and rigorously tested.  I haven't had time
to do this.

If you are looking for a relatively small and well-defined
project, I'll suggest looking at implementations for the
new intrinsic subprograms SPLIT() and TOKENIZE().  As far as
I know, no one is working on these routines.

-- 
steve

On Mon, Mar 24, 2025 at 04:45:06PM +, Yuao Ma wrote:
> Hello GCC Community,
> 
> I hope this message finds you well. My name is Yuao, and I’m excited to 
> express
> my interest in the "Fortran – 2018/202x" project for Google Summer of Code. 
> I’m
> writing to clarify the scope of this project and gather any recommendations 
> you
> may have.
> 
> >From the project documentation and the "What's New in 202x" resources, I
> understand that “Extracting tokens from a string,” “Interoperability with C,”
> and “Trig function changes” would be considered a medium-sized undertaking.
> After exploring the codebase, I noticed that trigonometric functions working 
> in
> degrees have already been implemented. I’d be very interested in continuing
> with the half-revolution functionality as well as addressing the “Changes for
> conformance with the new IEEE standard.” I’d love to hear your thoughts on
> whether this focus is aligned with current project needs or if there are other
> areas you recommend I prioritize.
> 
> Thank you for your time and guidance. I look forward to your feedback on how I
> can best contribute.
> 
> Kind regards,
> Yuao

-- 
Steve


Re: [Patch, Fortran] C prototypes for functions returning C function pointers

2025-03-24 Thread Harald Anlauf

Hi Thomas,

Am 24.03.25 um 22:28 schrieb Thomas Koenig:

Hi Harald,


the attached patch contains a chunk changing resolve.cc
that is neither described in the suggested commit message,
and it fails to compile here:

../../gcc-trunk/gcc/fortran/resolve.cc: In function 'void
check_c_funptr_assign_interface(gfc_expr*, gfc_expr*)':
../../gcc-trunk/gcc/fortran/resolve.cc:12248:48: error: 'gfc_expr' {aka
'struct gfc_expr'} has no member named 'is_c_interop'
12248 |   if (rhs->expr_type != EXPR_FUNCTION || !rhs->is_c_interop)
   |    ^~~~

Can you please check whether you inadvertently added something
that was not planned or tested?


I sent out the wrong version of the patch, sorry (one which contained
an intermediate stage of something I tried, and then abandoned).

Here is the one that actually in my tree, and that I regression-tested.


this is better.

Two things:

+/* Write out an interoperable function returning a function pointer.
Better
+   handled separately.  As we know nothing about the type, assume
+   a C default return of int.  */
+
+static void
+write_funptr_fcn (gfc_symbol *sym)
+{
+  fprintf (dumpfile, "void (*%s (", sym->binding_label);

The comment does not match the code: the return type is (void *),
isn't it?

Second:

+  if (sym->ts.type == BT_DERIVED
+ && strcmp (sym->ts.u.derived->name, "c_funptr") == 0)

Wouldn't it be better to test for:

sym->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR

so that we do not accidentally handle a user-defined type
of same name and bind(c)?

OK with the above addressed.

Thanks for the patch!

Harald


Best regards

 Thomas






Re: GSoC Fortran – 2018/202x – Inquiry About Project Scope

2025-03-24 Thread Janne Blomqvist
On Mon, Mar 24, 2025 at 8:25 PM Steve Kargl
 wrote:
>
> I've already written a prototype of the half-cycle trig
> functions.
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113152
>
> There are two issues that need to be address.  First, some
> operating systems provide half-cycle trig functions in their
> libm.  The initial patch tries to use libm functions if
> found, but in hindsight I think gfortran should simply
> provide its own implementations. ith C,”

Hello Steve, long time no see. AFAIU the motivation for these
half-cycle functions is to avoid the non-trivial gymnastics associated
with argument reduction of a multiple of pi. Both in terms of cpu
time, and in the possibility of getting it wrong and not producing a
correctly rounded result. It seems to me that if libm provides said
functions it would be preferably to call those directly rather than
always using some fallback implementation that ends up calling the
"normal" trig functions. Not sure how that should be implemented,
maybe some kind of weak symbol trickery to use the libgfortran
fallback implementations in case libm doesn't provide it?

-- 
Janne Blomqvist


Re: GSoC Fortran – 2018/202x – Inquiry About Project Scope

2025-03-24 Thread Steve Kargl
On Mon, Mar 24, 2025 at 08:46:50PM +0200, Janne Blomqvist wrote:
> On Mon, Mar 24, 2025 at 8:25 PM Steve Kargl
>  wrote:
> >
> > I've already written a prototype of the half-cycle trig
> > functions.
> >
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113152
> >
> > There are two issues that need to be address.  First, some
> > operating systems provide half-cycle trig functions in their
> > libm.  The initial patch tries to use libm functions if
> > found, but in hindsight I think gfortran should simply
> > provide its own implementations. ”
> 
> Hello Steve, long time no see. AFAIU the motivation for these
> half-cycle functions is to avoid the non-trivial gymnastics associated
> with argument reduction of a multiple of pi. Both in terms of cpu
> time, and in the possibility of getting it wrong and not producing a
> correctly rounded result. It seems to me that if libm provides said
> functions it would be preferably to call those directly rather than
> always using some fallback implementation that ends up calling the
> "normal" trig functions. Not sure how that should be implemented,
> maybe some kind of weak symbol trickery to use the libgfortran
> fallback implementations in case libm doesn't provide it?
> 

Hi Janne,

Indeed, it's been awhile.  I wrote FreeBSD's sinpi(), cospi(), and
tanpi().   I haven't contributed asinpi() and friends to FreeBSD,
yet.

The argument reduction isn't too tricky.  One simply breaks 'x'
into 'x = n + r' with 'n' some integer and '0 <= r < 1'.  The
algorithm description for sinpi() is in the leading comment here

https://cgit.freebsd.org/src/tree/lib/msun/src/s_sinpi.c

Similar comments are in cospi() and tanpi().

The nice features of these functions are the special cases, e.g.,
'sinpi(int(x)) = +-0' exactly.  The sign is chosen based on 
whether int(x) is even or odd.

I think the biggest issues will come with REAL(10) and REAL(16)
on X86 hardware.  The former is typically C's 'long double' and
the functions are likely present in libm.   REAL(16) is __Float128,
which I have not used, so would/will need to learn how to use.  For 
non-X86 hardware, REAL(16) is either IEEE binary128 type or IBM
double-double representation.  If the OS's libm does not have
an appropriate function, we'll need a fallback (and I would
likely write it in Fortran).
 
One other issue to consider is that weak symbol trickery
does not work with static linking. 

-- 
Steve


Re: [Patch, Fortran] C prototypes for functions returning C function pointers

2025-03-24 Thread Harald Anlauf

Hi Thomas,

Am 24.03.25 um 21:40 schrieb Thomas Koenig:

Hello world,

the attached patch handles dumping prototypes for C functions returning
function pointers.  For the test case

MODULE test
    USE, INTRINSIC :: ISO_C_BINDING
CONTAINS
    FUNCTION lookup(idx) BIND(C)
  type(C_FUNPTR) :: lookup
  integer(C_INT), VALUE :: idx
  lookup = C_FUNLOC(x1)
    END FUNCTION lookup

    subroutine x1()
    end subroutine x1
  END MODULE test

the prototype is

void (*lookup (int idx)) ();

Regression-tested.  Again no test case because I don't know
how.  During testing, I also found that vtabs were dumped,
this is also corrected.

OK for trunk?


the attached patch contains a chunk changing resolve.cc
that is neither described in the suggested commit message,
and it fails to compile here:

../../gcc-trunk/gcc/fortran/resolve.cc: In function 'void
check_c_funptr_assign_interface(gfc_expr*, gfc_expr*)':
../../gcc-trunk/gcc/fortran/resolve.cc:12248:48: error: 'gfc_expr' {aka
'struct gfc_expr'} has no member named 'is_c_interop'
12248 |   if (rhs->expr_type != EXPR_FUNCTION || !rhs->is_c_interop)
  |^~~~

Can you please check whether you inadvertently added something
that was not planned or tested?

Cheers,
Harald



Best regards

 Thomas

gcc/fortran/ChangeLog:

 PR fortran/119419
 * dump-parse-tree.cc (write_funptr_fcn): New function.
 (write_type): Invoke it for C_FUNPTR.
 (write_interop_decl): Do not dump vtabs.





Re: [Patch, Fortran] C prototypes for functions returning C function pointers

2025-03-24 Thread Steve Kargl
On Mon, Mar 24, 2025 at 09:40:38PM +0100, Thomas Koenig wrote:
>
> Regression-tested.  Again no test case because I don't know
> how.  During testing, I also found that vtabs were dumped,
> this is also corrected.
> 
> OK for trunk?

Thanks for working on this, but ...

> 
>  /* This section deals with dumping the global symbol tree.  */
> diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
> index 34c8210f66a..efc059908f7 100644
> --- a/gcc/fortran/resolve.cc
> +++ b/gcc/fortran/resolve.cc
> @@ -12187,6 +12187,34 @@ caf_possible_reallocate (gfc_expr *e)
>return last_arr_ref && last_arr_ref->u.ar.type == AR_FULL;
>  }
>  
> +/*  Handle C_FUNPTR assignments, for generating C prototypes and for warning 
> if
> +pointers are assigned to procedures with different interfaces.  */
> +
> +static void
> +check_c_funptr_assign_interface (gfc_expr *lhs, gfc_expr *rhs)
> +{
> +
> +  fprintf (stderr,"%p %p\n", (void *) lhs, (void *) rhs);

This looks like a debugging printf() statement.  If it is
meant to be informative, I would expect gfc_warning( ) or
gfc_error().

-- 
Steve


GSoC Fortran – 2018/202x – Inquiry About Project Scope

2025-03-24 Thread Yuao Ma
Hello GCC Community,

I hope this message finds you well. My name is Yuao, and I’m excited to express
my interest in the "Fortran – 2018/202x" project for Google Summer of Code. I’m
writing to clarify the scope of this project and gather any recommendations you
may have.

>From the project documentation and the "What's New in 202x" resources, I
understand that “Extracting tokens from a string,” “Interoperability with C,”
and “Trig function changes” would be considered a medium-sized undertaking.
After exploring the codebase, I noticed that trigonometric functions working in
degrees have already been implemented. I’d be very interested in continuing
with the half-revolution functionality as well as addressing the “Changes for
conformance with the new IEEE standard.” I’d love to hear your thoughts on
whether this focus is aligned with current project needs or if there are other
areas you recommend I prioritize.

Thank you for your time and guidance. I look forward to your feedback on how I
can best contribute.

Kind regards,
Yuao


[Patch, Fortran] C prototypes for functions returning C function pointers

2025-03-24 Thread Thomas Koenig

Hello world,

the attached patch handles dumping prototypes for C functions returning
function pointers.  For the test case

MODULE test
   USE, INTRINSIC :: ISO_C_BINDING
CONTAINS
   FUNCTION lookup(idx) BIND(C)
 type(C_FUNPTR) :: lookup
 integer(C_INT), VALUE :: idx
 lookup = C_FUNLOC(x1)
   END FUNCTION lookup

   subroutine x1()
   end subroutine x1
 END MODULE test

the prototype is

void (*lookup (int idx)) ();

Regression-tested.  Again no test case because I don't know
how.  During testing, I also found that vtabs were dumped,
this is also corrected.

OK for trunk?

Best regards

Thomas

gcc/fortran/ChangeLog:

PR fortran/119419
* dump-parse-tree.cc (write_funptr_fcn): New function.
(write_type): Invoke it for C_FUNPTR.
(write_interop_decl): Do not dump vtabs.

diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc
index 1a15757b57b..837469c8aae 100644
--- a/gcc/fortran/dump-parse-tree.cc
+++ b/gcc/fortran/dump-parse-tree.cc
@@ -4038,6 +4038,7 @@ static void write_interop_decl (gfc_symbol *);
 static void write_proc (gfc_symbol *, bool);
 static void show_external_symbol (gfc_gsymbol *, void *);
 static void write_type (gfc_symbol *sym);
+static void write_funptr_fcn (gfc_symbol *);
 
 /* Do we need to write out an #include  or not?  */
 
@@ -4379,9 +4380,10 @@ write_type (gfc_symbol *sym)
 {
   gfc_component *c;
 
-  /* Don't dump our iso c module.  */
+  /* Don't dump our iso c module, nor vtypes.  */
 
-  if (sym->from_intmod == INTMOD_ISO_C_BINDING || sym->attr.flavor != FL_DERIVED)
+  if (sym->from_intmod == INTMOD_ISO_C_BINDING || sym->attr.flavor != FL_DERIVED
+  || sym->attr.vtype)
 return;
 
   fprintf (dumpfile, "typedef struct %s {\n", sym->name);
@@ -4495,6 +4497,18 @@ write_formal_arglist (gfc_symbol *sym, bool bind_c)
 
 }
 
+/* Write out an interoperable function returning a function pointer.  Better
+   handled separately.  As we know nothing about the type, assume
+   a C default return of int.  */
+
+static void
+write_funptr_fcn (gfc_symbol *sym)
+{
+  fprintf (dumpfile, "int (*%s (", sym->binding_label);
+  write_formal_arglist (sym, 1);
+  fputs (")) ();\n", dumpfile);
+}
+
 /* Write out a procedure, including its arguments.  */
 static void
 write_proc (gfc_symbol *sym, bool bind_c)
@@ -4552,7 +4566,13 @@ write_interop_decl (gfc_symbol *sym)
   else if (sym->attr.flavor == FL_DERIVED)
 write_type (sym);
   else if (sym->attr.flavor == FL_PROCEDURE)
-write_proc (sym, true);
+{
+  if (sym->ts.type == BT_DERIVED
+	  && strcmp (sym->ts.u.derived->name, "c_funptr") == 0)
+	write_funptr_fcn (sym);
+  else
+	write_proc (sym, true);
+}
 }
 
 /* This section deals with dumping the global symbol tree.  */
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 34c8210f66a..efc059908f7 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -12187,6 +12187,34 @@ caf_possible_reallocate (gfc_expr *e)
   return last_arr_ref && last_arr_ref->u.ar.type == AR_FULL;
 }
 
+/*  Handle C_FUNPTR assignments, for generating C prototypes and for warning if
+pointers are assigned to procedures with different interfaces.  */
+
+static void
+check_c_funptr_assign_interface (gfc_expr *lhs, gfc_expr *rhs)
+{
+  gfc_symbol *lsym, *l_derived_sym, *rsym;
+  if (lhs->expr_type != EXPR_VARIABLE)
+return;
+
+  lsym = lhs->symtree->n.sym;
+  if (lsym->ts.type != BT_DERIVED || !lsym->attr.is_bind_c)
+return;
+
+  l_derived_sym = lsym->ts.u.derived;
+
+  if (!l_derived_sym->attr.is_c_interop
+  || strcmp (l_derived_sym->name, "c_funptr") != 0)
+return;
+
+  if (rhs->expr_type != EXPR_FUNCTION || !rhs->is_c_interop)
+return;
+
+  rsym = rhs->symtree->n.sym;
+
+  fprintf (stderr,"%p %p\n", (void *) lhs, (void *) rhs);
+}
+
 /* Does everything to resolve an ordinary assignment.  Returns true
if this is an interface assignment.  */
 static bool
@@ -12437,6 +12465,9 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
 
   gfc_check_assign (lhs, rhs, 1);
 
+  if (warn_external_argument_mismatch)
+check_c_funptr_assign_interface (lhs, rhs);
+  
   return false;
 }
 


Re: [Patch, Fortran] C prototypes for functions returning C function pointers

2025-03-24 Thread Thomas Koenig

Hi Harald,


the attached patch contains a chunk changing resolve.cc
that is neither described in the suggested commit message,
and it fails to compile here:

../../gcc-trunk/gcc/fortran/resolve.cc: In function 'void
check_c_funptr_assign_interface(gfc_expr*, gfc_expr*)':
../../gcc-trunk/gcc/fortran/resolve.cc:12248:48: error: 'gfc_expr' {aka
'struct gfc_expr'} has no member named 'is_c_interop'
12248 |   if (rhs->expr_type != EXPR_FUNCTION || !rhs->is_c_interop)
   |    ^~~~

Can you please check whether you inadvertently added something
that was not planned or tested?


I sent out the wrong version of the patch, sorry (one which contained
an intermediate stage of something I tried, and then abandoned).

Here is the one that actually in my tree, and that I regression-tested.

Best regards

Thomas


diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc
index 1a15757b57b..3e4a30fe0de 100644
--- a/gcc/fortran/dump-parse-tree.cc
+++ b/gcc/fortran/dump-parse-tree.cc
@@ -4038,6 +4038,7 @@ static void write_interop_decl (gfc_symbol *);
 static void write_proc (gfc_symbol *, bool);
 static void show_external_symbol (gfc_gsymbol *, void *);
 static void write_type (gfc_symbol *sym);
+static void write_funptr_fcn (gfc_symbol *);
 
 /* Do we need to write out an #include  or not?  */
 
@@ -4379,9 +4380,10 @@ write_type (gfc_symbol *sym)
 {
   gfc_component *c;
 
-  /* Don't dump our iso c module.  */
+  /* Don't dump our iso c module, nor vtypes.  */
 
-  if (sym->from_intmod == INTMOD_ISO_C_BINDING || sym->attr.flavor != FL_DERIVED)
+  if (sym->from_intmod == INTMOD_ISO_C_BINDING || sym->attr.flavor != FL_DERIVED
+  || sym->attr.vtype)
 return;
 
   fprintf (dumpfile, "typedef struct %s {\n", sym->name);
@@ -4495,6 +4497,18 @@ write_formal_arglist (gfc_symbol *sym, bool bind_c)
 
 }
 
+/* Write out an interoperable function returning a function pointer.  Better
+   handled separately.  As we know nothing about the type, assume
+   a C default return of int.  */
+
+static void
+write_funptr_fcn (gfc_symbol *sym)
+{
+  fprintf (dumpfile, "void (*%s (", sym->binding_label);
+  write_formal_arglist (sym, 1);
+  fputs (")) ();\n", dumpfile);
+}
+
 /* Write out a procedure, including its arguments.  */
 static void
 write_proc (gfc_symbol *sym, bool bind_c)
@@ -4552,7 +4566,13 @@ write_interop_decl (gfc_symbol *sym)
   else if (sym->attr.flavor == FL_DERIVED)
 write_type (sym);
   else if (sym->attr.flavor == FL_PROCEDURE)
-write_proc (sym, true);
+{
+  if (sym->ts.type == BT_DERIVED
+	  && strcmp (sym->ts.u.derived->name, "c_funptr") == 0)
+	write_funptr_fcn (sym);
+  else
+	write_proc (sym, true);
+}
 }
 
 /* This section deals with dumping the global symbol tree.  */


Re: Gsoc: Fortran-Do Concurrent

2025-03-24 Thread Martin Jambor
Hello,

we are delighted you found contributing to GCC interesting.

On Thu, Mar 13 2025, ahmad tariq via Gcc wrote:
> Hi,
> I'm Ahmad Abdul Rehman, a third year computer science undergraduate from
> FAST(Pakistan). I am interested in the "Do-Concurrent" project, and I
> noticed that some work has already been done. I wanted to know what the
> organization is specifically expecting from this project.Few things listed
> in the description of the project overlap with work done by the previous
> contributor.

As far as I understand it, the completed project added the ability to
parse the do concurrent "construct" and internally turned the loops into
a form which can be run concurrently (I assume by "privatizing" some
data so that the different concurrent iterations don't step on each
other's intermediate results).  But the task to actually use libgomp to
run the loops in parallel remains, as does some masking functionality.

(Tobias, please correct me if I am somehow very wrong.)

> Additionally it was asked to contact before working on the details of the
> project thus I would appreciate if you could provide details regarding
> scope of work.

The scope is working towards the goals listed under "Goal is to execute
the loops actually in parallel" at our GSoC wiki page.

Good luck!

Martin


Re: [COMMITTED] libgfortran/intrinsics: Fix build for targets with int32_t=long int

2025-03-24 Thread Steve Kargl
On Sun, Mar 23, 2025 at 10:09:46AM +0100, Thomas Koenig wrote:
> Hi Paul,
> 
> > By the way, the standard just specifies integer for 'dim' in reduce,
> > which I take to mean it should be default_integer_kind.
> 
> Hmm... I'm not sure that this is actually the case; I believe it
> can actually be any integer kind, although anything larger than
> default integer would be kind of funny, or a funny kind, so what
> is passed to the library after conversion is whatever we chose it to be.

Yes, 'dim' can be an integer of any kind.  In section 16, if
there is a specific kind requirement, then it would have stated
that 'dim' had a default integer kind.  See for example,
16.9.169 RANDOM_SEED([SIZE, PUT, GET]) where one has

  SIZE (optional) shall be a default integer scalar.


> > I didn't see any obvious way of finding that in the library. Could
> > somebody on the list advise, please?
> 
> That is always 4, unless the user directed us to do something
> horrible; see gfc_init_kinds().
> 
> Maybe we could use a constant like "GFC_DEFAULT_DEFAULT_INTEGER_KIND"
> for calling library functions to avoid the potential mess with
> -fdefault-integer=...

We could remove of the -fdefault-* options.  Problem solved.

-- 
Steve