Intel Fortran to GNU Fortran Conversion [closed] - makefile

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am working on a custom CFD Solver written in Fortran 90 and MPI.
The code contain 15+ Modules and was initially designed to work with the Intel Fortran compiler. Now since i do not have access to the Intel compiler I need to make it work using the GNU Fortran Compiler.
I made changes in the Makefile that initially had flags suitable for the ifort.
I am using it on Ubuntu with GNU Fortran and Openmpi
I am sorry I am unable to put in anything from the code structure or terminal output due to IP restrictions of my university. Nevertheless,I will try to best describe the issues
So now when I compile the code I am having some strange issues.
The GNU Fortran is not able to read lines that are too long and I get errors during compilation. As a result I have to break it into multiple lines using the '&' symbol
A module D.f90 contains all the Global variables declared. However, now I during compilation i get error is in module B.F90.
The error I get is 'Unclassified Statement Error', I was able to fix it in some subroutines and functions by locally declaring the variables again.
I am not the most experienced person in Fortran, but I thought that the change in compiler should not be a reason for new found syntax errors.
The errors described above so far could be remedied but considering the expanse of the code it is impractical.
I was hoping if anyone could share views on this matter and provide guidance on how to tackle it.

You should start reading three pieces of documentation:
The Fortran 90 standard (alternatively, other versions), which tells you what is legal, standard Fortran and what is not. Whenever you find some error, look at your code and check if what you are doing is legal, standard Fortran. Likely, the code in question will either be completely nonstandard (e.g. REAL*8, although that extension is fairly well understood) or rely on unspecified behaviour that Intel Fortran and GFortran are interpreting in different ways.
The GFortran manual for your version, which tells you how GFortran decides such unspecified cases, what intrinsic functions are available, how to change some options/flags, etc. This would tell you that your problem with the line lengths would be solved by adding -ffree-line-length-none.
The Intel Fortran manual for your version, which in cases of non-standard or unspecified behaviour, will allow you to know what the code you are reading was written to do, e.g. the behaviour that you would expect. In particular, it will allow you to decipher what the compiler flags that are currently being used mean. They may or may not need translation to GFortran, e.g. /Qsave will need to become -f-no-automatic.
A concrete example of interpretative differences within the range allowed be the standard: until Fortran 2003, the units for the "record length" in random access record files were left unspecified. Intel Fortran used "one machine word" (4 bytes in x86) while GFortran used 1 byte. Both were compliant with the standard letter, but incompatible.
Furthermore, even when coding "to standard", you may hit a wall if the compiler does not implement part of the Fnn standard, or it is buggy. Case in point: Intel Fortran 12.0 (old, but it's what I work with) does not the implement the ALLOCATE(y, SOURCE=x) construct for polymorphic x (the "clone allocation"). On the other hand, GFortran has not completely implemented FINAL type-bound procedures (destructors).
In both cases, you will need to find workarounds. For example, for the first issue you can use a special form of the INQUIRE statement (kudos to #haraldkl). In other cases, the workaround might even involve using some kind of feature detection (see autoconf, CMake, etc.) and storing the results as PARAMETER variables in a config.f90 file that is included by your code. Your code would then take decisions based on it, as in:
! config.f90.in (things in #x# would get subtituted by automake, for example)
INTEGER, PARAMETER :: RECORD_LEN_BYTES = #RECORD_LEN_BYTES#
! Some other file which opens a file
INCLUDE "config.f90"
!...
OPEN(u, FILE='DE430.BIN', ACCESS='direct', FORM='unformatted', RECL=56 / RECORD_LEN_BYTES)

People have been having complaints about following the standard since at least the 60s. But those cDEC$ features were put in a for good reasons...
It is valuable to cross compile though and you usually have things caught in one compiler or the other.
For you question #1 "The GNU Fortran is not able to read lines that are too long and I get errors during compilation. As a result I have to break it into multiple lines using the '&' symbol"
In the days of old there was:
options/extended_source
SUBROUTINE...
In fort it is -132, but I have not found a gfortran equivalent to -132 . It may be -ffixed-line-length-n -ffixed-line-length-none -ffree-line-length-n -ffree-line-length-none per the link: http://www.math.uni-leipzig.de/~hellmund/Vorlesung/gfortran.html#SEC8
Also the ifort standard for .f90 and .f95 is the the compiler switch '-free' '-fixed' is the standard <.f90... However one can use -fixed with .f90 and use column 6 and 'D' in column #1... Which is handy with '-D_lines' or '-DD'.
Per the link: https://software.intel.com/sites/default/files/m/f/8/5/8/0/6366-ifort.txt
For you question #2: "A module D.f90 contains all the Global variables declared. However, now I during compilation i get error is in module B.F90. The error I get is 'Unclassified Statement Error', I was able to fix it in some subroutines and functions by locally declaring the variables again."
You probably need to put in the offending line, if you can get an IP waiver.
Making variables local if they are expected to be shared in a /common/ or shared in a module will not work.
If there were in /common/ or PUBLIC then they are shared.
If they are local then they are PRIVATE.
it would be easy to get that error if a PRIVATE statement was in the wrong place, or a USE statement was omitted.

Related

GCC [for ARM] force no floating point

I would like to create a build of my embedded C code which specifically checks that floating point operations aren't introduced into it by accident. I've tried adding +nofp to my [cortex-m3] processor architecture but GCC for ARM doesn't like that (probably because the cortex-m3 doesn't have a floating point unit). I've tried specifying -mfpu=none but that isn't a permitted option. I've tried leaving -lm off the linker command-line but the linker seems too clever to be fooled by that and is compiling code with double in it and resolving pow() anyway.
This post: https://gcc.gnu.org/legacy-ml/gcc-help/2011-07/msg00093.html from 2011 hints that GCC has no such option, since no-one is interested in it, which surprises me as it seems like a common thing to want, at least from an embedded standpoint, to avoid accidental C-library bloat.
Does anyone know of a way to do this with GCC/newlib without me having to go through and manually hack stuff out of the C library file it chooses?
It is not just a library issue. Your target will use soft-fp, and the compiler will supply floating point code to implement arithmetic operators regardless of the library.
The solution I generally apply is to scan the map file for instances of the compiler supplied floating-point routines. If your code is "fp clean" there will be no such references. The math library and any other code that perform floating-point arithmetic operations will use these operator implementations, so you only need look for these operator calls and can ignore the Newlib math library functions.
The internal soft-fp routines are listed at https://gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html. It is probably feasible to manually check the mapfile for fp symbols but you might write yourself a script or tool to scan the map file for these names to check your. The cross-reference section of the map file will list all modules these symbols are used in so you can use that to identify where the floating point code is used.
The Newlib stdio functions support floating-point by default. If your formatted I/O is limited to printf() you can use iprintf() instead or you can rebuild Newlib with FLOATING_POINT undefined to remove floating point support from all but scanf() (no idea why). You can then use the map file technique again to find "banned" formatted I/O functions (although these are likely to also use the floating point operator functions in any case, so you will already have spotted them indirectly).
An alternative is to use an alternative stdio library to override the Newlib versions. There are any number of "tiny printf" implementations available you could use. If you link such a library as object code or list its library ahead of Newlib in the link command, it will override the Newlib versions.

Where is __builtin_va_start defined?

I'm trying to locate where __builtin_va_start is defined in GCC's source code, and see how it is implemented. (I was looking for where va_start is defined and then found that this macro is defined as __builtin_va_start.) I used cscope -r in GCC 9.1's source code directory to search the definition but haven't found it. Can anyone point where this function is defined?
That __builtin_va_start is not defined anywhere. It is a GCC compiler builtin (a bit like sizeof is a compile-time operator). It is an implementation detail related to the <stdarg.h> standard header (provided by the compiler, not the C standard library implementation libc). What really matters are the calling conventions and ABI followed by the generated assembler.
GCC has special code to deal with compiler builtins. And that code is not defining the builtin, but implementing its ad-hoc behavior inside the compiler. And __builtin_va_start is expanded into some compiler-specific internal representation of your compiled C/C++ code, specific to GCC (some GIMPLE perhaps)
From a comment of yours, I would infer that you are interested in implementation details. But that should be in your question
If you study GCC 9.1 source code, look inside some of gcc-9.1.0/gcc/builtins.c (the expand_builtin_va_start function there), and for other builtins inside gcc-9.1.0/gcc/c-family/c-cppbuiltin.c, gcc-9.1.0/gcc/cppbuiltin.c, gcc-9.1.0/gcc/jit/jit-builtins.c
You could write your own GCC plugin (in 2Q2019, for GCC 9, and the C++ code of your plugin might have to change for the future GCC 10) to add your own GCC builtins. BTW, you might even overload the behavior of the existing __builtin_va_start by your own specific code, and/or you might have -at least for research purposes- your own stdarg.h header with #define va_start(v,l) __my_builtin_va_start(v,l) and have your GCC plugin understand your __my_builtin_va_start plugin-specific builtin. Be however aware of the GCC runtime library exception and read its rationale: I am not a lawyer, but I tend to believe that you should (and that legal document requires you to) publish your GCC plugin with some open source license.
You first need to read a textbook on compilers, such as the Dragon book, to understand that an optimizing compiler is mostly transforming internal representations of your compiled code.
You further need to spend months in studying the many internal representations of GCC. Remember, GCC is a very complex program (of about ten millions lines of code). Don't expect to understand it with only a few days of work. Look inside the GCC resource center website.
My dead GCC MELT project had references and slides explaining more of GCC (the design philosophy and architecture of GCC changes slowly; so the concepts are still relevant, even if individual details changed). It took me almost ten years full time to partly understand some of the middle-end layers of GCC. I cannot transmit that knowledge in a StackOverflow answer.
My draft Bismon report (work in progress, funded by H2020, so lot of bureaucracy) has a dozen of pages (in its sections ยง1.3 and 1.4) introducing the internal representations of GCC.

Find write statement in Fortran

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.

Boost pretty print for GCC error messages

I'm using GCC 4.7.2. My code is rather heavy on template, STL and boost usage. When I compile and there is an error in some class or function that is derived from or uses some boost/STL functionality, I get error messages showing spectacularly hideous return types and/or function arguments for my classes/function.
My question:
Is there a prettyprint type of thing for GCC warnings/errors containing boost/STL types, so that the return types shown in error messages correspond to what I've typed in the code, or at least, become more intelligible?
I have briefly skimmed through this question, however, that is about GDB rather than GCC...
I've also come across this pretty printer in Haskell, but that just seems to add structure, not take away (mostly) unneeded detail...
Any other suggestions?
I asked a similar question, where someone suggested I try gccfilter. It's a Perl script that re-formats the output of g++ and colorizes it, shortens it, hides full pathnames, and lots more.
Actually, that suggestion answers this question really well too: it's capable of hiding unneeded detail and pretty-printing both STL and boost types. So: I'll leave this here as an answer too.
The only drawback I could see is that g++ needs to be called from within the script (i.e., piping to it is not possible at the time). I suspect that's easily fixed, and in any case, it's a relatively minor issue.
You could try STLfilt as mentioned in 'C++ Template Metaprogramming' by David Abrahms & Alesky Gurtovoy.
The book contains a chapter on template message diagnostics. It suggests using the STLFilt /showback:N to eliminate compiler backtrace material in order to get simplified output.

Syntax Checking with unsupported languages

I have some files that have a particular syntax that is similar to ada (not identical though), however I would like to verify the syntax before going and running them. There isn't a compiler for these files, so I can't check them before using them. I tried to use the following:
gcc -c -gnats <file>
However this says compilation unit expected. I've tried a few variations on this, but to no avail.
I just want to make sure the file is syntactically correct before using it, but I'm not sure how to do it, and I really don't want to write an entire syntax checker just for this.
Is there some way to include an additional unsupported language to gcc without going through a recompile? Also is this simply a file that details to gcc what the syntax constructs are, or what would be entailed? I don't need a full compile, only a syntax check.
Alternately, are there any syntax checkers I can use that I can update an ada syntax check with the small number of changes required for this language?
I've listed Ada as a tag, since the syntax is nearly identical, and finding something that will do ada syntax checking without compiling will be a 90% solution for me.
You could try running the files through gnatchop first. The GCC Ada compiler is rather unique in that it expects filenames to match up with the main unit names inside the file. That may be what your error message is trying to say.
gnatchop will go through any files you give it and write out Ada source files with the appropriate names to make gcc happy (even splitting files into multiple files if needed).
Another option you might be interested in is OpenToken. It is a parser construction toolkit, written in Ada, that allows you to build your own parsers fairly easily. It comes with a syntax recognizer for Ada, so you may just be able to tweak that a bit for your needs.

Resources