【问题标题】:Compiler errors for GCC (via CUDA) intrinsic functions, but I'm not using anyGCC(通过CUDA)内在函数的编译器错误,但我没有使用任何
【发布时间】:2017-11-29 22:47:26
【问题描述】:

问题

我写了一堆小的 CUDA 程序。他们中的大多数在调试和发布版本中编译得很好。但是,在发布模式下编译时有一些失败,因为各种 GCC 内在函数被赋予了错误的指针类型。 但我实际上并没有使用内在函数。这个程序部分地重现了我的问题:

#include <iostream>
#include <cuda_runtime.h> // To pacify the syntax highlighter
#include <immintrin.h> // NOTE: I don't ever include this header in my real code

__global__ void kernel() {
  // Do nothing
}

using namespace std;

int main() {
  kernel<<<1, 1>>>();
  cout << "Hello, world!" << endl;

  return 0;
}

然而,问题在于,在我的实际代码中我没有包含&lt;immintrin.h&gt; 或使用任何类型的 GCC 内部函数。我使用的某些库代码可能确实如此,但我不确定。如果我从这个例子中删除&lt;immintrin.h&gt;,程序编译并运行良好。

真正的罪犯是herehere,如果你想看看的话。

相关事实

  • 我正在使用以下软件:

    • Ubuntu 17.04
    • nvcc 8.0.44版
    • gcc 5.4.1 版
    • cmake 版本 3.8.20170418
  • 项目在调试模式下构建和运行非常好,包括上面的示例程序。

  • 大部分我的小型 CUDA 程序在 Release 版本中都能正常编译,但我无法在失败的程序中找出任何模式。
  • Release build编译命令如下:
    • /usr/bin/g++-5 -std=c++11 -fopenmp -O3 -DNDEBUG -rdynamic CMakeFiles/DotProduct.dir/DotProduct_generated_main.cu.o CMakeFiles/DotProduct.dir/DotProduct_intermediate_link.o -o DotProduct -Wl,-Bstatic -lcudart_static -Wl,-Bdynamic -lpthread -ldl -lrt ../../Common/libCommon.a -Wl,-Bstatic -lcudart_static -Wl,-Bdynamic -lpthread -ldl -lrt -Wl,-Bstatic -lcudadevrt -Wl,-Bdynamic -L/usr/lib/x86_64-linux-gnu -lSDL2 -lSDL2_ttf -lSDL2 -lGLEW -lGLU -lGL
  • 完整的构建日志太大而无法附加,但可以找到here。以下是错误的相关示例:
/usr/lib/gcc/x86_64-linux-gnu/5/include/avx512fintrin.h(9533):错误:“void *”类型的参数与“long long *”类型的参数不兼容 /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512fintrin.h(9542):错误:“void *”类型的参数与“long long *”类型的参数不兼容 /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512pfintrin.h(54):错误:“const void *”类型的参数与“const long long *”类型的参数不兼容 /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512pfintrin.h(62):错误:“const void *”类型的参数与“const int *”类型的参数不兼容 /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512pfintrin.h(70):错误:“const void *”类型的参数与“const long long *”类型的参数不兼容 /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512pfintrin.h(78):错误:“const void *”类型的参数与“const int *”类型的参数不兼容 /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512pfintrin.h(86):错误:“void *”类型的参数与“const long long *”类型的参数不兼容
  • 错误日志没有说明谁在实际使用这些内在函数。
  • 事实证明,标头的顺序如下:&lt;random&gt; -> &lt;opt_random.h&gt; -> &lt;x86intrin.h&gt; -> &lt;immintrin.h&gt; ->(错误日志中提到的所有其他标头)。我现在的新目标是启用所有常见的优化除了那些内在函数。

【问题讨论】:

  • 您需要为不兼容的类型添加显式强制转换,即 myLongLongPtr = (long long *)myVoidPtr;
  • @Serge 在哪里?我实际上并没有使用这些功能,也不知道是谁。
  • CUDA 不支持您的编译器版本或操作系统。 docs.nvidia.com/cuda/cuda-installation-guide-linux/…
  • 升级到 CUDA 8.0.61 没有帮助...
  • 我会更明确地重复一遍。没有任何版本的 CUDA 8 支持 Ubuntu 17,也不支持您正在使用的规范 gcc 5.4-1 构建

标签: c++ gcc compiler-errors cuda intrinsics


【解决方案1】:

事实证明,这很可能是一个 nvcc 错误,源于 CUDA 声明对我的特定系统配置缺乏支持。我提交了报告here(您需要登录才能查看)。

目前,我通过不使用任何需要内在函数的东西来解决它。就我而言,我使用Thrust's random number generators 而不是the standard library's。我交谈过的人建议我也可以更仔细地分离我的主机和设备代码,这样nvcc 处理的源文件就不会包含&lt;immintrin.h&gt;。没试过,以后看到这个的人,值得一试。

【讨论】:

    【解决方案2】:

    问题不在于 GCC,而只是 nvcc 与 gcc 不兼容。

    以下是一个简单的解决方法,不会弄乱系统文件。

    如果您的 CPU 不支持 avx512,这样做应该是安全的。

    1. immintrin.h/usr/lib/gcc/x86_64-linux-gnu/5/include/复制到任何你想要的地方。
    2. 注释掉所有包含的 avx512*.h。
    3. 将包含目录提供给主机编译器(使用 nvcc 执行,然后将其传播到 gcc)并覆盖系统目录。

    您可以使用以下 cmake 代码安全地执行此操作。

    # Otherwise, avx512*intrin.h error: argument of type "const void *" is incompatible with parameter of type "const float *", etc...
    if(CUDA_VERSION STREQUAL "8.0" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
      execute_process(COMMAND ${CUDA_HOST_COMPILER} -dumpversion OUTPUT_VARIABLE
                      TEMP_CUDA_HOST_COMPILER_VERSION)
    
      if(${TEMP_CUDA_HOST_COMPILER_VERSION} VERSION_EQUAL "5.5" OR
         ${TEMP_CUDA_HOST_COMPILER_VERSION} VERSION_GREATER "5.5")
        # maybe simply downgrade the host compiler
        # set(CUDA_HOST_COMPILER "/usr/bin/gcc-4.9")
        set(CUDA_NVCC_FLAGS "-Xcompiler -I${CMAKE_CURRENT_SOURCE_DIR}/include/fix-cu80-gcc5;${CUDA_NVCC_FLAGS}")
        message(WARNING " CUDA 8.0 does not works well with GCC == 5.5.0 due to AVX512 intrinsics.\n"
                        " Will use\n"
                        "   include/fix-cu80-gcc5/immintrin.h\n"
                        " as a replacement of\n"
                        "   /usr/lib/gcc/x86_64-linux-gnu/5/include/immintrin.h\n")
      endif()
      unset(TEMP_CUDA_HOST_COMPILER_VERSION)
    endif()
    

    如果您的 CPU 确实支持 avx512,您可能需要提供一组 -mno-avx512f -mno-avx512pf ... 标志来明确禁用它们。

    【讨论】:

    • -march=native -mno-avx512f 应该禁用所有其他 AVX512 扩展;他们其他人都依赖于 AVX512-Foundation 扩展。就像 -mno-avx 也禁用 AVX2 和 FMA。除非 nvcc 与 gcc/clang 选项的工作方式非常不同......
    猜你喜欢
    • 2016-09-03
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多