【问题标题】:How to compile Cuda within Clang when included by main c++ file?包含在 C++ 主文件中时如何在 Clang 中编译 Cuda?
【发布时间】:2019-05-22 17:08:33
【问题描述】:

我目前正在做一个项目,我想在 Cuda 中执行一些代码,这些代码应该从主 c++ 文件中调用。当我使用 Clang 编译时,仅编译 .cpp 文件,编译器在 >> 内核调用符号上告诉我“预期的表达”。知道如何解决这个问题吗?

我有一个包含定义的 .cuh 文件和一个 .cu 源文件。我正在使用 CMake 配置项目并使用 Ninja 构建它。

我正在使用 ccached clang++ 并提供“--cuda-path=/usr/local/cuda-10.1 --cuda-gpu-arch=sm_61 -L/usr/local/cuda-10.1/lib64 -lcudart_static -ldl -lrt -pthread -std=c++17" 到 clang args。

当我添加 -x cuda 标志时,错误不会出现,而是告诉我我链接的库不允许覆盖某些 host 函数,但我认为这是因为它想把所有东西都编译成 cuda,这不是有意的。

我通过 GLOB ${APP_PATH}/src/* 将我的源文件夹中的所有文件传递给 CMake 中的 add_executable,它应该添加所有文件。

main.cpp

#include "ParticleEngine.cuh"

...

int main(){
 simulation_timestep(&this->particles[0], this->gravity, 1, delta_frame,
                      this->particles.size());
}

ParticleEngine.cuh

#pragma once
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

void simulation_timestep(Particle *particles, ci::vec3 gravity, double mass,
                         double time_delta, unsigned long long n_particles);

ParticleEngine.cu

#include "ParticleEngine.cuh"

__global__ void particle_kernel(Particle *particles, ci::vec3 *gravity,
                                double *mass, double *time_delta) {
...
}


void simulation_timestep(Particle *particles, ci::vec3 gravity, double mass,
                         double time_delta, unsigned long long n_particles) {

  ... //memcpy stuff

  particle_kernel<<<dimgrid, dimblock>>>(cuda_particles, cuda_gravity,
                                         cuda_mass, cuda_time_delta);

  ...
}

编辑: 完整的错误信息:

[build] In file included from ../src/main.cpp:1:
[build] ../src/ParticleEngine.cu:43:20: error: expected expression
[build]   particle_kernel<<<dimgrid, dimblock>>>(cuda_particles, cuda_gravity,
[build]                    ^

编辑: 使用 -x cuda 执行 clang 时出现错误消息:

[build] /home/mebenstein/Cinder/include/glm/gtx/io.inl:97:32: error: __host__ __device__ function 'get_facet' cannot overload __host__ function 'get_facet'
[build]         GLM_FUNC_QUALIFIER FTy const& get_facet(std::basic_ios<CTy, CTr>& ios)
[build]                                       ^
[build] /home/mebenstein/Cinder/include/glm/gtx/io.hpp:145:14: note: previous declaration is here
[build]                 FTy const& get_facet(std::basic_ios<CTy,CTr>&);
[build]                            ^

我在 main.cpp 中包含了 c++ 库 cinder 并出现此错误。

【问题讨论】:

  • 将带有 CUDA 代码的 .cpp 文件重命名为 .cu?
  • 带有CUDA代码的文件是ParticleEngine.cu。问题是它没有编译为 CUDA,导致编译失败,因为编译 main.cpp 时它也被视为 c++ 文件。
  • 如果是这种情况,我们将需要更多信息,包括实际的错误消息。事实上,在 StackOverflow 上,您应该提供 minimal reproducible example 来回答“为什么这段代码不起作用?”这样的问题。
  • 上面的代码就是你所需要的。我在问题中添加了完整的错误消息。
  • 不要 #include 将 .cu 文件转换为 C++ 文件。您需要将 .cu 文件编译为单独的编译单元,否则编译器会尝试将其解释为(纯)C++。

标签: cmake cuda clang clang++ ninja


【解决方案1】:

#include 在 C++ 中的工作方式是将该语句替换为包含文件的内容。因此,包含的文件也被解析为 C++ 代码。

要将文件编译为 CUDA 代码,该文件需要是一个单独的编译单元,即作为 clang 调用的参数给出。它还需要有一个以.cu 结尾的名称,或者需要将-x cuda 标志提供给clang

在问题中包含错误消息后

更新

由于difference in how __host__/__device__ attributes are treated,Cinder 似乎不支持使用 clang++ 编译 CUDA 部分。

此时您的选择如下:

  1. 您可以修改 Cinder 使其也支持 clang++,它是开源的。

  2. 您可以询问 Cinder 作者或第三方是否愿意进行必要的更改。现金奖励可能会或可能不会增加意愿。

  3. 可以使用nvcc编译代码。

【讨论】:

  • 感谢您的回答。正如我在问题中已经提到的那样,我将 -x cuda 传递给 clang 并得到了另一个错误,因为它试图用它编译包含的第三方库。
  • 错误信息,或者它没有发生。
  • 我在问题中添加了错误消息。很抱歉我之前没有这样做。
  • 好吧,这终于告诉我们一些事情了。由于 __host__/__device 属性的处理方式不同,Cinder 无法使用 clang++ 进行编译。很好地询问 Cinder 作者是否愿意为 CUDA 代码支持 clang++,或者使用 nvcc。
  • 下次请检查How to Ask页面并立即提供错误消息。回答您的问题只需几分钟而不是几小时。你很幸运,这次我表现出这么大的毅力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 2010-11-13
  • 1970-01-01
  • 2021-08-02
  • 2021-03-21
  • 1970-01-01
  • 2021-11-14
相关资源
最近更新 更多