linuxcompiler-errorscudanvcc

NVCC compilation error: exception specification is incompatible with that of previous function "cospi"


When I try to compile a simple CUDA program, e.g. the vectorAdd sample, I get errors about incompatible exception specifications:

$ nvcc -I ../../../Common/ -ccbin g++-13 -Wno-deprecated-gpu-targets vectorAdd.cu 
/usr/include/x86_64-linux-gnu/bits/mathcalls.h(79): error: exception specification is incompatible with that of previous function "cospi" (declared at line 2601 of /usr/local/cuda/bin/../targets/x86_64-linux/include/crt/math_functions.h)
   extern double cospi (double __x) noexcept (true); extern double __cospi (double __x) noexcept (true);
                                    ^

/usr/include/x86_64-linux-gnu/bits/mathcalls.h(81): error: exception specification is incompatible with that of previous function "sinpi" (declared at line 2556 of /usr/local/cuda/bin/../targets/x86_64-linux/include/crt/math_functions.h)
   extern double sinpi (double __x) noexcept (true); extern double __sinpi (double __x) noexcept (true);
                                    ^

/usr/include/x86_64-linux-gnu/bits/mathcalls.h(79): error: exception specification is incompatible with that of previous function "cospif" (declared at line 2623 of /usr/local/cuda/bin/../targets/x86_64-linux/include/crt/math_functions.h)
   extern float cospif (float __x) noexcept (true); extern float __cospif (float __x) noexcept (true);
                                   ^

/usr/include/x86_64-linux-gnu/bits/mathcalls.h(81): error: exception specification is incompatible with that of previous function "sinpif" (declared at line 2579 of /usr/local/cuda/bin/../targets/x86_64-linux/include/crt/math_functions.h)
   extern float sinpif (float __x) noexcept (true); extern float __sinpif (float __x) noexcept (true);
                                   ^

4 errors detected in the compilation of "vectorAdd.cu".

This didn't use to happen on my system before... what's going on?

System information:


Solution

  • As @RobertCrovella said on the NVIDIA developer forums - this is due to your system using glibc version 2.41. You can overcome this by patching the relevant header (math_functions.h) to bring the noexcept specification in line with your system's glibc header. Here's a patch with the necessary changes, up to line numbers; thanks goes to stefantalparau at the aforementioned forum:

    --- a/math_functions.h  00:02:30.815134398 +0300
    +++ b/math_functions.h  00:03:30.815134398 +0300
    @@ -2547,7 +2547,7 @@
      *
      * \note_accuracy_double
      */
    -extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 sinpi(double x);
    +extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 sinpi(double x) noexcept (true);
     /**
      * \ingroup CUDA_MATH_SINGLE
      * \brief Calculate the sine of the input argument 
    @@ -2570,7 +2570,7 @@
      *
      * \note_accuracy_single
      */
    -extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  sinpif(float x);
    +extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  sinpif(float x) noexcept (true);
     /**
      * \ingroup CUDA_MATH_DOUBLE
      * \brief Calculate the cosine of the input argument 
    @@ -2592,7 +2592,7 @@
      *
      * \note_accuracy_double
      */
    -extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 cospi(double x);
    +extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 cospi(double x) noexcept (true);
     /**
      * \ingroup CUDA_MATH_SINGLE
      * \brief Calculate the cosine of the input argument 
    @@ -2614,7 +2614,7 @@
      *
      * \note_accuracy_single
      */
    -extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  cospif(float x);
    +extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  cospif(float x) noexcept (true);
     /**
      * \ingroup CUDA_MATH_DOUBLE
      * \brief  Calculate the sine and cosine of the first input argument
    

    You need to apply this patch in the directory in which the math_functions.h file is located; or alternatively, do this:

    pushd /usr/local/cuda/include/crt
    patch < /path/to/cuda_glibc_241_compat.diff
    popd
    

    assuming CUDA is installed under /usr/local/cuda; that you've saved this patch as /path/to/cuda_glibc_241_compat.diff; and that you're root and have write access to that directory.

    Note: Some commenters suggest there may be additional functions which need to be marked noexcept (true), like rsqrt() - but possibly only with other combinations of CUDA and glibc versions, respectively. At any rate, the principle would be the same as for these trigonometric functions.


    Q: But is that safe to do?

    A: Umm... I think so. That's because noexcept does not distinguish between functions - unlike the function name and the parameter types; and these are device builtin functions, which would not throw an exception anyway. So, it should still be the "same" function. I believe it should not matter whether or not you device-link together code compiled using the different versions of this header. But - I'm not 100% sure. edit: Remember to watch out for snags if you later update your glibc or CUDA version.