使用 clang-llvm 编译器在 CUDA 中添加对类似于 __shared__ 的内存类型的支持
Adding support for a memory type similar to __shared__ in CUDA using clang-llvm compiler
我正在努力在 CUDA 中添加一种类似于 __shared__
的新内存类型,称为 __noc__
,需要使用 clang-llvm 进行编译。以下是实现从 :
引用的新内存类型解析的步骤
第一步: 在clangs的Attr.td文件(clang/include/clang/Basic/Attr.td)中,添加了类似shared关键字的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
类似,clang/lib/Sema/SemaDeclAttr.cpp.
中添加了CUDANocAttr
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;
第三步:在SemaDecl.cpp文件中,加入CUDANocAttr
强制noc为静态存储(类似于shared)
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
地址 space 访问 cuda_noc
地址 space =23=]
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
数组以允许新类型的地址 space
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中,没有观察到__noc__
对应的addrspace(6)
。
从放入文件 clang/lib/Sema/SemaDeclAttr.cpp(第 2 步)的调试 printf 中,可以观察到 AttributeList::AT_CUDANoc
的情况没有得到执行。
任何建议或直觉都会有很大帮助。在编译 llvm 源代码以使 *.td 文件中的输入显示为 C++ 源代码之前,是否有任何脚本要明确 运行...
__location__(noc)
扩展为 __attribute__((noc))
。这是 GNU 或 gcc 属性语法。所以问题在于这一行:
let Spellings = [Keyword<"noc">];
为了 noc
使用 __location__
宏,您应该使用 GNU<"noc">
而不是 Keyword<"noc">
。
我正在努力在 CUDA 中添加一种类似于 __shared__
的新内存类型,称为 __noc__
,需要使用 clang-llvm 进行编译。以下是实现从
第一步: 在clangs的Attr.td文件(clang/include/clang/Basic/Attr.td)中,添加了类似shared关键字的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
类似,clang/lib/Sema/SemaDeclAttr.cpp.
CUDANocAttr
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;
第三步:在SemaDecl.cpp文件中,加入CUDANocAttr
强制noc为静态存储(类似于shared)
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
地址 space 访问 cuda_noc
地址 space =23=]
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
数组以允许新类型的地址 space
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中,没有观察到__noc__
对应的addrspace(6)
。
从放入文件 clang/lib/Sema/SemaDeclAttr.cpp(第 2 步)的调试 printf 中,可以观察到 AttributeList::AT_CUDANoc
的情况没有得到执行。
任何建议或直觉都会有很大帮助。在编译 llvm 源代码以使 *.td 文件中的输入显示为 C++ 源代码之前,是否有任何脚本要明确 运行...
__location__(noc)
扩展为 __attribute__((noc))
。这是 GNU 或 gcc 属性语法。所以问题在于这一行:
let Spellings = [Keyword<"noc">];
为了 noc
使用 __location__
宏,您应该使用 GNU<"noc">
而不是 Keyword<"noc">
。