Identical source not compiling on Linux although compiling & runs OK on Windows

I've developed code in C++ (GCC ver. 4.9.2.) with LAPACKE and MPI libraries on a Windows machine where the code compiles and works well. When I migrate the code to Linux(CentOS) server (GCC ver. 4.4.7), the code failed to compile! COULD THE DIFFERENCE IN GCC VERSIONS BE THE PROBLEM? Please advise.

Here is some more info.
Upon inspecting preprocessor output on both Win and Linux machines, it seems like the problem is that compiler (GCC on Linux machine) wrongly translates complex C++ type (and similar LAPACKE complex types).
For example:
IN THE ORIGINAL SOURCE: lapack_complex_double* HAMILTONIAN;
IN THE WINDOWS PREPROC. FILE (works well): _lapack_complex_double* HAMILTONIAN;
IN THE LINUX PREPROC. FILE (fails to compile): double _Complex* HAMILTONIAN;
Last edited on
Custom types (like lapack_complex_double) are not GCC's doing. They must come from some third-party library (lapack?) that you do include.


You seem to have CentOS 6. You can get a second GCC like this:
1. install packages:
sudo yum install centos-release-scl-rh
sudo yum install devtoolset-4-toolchain

2. start a new shell:
scl enable devtoolset-4 bash

Within that bash session you will have GCC 5

(The "scl" is Software Collections -- a Red Hat tool that allows parallel installations. Read about it.)


Which version of lapack do you have in each platform?


What are the exact error messages?
Many thanks for your help. I'll see with root/admin to update the GCC on this CentOS machine and will report later on that. The "lapack_complex_double" is indeed LAPACK(E) type and I can say something about it later, but it narrows down to the same errors reported for the original C++ type "complex". Here is the example:


--ERRORS DURING BUILD (compilation) STAGE on the LINUX machine:
EPM_HEADER_FILES/MathsForEPM.h:1: error: expected unqualified-id before '__complex__'
EPM_HEADER_FILES/MathsForEPM.h:2: error: expected unqualified-id before '__complex__'
EPM_HEADER_FILES/MathsForEPM.h:159: error: expected unqualified-id before '__complex__'


--ORIGINAL SOURCE CODE USED ON BOTH MACHINES (excerpt from MathsForEPM.h)
1: const std::complex<double> i1(0.0,1.0);
2: const std::complex<double> ComplexZero(0.0,0.0);
159: std::complex<double>** ALLOCATE_MatrixMemory_ComplexDouble(int numRows, int numCols)

--In the preprocessor output (.o file) on the LINUX macnine:
const std::_Complex<double> i1(0.0,1.0);
const std::_Complex<double> ComplexZero(0.0,0.0);
std::_Complex<double>** ALLOCATE_MatrixMemory_ComplexDouble(int numRows, int numCols)

--On the other hand, the preprocessor output (.o file) on WINDOWS machine:
const std::complex<double> i1(0.0,1.0);
const std::complex<double> ComplexZero(0.0,0.0);
std::complex<double>** ALLOCATE_MatrixMemory_ComplexDouble(int numRows, int numCols)

So, it looks like on Linux "complex" was translated as "_Complex" on these three lines where the errors were reported (IN THE HEADER FILE), as well as IN THE REST OF THE MAIN SOURCE CODE, BUT LINES IN THE MAIN SOURCE CODE WERE NOT FLAGGED AS ERRORS(!?). On the other hand, in the preprocessor output (.o file) on WINDOWS there is no single "_Complex".

I've tried to add "#define _Complex complex" to my source and (as expected) it didn't help - some problems were resolved, but new ones were created (a lot more).

Thanks so much for your input and help.
Last edited on
As per your question of the version of LAPACK on both machines, here is the info.
[NOTE: LapackE (note "E") is C-language wrapper for the (Fortan) Lapack library.]


--Windows: LapackE utilizes pre-built libraries for Windows that correspond to Lapack 3.6.0. [http://icl.cs.utk.edu/lapack-for-windows/lapack/index.html]

--CentOS: I've installed in my home directory Lapack 3.6.1 and I am linking to it when compiling, from it I have installed LapackE. However, command "yum info lapack" gives Lapack ver. 3.2.1.

Thanks so much.
Last edited on
Problems like that can happen if the C header complex.h is included because it defines complex as _Complex.

http://en.cppreference.com/w/c/numeric/complex/complex

I don't fully understand if this is supposed to happen in C++ but it only seems to be an issue with GNU language extensions turned on. Using the compiler flag -std=c++14 (substitute with whatever version of C++ you want) seems to fix the issue.
Last edited on
Thanks Peter87.

I've tried to compile it C++14 standard:
mpiCC main.cpp -o mainE -std=c++14 -L/home/lapack-3.6.1 -llapacke -llapack -lblas -lm -Wall

and got error:
cc1plus: error: unrecognized command line option "-std=c++14"

On the CentOS machine I have: gcc --version
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4)
[this is to be updated soon]


I too think the problem is with C vs C++ declarations for complex entities. Here is indicative link:http://stackoverflow.com/questions/23414270/c-complex-and-complex-h-in-the-same-file
Last edited on
I think your GCC version is too old to support C++14. Try C++11 or C++03 instead.
C++03 didn't work either, nor C++11 :-(
Last edited on
Do:
man g++

search for "-std=". Not the first hit.

There is a list of possible values. On that Red Hat 4.4.7 there is no c++11, but there might be c++0x (partial support of the "future" standard).



Note: Your GCC will not be updated. That is not possible. An update replaces a package and the CentOS 6 depends on that 4.4.7 package. Your admin can install on the side and alternative (newer) version of GCC.


mpiCC .. which MPI do you use? There are several available for CentOS 6 as packages.


Is it your code that contains #include <complex.h> ?
If yes, why?
C++03 didn't work either, nor C++11 :-(

Make sure you spell it with lower case c. -std=c++03
Last edited on
Yes, I did so, as in -std=c++14, thanks!
@ keskiverto: Thanks for the clarification, I didn't know that newer GCC has to be installed on the side. I'll put a note for the admin.

As per the version of MPI, here is the info: MPICH2 Version: 1.2.1.
MPI works well on that machine, I've tested it with C++ code that doesn't use LapackE, magnificent performance: 3-7 times faster than on Windows.

My code uses <complex> and works normally on Win. But, whether I use #include<complex> or #include<complex.h> I get errors on the Liniux machine. Two out of five LapackE header files, lapacke.h and lapacke_config.h, use #include <complex.h>.

Last edited on
@ keskiverto: I've found -std=c++0x and the only difference is that it gives more errors reported. The build fails anyway.Thanks for the help, in any case.
Last edited on
@ keskiverto:

Following your advice, now I have two GCC compilers installed on the Linux (CentOS) machine. The old version of GCC (4.4.7) is in the default folder (came with CentOS) and the newer one that I intend to use is in /usr/local/gcc/4.9.3/. My code utilizes MPI and LAPACK/LAPACKE/BLAS libraries and with the old GCC I used to compile source (for example “main.cpp”) like this:

mpiCC main.cpp -o main -L/home/USER1/lapack-3.6.1 -llapacke -llapack -lblas -lm –Wall

How should I modify the above compilation command so that MPI compilation (mpiCC) invokes GCC from the new location at /usr/local/gcc/4.9.3/ ?

To be precise, the actual executables of the new GCC are in /usr/local/gcc/4.9.3/el6/bin/.

Thanks!
Last edited on
Following your advice

Sorry, but that is bollocks

What you did was an unmanaged source install -- not what was adviced:
I wrote:
You seem to have CentOS 6. You can get a second GCC like this:
1. install packages:
sudo yum install centos-release-scl-rh
sudo yum install devtoolset-4-toolchain

2. start a new shell:
scl enable devtoolset-4 bash

Within that bash session you will have GCC 5

The step 1 is done by the admin.

The step 2 is done by you every time you want to use that GCC.
@keskiverto: Thanks, let me digest your reply and will post what I did.
Finally, problem solved. Thank you all who gave input.
This is what worked for me (two steps):

1) Make sure GCC is ver. 4.8 or higher set as the default compiler for MPICH:
Since we had to keep the old GCC 4.4.7 ver, the new GCC 4.9.2 was installed "on the side." To chose the newer one between the two, do following.
--make sure your shell is bash
--add new GCC's bin folder to the FRONT of the PATH :
bash-4.1$ export PATH=/usr/local/gcc/4.9.3/el6/bin:$PATH
--check the compiler version:
bash-4.1$ gcc --version
gcc (GCC) 4.9.3 [in my case]

2) Since we are using LapackE (the C wrapper for Lapack), when compiling (mpiCC) make sure to add following preprocessor defines (-D):
-D LAPACK_COMPLEX_STRUCTURE -D HAVE_LAPACK_CONFIG_H -D ADD_

Cheers!

Last edited on
Topic archived. No new replies allowed.