Clang/CUDA解析CUDA关键字共享

Clang/CUDA解析CUDA关键字共享,cuda,clang,llvm-clang,llvm-ir,Cuda,Clang,Llvm Clang,Llvm Ir,由于可以使用Clang进行CUDA编译,因此我有兴趣研究通过Clang到中间表示(IR)的CUDA代码(.cu文件)转换 Clang编译CUDA需要特定的CUDA库。那么,CUDA程序中关键字\uu_shared\u_的解析是由Clang还是由CUDA编译器完成的呢?从我最初的搜索中,我相信转换是由CUDA完成的,而不是Clang。这种理解正确吗 > P>当CLAN编译CUDA代码时,英伟达NVCC编译器不参与。 \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu共享或更准确地说\u

由于可以使用Clang进行CUDA编译,因此我有兴趣研究通过Clang到中间表示(IR)的CUDA代码(.cu文件)转换


Clang编译CUDA需要特定的CUDA库。那么,CUDA程序中关键字
\uu_shared\u_
的解析是由Clang还是由CUDA编译器完成的呢?从我最初的搜索中,我相信转换是由CUDA完成的,而不是Clang。这种理解正确吗

> P>当CLAN编译CUDA代码时,英伟达NVCC编译器不参与。
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu共享
或更准确地说
\uuuuuuuuuuuuu属性((共享))
是叮当知道的一个属性。如果clang遇到一个标记为shared属性的变量,它将做两件事:

  • 变量将具有静态链接。这意味着变量的定义从内核函数移动到模块范围
  • 变量将被放置在地址空间3中,地址空间3被定义为共享内存地址空间 用叮当声编译这个小程序:

    __global__ void foo(int* tmp)
    {
      __shared__ int vec[32];
      vec[threadIdx.x] = tmp[threadIdx.x];
      tmp[threadIdx.y] = vec[threadIdx.y];
    }
    
    int main()
    {
      int* tmp;
      foo<<<1, 1>>>(tmp);
      return tmp[0];
    }
    
    您可以看到变量
    vec
    在模块内部具有静态(但内部)链接,并驻留在地址空间3中

    Clang遵循可以找到的NVVM IR规范。但是,NVVM IR是为LLVM 3.4指定的,如果使用较新LLVM/Clang版本生成的IR,可能会遇到问题。然而,LLVM中的NVPTX后端没有这种限制,可以毫无问题地生成PTX代码。Clang(在更新的版本中)将像NVCC一样构建一个肥箱。在旧版本的Clang中,您必须自己构建可执行文件,并使用
    CUDAIsDevice
    命令行标志编译程序的设备部分

    PTX代码可以通过与CUDA API链接来编程GPU

    编辑: 既然问题出在哪里定义了
    \uuuuu shared\uuuu
    属性,那么这里就是: 在clang头文件中,CUDA工具包中包含了host_defines.h。在
    host_defines.h
    (来自CUDA 7.5)中,您可以看到:

      192 #define __shared__ \
      193         __location__(shared)
    
    \uuuuuuuuuuuuuuuuu
    (这是另一个宏定义)扩展为
    \uuuuuuuuuuuu注释\uuuuuuuu

       85 #define __annotate__(a) \
       86         __attribute__((a))
       87 #define __location__(a) \
       88         __annotate__(a)
    

    正如我在回答的第一部分中所写的,它被扩展为
    \uuuuuuu属性\uuuuuu
    。因此,<>代码>英伟达(So.Dealdx)//Cuff>扩展到AyAtditTyx((共享)) ./P> < P>当CLAN编译CUDA代码时,NVIDIA NVCC编译器不参与。p>
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu共享
    或更准确地说
    \uuuuuuuuuuuuu属性((共享))
    是叮当知道的一个属性。如果clang遇到一个标记为shared属性的变量,它将做两件事:

  • 变量将具有静态链接。这意味着变量的定义从内核函数移动到模块范围
  • 变量将被放置在地址空间3中,地址空间3被定义为共享内存地址空间 用叮当声编译这个小程序:

    __global__ void foo(int* tmp)
    {
      __shared__ int vec[32];
      vec[threadIdx.x] = tmp[threadIdx.x];
      tmp[threadIdx.y] = vec[threadIdx.y];
    }
    
    int main()
    {
      int* tmp;
      foo<<<1, 1>>>(tmp);
      return tmp[0];
    }
    
    您可以看到变量
    vec
    在模块内部具有静态(但内部)链接,并驻留在地址空间3中

    Clang遵循可以找到的NVVM IR规范。但是,NVVM IR是为LLVM 3.4指定的,如果使用较新LLVM/Clang版本生成的IR,可能会遇到问题。然而,LLVM中的NVPTX后端没有这种限制,可以毫无问题地生成PTX代码。Clang(在更新的版本中)将像NVCC一样构建一个肥箱。在旧版本的Clang中,您必须自己构建可执行文件,并使用
    CUDAIsDevice
    命令行标志编译程序的设备部分

    PTX代码可以通过与CUDA API链接来编程GPU

    编辑: 既然问题出在哪里定义了
    \uuuuu shared\uuuu
    属性,那么这里就是: 在clang头文件中,CUDA工具包中包含了host_defines.h。在
    host_defines.h
    (来自CUDA 7.5)中,您可以看到:

      192 #define __shared__ \
      193         __location__(shared)
    
    \uuuuuuuuuuuuuuuuu
    (这是另一个宏定义)扩展为
    \uuuuuuuuuuuu注释\uuuuuuuu

       85 #define __annotate__(a) \
       86         __attribute__((a))
       87 #define __location__(a) \
       88         __annotate__(a)
    

    正如我在回答的第一部分中所写的,它被扩展为
    \uuuuuuu属性\uuuuuu
    。因此,
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。如果Clang将.cu文件完全转换为IR,那么使用CUDA库进行编译的目的是什么…Clang在最终可执行文件中生成对CUDA库的调用,以加载和执行内核。我可以看到#定义为共享为u属性u((共享))在CUDA库中以及在clang/test/和clang/unittest/文件夹中。但是对于从.cu到IR的转换,可以使用哪一个呢?…Clang带来了一个名为“cuda_runtime.h”的内部头文件,它包含了来自cuda的所有必要部分。其他定义仅用于测试目的,因为它们位于clang的单元测试目录中。在使用clang编译CUDA代码(.cu文件)时,必须指定nvptx目标。我们使用CUDA库。如果Clang将.cu文件完全转换为IR,那么使用CUDA库进行编译的目的是什么…Clang在最终可执行文件中生成对CUDA库的调用,以加载和执行内核。我可以看到#定义为共享为u属性u((共享))在CUDA库中以及在clang/test/和clang/unittest/文件夹中。但是对于从.cu到IR的转换,可以使用哪一个呢?…Clang带来了一个名为“cuda_runtime.h”的内部头文件,它包含了来自cuda的所有必要部分。其他定义仅用于测试目的,因为它们位于clang的单元测试目录中。您必须指定一个nvptx目标