Issues configuring CDO 1.9.0 with PGI 17.5

All,

I recently updated a set of libraries I build for GEOS, a climate model, and I’m hitting all sorts of issues with PGI and a few of them (NCO, CDO, SDPToolkit). I’m going to start with CDO since it dies at configure, not in the build, and seems to be C++ related (as NCO is).

The issue I’m seeing is that it says it is not a C++11 compiler:

..snip..
checking for mpic++ option to produce PIC... -fPIC -DPIC
checking if mpic++ PIC flag -fPIC -DPIC works... yes
checking if mpic++ static flag -static works... no
checking if mpic++ supports -c -o file.o... yes
checking if mpic++ supports -c -o file.o... (cached) yes
checking whether the mpic++ linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking dynamic linker characteristics... (cached) GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking for C/C++ restrict keyword... __restrict
checking whether mpic++ supports C++11 features by default... no
checking whether mpic++ supports C++11 features with -std=gnu++11... no
checking whether mpic++ supports C++11 features with -std=gnu++0x... no
checking whether mpic++ supports C++11 features with -std=c++11... no
checking whether mpic++ supports C++11 features with +std=c++11... no
checking whether mpic++ supports C++11 features with -h std=c++11... no
checking whether mpic++ supports C++11 features with -std=c++0x... no
checking whether mpic++ supports C++11 features with +std=c++0x... no
checking whether mpic++ supports C++11 features with -h std=c++0x... no
configure: error: *** A compiler with support for C++11 language features is required.
make[1]: *** [cdo.config] Error 1

As far as I know, -std=c++11 is a good flag for pgc++, so hmm. Digging through config.log, it seems to be tripping at:

  // If the compiler admits that it is not ready for C++11, why torture it?
  // Hopefully, this will speed up the test.
  
  #ifndef __cplusplus
  
  #error "This is not a C++ compiler"
  
  #elif __cplusplus < 201103L
  
  #error "This is not a C++11 compiler"
  
  #else
  ...

when I run:

(79)((HEAD detached at d5a54b9)) $ mpic++ -std=c++11 ~/conftest.cpp 
"/home/mathomp4/conftest.cpp", line 36: catastrophic error: #error directive:
          "This is not a C++11 compiler"
  #error "This is not a C++11 compiler"
   ^

1 catastrophic error detected in the compilation of "/home/mathomp4/conftest.cpp".
Compilation terminated.

Now, for your edification:

(105)((no branch)) $ mpic++ --version

pgc++ 17.5-0 64-bit target on x86-64 Linux -tp nehalem 
PGI Compilers and Tools
Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
(106)((no branch)) $ g++ --version
g++ (GCC) 6.3.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

My first thought was perhaps GCC 6.3.0 is too new for PGI 17.5, but even if I downgrade to GCC 6.1.0 or 5.3.0, I get the same error. (I even tried 7.1.0 in a fit of pique.) Any ideas?

I have asked for PGI 17.7 to be installed on this box, so I’ll test that soon.

Matt

Does

setenv CXXFLAGS “-D__cplusplus=201103L --c++11”

work as a workaround?

dave

Yes it does. Took me a while to get GNU make to pass it in correctly, but it does…and then it fails later on:

	mpic++ -DHAVE_CONFIG_H -I.  -I../libcdi/src -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include -DpgiFortran  -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/zlib    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/szlib    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/jpeg    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/hdf5    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/hdf    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/uuid    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/netcdf    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/udunits2    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/gsl    -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/antlr   -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include -I/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.5-openmpi_2.1.1-gcc_6.3.0/Linux/include/udunits2  -D__cplusplus=201103L --c++11   -c -o cdo-cdo.o `test -f 'cdo.cc' || echo './'`cdo.cc
"/usr/include/c++/4.4.7/ratio", line 102: error: identifier "__INTMAX_MAX__" is
          undefined
        static_assert(__b0 * __a0 <= __INTMAX_MAX__, 
                                     ^

"/usr/include/c++/4.4.7/ratio", line 114: error: identifier "__INTMAX_MAX__" is
          undefined
      : integral_constant<bool, (_Pn <= __INTMAX_MAX__ - _Qn)>
                                        ^

"cdo_int.h", line 69: warning: allowing all exceptions is incompatible with
          previous function "strdup" (declared at line 175 of
          "/usr/include/string.h")
  char *strdup(const char *s);
                             ^

"cdo.cc", line 141: warning: allowing all exceptions is incompatible with
          previous function "feenableexcept" (declared at line 123 of
          "/usr/include/fenv.h")
    int feenableexcept(int);
                           ^

2 errors detected in the compilation of "cdo.cc".

Easybuild seems to have encountered something similar:

https://github.com/easybuilders/easybuild-easyblocks/issues/830

but I’m not setting CPATH in my module for PGI 17.5.

And isn’t INTMAX_MAX defined in stdint.h?

Matt

I have filed TPR 24679 to set _cplusplus correctly, and the
INTMAX_MAX issue.

dave

Dave,

Thanks. Any possible workaround?

From Engineering

  1. __cplusplus is set correctly to 201103L when compiling with --c++11. But __cplusplus is set to 201103L instead of 201402L when compiling with --c++14. That is a bug in pgc++. I cannot reproduce the problem that the user saw with “mpic++ -std=c++11”. In all the tests I ran, mpic++ is correctly passing the C++11 option through to pgc++.

  2. pgc++ automatically defines INTMAX_MAX on systems with GCC 4.7 or higher. But the user is on a GCC 4.4 system. The failure to define INTMAX_MAX on GCC 4.4 systems is a bug in pgc++

=========================================================

if you don’t know (and you wouldn’t unless you read the release notes),
you should only use -c++11 and -c++14 with gcc 5.1 or newer. We need gcc to support c++11 and c++14 as well for things to work with pgc++…

dave.

First, I can confirm the same issues with PGI 17.7. Figured it would be that way, but, good to confirm.

In re answer #1, how can I tell if mpic++ is getting the option through? Everything I can see with my testing says it isn’t working even with pgc++:

(156) $ g++ --version
g++ (GCC) 6.3.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

(157) $ pgc++ --version

pgc++ 17.7-0 64-bit target on x86-64 Linux -tp nehalem 
PGI Compilers and Tools
Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
(158) $ cat conftest_small.cpp
// If the compiler admits that it is not ready for C++11, why torture it?
// Hopefully, this will speed up the test.

#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201103L
#error "This is not a C++11 compiler"
#else
#include <iostream>
int main()
{
   std::cout << "Hello world\n";
}
#endif  // __cplusplus >= 201103L
(159) $ pgc++ --c++11 conftest_small.cpp
"conftest_small.cpp", line 7: catastrophic error: #error directive: "This is
          not a C++11 compiler"
  #error "This is not a C++11 compiler"
   ^

1 catastrophic error detected in the compilation of "conftest_small.cpp".
Compilation terminated.
(160) $ g++ --std=c++11 conftest_small.cpp
(161) $ ./a.out
Hello world

As for #2, yeah, my test bed is still running RHEL 6. I’ve kept it there because I still support some 6 desktops that haven’t moved to 7. Hmm. Maybe it’s time to upgrade it to 7 and use another 6 box when needed since our PGI is node-locked anyway so for PGI use 7 is as good as 6.

Matt

Dave,

Further question. I have loaded GCC 6.3.0 as a module in combination with PGI 17.5/7. But, is PGI seeing this? Is there a way to test to see which g++ that pgc++ is seeing during its use? Because, if so, shouldn’t PGI be seeing that g++ and not my 4.4?

Matt

We do not detect the gcc version on the fly. If you wish for pgi compilers
to run with different versions of gcc, you need a localrc file for each
version.

If your system has ‘locate’, you can run ‘addlocalrc’
out of the PGI bin directory, and it will find and gcc versions you have
and create localrc files for it. Then set $PGI_LOCALRC to point to
the rc file, and it will use it.

This only works on Linux with a Network Installation, because all
the different PGI headers and libs are provided with a network install.

So

  1. be on Linux.
  2. Install the compilers with a ‘Network Install’. This will install to the
    default gcc version.
  3. chmod +x addlocalrc ! to make it executable.
  4. addlocalrc
    which will create and name a number of localrc files.
  5. export PGI_LOCALRC=/path/to/localrc.gccversion

run the compilers now.


% more yy.cpp
#include

int main(){
std::cout << INTMAX_MAX << ‘\n’;
#if defined(__cplusplus)
std::cout <<"__cplusplus is " << __cplusplus << ‘\n’;
#endif
#if (__cplusplus < 201402L )
std::cout <<"__cplusplus is < 201402L" << ‘\n’;
#endif
#if (__cplusplus < 201103L )
std::cout <<"__cplusplus is < 201103L" << ‘\n’;
#endif

return 0;
}

% pgc++ -o pgi_yy_no_switch yy.cpp
% pgc++ -o pgi_yy_c++11 yy.cpp -std=c++11
% pgc++ -o pgi_yy_c++14 y.cpp -std=c++14

% g++ -o gnu_yy_no_switch yy.cpp
% g++ -o gnu_yy_c++11 yy.cpp -std=c++11
% g++ -o gnu_yy_c++14 y.cpp -std=c++14

and see what happens.

looks like g++ 4.7 and above do c++11, and g++ 5.2 and above do c++14

dave

dave,

Well, I had to hack addlocalrc a bit to work on my system (my GCC 6.3.0 isn’t in a place indexed by locate), but I think I got there.

And when I do that, CDO and NCO still don’t build…but it’s a different error. NCO:

libtool: link: mpic++ -g -O2 -o ncap2 Invoke.o ncap2.o ncap2_utl.o ncap2_att.o sdo_utl.o sym_cls.o fmc_cls.o fmc_all_cls.o fmc_gsl_cls.o prs_cls.o NcapVar.o
 NcapVarVector.o ncoLexer.o ncoParser.o ncoTree.o nco_gsl.o  -L../nco /ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/src/nco/src/nco/.libs/libnco.a -
L/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib -L/ford1/share/gmao_SIteam/
Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux//lib /ford1/share/gmao_SIteam/MPI/openmpi_2.1.1-pgi_17.7-
gcc_6.3.0/lib/libmpi.so /ford1/share/gmao_SIteam/MPI/openmpi_2.1.1-pgi_17.7-gcc_6.3.0/lib/libopen-rte.so /ford1/share/gmao_SIteam/MPI/openmpi_2.1.1-pgi_17.7
-gcc_6.3.0/lib/libopen-pal.so -lutil /ford1/local/gcc/gcc-6.3.0/lib/../lib64/libstdc++.so /ford1/local/gcc/gcc-6.3.0/lib/../lib64/libatomic.so -lantlr /ford
1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/libgslcblas.a /ford1/share/gmao_S
Iteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/libgsl.a /ford1/share/gmao_SIteam/Baselibs/ESMA
-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/libnetcdf.a /ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/
x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/libhdf5_hl.a /ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-
linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/libhdf5.a /ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortra
n_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/libz.a /ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-
gcc_6.3.0/Linux/lib/libudunits2.a -lexpat /ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.
3.0/Linux/lib/libmfhdf.a /ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/lib
df.a /ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/libsz.a -ljpeg /ford1/s
hare/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/x86_64-unknown-linux-gnu/pgfortran_17.7-openmpi_2.1.1-gcc_6.3.0/Linux/lib/libcurl.a -lssl -lcrypto -lz -lrt -l
dl -lm -pthread -mp -Wl,-rpath -Wl,/ford1/share/gmao_SIteam/MPI/openmpi_2.1.1-pgi_17.7-gcc_6.3.0/lib -Wl,-rpath -Wl,/ford1/local/gcc/gcc-6.3.0/lib/../lib64 
-Wl,-rpath -Wl,/ford1/share/gmao_SIteam/MPI/openmpi_2.1.1-pgi_17.7-gcc_6.3.0/lib -Wl,-rpath -Wl,/ford1/local/gcc/gcc-6.3.0/lib/../lib64
ncoLexer.o: In function `.st133150':
ncoLexer.cpp:(.data+0xe70): undefined reference to `.LB21098'
ncoLexer.cpp:(.data+0xe78): undefined reference to `.LB21098'
ncoLexer.cpp:(.data+0xe80): undefined reference to `.LB21098'
ncoLexer.cpp:(.data+0xe88): undefined reference to `.LB21098'
ncoLexer.cpp:(.data+0xe90): undefined reference to `.LB21098'
ncoLexer.o:ncoLexer.cpp:(.data+0xe98): more undefined references to `.LB21098' follow
ncoLexer.o: In function `.st133549':
ncoLexer.cpp:(.data+0x10d0): undefined reference to `.LB21231'
ncoLexer.cpp:(.data+0x10d8): undefined reference to `.LB21231'
ncoLexer.cpp:(.data+0x10e0): undefined reference to `.LB21231'
ncoLexer.cpp:(.data+0x10e8): undefined reference to `.LB21231'
ncoLexer.cpp:(.data+0x10f0): undefined reference to `.LB21231'
ncoLexer.o:ncoLexer.cpp:(.data+0x10f8): more undefined references to `.LB21231' follow
ncoLexer.o: In function `.st135824':
ncoLexer.cpp:(.data+0x17f0): undefined reference to `.LB21409'
ncoLexer.cpp:(.data+0x17f8): undefined reference to `.LB21409'
ncoLexer.cpp:(.data+0x1800): undefined reference to `.LB21409'
ncoLexer.cpp:(.data+0x1808): undefined reference to `.LB21409'
ncoLexer.cpp:(.data+0x1810): undefined reference to `.LB21409'
ncoLexer.o:ncoLexer.cpp:(.data+0x1818): more undefined references to `.LB21409' follow
ncoLexer.o: In function `.st138885':
ncoLexer.cpp:(.data+0x1cb0): undefined reference to `.LB21629'
ncoLexer.cpp:(.data+0x1cb8): undefined reference to `.LB21629'
ncoLexer.cpp:(.data+0x1cc0): undefined reference to `.LB21629'
ncoLexer.cpp:(.data+0x1cc8): undefined reference to `.LB21629'
ncoLexer.cpp:(.data+0x1cd0): undefined reference to `.LB21629'
ncoLexer.o:ncoLexer.cpp:(.data+0x1cd8): more undefined references to `.LB21629' follow
make[4]: *** [ncap2] Error 2

CDO had many instances of:

"array.cc", line 100: error: more than one instance of overloaded function
          "isnan" matches the argument list:
            function "isnan(double)"
            function "std::isnan(double)"
            argument types are: (double)
    *rmean = DBL_IS_EQUAL(rsumw, 0.) ? missval : rsum/rsumw;
             ^

So…yeah. Actually, doing this led to ESMF failing to build as well:

"/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/src/esmf/src/Infrastruct
          ure/Mesh/src/Moab/moab/Util.hpp", line 66: error: more than one
          instance of overloaded function "isinf" matches the argument list:
            function "isinf(double)"
            function "std::isinf(double)"
            argument types are: (double)
    return moab_isfinite(value);
           ^
          detected during instantiation of "bool moab::Util::is_finite(T) [with
                    T=double]" at line 165 of
                    "/ford1/share/gmao_SIteam/Baselibs/ESMA-Baselibs-5.0.5/src/
                    esmf/src/Infrastructure/Mesh/src/Moab/BSPTree.cpp"

I’m thinking that I’ve now double-defined something in the last two cases (too many include directories?).

Matt

Hey Matt,

Dave’s out this week so I thought I’d jump in an try to help.

It took awhile, but I was finally able to reproduce the NCO error on a system with GNU 6.2 installed. While I haven’t dug into it, whenever I’ve seen these errors before, it’s due to the compiler optimizing away portions of the code but missing some labels. In this case, these appear to be debugging labels so the work around is to edit the Makefile in “src/nco++” and either remove “-g” or change it to “-gopt” for the CXXFLAGS.

I’m out of time for today, but tomorrow will try to put together a reproducer for our compiler folks so they can investigate.

I’ll also take a look at the CDO and ESMF issues but it appears the compiler doesn’t know which isnan the program wants to use. The C99 version or the C++ version. You might try modifying the DBL_IS_EQUAL macro to use “std::isnan” so there’s no confusion.

-Mat