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. </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""> </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> Config =3D> =
(</div><div class=3D""> =
SOURCE =3D> =
"ModMatrixOps.f03",</div><div class=3D""> =
LIBRARY =
=3D> "libMatrixOps.so",</div><div class=3D""> =
LIBTYPE =
=3D> ".so",</div><div class=3D""> =
DIRECTORY =3D> =
"BLD_Linux.AMD64_nagfor",</div><div class=3D""> =
FOR =
=3D> "nagfor",</div><div class=3D""> =
=
FORFLG =3D> "-v -g90 -gline -otype=3Dobj -f2003 =
-fpp"</div><div class=3D""> =
);</div><div class=3D"">use Inline C =3D> =
Config =3D> (</div><div class=3D""> =
MYEXTLIB =3D> =
"/u/BLD_Linux.AMD64_nagfor/libMatrixOps.so",</div><div class=3D""> =
DIRECTORY =
=3D> "BLD_Linux.AMD64_perl",</div><div class=3D""> =
CCFLAGSEX =3D> =
"-std=3Dc99"</div><div class=3D""> =
);</div><div class=3D"">use Inline F2003 =3D> =
"DATA";</div><div class=3D"">use Inline C =3D> =
"DATA";</div><div class=3D""><br class=3D""></div><div =
class=3D"">MainFunction: {</div><div class=3D""> my =
($M1_rows, $M1_cols) =3D (3, 3);</div><div class=3D""> my =
($M2_rows, $M2_cols) =3D (3, 3);</div><div class=3D""><br =
class=3D""></div><div class=3D""> my @M1_data =3D ( 2.4, =
0.0, 0.0,</div><div class=3D""> =
2.4, 3.8, =
0.0,</div><div class=3D""> =
0.0, 3.8, 0.0 =
);</div><div class=3D""> my @M2_data =3D ( 2.4, =
2.4, 0.0,</div><div class=3D""> =
0.0, 3.8, =
3.8,</div><div class=3D""> =
1.25, 1.25, 1.25 );</div><div =
class=3D""><br class=3D""></div><div class=3D""> =
MatrixMultiply( $M1_rows, $M1_cols, @M1_data,</div><div =
class=3D""> =
$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, &</div><div =
class=3D""> =
M2_rows, M2_cols, =
C_M2_data ) &</div><div class=3D""> =
BIND(C, NAME=3D"FOR_MatrixMultiply")</div><div class=3D""><br=
class=3D""></div><div class=3D""> USE, INTRINSIC :: =
ISO_C_BINDING, &</div><div class=3D""> =
ONLY : C_INT, C_DOUBLE, =
C_PTR, C_F_POINTER</div><div class=3D""> USE =
ModMatrixOps</div><div class=3D""> IMPLICIT NONE</div><div =
class=3D""><br class=3D""></div><div class=3D""> INTEGER =
(KIND=3DC_INT), VALUE, INTENT(IN) :: M1_rows, M1_cols</div><div =
class=3D""> INTEGER (KIND=3DC_INT), VALUE, INTENT(IN) :: =
M2_rows, M2_cols</div><div class=3D""> REAL (KIND=3DC_DOUBLE),=
POINTER :: M1_data(:) =3D> NULL()</div><div class=3D""> =
REAL (KIND=3DC_DOUBLE), POINTER :: M2_data(:) =3D> =
NULL()</div><div class=3D""> TYPE (C_PTR), INTENT(IN) :: =
C_M1_data, C_M2_data</div><div class=3D""><br class=3D""></div><div =
class=3D""> CALL C_F_POINTER (C_M1_data, M1_data, [M1_rows * =
M1_cols])</div><div class=3D""> CALL C_F_POINTER (C_M2_data, =
M2_data, [M2_rows * M2_cols])</div><div class=3D""><br =
class=3D""></div><div class=3D""> CALL MOD_SetMatrix =
(M1_rows, M1_cols, M1_data)</div><div class=3D""> CALL =
MOD_SetMatrix (M2_rows, M2_cols, M2_data)</div><div class=3D""> =
CALL MOD_MatrixMultiply()</div><div class=3D""><br =
class=3D""></div><div class=3D""> IF (MOD_MatrixOp_OK()) =
THEN</div><div class=3D""> CALL =
MOD_MatrixDisplay()</div><div class=3D""> ELSE</div><div =
class=3D""> PRINT "(A)", "FOR_MatrixMultiply: Error =
Condition Occurred."</div><div class=3D""> END IF</div><div =
class=3D""><br class=3D""></div><div class=3D""> 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""> double =
M1_data[MAX_MATRIX_SZ], M2_data[MAX_MATRIX_SZ];</div><div =
class=3D""> int M1_rows, M1_cols, M2_rows, =
M2_cols;</div><div class=3D""> int ix, arg_ix =3D=
0;</div><div class=3D""><br class=3D""></div><div class=3D""> =
Inline_Stack_Vars;</div><div class=3D""><br class=3D""></div><div =
class=3D""> M1_rows =3D =
SvIV(Inline_Stack_Item(arg_ix++));</div><div class=3D""> =
M1_cols =3D SvIV(Inline_Stack_Item(arg_ix++));</div><div =
class=3D""> /*</div><div class=3D""> * Fill =
values for Matrix 1</div><div class=3D""> */</div><div =
class=3D""> for (ix=3D0; ix < M1_rows*M1_cols; ix++) =
{</div><div class=3D""> M1_data[ix] =3D =
SvNV(Inline_Stack_Item(arg_ix++));</div><div class=3D""> =
}</div><div class=3D""><br class=3D""></div><div class=3D""> =
M2_rows =3D SvIV(Inline_Stack_Item(arg_ix++));</div><div =
class=3D""> M2_cols =3D =
SvIV(Inline_Stack_Item(arg_ix++));</div><div class=3D""> =
/*</div><div class=3D""> * Fill values for Matrix =
2</div><div class=3D""> */</div><div class=3D""> =
for (ix=3D0; ix < M2_rows*M2_cols; ix++) {</div><div =
class=3D""> M2_data[ix] =3D =
SvNV(Inline_Stack_Item(arg_ix++));</div><div class=3D""> =
}</div><div class=3D""><br class=3D""></div><div class=3D""> =
FOR_MatrixMultiply(M1_rows, M1_cols, M1_data,</div><div =
class=3D""> =
M2_rows, M2_cols, M2_data );</div><div class=3D""><br=
class=3D""></div><div class=3D""> =
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--