I'm asked to give input to a discussion in our research group (see URL below)
about a switch to Fortran 90 constructs / features for our model code.
I'm trying to determine whether we would likely meet any problems using
modules.
The central point of my concern is that I have gotten the impression from
posts to this group that different compilers deal with them in different ways
- however, because I never used them myself, I simply don't know.
Since we have to support the model code on machines as different as Fujitsu
VPP, NEC SX, Cray (both PVP and T3E), Sun's, SGI's, Alpha's and Linux, we're
a bit weary to have to deal with differences between compilers (having to
support all sorts of compiler directives for parallellisation and
vectorisation is hard enough).
So I would appreciate answers to the following questions - I'll post a
summary if there's interest:
1. Do compilers (pre?)compile modules, and if yes, where do they
leave the precompiled code and what are the file name extensions
of those files ?
2. How does one specify the dependence between (precompiled) modules
and the source files that depend on them in Makefiles ?
3. What is the file extension used for module source code files
themselves ?
4. Where does the compiler "look" for USEd modules ?
Thanks in advance,
--
Toon Moene (mailto:to...@moene.indiv.nluug.nl)
Saturnushof 14, 3738 XG Maartensdijk, The Netherlands
Phone: +31 346 214290; Fax: +31 346 214286
g77 Support: mailto:for...@gnu.org; NWP: http://www.knmi.nl/hirlam
Yes.
...
> 1. Do compilers (pre?)compile modules,
??? they compile them; don't know what you mean by precompile.
> and if yes, where do they
> leave the precompiled code
In a .o file; in addition they may create other files that have
to be present. But f90 doesn't dictate that this must happen,
and certainly doesn't dictate naming conventions for these other
files, and actual naming conventions vary all over the place.
...
> 2. How does one specify the dependence between (precompiled) modules
> and the source files that depend on them in Makefiles ?
If by "module" files you mean these extra files, it's hard to
specify them because they need not exist.
> 3. What is the file extension used for module source code files
> themselves ?
A source code file containing a module is named exactly the way
any other fortran file is named; this depends on your OS. Common
choices are <name>.f, <name>.for and <name>.f90.
> 4. Where does the compiler "look" for USEd modules ?
Depends on the development environment. On most UNIX systems, USE
works a bit like INCLUDE, at least conceptually.
To get at what I think you're trying to ask, let me propose two
ways to go: the easy way and the hard way.
1. The Easy Way. Put each module in a source file by itself. Make
each .f file that USEs modules dependent upon all the .o files
for the modules it uses. In a Makefile, we'd have dependency
lines that look like this:
user.o: user.f90 mod1.o mod2.o # if user.f90 USEs mod1 and mod2
mod1.o: mod1.f90
mod2.o: mod2.f90 mod1.o # if mod2 USEs mod1
Advantages: it's easy and it works. Disadvantage: if, in fact,
compiling mod1.f90 produces mod1.o and also a file called mod1.mod,
and if "USE mod1" is implemented by the compiler as "INCLUDE
mod1.mod"
(or something like that), then a change in the *code* of mod1 which
does not cause a change in the *interface* info in mod1.mod will
cause user.o to be remade even though it really doesn't have to be.
2. The Hard Way. See my recent posting on this subject for info on
how to avoid unnecessary f90 recompilation using make. Advantages:
seems to work, given systems in which USE is implemented somewhat
analogously to INCLUDE. Disadvantages: it's complicated, requires
processor-specific macros for the ".mod-file" names, it's
relatively untested, and it is pretty much guaranteed not to work
for parallel makes. Not to mention the fact that the F90 standard
does not *require* that USE be implemented more or less as INCLUDE,
which the method relies upon.
What do I do? As the inventor of The Hard Way, I nevertheless use The
Easy Way myself for large projects, pending further testing of The Hard
Way on smaller projects.
Enjoy (if that's the word I want),
-P.
--
************** In memoriam, Grandpa Jones, 1913-1998, R.I.P.
**************
* Peter S. Shenkin; Chemistry, Columbia U.; 3000 Broadway, Mail Code
3153 *
** NY, NY 10027; she...@columbia.edu; (212)854-5143; FAX: 678-9039
***
*MacroModel WWW page:
http://www.columbia.edu/cu/chemistry/mmod/mmod.html *
Can you build libraries that work?
pag:kargl[55] cat types.f90
module types
integer, parameter :: small_int = selected_int_kind(8)
end module types
pag:kargl[56] cat t.f90
program t
use types
integer(small_int) j
do j = 1,10
print*, j
enddo
end program t
pag:kargl[61] f90 -c types.f90 ; ar ruv t.a types.o
r - types.o
pag:kargl[62] f90 -o t t.f90 t.a
ld:
Archive: t.a has no table of contents (not searched)
add one with 'ar ts'
--
Steve
finger ka...@troutmask.apl.washington.edu
http://troutmask.apl.washington.edu/~clesceri/kargl.html
compiler dependent.
Sgi and Nag create both an object file (.o) per source file and a module
information file (*.mod) per module.
>
> 2. How does one specify the dependence between (precompiled) modules
> and the source files that depend on them in Makefiles ?
>
Easiest way: write the dependences in terms of object files which is a
bit of a pain in term of re-compilation but is portable amongst a wider
variety of compiler.
And use a makedepend script available on the web to update your
makefile.
(see
http://www.math.psu.edu/dna/num_methods.html
http://www.ifremer.fr/ditigo/molagnon/fortran90/engfaq.html
)
> 3. What is the file extension used for module source code files
> themselves ?
Often .mod but the name is very specific (uppercase, lowercase, trimed
name to respect a 8.3 format on dos, etc).
Shame that even a quality compiler such as Nagf95 hasn't a option to
tell, given a source file, what module information files will be
generated.
>
> 4. Where does the compiler "look" for USEd modules ?
It depends but, generally, you have to provide at the compilation a list
of paths where to look.
Often it is something like: -Ipath1 -Ipath2 or -I path1 -I path2.
One solution is to isolate in a set a few variables the needed options
of your compiler.
For instance, in your .chsrc (or whatever).
# sgi f90 7.2
setenv P_FINC_OPT '-I'
setenv P_FC 'f90'
setenv P_FFLAGS '-trapuv'
setenv P_FDEBUG '-g -trapuv -C -DEBUG:div_check=3'
And next, in the makefile something like:
FC = $(P_FC)
FINC_OPT = $(P_FINC_OPT)
# paths of libraries
# lib 2
FINC_DIR = $(FINC_OPT)../../../$(lib2)_$(VERSION2)/sources
# lib 3
FINC_DIR = $(FINC_DIR)
$(FINC_OPT)../../../$(lib3)_$(VERSION3)/sources
FFLAGS2 = $(P_FFLAGS) $(FINC_DIR)
FDEBUG = $(P_FDEBUG) $(FINC_DIR)
.f90.o:
$(FC) $(FFLAGS2) -c $<
etc...
Cheers,
Arnaud
--
_______________________________________________________________________
Arnaud Desitter
Department of Geography, University of Bristol
University Road, Bristol, BS8 1SS, United Kingdom
mailto:Arnaud....@bristol.ac.uk Fax: +44 (0)117 928 7878
http://www.ggy.bris.ac.uk/
_______________________________________________________________________
> I'm trying to determine whether we would likely meet
> any problems using modules.
If you don't take silly chances, you won't. But as pointed out by
Peter Shenkin, they may cost you a few recompilations.
> The central point of my concern is that I have gotten
> the impression from posts to this group that different
> compilers deal with them in different ways - however,
> because I never used them myself, I simply don't know.
At the semantic level, all standard-conforming compilers deal with
them in the same way. The differences lie in the intermediate
representations the compilers use when you don't compile your entire
application in one go.
> 1. Do compilers (pre?)compile modules, and if yes,
> where do they
> leave the precompiled code and what are the file
> name extensions of those files ?
All the compilers I have tried allow separate compilation of modules,
and require (some of) the results of compiling a module to be
available when compiling a USE statement referencing that module.
Cray cf90 on UNICOS stores the interface information about the module
in the .o file, along with the object code for the module. Advantage:
it's impossible for the object code and the module information to ever get
out of sync.
Other compilers use either a <module_name>.mod or a <file_name>.mod
scheme (occasionally with a suffix .kmo or .M rather than .mod). The
<module_name>.mod approach seems to be gaining ground.
One drawback is if different source files contain identically named
modules (in which case compiling one may overwrite the other's
<module_name>.mod file). So one should adopt a strict rule of one
module per source file, with the file name being the same as the
module name.
> 2. How does one specify the dependence between
> (precompiled) modules
> and the source files that depend on them in
> Makefiles ?
I find that the most portable approach is to make the source files
dependent on the modules' .o files rather than on their .mod files.
Strictly speaking, one should make them dependent on both (when
applicable), and avoid making the .mod file dependent on the
associated .o file (and vice-versa, of course). The reason for the
latter rule is that the .mod file is often produced in an earlier
compiler pass than the .o file, and will have a correspondingly
earlier time stamp.
If you autogenerate your makefiles, you should be able to tailor this
to the particular compiler being used.
> 3. What is the file extension used for module source
> code files themselves ?
I assume you mean the module auxiliary files; module source code files are
just ordinary Fortran source files, usually .f or .f90 or .for.
I've seen .o, .mod, .kmo, and heard reports of .M (Sun f90 v1).
Note that to my knowledge *no* vendor has ever made a written promise
that the .mod file only contains information about the public
interface of a module. It is possible for the .mod file to change
even when only private internal properties of the module have changed.
However, it is often possible to determine that the module's .o file
is not needed for compiling USErs of the module, in which case if a
recompilation produces a .mod file identical to the earlier one it
should be permissible not to recompile the USErs of that module.
> 4. Where does the compiler "look" for USEd modules ?
The current directory is always searched. I haven't investigated
about other places. If necessary, I would recommend making copies
or symbolic links in the current directory.
Exception: Cray cf90 on UNICOS requires a "-p file.o" on the command
line for each module USEd during the compilation.
---------------------------------------------------------------------
My personal assessment is that it's OK to use modules provided certain
precautions are taken:
1) Adhere strictly to the rule that each module should reside in its
own source file named after the module. (Some compilers will translate the
module name to all uppercase or all lowercase when generating the .mod file
name; avoid relying on case in file names.)
2) In a makefile, either make USErs' .o files depend on the module's
.o file alone, or on both the .o and the .mod file. (You may relax
this rule if the .o files are to be part of a library; but then you
would presumably make the USErs dependent on the library as a whole
rather than on its individual components.)
3) Never make modname.mod dependent on modname.o or vice-versa;
instead, write
modname.mod modname.o : modname.f90 usedmodule.o
or something like that.
4) For maximum portability, you'll need something like imake or jmake
to generate platform-dependent makefiles from a higher level
description. This holds in particular for compilers like cf90
where the USEd modules must be named on the compilation command line
and not just in the makefile dependencies line.
There is a perl script called sfmakedepend which you may find useful
for this purpose. (It unfortunately violates my rules 2 and 3, so
you may want to modify it.)
Ultimately, the problem is that Unix make is too crude to handle
languages like Fortran or Ada. (I don't know about C++. I actually
have my doubts even about C, since it is possible for a C preprocessor -D
option to change the include file dependency tree in ways the makefile may
not have foreseen.) But we'll have to live with that until someone actually
designs a better tool. I'm only worried that any such improved tool will have
to be tightly integrated with the compiler and linker, and therefore
non-portable. (I assumed that
your questions were meant to refer only to Unix-like development
environments; for anything fancier than that the answers may well
be different. I haven't tried Digital Visual Fortran on Windows 95/NT, but
from what I've read it might be an example of such a "fancier development
environment".)
I hope this is useful to others too.
Apparently, you haven't seen my other post to this thread.
Building a library with *.o files containing module definitions
can have problems (at least with Digital Unix and Digital Fortran).
> In article <6d90ta$977$1...@news.utrecht.nl.net>,
> Toon Moene <to...@moene.indiv.nluug.nl> writes:
[ Quoting Sergio Gelato ... I didn't know about this stuff until
Saturday ... ]
> > ---------------------------------------------------------------------
> > My personal assessment is that it's OK to use modules provided certain
> > precautions are taken:
> >
> > 2) In a makefile, either make USErs' .o files depend on the module's
> > .o file alone, or on both the .o and the .mod file. (You may relax
> > this rule if the .o files are to be part of a library; but then you
> > would presumably make the USErs dependent on the library as a whole
> > rather than on its individual components.)
> Apparently, you haven't seen my other post to this thread.
This could easily be - others have sent me mail copies of their posts
(perhaps I should have conducted a search on DejaNews before summarising ...)
> Building a library with *.o files containing module definitions
> can have problems (at least with Digital Unix and Digital Fortran).
Could you explain them again ? DU + DF is one of the target platforms we
support now.
Thanks in advance.
In article <6dfau0$8um$1...@news.utrecht.nl.net>,
Toon Moene <to...@moene.indiv.nluug.nl> writes:
> ka...@troutmask.apl.washington.edu (Steven G. Kargl) wrote:
>
>> In article <6d90ta$977$1...@news.utrecht.nl.net>,
>> Toon Moene <to...@moene.indiv.nluug.nl> writes:
>
>> > ---------------------------------------------------------------------
>> >
>> > 2) In a makefile, either make USErs' .o files depend on the module's
>> > .o file alone, or on both the .o and the .mod file. (You may relax
>> > this rule if the .o files are to be part of a library; but then you
>> > would presumably make the USErs dependent on the library as a whole
>> > rather than on its individual components.)
>
>> Apparently, you haven't seen my other post to this thread.
>
> This could easily be - others have sent me mail copies of their posts
> (perhaps I should have conducted a search on DejaNews before summarising ...)
>
>> Building a library with *.o files containing module definitions
>> can have problems (at least with Digital Unix and Digital Fortran).
>
> Could you explain them again ? DU + DF is one of the target platforms we
> support now.
>
pag:kargl[202] cat types.f90
module types
integer, parameter :: small_int = selected_int_kind(8)
end module types
pag:kargl[203] cat test.f90
program test
use types
integer(small_int) i
i = small_int
print *,'small_int = ', i
end program test
pag:kargl[204] f90 -o test types.f90 test.f90
pag:kargl[205] test
small_int = 4
pag:kargl[208] f90 -c types.f90
pag:kargl[209] f90 -o test test.f90 types.o
pag:kargl[210] test
small_int = 4
pag:kargl[217] ar -rs libt.a types.o
pag:kargl[218] f90 -o test test.f90 -L. -lt
ld:
Archive: ./libt.a has no table of contents (not searched)
add one with 'ar ts'
pag:kargl[219] ar ts livbt.a
types.o
pag:kargl[220] nm types.o
Name Value Type Size
_fpdata | 0000000000000000 | U | 0000000000000000
As far as I can tell, the "parameter" attribute in the declaration
contained in types.f90 is causing problems. Digital's Fortran 90
compiler interprets "parameter" in such a manner as to eliminate symbols
from the object file.