develooper Front page | perl.inline | Postings from May 2017

Inline::F2003 - New ILSM proposed

Thread Next
Ron Grunwald via inline
May 22, 2017 13:56
Inline::F2003 - New ILSM proposed
Message ID:
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. 

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.



use strict;
use warnings;
use Inline F2003 => Config => (
                       SOURCE    => "ModMatrixOps.f03",
                       LIBRARY   => "",
                       LIBTYPE   => ".so",
                       DIRECTORY => "BLD_Linux.AMD64_nagfor",
                       FOR       => "nagfor",
                       FORFLG    => "-v -g90 -gline -otype=obj -f2003 -fpp"
use Inline C => Config => (
                   MYEXTLIB  => "/u/BLD_Linux.AMD64_nagfor/",
                   DIRECTORY => "BLD_Linux.AMD64_perl",
                   CCFLAGSEX => "-std=c99"
use Inline F2003 => "DATA";
use Inline C     => "DATA";

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

   my @M1_data = ( 2.4,  0.0,  0.0,
                   2.4,  3.8,  0.0,
                   0.0,  3.8,  0.0  );
   my @M2_data = ( 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 );


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

                     ONLY : C_INT, C_DOUBLE, C_PTR, C_F_POINTER
   USE ModMatrixOps

   INTEGER (KIND=C_INT), VALUE, INTENT(IN) :: M1_rows, M1_cols
   INTEGER (KIND=C_INT), VALUE, INTENT(IN) :: M2_rows, M2_cols
   REAL (KIND=C_DOUBLE), POINTER :: M1_data(:) => NULL()
   REAL (KIND=C_DOUBLE), POINTER :: M2_data(:) => 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()
      PRINT "(A)", "FOR_MatrixMultiply: Error Condition Occurred."

   CALL MOD_MatrixDestroy()


#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 = 0;


   M1_rows = SvIV(Inline_Stack_Item(arg_ix++));
   M1_cols = SvIV(Inline_Stack_Item(arg_ix++));
    * Fill values for Matrix 1
   for (ix=0; ix < M1_rows*M1_cols; ix++) {
      M1_data[ix] = SvNV(Inline_Stack_Item(arg_ix++));

   M2_rows = SvIV(Inline_Stack_Item(arg_ix++));
   M2_cols = SvIV(Inline_Stack_Item(arg_ix++));
    * Fill values for Matrix 2
   for (ix=0; ix < M2_rows*M2_cols; ix++) {
      M2_data[ix] = SvNV(Inline_Stack_Item(arg_ix++));

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


Ron Grunwald

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About