cuda - 使用 clang-llvm 编译器在 CUDA 中添加对类似于 __shared__ 的内存类型的支持

标签 cuda clang llvm llvm-clang llvm-ir

我正在努力添加类似于 __shared__ 的新内存类型在 CUDA 中称为 __noc__需要使用 clang-llvm 进行编译。以下是实现新内存类型解析的步骤,引用 answer :

第 1 步:在 clangs 的 Attr.td 文件 (clang/include/clang/Basic/Attr.td) 中,添加了与共享关键字类似的 noc 关键字。

def CUDAShared : InheritableAttr {
  let Spellings = [GNU<"shared">];
  let Subjects = SubjectList<[Var]>;
  let LangOpts = [CUDA];
  let Documentation = [Undocumented];
}

def CUDANoc : InheritableAttr {
  let Spellings = [Keyword<"noc">];
  let Subjects = SubjectList<[Var]>;
  let LangOpts = [CUDA];
  let Documentation = [Undocumented];
}

第 2 步:类似于 CUDASharedAttr , CUDANocAttr添加到 clang/lib/Sema/SemaDeclAttr.cpp 中。

  case AttributeList::AT_CUDAShared:
    handleSimpleAttribute<CUDASharedAttr>(S, D, Attr);
    break;
  case AttributeList::AT_CUDANoc:
    handleSimpleAttribute<CUDANocAttr>(S, D, Attr);
    printf("\n T1:SemaDeclAttr.cpp"); //testpoint 1 : for noc debugging
    break;

第 3 步:在 SemaDecl.cpp 文件中,CUDANocAttr添加以强制 noc 为静态存储(类似于共享)

  if (getLangOpts().CUDA) {
    if (EmitTLSUnsupportedError && DeclAttrsMatchCUDAMode(getLangOpts(), NewVD))
      Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
           diag::err_thread_unsupported);
    // CUDA B.2.5: "__shared__ and __constant__ variables have implied static
    // storage [duration]."
    if (SC == SC_None && S->getFnParent() != nullptr &&
        (NewVD->hasAttr<CUDASharedAttr>() ||
         NewVD->hasAttr<CUDANocAttr>()||
         NewVD->hasAttr<CUDAConstantAttr>())) {
      NewVD->setStorageClass(SC_Static);
    }
  }

第4步:在CodeGenModule (llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp)中添加NOC以允许cuda_noc的访问地址空间来自NVPTXAddrSpaceMap

    else if (D->hasAttr<CUDASharedAttr>())
      AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_shared);
    else if (D->hasAttr<CUDANocAttr>())
      AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_noc);
    else
      AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_device);
  }

  return AddrSpace;
}

第 5 步:cuda_noc添加到NVPTXAddrSpaceMap数组以允许新类型的地址空间

static const unsigned NVPTXAddrSpaceMap[] = {
    1, // opencl_global
    3, // opencl_local
    4, // opencl_constant
    // FIXME: generic has to be added to the target
    0, // opencl_generic
    1, // cuda_device
    4, // cuda_constant
    3, // cuda_shared
    6, // cuda_noc
};

第 6 步:宏 #define __noc__ __location__(noc)添加到文件 clang/lib/Headers/__clang_cuda_runtime_wrapper.h,其中包含来自 CUDA 的 host_defines.h。

llvm源代码已成功编译并安装。但是当尝试使用内存类型 __noc__ 编译 CUDA 源文件时,它会给出以下警告:

warning: unknown attribute 'noc' ignored [-Wunknown-attributes]
        __noc__ int c_shared[5];
        ^

/usr/local/bin/../lib/clang/3.8.0/include/__clang_cuda_runtime_wrapper.h:69:30: note: expanded from macro '__noc__'
#define __noc__ __location__(noc)
                             ^
1 warning generated.

从警告中可以看出__noc__被忽略。在生成的 IR 中,addrspace(6)对应__noc__未观察到。

从放入文件 clang/lib/Sema/SemaDeclAttr.cpp 的调试 printf(步骤 2)中,可以观察到 AttributeList::AT_CUDANoc 的情况。没有被处决。

任何建议或直觉都会有很大帮助。在编译 llvm 源代码之前是否有任何脚本需要显式运行,以使 *.td 文件中的输入显示为 C++ 源代码...

最佳答案

__location__(noc)扩展为 __attribute__((noc)) 。这是 GNU 或 gcc 属性语法。所以问题出在这一行:

let Spellings = [Keyword<"noc">];

为了noc__location__ 一起工作宏,你应该使用 GNU<"noc">而不是Keyword<"noc"> .

关于cuda - 使用 clang-llvm 编译器在 CUDA 中添加对类似于 __shared__ 的内存类型的支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35519825/

相关文章:

c++ - CUDA 内核自动调用内核完成 vector 加法。为什么?

c++ - "Duplicate symbol"小于 "-O2"

emacs - Flycheck - 禁用 Clang 作为检查器*永久*

c++ - LLVM 自动 C++ 链接

iphone - 是否可以使用来自非 Apple 操作系统的兼容 LLVM IR/位码来定位 iPhone?

ios - 如何交叉编译 GCC 以生成适用于 iOS 设备(arm、armv7)的 libgfortran?

assertion - CUDA:如何在内核代码中断言?

cuda - 为什么 Cuda 运行时在初始化时保留 80 GiB 虚拟内存?

c++ - 使用内核参数在 CUDA 内核中声明数组

c++ - 二进制表达式 ('std::ostream' (又名 'basic_ostream<char>' )和 'const char *' 的无效操作数