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. Cheers, Ron. #!/usr/local/ActivePerl/bin/perl # use strict; use warnings; use Inline F2003 => Config => ( SOURCE => "ModMatrixOps.f03", LIBRARY => "libMatrixOps.so", 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/libMatrixOps.so", 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 ); } __DATA__ __F2003__ SUBROUTINE FOR_MatrixMultiply (M1_rows, M1_cols, C_M1_data, & M2_rows, M2_cols, C_M2_data ) & BIND(C, NAME="FOR_MatrixMultiply") USE, INTRINSIC :: ISO_C_BINDING, & ONLY : C_INT, C_DOUBLE, C_PTR, C_F_POINTER USE ModMatrixOps IMPLICIT NONE 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() 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 = 0; Inline_Stack_Vars; 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 ); Inline_Stack_Void; } ________________________________________ Ron Grunwald ron...@yahoo.com.au http://www.dvlcorner.org