You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CuPy RawKernel加载.cu文件时出现CompileException编译错误的求助

CuPy RawKernel加载.cu文件时出现CompileException编译错误的求助

问题重现

我有一个包含以下头文件引用的.cu文件:

#include </usr/include/features.h>
#include </usr/include/assert.h>
#include </usr/include/stdio.h>

用nvcc命令编译这个文件能正常通过,但通过cupy.RawKernel()加载执行时,直接抛出了编译异常,核心错误信息如下:

cupy.cuda.compiler.CompileException: /usr/include/features.h(439): catastrophic error: cannot open source file "stdc-predef.h"

问题原因

这是因为CuPy RawKernel底层依赖的NVRTC(NVIDIA Runtime Compilation),和传统nvcc离线编译的环境逻辑完全不同:

  • 传统nvcc编译时,会自动衔接系统标准头文件的完整依赖链,能顺利找到stdc-predef.h这类子依赖文件;
  • 但NVRTC的头文件搜索规则和系统gcc的默认路径不兼容,你用绝对路径硬指定/usr/include下的头文件,会导致NVRTC无法解析这些头文件内部引用的其他依赖(比如features.h里调用的stdc-predef.h)——因为NVRTC默认不会去遍历系统级的深层头文件路径;
  • 更关键的是,/usr/include下的很多头文件是针对CPU主机端的,而CuPy RawKernel运行的是GPU设备端代码,这些主机头文件大多是完全不需要的。

解决方法

给你几个逐步推进的解决步骤:

  1. 去掉头文件的绝对路径,改用标准引用写法
    把你的头文件引用改成C/C++标准的包含方式,让NVRTC自动去查找适配GPU环境的头文件版本:

    #include <features.h>
    #include <assert.h>
    #include <stdio.h>
    

    绝大多数情况下,NVRTC会自动匹配CUDA工具链提供的设备端兼容头文件,不会再出现找不到子依赖的问题。

  2. 移除不必要的主机端头文件
    仔细检查你的.cu代码:如果是给RawKernel用的设备端逻辑,features.h这类系统主机头文件完全可以直接删掉;如果需要断言或打印功能,assert.h和stdio.h在CUDA设备端本身就有支持(比如用<cstdio>实现设备端printf),不需要依赖系统主机头文件。

  3. 手动指定头文件搜索路径(兜底方案)
    如果上面的方法还是无法解决,可以在创建RawKernel时,给NVRTC手动添加系统头文件的搜索路径参数:

    from cupy import RawKernel
    
    # 读取你的CUDA内核代码
    with open("your_kernel.cu", "r") as f:
        kernel_code = f.read()
    
    # 传入编译选项,指定系统头文件路径(根据你的系统实际路径调整)
    raw_kernel = RawKernel(
        kernel_code, 
        "your_kernel_name", 
        options=("-I/usr/include", "-I/usr/lib/gcc/x86_64-linux-gnu/11/include")
    )
    

    注意这里的gcc版本路径要和你系统的实际安装情况匹配,这个方法只作为兜底,优先推荐前两种更规范的写法。

额外提示

CuPy RawKernel的代码是要运行在GPU设备上的,尽量只引入CUDA设备端兼容的头文件,避免混入主机端的系统头文件,这不仅能规避编译问题,还能让内核代码更轻量化。

备注:内容来源于stack exchange,提问作者forestbat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:03:03