Inline::F2003 - New ILSM proposed

[email protected] (Ron Grunwald via inline) Mon, 22 May 2017 21:55:53 +0800
Newsgroups perl.inline
Message-ID <[email protected]>
--Apple-Mail=_89967FB6-53A4-4D19-9E1E-4B0956278A96
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

Hello all,

I've been thinking about this for quite some time now, and have finally =
decided to pursue the idea of a modern FORTRAN Inline module. Given that =
soon I'll be having some time available through to the end of this year, =
I'm confident that I can make this work.

The name of the proposed module is Inline::F2003

The module will only work for compilers that are compliant with the =
FORTRAN 2003 standard and above. The reason for this is that FORTRAN =
2003 introduced a new feature named "C Interoperability". This feature, =
coupled with Inline::C, are the core mechanisms that will make =
Inline::F2003 work.

For those who have an interest in programming using modern FORTRAN, =
below is an example Perl program that illustrates how Inline::F2003 =
would be used. The program performs multiplication of two matrices. =
Notice the two sections __F2003__ and __C__

The __F2003__ section contains the FORTRAN subroutine that performs the =
actual matrix multiplication. The subroutine utilises FORTRAN 2003's C =
interoperability features to make it callable from C.

The __C__ section is the crucial part of an Inline::F2003 program, and =
must always be present. It prepares any data from Perl that needs to be =
passed into FORTRAN, and finally calls the FORTRAN subroutine with that =
data.=20

I am always interested to hear people's views. So, if you have any =
comments/suggestions/questions, please post them or send me an e-mail.

Many thanks for reading this post and reviewing the example program =
below.

Cheers,

Ron.
=20

#!/usr/local/ActivePerl/bin/perl
#
use strict;
use warnings;
use Inline F2003 =3D> Config =3D> (
                       SOURCE    =3D> "ModMatrixOps.f03",
                       LIBRARY   =3D> "libMatrixOps.so",
                       LIBTYPE   =3D> ".so",
                       DIRECTORY =3D> "BLD_Linux.AMD64_nagfor",
                       FOR       =3D> "nagfor",
                       FORFLG    =3D> "-v -g90 -gline -otype=3Dobj =
-f2003 -fpp"
                    );
use Inline C =3D> Config =3D> (
                   MYEXTLIB  =3D> =
"/u/BLD_Linux.AMD64_nagfor/libMatrixOps.so",
                   DIRECTORY =3D> "BLD_Linux.AMD64_perl",
                   CCFLAGSEX =3D> "-std=3Dc99"
                );
use Inline F2003 =3D> "DATA";
use Inline C     =3D> "DATA";

MainFunction: {
   my ($M1_rows, $M1_cols) =3D (3, 3);
   my ($M2_rows, $M2_cols) =3D (3, 3);

   my @M1_data =3D ( 2.4,  0.0,  0.0,
                   2.4,  3.8,  0.0,
                   0.0,  3.8,  0.0  );
   my @M2_data =3D ( 2.4,  2.4,  0.0,
                   0.0,  3.8,  3.8,
                   1.25, 1.25, 1.25 );

   MatrixMultiply( $M1_rows, $M1_cols, @M1_data,
                   $M2_rows, $M2_cols, @M2_data );
}

__DATA__
__F2003__

SUBROUTINE FOR_MatrixMultiply (M1_rows, M1_cols, C_M1_data,  &
                               M2_rows, M2_cols, C_M2_data ) &
           BIND(C, NAME=3D"FOR_MatrixMultiply")

   USE, INTRINSIC :: ISO_C_BINDING, &
                     ONLY : C_INT, C_DOUBLE, C_PTR, C_F_POINTER
   USE ModMatrixOps
   IMPLICIT NONE

   INTEGER (KIND=3DC_INT), VALUE, INTENT(IN) :: M1_rows, M1_cols
   INTEGER (KIND=3DC_INT), VALUE, INTENT(IN) :: M2_rows, M2_cols
   REAL (KIND=3DC_DOUBLE), POINTER :: M1_data(:) =3D> NULL()
   REAL (KIND=3DC_DOUBLE), POINTER :: M2_data(:) =3D> NULL()
   TYPE (C_PTR), INTENT(IN) :: C_M1_data, C_M2_data

   CALL C_F_POINTER (C_M1_data, M1_data, [M1_rows * M1_cols])
   CALL C_F_POINTER (C_M2_data, M2_data, [M2_rows * M2_cols])

   CALL MOD_SetMatrix (M1_rows, M1_cols, M1_data)
   CALL MOD_SetMatrix (M2_rows, M2_cols, M2_data)
   CALL MOD_MatrixMultiply()

   IF (MOD_MatrixOp_OK()) THEN
      CALL MOD_MatrixDisplay()
   ELSE
      PRINT "(A)", "FOR_MatrixMultiply: Error Condition Occurred."
   END IF

   CALL MOD_MatrixDestroy()

END SUBROUTINE FOR_MatrixMultiply

__C__
#define MAX_MATRIX_SZ 50

extern void FOR_MatrixMultiply(int, int, double *, int, int, double *);

void MatrixMultiply(SV* matrix_data, ...) {

   double M1_data[MAX_MATRIX_SZ], M2_data[MAX_MATRIX_SZ];
   int    M1_rows, M1_cols, M2_rows, M2_cols;
   int    ix, arg_ix =3D 0;

   Inline_Stack_Vars;

   M1_rows =3D SvIV(Inline_Stack_Item(arg_ix++));
   M1_cols =3D SvIV(Inline_Stack_Item(arg_ix++));
   /*
    * Fill values for Matrix 1
    */
   for (ix=3D0; ix < M1_rows*M1_cols; ix++) {
      M1_data[ix] =3D SvNV(Inline_Stack_Item(arg_ix++));
   }

   M2_rows =3D SvIV(Inline_Stack_Item(arg_ix++));
   M2_cols =3D SvIV(Inline_Stack_Item(arg_ix++));
   /*
    * Fill values for Matrix 2
    */
   for (ix=3D0; ix < M2_rows*M2_cols; ix++) {
      M2_data[ix] =3D SvNV(Inline_Stack_Item(arg_ix++));
   }

   FOR_MatrixMultiply(M1_rows, M1_cols, M1_data,
                      M2_rows, M2_cols, M2_data );

   Inline_Stack_Void;
}

________________________________________
Ron Grunwald
[email protected]
http://www.dvlcorner.org




--Apple-Mail=_89967FB6-53A4-4D19-9E1E-4B0956278A96
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=us-ascii

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html =
charset=3Dus-ascii"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D""><div class=3D""><font face=3D"Avenir Next" class=3D""><div =
class=3D"">Hello all,</div><div class=3D""><br class=3D""></div><div =
class=3D"">I've been thinking about this for quite some time now, and =
have finally decided to pursue the idea of a modern FORTRAN Inline =
module. Given that soon I'll be having some time available through to =
the end of this year, I'm confident that I can make this work.</div><div =
class=3D""><br class=3D""></div><div class=3D"">The name of the proposed =
module is Inline::F2003</div><div class=3D""><br class=3D""></div><div =
class=3D"">The module will only work for compilers that are compliant =
with the FORTRAN 2003 standard and above. The reason for this is that =
FORTRAN 2003 introduced a new feature named "C Interoperability". This =
feature, coupled with Inline::C, are the core mechanisms that will make =
Inline::F2003 work.</div><div class=3D""><br class=3D""></div><div =
class=3D"">For those who have an interest in programming using modern =
FORTRAN, below is an example Perl program that illustrates how =
Inline::F2003 would be used. The program performs multiplication of two =
matrices. Notice the two sections __F2003__ and __C__</div><div =
class=3D""><br class=3D""></div><div class=3D"">The __F2003__ section =
contains the FORTRAN subroutine that performs the actual matrix =
multiplication. The subroutine utilises FORTRAN 2003's C =
interoperability features to make it callable from C.</div><div =
class=3D""><br class=3D""></div><div class=3D"">The __C__ section is the =
crucial part of an Inline::F2003 program, and must always be present. It =
prepares any data from Perl that needs to be passed into FORTRAN, and =
finally calls the FORTRAN subroutine with that data.&nbsp;</div><div =
class=3D""><br class=3D""></div><div class=3D"">I am always interested =
to hear people's views. So, if you have any =
comments/suggestions/questions, please post them or send me an =
e-mail.</div><div class=3D""><br class=3D""></div><div class=3D"">Many =
thanks for reading this post and reviewing the example program =
below.</div><div class=3D""><br class=3D""></div><div =
class=3D"">Cheers,</div><div class=3D""><br class=3D""></div><div =
class=3D"">Ron.</div><div class=3D"">&nbsp;</div><div class=3D""><br =
class=3D""></div></font></div><div class=3D""><font face=3D"Courier" =
class=3D""><div class=3D"">#!/usr/local/ActivePerl/bin/perl</div><div =
class=3D"">#</div><div class=3D"">use strict;</div><div class=3D"">use =
warnings;</div><div class=3D"">use Inline F2003 =3D&gt; Config =3D&gt; =
(</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SOURCE &nbsp; &nbsp;=3D&gt; =
"ModMatrixOps.f03",</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LIBRARY &nbsp; =
=3D&gt; "libMatrixOps.so",</div><div class=3D"">&nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LIBTYPE =
&nbsp; =3D&gt; ".so",</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DIRECTORY =3D&gt; =
"BLD_Linux.AMD64_nagfor",</div><div class=3D"">&nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FOR &nbsp; =
&nbsp; &nbsp; =3D&gt; "nagfor",</div><div class=3D"">&nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp;FORFLG &nbsp; &nbsp;=3D&gt; "-v -g90 -gline -otype=3Dobj -f2003 =
-fpp"</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; );</div><div class=3D"">use Inline C =3D&gt; =
Config =3D&gt; (</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MYEXTLIB &nbsp;=3D&gt; =
"/u/BLD_Linux.AMD64_nagfor/libMatrixOps.so",</div><div class=3D"">&nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DIRECTORY =
=3D&gt; "BLD_Linux.AMD64_perl",</div><div class=3D"">&nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CCFLAGSEX =3D&gt; =
"-std=3Dc99"</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; );</div><div class=3D"">use Inline F2003 =3D&gt; =
"DATA";</div><div class=3D"">use Inline C &nbsp; &nbsp; =3D&gt; =
"DATA";</div><div class=3D""><br class=3D""></div><div =
class=3D"">MainFunction: {</div><div class=3D"">&nbsp; &nbsp;my =
($M1_rows, $M1_cols) =3D (3, 3);</div><div class=3D"">&nbsp; &nbsp;my =
($M2_rows, $M2_cols) =3D (3, 3);</div><div class=3D""><br =
class=3D""></div><div class=3D"">&nbsp; &nbsp;my @M1_data =3D ( 2.4, =
&nbsp;0.0, &nbsp;0.0,</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2.4, &nbsp;3.8, =
&nbsp;0.0,</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.0, &nbsp;3.8, &nbsp;0.0 =
&nbsp;);</div><div class=3D"">&nbsp; &nbsp;my @M2_data =3D ( 2.4, =
&nbsp;2.4, &nbsp;0.0,</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.0, &nbsp;3.8, =
&nbsp;3.8,</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1.25, 1.25, 1.25 );</div><div =
class=3D""><br class=3D""></div><div class=3D"">&nbsp; =
&nbsp;MatrixMultiply( $M1_rows, $M1_cols, @M1_data,</div><div =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;$M2_rows, $M2_cols, @M2_data );</div><div =
class=3D"">}</div><div class=3D""><br class=3D""></div><div =
class=3D"">__DATA__</div><div class=3D"">__F2003__</div><div =
class=3D""><br class=3D""></div><div class=3D"">SUBROUTINE =
FOR_MatrixMultiply (M1_rows, M1_cols, C_M1_data, &nbsp;&amp;</div><div =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;M2_rows, M2_cols, =
C_M2_data ) &amp;</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;BIND(C, NAME=3D"FOR_MatrixMultiply")</div><div class=3D""><br=
 class=3D""></div><div class=3D"">&nbsp; &nbsp;USE, INTRINSIC :: =
ISO_C_BINDING, &amp;</div><div class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ONLY : C_INT, C_DOUBLE, =
C_PTR, C_F_POINTER</div><div class=3D"">&nbsp; &nbsp;USE =
ModMatrixOps</div><div class=3D"">&nbsp; &nbsp;IMPLICIT NONE</div><div =
class=3D""><br class=3D""></div><div class=3D"">&nbsp; &nbsp;INTEGER =
(KIND=3DC_INT), VALUE, INTENT(IN) :: M1_rows, M1_cols</div><div =
class=3D"">&nbsp; &nbsp;INTEGER (KIND=3DC_INT), VALUE, INTENT(IN) :: =
M2_rows, M2_cols</div><div class=3D"">&nbsp; &nbsp;REAL (KIND=3DC_DOUBLE),=
 POINTER :: M1_data(:) =3D&gt; NULL()</div><div class=3D"">&nbsp; =
&nbsp;REAL (KIND=3DC_DOUBLE), POINTER :: M2_data(:) =3D&gt; =
NULL()</div><div class=3D"">&nbsp; &nbsp;TYPE (C_PTR), INTENT(IN) :: =
C_M1_data, C_M2_data</div><div class=3D""><br class=3D""></div><div =
class=3D"">&nbsp; &nbsp;CALL C_F_POINTER (C_M1_data, M1_data, [M1_rows * =
M1_cols])</div><div class=3D"">&nbsp; &nbsp;CALL C_F_POINTER (C_M2_data, =
M2_data, [M2_rows * M2_cols])</div><div class=3D""><br =
class=3D""></div><div class=3D"">&nbsp; &nbsp;CALL MOD_SetMatrix =
(M1_rows, M1_cols, M1_data)</div><div class=3D"">&nbsp; &nbsp;CALL =
MOD_SetMatrix (M2_rows, M2_cols, M2_data)</div><div class=3D"">&nbsp; =
&nbsp;CALL MOD_MatrixMultiply()</div><div class=3D""><br =
class=3D""></div><div class=3D"">&nbsp; &nbsp;IF (MOD_MatrixOp_OK()) =
THEN</div><div class=3D"">&nbsp; &nbsp; &nbsp; CALL =
MOD_MatrixDisplay()</div><div class=3D"">&nbsp; &nbsp;ELSE</div><div =
class=3D"">&nbsp; &nbsp; &nbsp; PRINT "(A)", "FOR_MatrixMultiply: Error =
Condition Occurred."</div><div class=3D"">&nbsp; &nbsp;END IF</div><div =
class=3D""><br class=3D""></div><div class=3D"">&nbsp; &nbsp;CALL =
MOD_MatrixDestroy()</div><div class=3D""><br class=3D""></div><div =
class=3D"">END SUBROUTINE FOR_MatrixMultiply</div><div class=3D""><br =
class=3D""></div><div class=3D"">__C__</div><div class=3D"">#define =
MAX_MATRIX_SZ 50</div><div class=3D""><br class=3D""></div><div =
class=3D"">extern void FOR_MatrixMultiply(int, int, double *, int, int, =
double *);</div><div class=3D""><br class=3D""></div><div class=3D"">void =
MatrixMultiply(SV* matrix_data, ...) {</div><div class=3D""><br =
class=3D""></div><div class=3D"">&nbsp; &nbsp;double =
M1_data[MAX_MATRIX_SZ], M2_data[MAX_MATRIX_SZ];</div><div =
class=3D"">&nbsp; &nbsp;int &nbsp; &nbsp;M1_rows, M1_cols, M2_rows, =
M2_cols;</div><div class=3D"">&nbsp; &nbsp;int &nbsp; &nbsp;ix, arg_ix =3D=
 0;</div><div class=3D""><br class=3D""></div><div class=3D"">&nbsp; =
&nbsp;Inline_Stack_Vars;</div><div class=3D""><br class=3D""></div><div =
class=3D"">&nbsp; &nbsp;M1_rows =3D =
SvIV(Inline_Stack_Item(arg_ix++));</div><div class=3D"">&nbsp; =
&nbsp;M1_cols =3D SvIV(Inline_Stack_Item(arg_ix++));</div><div =
class=3D"">&nbsp; &nbsp;/*</div><div class=3D"">&nbsp; &nbsp; * Fill =
values for Matrix 1</div><div class=3D"">&nbsp; &nbsp; */</div><div =
class=3D"">&nbsp; &nbsp;for (ix=3D0; ix &lt; M1_rows*M1_cols; ix++) =
{</div><div class=3D"">&nbsp; &nbsp; &nbsp; M1_data[ix] =3D =
SvNV(Inline_Stack_Item(arg_ix++));</div><div class=3D"">&nbsp; =
&nbsp;}</div><div class=3D""><br class=3D""></div><div class=3D"">&nbsp; =
&nbsp;M2_rows =3D SvIV(Inline_Stack_Item(arg_ix++));</div><div =
class=3D"">&nbsp; &nbsp;M2_cols =3D =
SvIV(Inline_Stack_Item(arg_ix++));</div><div class=3D"">&nbsp; =
&nbsp;/*</div><div class=3D"">&nbsp; &nbsp; * Fill values for Matrix =
2</div><div class=3D"">&nbsp; &nbsp; */</div><div class=3D"">&nbsp; =
&nbsp;for (ix=3D0; ix &lt; M2_rows*M2_cols; ix++) {</div><div =
class=3D"">&nbsp; &nbsp; &nbsp; M2_data[ix] =3D =
SvNV(Inline_Stack_Item(arg_ix++));</div><div class=3D"">&nbsp; =
&nbsp;}</div><div class=3D""><br class=3D""></div><div class=3D"">&nbsp; =
&nbsp;FOR_MatrixMultiply(M1_rows, M1_cols, M1_data,</div><div =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; M2_rows, M2_cols, M2_data );</div><div class=3D""><br=
 class=3D""></div><div class=3D"">&nbsp; =
&nbsp;Inline_Stack_Void;</div><div class=3D"">}</div><div class=3D""><br =
class=3D""></div></font><div apple-content-edited=3D"true" class=3D"">
<div style=3D"color: rgb(0, 0, 0); letter-spacing: normal; orphans: =
auto; text-align: start; text-indent: 0px; text-transform: none; =
white-space: normal; widows: auto; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D""><div =
class=3D"">________________________________________</div><div =
class=3D""><div style=3D"margin: 0px;" class=3D"">Ron Grunwald</div><div =
style=3D"margin: 0px;" class=3D""><a href=3D"mailto:[email protected]" =
class=3D"">[email protected]</a></div><div style=3D"margin: 0px;" =
class=3D""><a href=3D"http://www.dvlcorner.org" =
class=3D"">http://www.dvlcorner.org</a></div></div><div class=3D""><br =
class=3D""></div></div><br class=3D"Apple-interchange-newline">

</div>
<br class=3D""></div></body></html>=

--Apple-Mail=_89967FB6-53A4-4D19-9E1E-4B0956278A96--