IFIP

Welcome to the IFIP Working Group 2.5 Page on MLP Code

This web site contains the commands and results for all the examples in the paper "Standardized Mixed Language Programming for Fortran and C", by Bo Einarsson, Richard J. Hanson, and Tim Hopkins. The paper has been published in the ACM Fortran Forum, December 2009, Vol. 28, Issue 3, pp. 8-22.

. Link to the issue.

Regrettably two links in the references are incorrect. Here are the correct ones.

The paper is also available at the Rogue Wave site.

The paper was presented at the "IFIP Working Group 2.5 Symposium 2009" in Raleigh, N.C.

The example files are obtained by clicking on the file names. You can download all the files simultaneously by using the compressed file all.zip.

We are here using the Sun system, for other systems the names of the compilers f95 and cc may have to be modified, for example to gfortran and gcc. The name of the Sun computer in Linköping is "arkimedes".

arkimedes[code]> f95 -V
f95: Sun Fortran 95 8.3 SunOS_sparc Patch 127000-01 2007/07/18
With the Intel compiler when the main program is in C, it is recommend to link with C instead of with Fortran (with the Portland compiler it is required, if not the system complains about double main programs). Therefore use the linking below to include some Fortran utilities:
icc -lifcore <etc.>
or
pgcc -pgf90libs <etc.>

Introduction

arkimedes[code]> f95 CandF.f90
arkimedes[code]> ./a.out
Default Fortran and C variables of type integer/int are interoperable
Default Fortran and C variables of type real/float are interoperable
Default Fortran and C variables of type double precision/double are interoperable
Default Fortran and C variables of type logical/boolean are NOT interoperable
Default Fortran and C variables of type character/char are interoperable
Default Fortran and C variables of type complex/float_complex are interoperable
NOTE: The Portland compiler pgf90 8.0-5 did not work properly in this case, a similar error message to the one below was generated. There was however no error message generated from pgf95 9.0-2, since it is logically correct that the KIND numbers -1 and 4 are not equal.
arkimedes[code]> f95 wrapper.f90
./a.out 
T T 
F F
NOTE: The Portland compilers pgf90 8.0-5 and pgf95 9.0-2 did not work properly in this case. We got the error message
pgf90 -c wrapper.f90 
PGF90-S-0081-Illegal selector - KIND value must be non-negative
(wrapper.f90: 5)
  0 inform,   0 warnings,   1 severes, 0 fatal for wrapper
Negative KIND numbers indicate that the corresponding data type has not been implemented.

Section 1

Only Fortran
arkimedes[code]> f95 f2sam.f90 sam.f90
f2sam.f90: 
sam.f90: 
Linking: 
arkimedes[code]> ./a.out  
    6  648          Bo G E  
Fortran and C mixed (some systems require linking with C)
arkimedes[code]> cc -c c2sam.c
arkimedes[code]> f95 c_sam.f90 sam.f90 c2sam.o  
c_sam.f90: 
sam.f90: 
Linking: 
arkimedes[code]> ./a.out  
 6 648 Bo G E   

Section 2

arkimedes[code]> cc -c mlp4.c
arkimedes[code]> f95 mlp3.f90 mlp4.o  
arkimedes[code]> ./a.out  
       1,3 
NOTE: This will not work with the Portland compiler, since the Fortran 2003 command "dc" for decimal comma is not implemented as of version 9.0-2. It is trivial to remove ",dc" from the Fortran source.

Section 3

Only Fortran
arkimedes[code]> f95 mlp0.f90 mlp2a.f90
mlp0.f90:
mlp2a.f90:
Linking:
arkimedes[code]> ./a.out
 786     3.200 
Fortran and C mixed, elementary version (some systems require linking with C)
arkimedes[code]> cc -c mlp1.c
arkimedes[code]> f95 mlp2b.f90 mlp1.o
arkimedes[code]> ./a.out  
 786     3.200 
Fortran and C mixed, recommended version
arkimedes[code]> cc -c mlp7.c
arkimedes[code]> f95 mlp6.f90 mlp7.o
arkimedes[code]> ./a.out
Fortran has common block /com/  786  3.20 
C gets Common block /com/: 786 3.200000  
 C gives Common block /com/: 457 17.500000  
 Fortran has the block /com/  457 17.50 

Section 4

Only C
arkimedes[code]> cc c_mean.c mean.c
c_mean.c: 
mean.c: 
arkimedes[code]> ./a.out  
 Mean value is  2.000000  
Fortran and C mixed
arkimedes[code]> cc -c mean.c
arkimedes[code]> f95 mlp8.f90 mean.o
arkimedes[code]> ./a.out  
  Mean value computed by C is  2.0

Section 5

Fortran and C mixed
arkimedes[code]> cc -c c_sgemm.c
arkimedes[code]> f95 sgemm_driver.f90 sgemm.f90 c_sgemm.o
sgemm_driver.f90:
sgemm.f90:
Linking:
arkimedes[code]> ./a.out
 Values of adjoint flags TRANSA, TRANSB = N,n
 Values of sizes m,n,k,lda,ldb and ldc = 4,3,2,5,3,5
 Values of alpha, beta = 5.000000e-01, 1.000000e-01
Value of i,j and A(i,j) = 1, 1, 1.100000e+00
Value of i,j and A(i,j) = 2, 1, 2.100000e+00
Value of i,j and A(i,j) = 3, 1, 3.100000e+00
Value of i,j and A(i,j) = 4, 1, 4.100000e+00
Value of i,j and A(i,j) = 1, 2, 1.200000e+00
Value of i,j and A(i,j) = 2, 2, 2.200000e+00
Value of i,j and A(i,j) = 3, 2, 3.200000e+00
Value of i,j and A(i,j) = 4, 2, 4.200000e+00

Value of i,j and B(i,j) = 1, 1, 1.100000e+00
Value of i,j and B(i,j) = 2, 1, 2.100000e+00
Value of i,j and B(i,j) = 1, 2, 1.200000e+00
Value of i,j and B(i,j) = 2, 2, 2.200000e+00
Value of i,j and B(i,j) = 1, 3, 1.300000e+00
Value of i,j and B(i,j) = 2, 3, 2.300000e+00

Value of i,j and C(i,j) = 1, 1, 1.866000e+00
Value of i,j and C(i,j) = 2, 1, 3.466000e+00
Value of i,j and C(i,j) = 3, 1, 5.066000e+00
Value of i,j and C(i,j) = 4, 1, 6.665999e+00
Value of i,j and C(i,j) = 1, 2, 1.981000e+00
Value of i,j and C(i,j) = 2, 2, 3.681000e+00
Value of i,j and C(i,j) = 3, 2, 5.381001e+00
Value of i,j and C(i,j) = 4, 2, 7.081000e+00
Value of i,j and C(i,j) = 1, 3, 2.096000e+00
Value of i,j and C(i,j) = 2, 3, 3.896000e+00
Value of i,j and C(i,j) = 3, 3, 5.696000e+00
Value of i,j and C(i,j) = 4, 3, 7.495999e+00
 Largest difference:  4.7683715E-7
 Relative error:      6.361222E-8
arkimedes[code]> 
NOTE: These last two values are implementation dependent!

In practice also some helper functions have to be called in addition to cublasSgemm. That version in a preliminary form is sss_sgemm.f90.

Section 6

We note that the enumerator concept is not included with Sun Fortran 8.3 or with Portland pgf90 8.0-5 (but with pgf95 9.0-2), hence the following is for a Linux computer "sibel" using g95.

Only Fortran

boein@sibel:~/Ex8$ g95 enumdefs.f90 f_print_days.f90 f_main.f90
boein@sibel:~/Ex8$ ./a.out
month  7 has 31 days
month  2 has 28 or 29 days
boein@sibel:~/Ex8$ 
Fortran as the main language and routine in C
boein@sibel:~/Ex8$ cc -c c_print_days.c
boein@sibel:~/Ex8$ g95 enumdefs.f90 c_print_days.o f_main.f90
boein@sibel:~/Ex8$ ./a.out
month  7 has 31 days
month  2 has 28 or 29 days
boein@sibel:~/Ex8$
C as the main language and routine in Fortran (some systems require linking with C)
boein@sibel:~/Ex8$ cc -c c_main.c
boein@sibel:~/Ex8$ g95 enumdefs.f90 f_print_days.f90 c_main.o
boein@sibel:~/Ex8$ ./a.out
month  7 has 31 days
month  2 has 28 or 29 days
boein@sibel:~/Ex8$
It also works with gfortran, but then an error message is generated:
SUBROUTINE print_days(month) BIND(C, NAME='printDays')
                           1
Warning: Variable 'month' at (1) is a parameter to the BIND(C)
procedure 'print_days' but may not be C interoperable.
This seems to be in violation with that the standard guarantees that constants declared as type enumerator will correspond to the same integer type used by C, int.

Remark 1

A reader using Windows Vista and g++ and gfortran has noted that the standard codes in section 4 did not work.

A solution was to in the code of mean.c replace

extern float mean (float x, float y);
with
extern "C"
followed by parenthesis { } around the remaining code.
Last modified: November 28, 2012
This website is sponsored by the National Supercomputer Centre in Linköping, Sweden.
Bo Einarsson, boein@nsc.liu.se