compiling and running a single OpenMP source file with several other non-OpenMP source files - fortran

I'm trying to compile multiple FORTRAN source files, where I applied some OpenMP directives to one of the source files. For instance :
The compilation flags :
COMPILE00='ifort -O3 -openmp -openmp_report -fpconstant -fp-model precise -fpe0 -traceback -ftrapuv'
COMPILE0='ifort -O3 -fpconstant -fp-model precise -fpe0 -traceback -ftrapuv'
The compiled files :
$COMPILE0 -c microprm.F90 modules.F90
$COMPILE0 -c jernewf3p_A.F90 SMAX.F90 DE_MOTT.F90 twoinitm.F90 helek03.F90
$COMPILE00 -c helek04.F90
$COMPILE0 -c jernewf3p_melt.F90 dmin_G.F90
$COMPILE0 -c submelt_condevap.F90
Linking :
$COMPILE00 -o TKE.x *.o -lm
So the source code helek04.F90 has some OpenMP directives. It is being called from submelt_condevap.F90 which hasn't.
Is this correct compilation practice ? How should I compile it using the use omp_lib module ? Is it code-safe to compile only one file with OpenMP and link all the others with OpenMP ?
The compilation was aborted. When compiling with $COMPILE00 for ALL the files, the simulation runs, but gets a floating point exception, which doesn't occur in the serial code.

There are couple of issues that can arise. Unfortunately your description is not detailed enough. I would generally recommend to use -openmp for all files, I don't see a reason for making a distinction. Intel Fortran by default does not make the code reentrant and if you call a subroutine that has not been compiled with -openmp from the parallel region race conditions can occur. Especially during I/O operations problems are quite likely. If you have some strange reason to avoid -openmp you can try -reentrancy threaded.
If there are no calls to other code from the parallel part, and it does not run concurrently with the non-parallel part, there shouldn't be issues with it.
It is quite possible you have some race condition or other threading problem in your OpenMP code. Use tools included in your compiler collection to debug them. Intel Inspector XE is a good tool for these kinds of problems. Use options like -warn -check -g -traceback to have some useful checks. Valgrind can also be useful.

Related

Is there a Gfortran flag similar to intel ifort's -ipo-c, that would generate single optimized object from all compiled files?

Intel Fortran compiler/linker has the optional flag -ipo-c or /Qipo-c which enables the generation of a single interprocedurally-optimized object file from all files, which can be later used for linking. Is there an equivalent flag to Intel's -ipo-cin gfortran?
GCC has -fwhole-program, does that work for gfortran?
Or if you don't want to pass all the Fortran source files on one giant command line, there's -flto link-time optimization which uses a linker "plugin" to run the optimizer on GIMPLE stored in .o files (instead of or as well as machine code).
LTO means you should pass all your optimization options to the invocation of gfortran that does the linking, as well as the gfortran -c that compiles to .o.
So you might use gfortran -ffast-math -O3 -march=native -flto to compile and link, assuming gfortran supports the same options as gcc. (And that -march=native is what you want: make an executable optimized for the computer you compiled on, which might SIGILL on other computers without all the ISA extensions this one supports.)

Code size is doubled when compiling with GCC ARM Embedded?

I've just ported a STM32 microcontroller project from Keil uVision (using Keil ARM Compiler) to CooCox CoIDE (using GCC ARM Embedded compiler).
Problem is, the code size is the double size when compiled in CoIDE with GCC compared to Keil uVision.
How can this be? What can I do?
Code size in Keil: 54632b (.text)
Code size in CoIDE: 100844b (.text)
GCC compiler flags:
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -g2 -Wl,-Map=project.map -Os
-Wl,--gc-sections -Wl,-TC:\arm-gcc-link.ld -g -o project.elf -L -lm
I am suspecting CoIDE and GCC to compile a lot of functions and files, that are present in the project, though aren't used (yet). Is it possible that it compiles whole files even if I only use 1 function out of 20 in there? (even though I have -Os)..
Hard to say which files are really compiled/linked in your final binary from the information you give. I suppose it takes all the C files it finds on your project if you did not explicitly specified which one to compile or if you don't use your own Makefile.
But from the compiler options you give, the linker flag --gc-sections won't do much garbage if you don't have the following compiler flags: -ffunction-sections -fdata-sections. Try to add those options to strip all unused functions and data at link time.
Since the question was tagged with C++, I wonder if you would like to disable exceptions and RTTI. Those take quite a bit of code. Add -fno-exceptions -fno-rtti to linker flags.

What is the -O5 flag for compiling gfortran .f90 files?

I see the flag in the documentation of how to compile some f90 code I have acquired (specifically, mpfi90 -O5 file.f90), but researching the -O5 flag turned up nothing in the gfortran docs, mpfi docs, or anywhere else. I assume it is an optimization flag like -O1, etc., but I'm not sure.
Thanks!
Source: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.xlf91a.doc%2Fxlfug%2Fhu00509.htm
The flag -O5 is an optimizer like -O3 and -O2. The linked source says,
qnoopt/-O0 Fast compilation, debuggable code, conserved program
semantics.
-O2 (same as -O) Comprehensive low-level optimization; partial debugging support.
-O3 More extensive optimization; some precision trade-offs.
-O4 and -O5 Interprocedural optimization; loop optimization; automatic machine tuning.
With each higher number containing all the optimizations of the lower levels.

What is the difference between -O0 ,-O1 and -g

I am wondering about the use of -O0,-O1 and -g for enabling debug symbols in a lib.
Some suggest to use -O0 to enable debug symbols and some suggest to use -g.
So what is the actual difference between -g and -O0 and what is the difference between -01 and -O0 and which is best to use.
-O0 is optimization level 0 (no optimization, same as omitting the -O argument)
-O1 is optimization level 1.
-g generates and embeds debugging symbols in the binaries.
See the gcc docs and manpages for further explanation.
For doing actual debugging, debuggers are usually not able to make sense of stuff that's been compiled with optimization, though debug symbols are useful for other things even with optimization, such as generating a stacktrace.
-OX specify the optimisation level that the compiler will perform. -g is used to generate debug symbols.
From GCC manual
http://gcc.gnu.org/onlinedocs/
3.10 Options That Control Optimization`
-O
-O1
Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for a large function. With -O, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.`
-O2
Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. As compared to -O, this option increases both compilation time and the performance of the generated code.`
-O3
Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload, -ftree-vectorize and -fipa-cp-clone options.`
-O0
Reduce compilation time and make debugging produce the expected results. This is the default. `
-g
Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF 2). GDB can work with this debugging information.`
-O0 doesn't enable debug symbols, it just disables optimizations in the generated code so debugging is easier (the assembly code follows the C code more or less directly). -g tells the compiler to produce symbols for debugging.
It's possible to generate symbols for optimized code (just continue to specify -g), but trying to step through code or set breakpoints may not work as you expect because the emitted code will likely not "follow along" with the original C source closely. So debugging in that situation can be considerably trickier.
-O1 (which is the same as -O) performs a minimal set of optimizations. -O0 essentially tells the compiler not to optimize. There are a slew of options that allow a very fine control over how you might want the compiler to perform: http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Optimize-Options.html#Optimize-Options
As mentioned by others, -O set of options indicate the levels of optimization that must be done by the compiler whereas, the -g option adds the debugging symbols.
For a more detailed understanding, please refert to the following links
http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options
http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging-Options

F77: problem to compile with g77 a program which was normally compiled with Absoft compiler

I am not a Fortran programmer (just a short experience), but I need to compile a program partly written in F77. Someone has compiled it with Absoft compiler before me, but now I need to repeat the procedure on another machine with g77. For Absoft, the makefile has
f77 -f -w -O -B100 -B108 -c *.f
mv *.f flib && mv *.o olib
f77 -B100 -o runme olib/*.o clib/*.o -L/usr/X11R6/lib64 -L/usr/X11R6/lib -lX11 -L$PVM_ROOT/lib/$PVM_ARCH -lfpvm3 -lpvm3 -L$ABSOFT/lib -lU77
I have modified these lines to be
g77 -w -O -B100 -B108 -c *.f
mv *.f flib && mv *.o olib
g77 -B100 -o runme olib/*.o clib/*.o -L/usr/X11R6/lib64 -L/usr/X11R6/lib -lX11 -L$PVM_ROOT/lib/$PVM_ARCH -lfpvm3 -lpvm3 -lgfortran -lgfortranbegin
But I get the following error messages
somefile.f:(.text+0x93): undefined reference to `for_open'
somefile.f:(.text+0xf4): undefined reference to `for_write_seq_fmt'
somefile.f:(.text+0x128): undefined reference to `for_write_seq_fmt_xmit'
somefile.f:(.text+0x454): undefined reference to `for_read_seq'
How can I fix this?
UPDATE1
If I add -libifcore to the end of the last line (linker), then I get
/usr/bin/ld: cannot find -libifcore
I have located the library
$ find /opt/intel/* -name 'libifcore*'
/opt/intel/fce/9.1.036/lib/libifcore.a
/opt/intel/fce/9.1.036/lib/libifcore.so
/opt/intel/fce/9.1.036/lib/libifcore.so.5
/opt/intel/fce/9.1.036/lib/libifcore_pic.a
/opt/intel/fce/9.1.036/lib/libifcoremt.a
/opt/intel/fce/9.1.036/lib/libifcoremt.so
/opt/intel/fce/9.1.036/lib/libifcoremt.so.5
/opt/intel/fce/9.1.036/lib/libifcoremt_pic.a
But even if I do the following in the source directory
$ export PATH=$PATH:/opt/intel/fce/9.1.036/lib/
$ ln -s /opt/intel/fce/9.1.036/lib/libifcore.so
it is not found.
Moreover, it is the same machine where I get another problem How to pass -libm to MPICC? libimf.so: warning: feupdateenv is not implemented and will always fail
It seems that the compiler should find the library, if needed
$ echo $LD_LIBRARY_PATH
/opt/intel/fce/9.1.036/lib:/opt/intel/cce/9.1.042/lib:/usr/local/lib/openmpi:/usr/local/lib:/usr/lib:
Absoft accepted an extended version of Fortran 77 that is not completely compatible with the extended version of Fortran 77 accepted by g77.
So there is no guarantee that you can do this without editing the code. I seem to recall that the Absoft compiler accepted a handy initialization syntax that can not be replicated with g77.
If you want to compile & link using g77, the easiest way is to use the command "g77". (What compiler does f77 invoke on your computer? Try "f77 -v" or similar to find out...) It should automatically find the g77 Fortran-specific libraries. You should not need to explicitly link to Fortran libraries, and especially not to the libraries of gfortran, which is a different compiler. You could also compile & link with gfortran -- it will probably recognize that the source code is Fortran 77 and compile appropriately if the files have the correct file type, otherwise you will have to use options -- for this compiler, use the command "gfortran".
With g77 and gfortran it should not need Intel libraries -- maybe f77 is connected to ifort, the Intel compiler, on your computer?
Edited later:
I suggest trying something simpler first to test your setup.
Try this FORTRAN 77 program as file "junk.f"
C234567
write (6, *) "Hello World"
stop
end
Try this command:
g77 junk.f -o junk.exe
Run it via:
./junk.exe
This will test whether g77 is working.
it looks like you are trying to link with libifcore.
Edit:
You can include this library by adding
'-lifcore' to your compiler options. To quote the gcc tutorial
In general, the compiler option -lNAME will attempt to link object files with a library file ‘libNAME.a’ in the standard library directories.
why do you use g77 and not gfortran?
what do you mean with multiprocessing? openmp or vectorized?
you can use openmp with the gfortran compiler and when you want to use vector mode like the ifort compiler does, you have to specify sse explicitly in the compiler options.
It seems that the problem was in an error in one of the source files, which wasn't a big deal for Absoft compiler. g77 was giving a warning about it, but compiling this file and producing the original errors (mentioned in the question) without a binary.
When I tried ifort, compilation of that file was aborted, but other files were compiled and a binary was created.
fortcom: Error: somefile.f, line 703: An extra comma appears in the format list. [)]
& (1p5e12.3,5h ...,))
-------------------------^
compilation aborted for somefile.f (code 1)
When I removed the extra comma, then both compilers have compiled everything and created binaries, although ifort produced a number of warnings.
Then, when I tried to run both binaries, the one made by Intel comiler was working fine, but the one by g77 was behaving very strange and didn't really do what I wanted.
So now the original problem is resolved, however the code doesn't run in multiprocessing mode, so the binary is unfortunately useless for me.