2

My C++ project main.cpp, compiled with pgcpp from PGI, calls a function cuda() containing CUDA code in a separate file cuda.cu, compiled with nvcc. Unless I wrap the cuda() function with extern "C" in the function declaration and the common header file, I get linking errors (undefined references).

Without extern "C" (symbol name mismatch => undefined reference):

$ nm main.o | grep -y cuda
U cuda__FPfPiT2iN32
$ nm cuda.o | grep -y cuda
T _Z13cudaPfPiS0_iS0_S0_S0_

With extern "C" (symbol name match => linking works fine):

$ nm main.o | grep -y cuda
U cuda
$ nm cuda.o | grep -y cuda
T cuda

It was my impression that nvcc used the host C++ compiler for host code, and that it would therefore mangle symbol names as in C++? What am I doing wrong then?

EDIT: Could this be due to the fact that nvcc actually uses the GNU compiler gcc for host code, and that this compiler mangles names differently than pgcpp?

EDIT2: My system has pgcpp 14.9, gcc 4.4.7, nvcc/CUDA 6.5

Robert Crovella
  • 143,785
  • 11
  • 213
  • 257
lodhb
  • 929
  • 2
  • 12
  • 29
  • 2
    nvcc in CUDA 6.5 and prior will use the host gnu compiler. PGI tools have both a PGI "native" toolchain and a PGI gnu-compatible toolchain. You can either switch to the PGI gnu-compatible toolchain (i.e. use `pgc++` instead of `pgcpp`), or you can switch to CUDA 7 which can use the PGI toolchain as your host compiler. You may want to study the [PGI documentation](https://www.pgroup.com/support/new_rel.htm). – Robert Crovella Feb 28 '15 at 14:09
  • Indeed this was my first reflex. The PGI User Guide does not indicate any difference between `pgc++` and `pgcpp`. The symbol names are indeed mangled identically when compiling the pure C++ code with `pgc++` instead of `pgcpp`. Thanks! – lodhb Feb 28 '15 at 14:20
  • 2
    Regarding this statement: "The PGI User Guide does not indicate any difference between pgc++ and pgcpp", try looking at page **xv** of the [PGI user guide](https://www.pgroup.com/doc/pgiug.pdf). – Robert Crovella Feb 28 '15 at 14:27
  • You are correct. I was given the 2014 version of the user guide. – lodhb Feb 28 '15 at 15:11

1 Answers1

2

nvcc uses (on linux) the host gcc/g++ (gnu) toolchain, by default.

PGI offers two slightly different toolchains for compiling C++ code. One toolchain is invoked using the pgcpp tool. This toolchain is not gnu-compatible, and will not necessarily produce gnu-compatible name-mangling. The other toolchain is invoked using the pgc++ tool, and it is advertised as gnu-compatible, and should produce gnu-compatible name mangling.

Linking problems of this type between objects produced by nvcc and PGI tools should be resolved by using the pgc++ tool.

As an aside, with CUDA 7 it is now possible to use the PGI compiler (pgc++) as the host compiler for nvcc. However this is not the crux of the issue here, although switching to that host compiler would fix the linking issue in a similar fashion.

Differences between pgcpp and pgc++ are referred to in current versions of the PGI users guide (e.g. page xv) and the PGI 2015 release notes:

PGI 2015 Features and Performance

•PGI C++ Compiler

◦PGC++ (pgc++) is now default on Linux and OS X. Features include GNU compatible name mangling and language features supporting g++ versions 4.2-4.8.

...

◦pgc++ is also now supported as an NVCC host compiler on Linux

Note that pgc++ is now (2015) considered "default" and pgcpp is listed as "deprecated."

Community
  • 1
  • 1
Robert Crovella
  • 143,785
  • 11
  • 213
  • 257