c++-14

Hi, I’m trying to compile some code written using some C+±14 features.

As an minimal example, consider this code “unique.cpp”:

#include <iostream>
#include <memory>

struct Vec3
{
    int x, y, z;
    Vec3() : x(0), y(0), z(0) { }
    Vec3(int x, int y, int z) :x(x), y(y), z(z) { }
    friend std::ostream& operator<<(std::ostream& os, Vec3& v) {
        return os << '{' << "x:" << v.x << " y:" << v.y << " z:" << v.z  << '}';
    }
};

int main()
{
    // Use the default constructor.
    std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();
    // Use the constructor that matches these arguments
    std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
    // Create a unique_ptr to an array of 5 elements
    std::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5);

    std::cout << "make_unique<Vec3>():      " << *v1 << '\n'
              << "make_unique<Vec3>(0,1,2): " << *v2 << '\n'
              << "make_unique<Vec3[]>(5):   " << '\n';
    for (int i = 0; i < 5; i++) {
      std::cout << "     " << v3[i] << '\n';
    }
}

On our cluster, the PGI compilers are built against GCC 6.4, I believe. When I compile with g+±6.4

g++ unique.cpp

Compilation succeeds.

With pgc++ however, I see numerous failures.

pgc++ --c++14  unique.cpp 
"unique.cpp", line 18: error: namespace "std" has no member "make_unique"
      std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();
                                      ^

"unique.cpp", line 18: error: type name is not allowed
      std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();
                                                  ^

"unique.cpp", line 18: error: expected an expression
      std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();
                                                        ^

"unique.cpp", line 20: error: namespace "std" has no member "make_unique"
      std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
                                      ^

"unique.cpp", line 20: error: type name is not allowed
      std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
                                                  ^

"unique.cpp", line 20: warning: expression has no effect
      std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
                                                        ^

"unique.cpp", line 20: warning: expression has no effect
      std::unique_ptr<Vec3> v2 = std::make_unique<Vec3>(0, 1, 2);
                                                        ^

"unique.cpp", line 22: error: namespace "std" has no member "make_unique"
      std::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5);
                                        ^

"unique.cpp", line 22: error: type name is not allowed
      std::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5);
                                                    ^

"unique.cpp", line 22: error: expected an expression
      std::unique_ptr<Vec3[]> v3 = std::make_unique<Vec3[]>(5);
                                                         ^

8 errors detected in the compilation of "unique.cpp".

Should I expect to be able to compile this code with PGI C++? If so is the issue related to the GCC PGI links with?

Thanks,

Trevor

I should mention I am using 18.7


pgc++ 18.7-0 64-bit target on x86-64 Linux -tp sandybridge 
PGI Compilers and Tools
Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.

Hi Greasy Chicken,

In order for pgc++ to be inter-operable with g++, we use the STL that comes with the GNU installation. I suspect that the g++ version that pgc++ is configured to use on your system is an earlier version that didn’t have C++14 support. I was able to reproduce the error on a system with GNU 4.8.5 installed, but was able to get to compile on another with GNU 5.4 and a third with GNU 6.4.1.

The PGI configuration information is stored in a file called “localrc” found in your PGI installation’s “bin” directory. I suspect that you’ll find that it’s pointing to an older GNU version. (The GNU version used will be based on the system where the PGI compilers were first installed)

To update the PGI configuration to use GNU 6.4, run the following command:

Code:
makelocalrc -x -d . -gcc <path/to/gnu6.4/bin/gcc> -g++ <path/to/gnu6.4/bin/g++> -g77 <path/to/gnu6.4/bin/gfortran>


This will create a new “localrc” file in your local directory.

From here, you can set the PGI environment variable “PGI_LOCALRC” to the fully qualified path to this localrc file.

Depending on how your cluster is configured, you can then overwrite the PGI installation with this new localrc file. However, this will effect every system on the cluster. Alternatively, you can copy the file to the PGI installation under a different name, such as “localrc.gnu641” and then set PGI_LOCALRC as before. This is particularly useful if your cluster uses modules where different GNU versions can be used. The module can then set the appropriate localrc file.

Alternatively, we do have a “network” install (set during installation) which will delay creation of the localrc until first use of the compilers on a system. Hence, each system on your cluster will have it’s own localrc file (named “localrc.systemname”). The caveat being that either users need write access to the PGI “bin” directory so they can create localrc files, or the system admin needs to run a PGI compilation on each system to create the localrc files.

Hope this helps,
Mat

Thanks so much, this was indeed the problem and I was unaware of the makelocalrc option.

For each PGI compiler, where is there documentation of which GCC are compatible. For instance, can I use gcc 8 with 18.4? Compiling a simple test example is not always illustrative of what is supported.

Cheers,

While not in tabular form, we do document when new GNU versions are interoperable in our release notes: Release Notes :: PGI version 18.7 Documentation for x86 and NVIDIA Processors

For example, from section 1.1 of the PGI 18.7 release notes:

The PGI compilers are now interoperable with GNU versions up to and including GCC 8.1. This includes interoperability between the PGI C++ compiler and g++ 8.1, and the ability for all of the PGI compilers to interoperate with the GCC 8.1 toolchain components, header files and libraries.

Hope this helps,
Mat

OK, thanks.

This is helpful, and I’ve tried all available options for GCC on our cluster. I’m still having issues compiling my target application, but I fear it’s due to PGI not being a supported compiler by one of the components:

Which is a bummer, but I learned a lot about the PGI toolchain. Thanks for your help.

Cheers

Greasy,

Do you have an isolated example of the problem? I pulled the latest version of Eigen down and I’m not seeing the same issue described in the SO link.

Sorry for the zombie thread…but I wanted to report that with 18.10 this issue has resolved itself and I can fully compile my project using the PGI toolchain.

Cheers,