Commit df8da932 authored by thomas.forbriger's avatar thomas.forbriger Committed by thomas.forbriger
Browse files

completely documented Fortran 77 considerations

This is a legacy commit from before 2015-03-01.
It may be incomplete as well as inconsistent.
See COPYING.legacy and README.history for details.


SVN Path:     http://gpitrsvn.gpi.uni-karlsruhe.de/repos/TFSoftware/trunk
SVN Revision: 1238
SVN UUID:     67feda4a-a26e-11df-9d6e-31afc202ad0c
parent 7d31ed2d
......@@ -3,7 +3,7 @@
*
* ----------------------------------------------------------------------------
*
* $Id: README.changelog,v 1.22 2002-12-27 13:12:17 forbrig Exp $
* $Id: README.changelog,v 1.23 2002-12-27 16:18:05 forbrig Exp $
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
......@@ -21,14 +21,14 @@
/*! \page page_changelog ChangeLog (AFF)
$Id: README.changelog,v 1.22 2002-12-27 13:12:17 forbrig Exp $
$Id: README.changelog,v 1.23 2002-12-27 16:18:05 forbrig Exp $
\sa \ref page_project_status
Major changes in the interface of the library are marked by \b !!.
- \b 27/12/2002 (thof)
- continued with Fortran interface documentation (\ref page_fortran)
- completed Fortran interface documentation (\ref page_fortran)
- \b 23/12/2002 (thof)
- coded class aff::Subarray
......@@ -96,7 +96,7 @@
/*! \page page_project_status Project status (AFF)
$Id: README.changelog,v 1.22 2002-12-27 13:12:17 forbrig Exp $
$Id: README.changelog,v 1.23 2002-12-27 16:18:05 forbrig Exp $
\sa \ref page_changelog
......@@ -256,23 +256,23 @@
<TD>does not check pathological cases</TD>
</TR>
<TR><TD>libaff/tests/f77common.inc</TD>
<TD>23/12/02</TD><TD> </TD><TD>23/12/02</TD>
<TD>23/12/02</TD><TD>27/12/02</TD><TD>23/12/02</TD>
<TD> </TD>
</TR>
<TR><TD>libaff/tests/f77interface.cc</TD>
<TD>23/12/02</TD><TD> </TD><TD>23/12/02</TD>
<TD>23/12/02</TD><TD>27/12/02</TD><TD>23/12/02</TD>
<TD> </TD>
</TR>
<TR><TD>libaff/tests/f77procs.f</TD>
<TD>23/12/02</TD><TD> </TD><TD>23/12/02</TD>
<TD>23/12/02</TD><TD>27/12/02</TD><TD>23/12/02</TD>
<TD> </TD>
</TR>
<TR><TD>libaff/tests/f77proto.h</TD>
<TD>23/12/02</TD><TD> </TD><TD>23/12/02</TD>
<TD>23/12/02</TD><TD>27/12/02</TD><TD>23/12/02</TD>
<TD> </TD>
</TR>
<TR><TD>libaff/tests/f77test.cc</TD>
<TD>23/12/02</TD><TD> </TD><TD>23/12/02</TD>
<TD>23/12/02</TD><TD>27/12/02</TD><TD>23/12/02</TD>
<TD> </TD>
</TR>
</TABLE>
......
......@@ -3,7 +3,7 @@
*
* ----------------------------------------------------------------------------
*
* $Id: README,v 1.8 2002-12-27 13:12:20 forbrig Exp $
* $Id: README,v 1.9 2002-12-27 16:18:07 forbrig Exp $
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
......@@ -19,7 +19,7 @@
* - 20/12/2002 V1.1 (thof)
* - complete revision of this file
* - 27/12/2002 V1.2 (thof)
* - continued with Fortran considerations
* - completed Fortran considerations
*
* ============================================================================
*/
......@@ -203,16 +203,133 @@ Aspects to consider:
-# passing fixed array dimensions from Fortran to C++
-# passing variable array dimensions from Fortran common block to C++
-# how to satisfy linker with a MAIN__ function
-# compiling f2c output with gcc (using -C++ option)
-# compiling f2c output with g++ (using -C++ option)
/*----------------------------------------------------------------------*/
\section sec_fortran_call Passing arrays through function calls
An example for passing AFF data to a Fortran function is given in
f77interface::fill. The interface function is defined in
tests/f77interface.cc. It is declared
\code
int f77interface::fill(const aff::Array<int>& a)
\endcode
The Array is converted into an aff::FortranArray by
\code aff::FortranArray<int> fa(a); \endcode
within the function.
From this the function retrieves the appropriate Fortran layout of the
array.
In case the Fortran code is modfified we only have to keep track within the
interface module (i.e. tests/f77interface.cc and tests/f77proto.h).
Aspects that had to be considered:
- The corresponding Fortran subroutine in tests/f77procs.f is compiled by
f2c and g++. Hence we pass the -C++ option to f2c.
- We have to link against libf2c.a and libm.a or their dynamic companions.
- We have to provide a MAIN__() function in our code to satisfy the
linker (discovered by wolle). This function, however is never called.
It must be declared with \c extern \c "C" linkage.
- For calling the Fortran functionality we provide an extra C++ interface.
This interface is presented in tests/f77proto.h and namespace
f77interface. The definitions are coded in tests/f77interface.cc.
- To ensure synchronous code between Fortran and the C++ interface, we use
prototypes written by f2c. They are generated by
\verbatim f2c -C++ -P -\!c tests/f77procs.f \endverbatim
to file tests/f77procs.P
- The prototypes are not declared with external C linkage. Therefore the
correspnding include section in tests/f77interface.cc reads like
\code extern "C" { #include "f77procs.P" } \endcode
- Additionally we must include \c f2c.h in tests/f77interface.cc.
- Within f77interface::fill type conversion must take place. The array
shape is derived as C++ \c int values. They are converted to values of
type \c integer (defined in f2c.h) with statements like
\code integer n1=fa.last(0); \endcode
and passed to the Fortran function as pointers of type \c integer* by
\code fill_(pa, &l1, &n1, &l2, &n2, &l3, &n3) \endcode
- The array values are access within the Fortran subroutine through a
pointer to the first element. This pointer is of type \c integer*,
which is defined as \c long \c int* in f2c.h. From the FortranArray
object we receive a pointer of type \c int*. The only way I see to
convert it is via
\code integer* pa=reinterpret_cast<integer *>(fa.pointer()); \endcode
which is a totally unchecked conversion.
We therefore additionally check the type size at runtime by
\code
AFF_assert((sizeof(integer)==sizeof(int)),
"ERROR (f77interface::fill): illegal type size!");
\endcode
Since the type size is known at compile-time, there should be a more
elegant way.
/*----------------------------------------------------------------------*/
\section sec_fortran_common Accessing arrays in common blocks
In many Fortran code modules essential array data is passed through global
common blocks between subroutines. It is possible to make this data visible
in form of an aff::Array object. However, this is slightly more complicated
than passing a C++ array to an underlying Fortran subroutine.
An example for this technique is given by the following functions:
-# f77interface::fillarray takes two 1D aff::Array<float> arguments and
passes them to the Fotran subroutine fillarray which calculates the
contents of a complex common block array from them.
-# f77interface::sums takes the result of the Fortran subroutine sums,
which calculates column-sums of the common block array, and
returns them as an aff::Array.
-# f77interface::viewcommon returns an aff::Array that offers direct
read/write access to the Fortran common block.
The interface functions are presented in tests/f77proto.h, are defined in
tests/f77interface.cc and the underlying Fortran subroutines are defined in
tests/f77procs.f. The common-block itself is defined in tests/f77common.inc.
Addtionally to the considerations for "\ref sec_fortran_call" we have to
discuss the following:
- f77interface::fillarray passes AFF arrays to Fortran code just in the
way f77interface::fill discussed above. Since Fortran doesn't know of
const-correctness it takes arguments of type
\code const aff::Array<float>& \endcode
rather than
\code const aff::Array<const float>& \endcode
(see also "\ref sec_design_const").
- f77interface::sums has to create an AFF array of appropriate size before
passing a pointer to the underlying Fortran subroutine. Since the
dimensions of fixed sized Fortran arrays are usually given by parameter
constants that are defined in include files, these values are not
accessible from the C++ code. We therefore introduced a Fortran
subroutine \c comdim, which can be used to read the dimensions of the
common-block array.
- f77interface::viewcommon creates an AFF array, which is simply a
reference to the common-block array and has appropriate shape. Shape and
representation (i.e. SharedHeap) are craeted separately. The SharedHeap
is intialized by
\code aff::SharedHeap<Tzvalue> repr(p, shape.memory_size()); \endcode
from a pointer \c p and a size in memory. Using this constructor
ensures, that SharedHeap will never try to deallocate the memory block.
- The common block definition is not visible from C++. To ensure
synchronous code after changes being applied to the Fortran code, we
must make use of automatic code generation by f2c. We use
\verbatim f2c -C++ -f -u -ec tests/f77procs.f
sed -e 's/^struct/extern struct/' tests/f77common_com.c > tests/f77common_com.P \endverbatim
to create a common block definition in tests/f77common_com.P.
This definition is read via
\code #include"f77common_com.P" \endcode
in tests/f77interface.cc.
The common block is then available as
\code struct { ... } f77common_ \endcode
with \c extern \c "C" linkage in the C++ code.
- \b Notice: The access shape of the AFF array returned by
f77interface::viewcommon is defined upon creation of the array.
Changing the actual access shape in the common block later (i.e. the
common block members \c na and \c nb), e.g. by calling subroutine
fillarray, is not reflected by the AFF array. This will first be noticed
by the next call to f77interface::viewcommon. It is the responsibility
of the programmer to avoid inconsistencies due to different access
shapes in Fortran and C++.
/*----------------------------------------------------------------------*/
\section sec_fortran_links Links to other helpful information
......
......@@ -3,11 +3,13 @@
*
* ----------------------------------------------------------------------------
*
* $Id: f77interface.cc,v 1.2 2002-12-23 18:07:32 forbrig Exp $
* $Id: f77interface.cc,v 1.3 2002-12-27 16:18:08 forbrig Exp $
* \author Thomas Forbriger
* \date 23/12/2002
*
* interface functions (implementation)
*
* \sa \ref page_fortran
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
......@@ -19,7 +21,7 @@
#define AFF_F77INTERFACE_CC_VERSION \
"AFF_F77INTERFACE_CC V1.0 "
#define AFF_F77INTERFACE_CC_CVSID \
"$Id: f77interface.cc,v 1.2 2002-12-23 18:07:32 forbrig Exp $"
"$Id: f77interface.cc,v 1.3 2002-12-27 16:18:08 forbrig Exp $"
// include assertions
#include<aff/lib/error.h>
......
......@@ -3,16 +3,21 @@
*
* ----------------------------------------------------------------------------
*
* $Id: f77proto.h,v 1.3 2002-12-23 18:07:32 forbrig Exp $
* $Id: f77proto.h,v 1.4 2002-12-27 16:18:08 forbrig Exp $
* \author Thomas Forbriger
* \date 22/12/2002
*
* prototypes for Fortran interface (prototypes)
*
* \sa \ref page_fortran
* \sa f77interface
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
* REVISIONS and CHANGES
* - 22/12/2002 V1.0 Thomas Forbriger
* - 27/12/2002 V1.1 (thof)
* - now provides some documentation
*
* ============================================================================
*/
......@@ -21,24 +26,64 @@
#ifndef AFF_F77PROTO_H_VERSION
#define AFF_F77PROTO_H_VERSION \
"AFF_F77PROTO_H V1.0 "
"AFF_F77PROTO_H V1.1"
#define AFF_F77PROTO_H_CVSID \
"$Id: f77proto.h,v 1.3 2002-12-23 18:07:32 forbrig Exp $"
"$Id: f77proto.h,v 1.4 2002-12-27 16:18:08 forbrig Exp $"
#include<aff/array.h>
#include<complex>
//! This namespace collects all test functions for interfacing Fortran 77
/*! \brief This namespace collects all test functions for interfacing Fortran 77
*
* \sa \ref page_fortran
* \sa tests/f77test.cc
* \sa tests/f77interface.cc
*/
namespace f77interface {
typedef aff::Array<std::complex<float> > Tcarray;
typedef aff::Array<std::complex<double> > Tzarray;
/*! \brief fill an AFF array thorugh a Fortran subroutine
*
* An aff::Array<int> object is passed to the Fortran subroutine fill and is
* filled with values there.
* The concept is discussed on page "\ref page_fortran".
*/
int fill(const aff::Array<int>& fa);
/*! \brief fill the Fortran common-block array
*
* Two aff::Array<float> objects are passed to the Fortran subroutine
* fillarray which calculates complex values from the elements of these arrays
* and fills the array in common-block \c f77common which is defined in
* tests/f77common.inc.
*
* The concept is discussed on page "\ref page_fortran".
*/
int fillarray(const aff::Array<float>& v1,
const aff::Array<float>& v2);
/*! \brief returns results from Fortran subroutine sums
*
* The Fortran subroutine sums calculates column-sums from the array in the
* common block. These values are return in an
* \code aff::Array<std::complex<float> > \endcode object.
*
* The concept is discussed on page "\ref page_fortran".
*/
Tcarray sums();
/*! \brief returns direct access to Fortran common block
*
* This function returns a
* \code aff::Array<std::complex<double> > \endcode object, which offers
* direct read/write access to the array in the Fortran common block
* f77common.
*
* The concept is discussed on page "\ref page_fortran".
*/
Tzarray viewcommon();
} // namespace f77interface
......
......@@ -3,11 +3,13 @@
*
* ----------------------------------------------------------------------------
*
* $Id: f77test.cc,v 1.4 2002-12-23 18:07:32 forbrig Exp $
* $Id: f77test.cc,v 1.5 2002-12-27 16:18:08 forbrig Exp $
* \author Thomas Forbriger
* \date 22/12/2002
*
* test interfacing Fortran code (implementation)
*
* \sa \ref page_fortran
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
......@@ -23,12 +25,13 @@
* from Fortran 77 common blocks.
*
* \sa tests/f77test.cc
* \sa \ref page_fortran
*/
#define AFF_F77TEST_CC_VERSION \
"AFF_F77TEST_CC V1.0 "
#define AFF_F77TEST_CC_CVSID \
"$Id: f77test.cc,v 1.4 2002-12-23 18:07:32 forbrig Exp $"
"$Id: f77test.cc,v 1.5 2002-12-27 16:18:08 forbrig Exp $"
#include <aff/array.h>
#include <aff/fortranshape.h>
......@@ -55,7 +58,10 @@ void section(const char* s, const char l='-')
/*======================================================================*/
//! test array interface to Fortran 77
/*! \brief test array interface to Fortran 77
*
* \sa \ref page_fortran
*/
int main()
{
cout << AFF_F77TEST_CC_VERSION << endl;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment