在 Windows 上使用 clang 编译 CUDA 时的重新定义
Redefinitions when compiling CUDA with clang on Windows
尽管已经问过一个几乎相同的 ,但答案是 OSX 并且不再成立(而且真的很老套)。
问题是在 windows 上用 clang 编译 cuda 时,math_functions.hpp
中有大量的重新定义。
经过一些调查,显然 cuda 决定将其 math_functions.hpp
和 math_functions.h
函数放在 namespace std
中(这甚至合法吗?),并与 [中的所有 libstdc++ 函数发生冲突=16=] 和 clang 自己编译 cuda 的头文件。
我该如何处理?最好不要使用上一个问题中显示的 hacky 方式?
旁注
根据 clang 的 documentation,clang 可以基于 __global__
/__device__
限定符进行重载,代码不应该直接编译吗?
详情
版本:
clang 4.0.0(像 this 一样构建)
libstdc++ 来自 gcc 7.1.0
库达 8.0
windows10
完整的错误输出
clang++ hellocuda.cu --cuda-path=E:\cuda\development --cuda-gpu-arch=sm_20 -LE:\cuda\development\lib\x64 -lcudart_static -ldl -lrt -std=c++1y -O2 -pedantic -Wall -Wextra -fms-extensions -o program.exe
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:1684:14: error: redefinition of
'__isnan'
__func__(int __isnan(double a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:525:28: note:
previous definition is here
__CRT_INLINE int __cdecl __isnan (double _x)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:1764:14: error: redefinition of
'__signbit'
__func__(int __signbit(double a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:611:28: note:
previous definition is here
__CRT_INLINE int __cdecl __signbit (double x) {
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:1776:17: error: redefinition of
'copysign'
__func__(double copysign(double a, double b))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:1069:31: note:
previous definition is here
__CRT_INLINE double __cdecl copysign (double x, double y)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3161:14: error: redefinition of
'__signbitl'
__func__(int __signbitl(long double a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:636:28: note:
previous definition is here
__CRT_INLINE int __cdecl __signbitl (long double x) {
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3166:14: error: redefinition of
'__signbitf'
__func__(int __signbitf(float a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:624:28: note:
previous definition is here
__CRT_INLINE int __cdecl __signbitf (float x) {
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3191:14: error: redefinition of
'__isnanl'
__func__(int __isnanl(long double a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:565:28: note:
previous definition is here
__CRT_INLINE int __cdecl __isnanl (long double _x)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3196:14: error: redefinition of
'__isnanf'
__func__(int __isnanf(float a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:546:28: note:
previous definition is here
__CRT_INLINE int __cdecl __isnanf (float _x)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3360:16: error: redefinition of
'copysignf'
__func__(float copysignf(float a, float b))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:1076:30: note:
previous definition is here
__CRT_INLINE float __cdecl copysignf (float x, float y)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:365:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isinf(double a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:107:17: note:
previous declaration is here
__DEVICE__ bool isinf(double);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:381:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isinf(float a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:108:17: note:
previous declaration is here
__DEVICE__ bool isinf(float);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:413:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isnan(double a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:115:17: note:
previous declaration is here
__DEVICE__ bool isnan(double);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:429:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isnan(float a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:116:17: note:
previous declaration is here
__DEVICE__ bool isnan(float);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:461:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isfinite(double a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:101:17: note:
previous declaration is here
__DEVICE__ bool isfinite(double);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:477:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isfinite(float a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:102:17: note:
previous declaration is here
__DEVICE__ bool isfinite(float);
~~~~ ^
14 errors generated.
makefile:15: recipe for target 'all' failed
mingw32-make: *** [all] Error 1
我尝试了很多东西。他们失败了。最后,我深入研究了 headers 并从字面上宏化了任何有冲突的东西,它们位于
- cuda 的 math_functions.hpp
- clang 的 __clang_cuda_math_forward_declares.h
- clang 的 __clang_cuda_cmath.h
clang 使用 _MSC_VER
来检测 Windows,它仅在使用 -fms-compatibility 标志时才定义,但是由于未知原因,这会在其他地方导致大量其他错误。
cuda 使用 _WIN32
和 _MSC_VER
的混合来检测 Windows。据我所知,将所有重新定义的内容宏化是最简单的方法。
这似乎有效,因为没有弹出其他 header 错误。
尽管已经问过一个几乎相同的
问题是在 windows 上用 clang 编译 cuda 时,math_functions.hpp
中有大量的重新定义。
经过一些调查,显然 cuda 决定将其 math_functions.hpp
和 math_functions.h
函数放在 namespace std
中(这甚至合法吗?),并与 [中的所有 libstdc++ 函数发生冲突=16=] 和 clang 自己编译 cuda 的头文件。
我该如何处理?最好不要使用上一个问题中显示的 hacky 方式?
旁注
根据 clang 的 documentation,clang 可以基于 __global__
/__device__
限定符进行重载,代码不应该直接编译吗?
详情
版本:
clang 4.0.0(像 this 一样构建)
libstdc++ 来自 gcc 7.1.0
库达 8.0
windows10
完整的错误输出
clang++ hellocuda.cu --cuda-path=E:\cuda\development --cuda-gpu-arch=sm_20 -LE:\cuda\development\lib\x64 -lcudart_static -ldl -lrt -std=c++1y -O2 -pedantic -Wall -Wextra -fms-extensions -o program.exe
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:1684:14: error: redefinition of
'__isnan'
__func__(int __isnan(double a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:525:28: note:
previous definition is here
__CRT_INLINE int __cdecl __isnan (double _x)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:1764:14: error: redefinition of
'__signbit'
__func__(int __signbit(double a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:611:28: note:
previous definition is here
__CRT_INLINE int __cdecl __signbit (double x) {
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:1776:17: error: redefinition of
'copysign'
__func__(double copysign(double a, double b))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:1069:31: note:
previous definition is here
__CRT_INLINE double __cdecl copysign (double x, double y)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3161:14: error: redefinition of
'__signbitl'
__func__(int __signbitl(long double a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:636:28: note:
previous definition is here
__CRT_INLINE int __cdecl __signbitl (long double x) {
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3166:14: error: redefinition of
'__signbitf'
__func__(int __signbitf(float a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:624:28: note:
previous definition is here
__CRT_INLINE int __cdecl __signbitf (float x) {
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3191:14: error: redefinition of
'__isnanl'
__func__(int __isnanl(long double a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:565:28: note:
previous definition is here
__CRT_INLINE int __cdecl __isnanl (long double _x)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3196:14: error: redefinition of
'__isnanf'
__func__(int __isnanf(float a))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:546:28: note:
previous definition is here
__CRT_INLINE int __cdecl __isnanf (float _x)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:191:
E:\cuda\development/include\math_functions.hpp:3360:16: error: redefinition of
'copysignf'
__func__(float copysignf(float a, float b))
^
E:\TDM-GCC\mingw64 7.1.0\mingw64\x86_64-w64-mingw32\include\math.h:1076:30: note:
previous definition is here
__CRT_INLINE float __cdecl copysignf (float x, float y)
^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:365:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isinf(double a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:107:17: note:
previous declaration is here
__DEVICE__ bool isinf(double);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:381:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isinf(float a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:108:17: note:
previous declaration is here
__DEVICE__ bool isinf(float);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:413:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isnan(double a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:115:17: note:
previous declaration is here
__DEVICE__ bool isnan(double);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:429:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isnan(float a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:116:17: note:
previous declaration is here
__DEVICE__ bool isnan(float);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:461:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isfinite(double a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:101:17: note:
previous declaration is here
__DEVICE__ bool isfinite(double);
~~~~ ^
In file included from <built-in>:1:
In file included from E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_runtime_wrapper.h:250:
E:\cuda\development/include\math_functions.hpp:477:43: error: functions that differ
only in their return type cannot be overloaded
static __inline__ __host__ __device__ int isfinite(float a)
~~~ ^
E:\LLVM\bin\..\lib\clang.0.0\include\__clang_cuda_math_forward_declares.h:102:17: note:
previous declaration is here
__DEVICE__ bool isfinite(float);
~~~~ ^
14 errors generated.
makefile:15: recipe for target 'all' failed
mingw32-make: *** [all] Error 1
我尝试了很多东西。他们失败了。最后,我深入研究了 headers 并从字面上宏化了任何有冲突的东西,它们位于
- cuda 的 math_functions.hpp
- clang 的 __clang_cuda_math_forward_declares.h
- clang 的 __clang_cuda_cmath.h
clang 使用 _MSC_VER
来检测 Windows,它仅在使用 -fms-compatibility 标志时才定义,但是由于未知原因,这会在其他地方导致大量其他错误。
cuda 使用 _WIN32
和 _MSC_VER
的混合来检测 Windows。据我所知,将所有重新定义的内容宏化是最简单的方法。
这似乎有效,因为没有弹出其他 header 错误。