Compilation error while porting from gfortran to ifort - compilation

I'm trying to port a program from gfortran to ifort (Intel Fortran Compiler 11). I'm stuck with two files that only compile with gfortran:
gfortran -x f77 -c daedrid.ff
gfortran -x f77-cpp-input -c daedris.ff
when I try to run intel fortran compiler with these files, I get:
ifort -fpp -c daedrid.ff
ifort: warning #10147: no action performed for specified file(s)
ifort -fpp -c daedris.ff
ifort: warning #10147: no action performed for specified file(s)
and no object files are created.
Now, how can I solve this problem o_O?
EDIT: Renaming the file extensions from ff to fpp
cp daedrid.ff daedrid.fpp
cp daedrid.ff daedrid.fpp
helps:
ifort -fpp -c daedrid.fpp
daedrid.fpp(1483): (col. 9) remark: LOOP WAS VECTORIZED.
daedrid.fpp(1490): (col. 11) remark: LOOP WAS VECTORIZED.
daedrid.fpp(1499): (col. 13) remark: LOOP WAS VECTORIZED.
ifort -fpp -c daedris.fpp
daedris.fpp(1626): (col. 9) remark: LOOP WAS VECTORIZED.
http://www.rcac.purdue.edu/userinfo/resources/black/userguide.cfm#compile_fortran_cpp
UPDATE: Is there a way to make the intel fortran compiler work without having to rename the files?

The options you're looking for are -Tf and -fpp (and optionally -fixed or -free. From ifort -help, the relevant lines are:
-Tf<file> compile file as Fortran source
-fpp[n] run Fortran preprocessor on source files prior to compilation
n=0 disable running the preprocessor, equivalent to no fpp
n=1,2,3 run preprocessor
-[no]fixed,-FI specifies source files are in fixed format
-[no]free, -FR specifies source files are in free format
So, all in all, if you have fixed-form source which needs preprocessing, you would use:
ifort -fpp -fixed -Tfa.ff
to compile file a.ff.

Related

gcov and gcovr: no .gcno files are generated after compiling

I am trying to get code coverage in my unit test project in windows system.
Description
After compiling with -fprofile-arcs -ftest-coverage, I found out the execution file is generated and works fine. However there's no any .gcno files in the folder. So I cannot output the coverage report properly by gcovr.
Software version
gcc 8.1.0/gcov 8.1.0/gcovr 5.1/python 3.10.2
Steps
Here's what I've done during the whole process. Please help me if there's something wrong.
There are only .c and .h files in one folder
Compile my project using gcc
gcc -Wall -Wno-unknown-pragmas -fcompare-debug-second -fprofile-arcs -ftest-coverage -DUTEST AllTests.c CuTest.c BZR2.c BZR2_test.c -o beta.exe
Then I got beta.exe in the folder.
After runing beta.exe, there's my test result(All tests are passed.) showing in the command line window. Besides there're .gcda files with the same filename as my .c files.
Then I run gcovr -r ., the result is showing below. I think the reson why gcovr can't show the coverage information is there's no any .gcno files generated after compiling my project. But I don't understand why and how to solve this.
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
------------------------------------------------------------------------------
TOTAL 0 0 --%
------------------------------------------------------------------------------
Thanks for your time!
Remove the -fcompare-debug-second option. It is used for debugging the compiler itself, and causes the compiler
to silence warnings, and omitting other options that would cause the compiler to produce output to files or to standard output as a side effect.
(see: https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Developer-Options.html)
Creation of gcno files is such a side effect.
General tips:
Instead of -fprofile-arcs -test-coverage you can simply use the --coverage option.
When you compile multiple source files in one go, then GCC tries to figure out file names for intermediate files, and also automatically derives some name for secondary outputs like gcno files. This used to be somewhat unintuitive, at least until reasonable behaviour was implemented in GCC 11.
To compile all of the files individually, we would use the structure:
OPTIONS="-Wall -Wno-unknown-pragmas --coverage -DUTEST"
# compile the individual compilation units
gcc -c $OPTIONS AllTests.c -o AllTests.o
gcc -c $OPTIONS BZR2.c -o BZR2.o
gcc -c $OPTIONS BZR2_test.c -o BZR2_test.o
# we should now have three gcno files
ls *.gcno
# link the final executable
gcc $OPTIONS CuTest.o BZR2.o BZR2_test.o -o beta.exe
At this point, it's typically appropriate to use a build system, for example by writing a Makefile:
CFLAGS += -Wall -Wno-unknown-pragmas --coverage -DUTEST
SOURCES = AllTests.c BZR2.c BZR2_tests.c
OBJECTS = $(SOURCES:.c=.o)
beta.exe: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $#

Getting assember output from GCC/Clang in LTO mode

Normally, one can get GCC's optimized assembler output from a source file using the -S flag in GCC and Clang, as in the following example.
gcc -O3 -S -c -o foo.s foo.c
But suppose I compile all of my source files using -O3 -flto to enable link-time whole-program optimizations and want to see the final compiler-generated optimized assembly for a function, and/or see where/how code gets inlined.
The result of compiling is a bunch of .o files which are really IR files disguised as object files, as expected. In linking an executable or shared library, these are then smushed together, optimized as a whole, and then compiled into the target binary.
But what if I want assembly output from this procedure? That is, the assembly source that results after link-time optimizations, during the compilation of IR to assembly, and before the actual assembly and linkage into the final executable.
I tried simply adding a -S flag to the link step, but that didn't really work.
I know disassembling the executable is possible, even interleaving with source, but sometimes it's nicer to look at actual compiler-generated assembly, especially with -fverbose-asm.
For GCC just add -save-temps to linker command:
$ gcc -flto -save-temps ... *.o -o bin/libsortcheck.so
$ ls -1
...
libsortcheck.so.ltrans0.s
For Clang the situation is more complicated. In case you use GNU ld (default or -fuse-ld=ld) or Gold linker (enabled via -fuse-ld=gold), you need to run with -Wl,-plugin-opt=emit-asm:
$ clang tmp.c -flto -Wl,-plugin-opt=emit-asm -o tmp.s
For newer (11+) versions of LLD linker (enabled via -fuse-ld=lld) you can generate asm with -Wl,--lto-emit-asm.

Compiling in gfortran with makefile

I have received a bunch of .f95 files to be compiled. The only info included regarding its compilation is the order in which these has to be compiled and that the files are in free-form. Besides that there is a Makefile but it is a Makefile made for Intel Fortran Compiler. I know nothing about Fortran and just need to make use of the code. I do not have access to Intel Fortran Compiler and gfortran in macosx is my only available choice. I compiled similar code previously in a similar way and it worked fine. Nevertheless I get multiple errors and nothing happens.
As I said the MakeFile is not complex and is split in three main sections. How could I "translate" this to gfortran syntaxis and compile the code. Is there an equivalence of options between the two? I enclose an abridged version of the MakeFile.
Mine
% ifort -o BIN1.exe -O3 -diag-disable 8291 file1.f90 file2.f90 ....
% ifort -g -check bounds -o BIN1n.exe -O3 file1.f90 file2.f90 ....
% ifort -g -debug full -traceback -check bounds -check uninit -check pointers -check output_conversion -check format -warn alignments -warn truncated_source -warn usage -ftrapuv -fp-stack-check -fpe0 -fpconstant -vec_report0 -diag-disable 8291 -warn unused -o BIN.exe -O3 file1.f90 file2.f90 ....
You need to convert the ifort flags to gfortran flags. To the best of my knowledge this can only be done by reading the documentation of ifort and gfortran. I'm no expert but:
maybe -fpconstant can be replaced by -fdefault-real-8 (if I understand correctly this gfortran flag has the effect of the ifort flags -r8 and -fpconstant),
maybe -fpe0 can be replaced by using -ffpe-trap=XXX.
PS: You can find some equivalence at the page Compiling with gfortran instead of ifort

Should OCaml compilation with custom linking work in Windows (via MinGW)?

I want to compile an OCaml program interfacing with C code, using a MinGW-based GCC, and using separate compilation (GCC produces the .o, then ocamlopt produces the final executable).
It's not clear to me if (1) this should work on Windows and, if so, (2) which command-line arguments are necessary.
I'm using Jonathan Protzenko's OCaml on Windows installer to install OCaml 4.02.1 along with a Cygwin shell (note that it uses a native windows OCaml compiler, not a Cygwin-based one). I installed gcc using Nuwen's MinGW (but had the same issue when using Strawberry Perl's gcc).
Here's my source code:
C file (tc.c):
#include <stdio.h>
#include "caml/mlvalues.h"
value print(value unused) {
printf("hello from C\n");
return Val_unit;
}
OCaml file (t.ml):
external print : unit -> unit = "print"
let () =
Printf.printf "platform: %s\n" (Sys.os_type);
print ();
The following works just fine:
and#win7 $ ocamlopt t.ml tc.c -o t.exe
and#win7 $ ./t.exe
platform: Win32
hello from C
However, if I use a .o instead of a .c, it doesn't work:
and#win7 $ gcc tc.c -c -I c:/OCaml/lib -o tc.o
and#win7 $ ocamlopt t.ml tc.o -o t.exe
** Cannot resolve symbols for tc.o:
puts
** Fatal error: Unsupported relocation kind 0004 for puts in tc.o
File "caml_startup", line 1:
Error: Error during linking
Both versions work fine on Linux.
I wonder if it's just some silly mistake that I can quickly fix by giving the right arguments to gcc/ocamlc/ocamlopt, or if it's a current limitation of OCaml's native compilation on Windows.
Edit: camlspotter identified the cause, so in retrospect, I did not need Nuwen's MinGW at all. OCaml on Windows already includes a MinGW-based C compiler, except that it is called i686-w64-mingw32-gcc and not gcc.
You are probably using a wrong C compiler or without appropriate options. The best way is to use the same C compiler + options used to build OCaml. You can check it by ocamlc -config:
$ ocamlc -config
version: 4.02.3
standard_library_default: C:/ocamlmgw64/lib
standard_library: C:/ocamlmgw64/lib
standard_runtime: ocamlrun
ccomp_type: cc
bytecomp_c_compiler: x86_64-w64-mingw32-gcc -O -mms-bitfields -Wall -Wno-unused
bytecomp_c_libraries: -lws2_32
native_c_compiler: x86_64-w64-mingw32-gcc -O -mms-bitfields -Wall -Wno-unused
native_c_libraries: -lws2_32
native_pack_linker: x86_64-w64-mingw32-ld -r -o
ranlib: x86_64-w64-mingw32-ranlib
...
For example, the above shows that my OCaml compiler is built over Cygwin 32 bit environment with x86_64-w64-mingw32-gcc. The same applies for the linker and ranlib. Since you can compile C with OCaml code with ocamlopt, the same C compiler must be already installed in your environment.
Building OCaml compiler by yourself to make sure the same C compiler is used both for C and OCaml may be the best way to avoid this sort of C compiler mismatch.

MEX File - Debugging LIBSVM in Visual Studio

I would like to debug a MEX file in Visual Studio (From MATLAB environment directly to C++ (Visual Studio 2012)).
I've understood that this it is possible by adding the -g option to the make file.
Attached you can find the makefile code I am using.
What changes should be applied to make it work?
Code:
# This Makefile is used under Linux
MATLABDIR ?= /usr/local/matlab
# for Mac
# MATLABDIR ?= /opt/local/matlab
CXX ?= g++
#CXX = g++-4.1
CFLAGS = -Wall -Wconversion -O3 -fPIC -I$(MATLABDIR)/extern/include -I..
MEX = $(MATLABDIR)/bin/mex
MEX_OPTION = CC\#$(CXX) CXX\#$(CXX) CFLAGS\#"$(CFLAGS)" CXXFLAGS\#"$(CFLAGS)"
# comment the following line if you use MATLAB on 32-bit computer
MEX_OPTION += -largeArrayDims
MEX_EXT = $(shell $(MATLABDIR)/bin/mexext)
OCTAVEDIR ?= /usr/include/octave
OCTAVE_MEX = env CC=$(CXX) mkoctfile
OCTAVE_MEX_OPTION = --mex
OCTAVE_MEX_EXT = mex
OCTAVE_CFLAGS = -Wall -O3 -fPIC -I$(OCTAVEDIR) -I..
all: matlab
matlab: binary
octave:
#make MEX="$(OCTAVE_MEX)" MEX_OPTION="$(OCTAVE_MEX_OPTION)" \
MEX_EXT="$(OCTAVE_MEX_EXT)" CFLAGS="$(OCTAVE_CFLAGS)" \
binary
binary: svmpredict.$(MEX_EXT) svmtrain.$(MEX_EXT) libsvmread.$(MEX_EXT) libsvmwrite.$(MEX_EXT)
svmpredict.$(MEX_EXT): svmpredict.c ../svm.h ../svm.o svm_model_matlab.o
$(MEX) $(MEX_OPTION) svmpredict.c ../svm.o svm_model_matlab.o
svmtrain.$(MEX_EXT): svmtrain.c ../svm.h ../svm.o svm_model_matlab.o
$(MEX) $(MEX_OPTION) svmtrain.c ../svm.o svm_model_matlab.o
libsvmread.$(MEX_EXT): libsvmread.c
$(MEX) $(MEX_OPTION) libsvmread.c
libsvmwrite.$(MEX_EXT): libsvmwrite.c
$(MEX) $(MEX_OPTION) libsvmwrite.c
svm_model_matlab.o: svm_model_matlab.c ../svm.h
$(CXX) $(CFLAGS) -c svm_model_matlab.c
../svm.o: ../svm.cpp ../svm.h
make -C .. svm.o
clean:
rm -f *~ *.o *.mex* *.obj ../svm.o
In general, you run the mex command with the -g option, and depending on your OS, either attach to MATLAB (Visual Studio in Windows) or start the debugger with the matlab startup script (e.g. matlab -Dgdb in Linux). Use these detailed instructions for your own MEX files.
However, for LIBSVM, you are provided with make.m, which can be used to build in any supported OS, and Makefile for use in Linux only. The Makefile is used for building the MEX files outside of MATLAB (i.e. without using mex.m, but instead a shell script in $(MATLABDIR)/bin/mex). In Windows, you need to edit make.m and add the -g option to each mex call:
mex CFLAGS="\$CFLAGS -std=c99" -largeArrayDims -g libsvmread.c
mex CFLAGS="\$CFLAGS -std=c99" -largeArrayDims -g libsvmwrite.c
mex CFLAGS="\$CFLAGS -std=c99" -largeArrayDims -g svmtrain.c ../svm.cpp svm_model_matlab.c
mex CFLAGS="\$CFLAGS -std=c99" -largeArrayDims -g svmpredict.c ../svm.cpp svm_model_matlab.c
Then, in MATLAB, run make (the modified make.m). Start Visual Studio, set one or more break points, and from the Debug menu, "Attach to Process...". Now you can run the MEX functions (e.g. svmtrain) and it will stop in Visual Studio when it hits the break points.
Just for completeness, if you were using Linux and wanted to go the Makefile route, just change the following line to build debug versions of the code:
MEX_OPTION += -largeArrayDims -g
First you have to compile the MEX-file with debugging information enabled. For instance use mex -g file.cpp or add the equivalent to your build system.
Next attach Visual Studio the the MATLAB process, open the C/C++ source file and place a breakpoint
Finally run the MEX function from MATLAB. VS will stop at that point and enter debugging mode.
Here is a page explaining the procedure.

Resources