I want to know if it is possible to select different parts of my Fortran 95 routine to compile.
For example, if I pass certain flag to gfortran, then the compiler chooses which section to use for a certain function. I know I can do it using if inside the routine, but the drawback is that I don't want the program to run the if all the time due to speed concerns. I suppose solution should be similar to this one
I am working specifically with a program that calculates energies in a many-body system (say, a million). Then I don't want to put an if each time that I need to use a different energy definition at compilation time.
I hope this is possible and that my question is clear.
You can use the C like preprocessor. The -cpp command line option to your command line. That option is not turned on by default (As per Vladimir F comment below), although it looks like using the .F90 filename extension (i.e. capital F, instead of .f90) will do the trick without the -cpp option.
Details about the option:
https://gcc.gnu.org/onlinedocs/gfortran/Preprocessing-Options.html
Then you can do the same as you pointed out, so the:
#ifdef <some-var>
code when <some-var> is true
#elif defined(<other-var>)
code when <other-var> is true
#endif
As required.
There are more examples on this page with actual code.
Also, like with C/C++, you can define macros on your command line with the-D option:
gfortran -DCASE1=3 ...
This will define CASE1 with the value 3. If you do not specify the value, then 1 is automatically assigned to the macro. This is documented on the same page.
Related
I'm looking for a simple way to localize certain g++ (g++-4.9 to be specific) compile options to certain lines of code or at least targeted functions. I'm interested generally speaking, but also specifically to the -fast-math, -ffinite-math-only and -fno-signed-zeros options.
I presume that localization at the *.cpp file level is possible with make utility, but I'm hoping there is a way to enable it in the code itself, through #pragma or __attribute__ or something. I want to do this not only to minimize dependencies to external files (i.e. risk of incorrect makefile) but also to hopefully hyperlocalize certain FP behavior to specific equations within a function.
Alternatively, if localization of FP behavior by inline directives is NOT possible, what can I do to at least trigger a compile time error if desired compiler directive is NOT enabled in project build (e.g. makefile is lost or inappropriately modified).
I would presume that such inline optimization might be compiler specific, g++ in this case, but that is a compromise I'm willing to take.
In gcc you can use function attribute optimize:
void f () __attribute__ ((optimize("fast-math"), optimize("finite-math-only"), optimize("no-signed-zeros")));
I'm not sure that you are using the "localize" word correctly. Localization is related to adapting software to users of different human languages (French, Russian, Chinese...)
Perhaps you want to ask the compiler to optimize some functions with other optimization flags.
This is possible using #pragma GCC optimize etc... or using some function attributes
You might be able to turn on some bits of this with the fpmath option in a function attribute, but this was not clear to me from the docs. In light of that, I will focus on detection instead:
-fast-math already turns on -ffinite-math-only, so you don't need to worry about that. The docs for -fast-math say:
This option causes the preprocessor macro FAST_MATH to be
defined.
Which means it can be detected via
#ifndef __FAST_MATH__
#error "The -fast-math compiler option is required"
#endif
I have not yet found a compile-time way to detect the presence of -fno-signed-zeros
I'm using Fortran for my research and sometimes, for debugging purposes, someone will insert in the code something like this:
write(*,*) 'Variable x:', varx
The problem is that sometimes it happens that we forget to remove that statement from the code and it becomes difficult to find where it is being printed. I usually can get a good idea where it is by the name 'Variable x' but it sometimes happens that that information might no be present and I just see random numbers showing up.
One can imagine that doing a grep for write(*,*) is basically useless so I was wondering if there is an efficient way of finding my culprit, like forcing every call of write(*,*) to print a file and line number, or tracking stdout.
Thank you.
Intel's Fortran preprocessor defines a number of macros, such as __file__ and __line__ which will be replaced by, respectively, the file name (as a string) and line number (as an integer) when the pre-processor runs. For more details consult the documentation.
GFortran offers similar facilities, consult the documentation.
Perhaps your compiler offers similar capabilities.
As has been previously implied, there's no Fortran--although there may be a compiler approach---way to change the behaviour of the write statement as you want. However, as your problem is more to do with handling (unintentionally produced) bad code there are options.
If you can't easily find an unwanted write(*,*) in your code that suggests that you have many legitimate such statements. One solution is to reduce the count:
use an explicit format, rather than list-directed output (* as the format);
instead of * as the output unit, use output_unit from the intrinsic module iso_fortran_env.
[Having an explicit format for "proper" output is a good idea, anyway.]
If that fails, use your version control system to compare an old "good" version against the new "bad" version. Perhaps even have your version control system flag/block commits with new write(*,*)s.
And if all that still doesn't help, then the pre-processor macros previously mentioned could be a final resort.
Can any one tell me which function in gcc source code is responsible for finding a macro in C file and repalce it with actual value ?
I want to know the function as I have to take log by making changes to it, so that at the end my log file will contain where all macro is used and its line number .
It's done by the preprocessor, prior to generating the output file. If you want to see what it is doing, try gcc -E
From man gcc:
-E Stop after the preprocessing stage; do not run the compiler proper.
The output is in the form of preprocessed source code, which is sent to
the standard output.
I recommend using clang for this type of task. It is pretty well documented and you don't need to change its source, as it's extendable with a plugin system.
In your case you create a plugin based on the PPCallbacks class and override its MacroExpanded method, and any other method you find useful. This is an easy starting point.
Is there an option that the GCC preprocessor could generate C source code and filter out irrelevant source code?
For example, a .c file has a #define switch to define for many different platforms. I'm only interested in one platform, and I want the C preprocessor to filter out unrelated code.
Does GCC support this?
Yes. Use the -E option:
gcc -E foo.c
While the -E option will perform all pre-processing, it also produces some very 'raw' output that might not be what you want (depending on what you want).
If you need to debug a macro expansion that's not doing what you expect, E is a good way to go. If you simply want to filter out the 'inactive code', but leave the remaining code in more-or-less original form, you might want to look at the answers to the following Stack Overflow question:
Is there a C pre-processor which eliminates #ifdef blocks based on values defined/undefined?
It sounds like you want unifdef, not the GCC preprocessor.
I am trying to save space in my executable and I noticed that several functions are being added into my object files, even though I never call them (the code is from a library).
Is there a way to tell gcc to remove these functions automatically or do I need to remove them manually?
If you are compiling into object files (not executables), then a compiler will never remove any non-static functions, since it's always possible you will link the object file against another object file that will call that function. So your first step should be declaring as many functions as possible static.
Secondly, the only way for a compiler to remove any unused functions would be to statically link your executable. In that case, there is at least the possibility that a program might come along and figure out what functions are used and which ones are not used.
The catch is, I don't believe that gcc actually does this type of cross-module optimization. Your best bet is the -Os flag to optimize for code size, but even then, if you have an object file abc.o which has some unused non-static functions and you link statically against some executable def.exe, I don't believe that gcc will go and strip out the code for the unused functions.
If you truly desperately need this to be done, I think you might have to actually #include the files together so that after the preprocessor pass, it results in a single .c file being compiled. With gcc compiling a single monstrous jumbo source file, you stand the best chance of unused functions being eliminated.
Have you looked into calling gcc with -Os (optimize for size.) I'm not sure if it strips unreached code, but it would be simple enough to test. You could also, after getting your executable back, 'strip' it. I'm sure there's a gcc command-line arg to do the same thing - is it --dead_strip?
In addition to -Os to optimize for size, this link may be of help.
Since I asked this question, GCC 4.5 was released which includes an option to combine all files so it looks like it is just 1 gigantic source file. Using that option, it is possible to easily strip out the unused functions.
More details here
IIRC the linker by default does what you want ins some specific cases. The short of it is that library files contain a bunch of object files and only referenced files are linked in. If you can figure out how to get GCC to emit each function into it's own object file and then build this into a library you should get what you are looking.
I only know of one compiler that can actually do this: here (look at the -lib flag)