【问题标题】:Redefinitions when compiling CUDA with clang on Windows在 Windows 上使用 clang 编译 CUDA 时的重新定义
【发布时间】:2017-05-26 06:46:06
【问题描述】:

尽管已经问过几乎相同的question,但答案是针对 OSX 的,不再适用(而且真的很老套)。

问题是在 windows 上使用 clang 编译 cuda 时,math_functions.hpp 中有大量的重新定义。

经过一些调查,显然 cuda 决定将其 math_functions.hppmath_functions.h 函数放在 namespace std 中(这是否合法?),并与 cmath 中的所有 libstdc++ 函数和 clang 自己的编译头文件发生冲突cuda。

我该如何处理?最好不要使用上一个问题中显示的hacky方式?

旁注

根据clang的documentation,clang可以基于__global__/__device__限定符重载,代码不应该只是编译吗?

详情

版本:
clang 4.0.0(像 this 一样构建)
libstdc++ 来自 gcc 7.1.0
cuda 8.0
窗户 10

完整的错误输出

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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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\4.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

【问题讨论】:

  • +1 用于尝试使用 clang 编译 CUDA 代码。无论谁回答 - 将您的答案放在更普遍地使用 CUDA 的 clang 的背景下,将不胜感激!
  • 您是否尝试过使用旧版本的 libstdc++ 甚至 libc++
  • @jlk clang 自己用于编译 cuda 的头文件与 cuda 的头文件发生冲突,因此切换库对此无济于事。我会试试 libc++ 看看那些cmath 会不会消失
  • @PasserBy libstdc++ 的 math.h 和 CUDA 的 math_functions.hpp 之间存在冲突,clang 只是试图通过在 __clang_cuda_runtime_wrapper.h 中做很多黑魔法来避免冲突,所以有可能在MinGW 的 libstdc++ 的最新版本。 Clang 的文档说从 2017 年 1 月 5 日起支持在 Windows 上编译 CUDA,所以我认为这在某个时候是可行的。请注意,在 Linux 上,像 __isnan 这样的函数没有在标准库中定义,并且在 CUDA 标头中它们由#if defined(_WIN32) 保护,因此问题可能只是由于缺乏测试。
  • 您尝试使用 Clang 编译 CUDA 定义。这会导致与预先存在的宏定义发生冲突。由于宏是无范围的,因此取消定义它们可能会有所帮助。

标签: c++ cuda clang++


【解决方案1】:

我尝试了很多东西。他们失败了。最后,我深入研究了标题并从字面上宏化了任何有冲突的东西,它们位于

  • 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。据我所知,将所有重新定义的东西宏化掉是最简单的方法。

这似乎有效,因为没有弹出其他标题错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 2012-03-14
    • 2021-11-02
    • 2012-10-18
    • 1970-01-01
    相关资源
    最近更新 更多