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;
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).
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.]
--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.
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.
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?
@ 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>.
@ 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.
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/.
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_