Using ubuntu 14.04 octave 3.8.1.
I'm attempting to create an .oct file which makes use of multithreaded fortran program. However, mkoctfile fails to use the related libraries during linking.
The files I'm using look as follows:
c:
#include <octave/oct.h>
extern "C" {
void fort5();
}
DEFUN_DLD (ce5, args, ,"help here")
{
fort5();
}
fortran:
subroutine fort5() bind(c)
use iso_c_binding
implicit none
!$OMP PARALLEL
write(*,*) "Hello"
!$OMP END PARALLEL
end subroutine fort5
I expect this code to result in output of four lines of "Hello".
I compile it with following command
mkoctfile CPP.cpp FORTRAN.f90
As a result I get only one output line, which indicates multitrhreading was ignored.
When compiled outside octave (with minor alterations to c++ file) with following command:
gcc -c CPP.cpp && gfortran -Wall -fimplicit-none -Wtabs -fdefault -real-8 -fopenmp -c FORTRAN.f90 &&gfortran -fopenmp -o3 CPP.o FORTRAN.o -lstdc++ -o OUT.out
The result is as it should be.
From several tests it becomes apparent, that mkoctfile is not capable to use -fopenmp flag in any form. As found on the internet this should be solvable by using LDFLAGS, however, for some reason I fail at that.
I set the enviroment variable in octave terminal with
setenv("LDFLAGS","-Wl,-Bsymbolic-functions, -Wl,-z,relro, -fopenmp")
setenv("FFLAGS","-g -O2 -fstack-protector --param=ssp-buffer-size=4 -fopenmp")
the $mkoctfile --print LDFLAGS indicates that the variable was set successfully. However, the compiled function fails to load: $undefined symbol: GOMP_parallel_start
I've tried explicitly listing the library but the result was the same.
mkoctfile ce5.cpp fort5.o '-Wl,-fopenmp' '-l /usr/lib/x86_64-linux-gnu/libgomp.so.1
mkoctfile ce5.cpp fort5.o '-Wl,-fopenmp' '-L /usr/lib/x86_64-linux-gnu/'
Did I use the flags correctly? What else should I do to get correct compilation?
Problem solved:
Seems like consecutive application of the following commands done the trick:
setenv("FFLAGS","-g -O2 -fstack-protector --param=ssp-buffer-size=4 -fopenmp")
setenv("LDFLAGS","-Wl,-Bsymbolic-functions, -Wl,-z,relro, -Wl,-fopenmp")
mkoctfile ce5.cpp fort5.o '-L, /usr/lib/x86_64-linux-gnu/libgomp.so.1'
Most likely the problem was setting correct flag for compiler ($-fopenmp in FFLAGS) and correct indication of library location.
Related
I have Matlab code that uses sparse and '\' as solver for a linear system. I have hand tailored a C++ function that uses the conjage gradient sparse solver from Eigen in order to run the code outside Matlab using the coder toolbox to export the rest of the Matlab code. I export a static library and I'm able to compile and execute it on my remote system without any problem. However, I'm not able to run the code using multi-threading. I have tried to export it as a Matlab executable (mex) and the whole code runs in parallel without problem inside Matlab.
So my conclusions are that it must be something different in the compiler/linker flags on my remote system. I use -fopenmp in both complier and linker and I run the executable with OMP_NUM_THREADS=n and if I read out "n" inside my program I get the same number as I have in my execution.
My question is, do I need to include anything else in my compiler/linker, apart from needed things related to my particular code, in order to get Eigen to run multi-threaded?
UPDATE:
On the remote system I do:
g++ -c -m64 -fopenmp -std=c++11 -I /usr/local/include/Eigen/src/misc/
~/src/myHandTailoredFile.cpp -o ~/src/myHandTailoredFile.o
and with linker options
-fopenmp -L /usr/local/lib64/ -llapack -L /usr/local/lib/ -lcurl
To compile my hand tailored file together with myBigProgram into a Mex-file I do
g++ -DHAVE_LAPACK_CONFIG_H -DLAPACK_COMPLEX_STRUCTURE -DMW_HAVE_LAPACK_DECLS -c -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread -D_GNU_SOURCE -DMATLAB_MEX_FILE -std=c++0x -fopenmp -DOMPLIBNAME="\"/usr/local/MATLAB/R2016a/sys/os/glnxa64/libiomp5.so\"" -O -DNDEBUG -I "/usr/local/MATLAB/R2016a/simulink/include" -I "/usr/local/MATLAB/R2016a/toolbox/shared/simtargets" -I "./interface" -I "/usr/local/lib" -I "/usr/local/MATLAB/R2016a/extern/include" -I "." "~/src/myHandTailoredFile.cpp"
with linker options set to
-pthread -Wl,--no-undefined -Wl,-rpath-link,/usr/local/MATLAB/R2016a/bin/glnxa64 -shared -L/usr/local/MATLAB/R2016a/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++ -lcurl -fPIC -L/usr/local/MATLAB/R2016a/sys/os/glnxa64 -liomp5 -o myBigProgram_mex.mexa64 -L"/usr/local/MATLAB/R2016a/bin/glnxa64" -lmwblas -lmwlapack -lemlrt -lcovrt -lut -lmwmathutil
Note that the compiler and linker options for the later is completely defined by Matlab.
I am a very new to programming and have a very basic question that may be answered in other threads however I think they are far too advanced for me to understand how. I have actually found many answers so far on this site but this is the first problem that forced me to create an account and ask.
Anyway i am running a very basic example program on linux mint 18.3. Now I have seen this exact code work on a machine with windows 8 I believe so I was wondering if that could be the problem. I have created a class and when i plug in my object then build and run I get:
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o||In function _start':|
(.text+0x20)||undefined reference tomain'|
This is the entire code:
#include <iostream>
#include "Gladius.h"
using namespace std;
int main()
{
Gladius io;
return 0;
}
Thats it very basic. here is the .h
#ifndef GLADIUS_H
#define GLADIUS_H
class Gladius
{
public:
Gladius();
};
#endif // GLADIUS_H
and the .cpp for the class.
#include "Gladius.h"
#include <iostream>
using namespace std;
Gladius::Gladius()
{
cout << "The Gladius is a short sword" << endl;
}
I know this seems extremely simple but I am just learning to code and i have been looking all over for an explanation why this isn't working yet I see it work on another pc exactly as is. Anyway any explanation would be greatly appreciated.
Here is what i found in command line If this answers your questions about what was in the cmd.
g++ -Wall -fexceptions -g -std=c++11 -Wall -I -c /home/gator/Documents/Spartan1/Gladius.cpp -o obj/Debug/Gladius.o
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function _start':
(.text+0x20): undefined reference tomain'
collect2: error: ld returned 1 exit status
Know the compiler options(gcc/g++ compiler):
-c : Compile and assemble, but do not link
-o file : Place the output into file
So when you run
g++ filename.cpp -o executable_name
, you generate an application which can be executed.
The problem is you are compiling, assembling as well as linking when you are trying to compile "Gladius.cpp" and compiler is trying to search for main() definition.
So in your case, the compilation steps would be:
First compile "Gladius.cpp" and generate object file "Gladius.o":
g++ -Wall -fexceptions -g -std=c++11 -c Gladius.cpp
Next compile "main.cpp" and generate object file "main.o":
g++ -Wall -fexceptions -g -std=c++11 -c main.cpp
Generate executable by linking "main.o" and "Gladius.o"
g++ -Wall -fexceptions -g -std=c++11 -o main main.o Gladius.o
Now you can run "main":
./main
Your compiler's command line contains -I -c sequence.
This -I option "swallows" your -c option. -I requires an additional argument, which is an include directory name. You failed to supply that argument, which is why -I assumes that -c that follows it is the directory name. So that -I consumes that -c.
The compiler never sees that -c. Without -c it assumes that you want to compile and link your program. Since Gladius.cpp does not have main in it, you get the error at linking stage.
Here 's a simple demo of the same problem: http://coliru.stacked-crooked.com/a/8a37cd3e90a443e2
You need to figure out why you have an orphaned -I in your command line.
If you are compiling this code using a command line like:
g++ -Wall -Wextra -Werror -O gladius.cpp -o output.exe
then make sure that you include all the .cpp files (not .h files) that contain code that your program needs.
g++ -Wall -Wextra -Werror -O gladius.cpp main.cpp -o output.exe
I explain this to beginners all the time as each .cpp being a bag of Lego's in a kit. You need all the bags that came with the box in order to build the kit. If you omitted main.cpp (or the file that contains main) then you will get the linker error that you are currently getting.
What command are you using to compile, link, and then execute? It should look something like
$ g++ main.cpp gladius.cpp -odemo
$ ./demo
check your command line for linking step.. You may forgot file with main as input, or you had forgot output file name after -o (and masked main.o in result)
I had this very kind of problem myself, and though it may not be the conventional, "proper" solution, I simply renamed the ".c" file to ".cpp", and it all worked.
After all, I was compiling both c and c++ together with a c++ compiler (recommended by the library), and the c code already had the proper c++ #extern flags (see here for more on that).
Also related:
C++ Error: undefined reference to `main'
Including C Code in C++
Why do you need an explicit `-lm` compiler option
Compilation on Linux - In function '_start': (.text+0x20): undefined reference to 'main'
I would like to profile some c++ code using gprof. I compile the program exactly like normal but with -pg added at the end; i.e. something like
g++ prog.cpp $(OBJECTS) -lgmp -lgmpxx -lmpfr -lmpc -msse2 -std=c++11 -O2 -o prog_P -pg
However when I run the resulting executable I get a bunch of errors that are not normally there. Specifically they are from the zkcm multiprecision library:
Warning: in zkcm_gauss::gauss, partial pivoting failed.
This is bad news for my LU decomposition. Any ideas?
EDIT: I use cygwin
I have been writing a c++ program in Ubuntu and window8 using armadillo. Under Windows8 the program compiles without problems.
The program is just using the linear systems solver.
Under Ubuntu the compiler says
"reference to `wrapper_dgels_' not defined"
The compiler line I use is:
mpic++ -O2 -std=c++11 -Wall -fexceptions -O2 -larmadillo -llapack -lblas program.o
However, right before the error I see:
g++ module_of_the_error.o
Which is something I haven't set.
I am using code blocks in Ubuntu, and I compiled armadillo with all the libraries that cmake asked. (BLAS< LAPACK, OpenBLAS, HDF5, ARPACK, etc)
I have no clue what might be causing the problem, since the exact same code compiles in visual studio.I have tried the compiler line modifications suggested but it does not seem to work.
Any help is appreciated.
This is one trap I fell into myself one time. You will not like the likely cause of your error.
The order of the arguments to the linker matters.
Instead of
mpic++ -O2 -std=c++11 -Wall -fexceptions -O2 -larmadillo -llapack -lblas program.o
try:
mpic++ -O2 -std=c++11 -Wall -fexceptions -O2 program.o -larmadillo -llapack -lblas
I.e., put the object files to be linked into the executable before the libraries.
By the way, at this stage you are only linking files that have already been compiled. It is not necessary to repeat command line options that are only relevant for compiling. So this will be equivalent:
mpic++ program.o -larmadillo -llapack -lblas
Moreover, depending on how you installed Armadillo, you are adding either one or two superfluous libraries in that line. One of the following should be enough:
mpic++ program.o -larmadillo
or
mpic++ program.o -llapack -lblas
EDIT: as the answer by rerx states, the problem is probably just a simple ordering of the switches/arguments supplied to g++. All the -l switches need to be after the -o switch. Or in other words, put the -o switch before any -l switches. For example:
g++ prog.cpp -o prog -O3 -larmadillo
original answer:
Looks like your compiler can't find the Armadillo run-time library. The proper solution is to specify the path for armadillo run-time library using the -L switch. For example, g++ -O2 blah.cpp -o blah -L /usr/local/lib/ -larmadillo
Another possible solution is to define ARMA_DONT_USE_WRAPPER before including the armadillo header, and then directly link with LAPACK and BLAS. For example:
#define ARMA_DONT_USE_WRAPPER
#include <armadillo>
More details are available at the Armadillo frequently asked questions page.
I am creating a python module that is implemented in C++. I am using SWIG to create the interface. There are various ways to create the extension, I'm using the "preferred approach," which is via python's distutils and which is described here. The name of my module is "ParseEvents," and to compile it I run the following two commands:
swig -c++ -python ParseEvents.i
python setup.py build_ext --inplace
The first command creates a file ParseEvents_wrap.cxx
The second command uses the following setup.py file:
from distutils.core import setup, Extension
ParseEvents_module = Extension('_ParseEvents',
sources=['ParseEvents_wrap.cxx',],
extra_compile_args=["-Wno-deprecated","-O3"],
)
setup (name = 'ParseEvents',
ext_modules = [ParseEvents_module,],
py_modules = ["ParseEvents"]
)
Question: Where and how do I specify that I want my C++ code to be compiled with the -O3 compiler tag? I guessed that it would just be in the "extra_compile_args" part of the setup.py file, but that doesn't seem to be the case. When I run the second command (python setup.py build_ext --inplace), here's the output:
running build_ext
building '_ParseEvents' extension
creating build
creating build/temp.linux-x86_64-2.6
gcc -pthread -fno-strict-aliasing -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fPIC -I/usr/include/python2.4 -c ParseEvents_wrap.cxx -o build/temp.linux-x86_64-2.4/ParseEvents_wrap.o -Wno-deprecated -O3
c++ -pthread -shared build/temp.linux-x86_64-2.4/ParseEvents_wrap.o -o _ParseEvents.so
Note that both the -O2 and -O3 flags are present in the second to last line in the output---I'd like to remove the -O2.
The GCC doc explicitly says:
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Optimize-Options.html
If you use multiple -O options, with or without level numbers, the last such option is the one that is effective.
This means your code will be compiled with -O3 in effect, just as you want it. No need to bother for duplicate optimization flags.
Distutils has the lovely feature of providing all the same flags that Python was compiled with. The result is that adding extra flags is easy, but removing them is a total pain. Doing so involves subclassing the compiler class, catching the arguments and manually removing the offending flag from the argument list used by the compile function. That's the theory anyway, the docs are too poor to actually guide you through what you have to do to make that happen.
But like Luther said, in your case the extra -O2 doesn't hurt anything.