如何用 CUB 库编译 C++?

Posted

技术标签:

【中文标题】如何用 CUB 库编译 C++?【英文标题】:How to compile C++ with CUB library? 【发布时间】:2020-03-30 22:33:19 【问题描述】:

我正在使用 CUB 设备功能,就像这里的示例 (https://forums.developer.nvidia.com/t/cub-library/37675/2)。我能够使用nvcc 编译上述示例中的.cu 源文件。

但是,我想知道是否可以在.cpp源文件中调用CUB设备函数并编译.cpp源文件(使用nvccg++)?我知道thrust 是可能的,因为示例here 对我有用。

目前我只是将 main 函数移动到一个新的 main.cpp 文件中,并将 cub 头文件包含在 main.cpp 中,但由于相同的错误,我无法使用 nvcc 或 g++ 编译它,部分错误消息:

/home/xx/cub/cub/block/specializations/../../block/../util_type.cuh:261:5: error: ‘__host__’ does not name a type; did you mean ‘__loff_t’?
         __host__ __device__ __forceinline__ NullType& operator =(const T&)  return *this; 
         ^~~~~~~~
         __loff_t
/home/xx/cub/cub/block/specializations/../../block/../util_type.cuh:316:19: error: ‘short4’ was not declared in this scope
     __CUB_ALIGN_BYTES(short4, 8)
                       ^
/home/xx/cub/cub/block/specializations/../../block/../util_type.cuh:314:52: error: ISO C++ forbids declaration of ‘__align__’ with no type [-fpermissive]
          enum  ALIGN_BYTES = b ; typedef __align__(b) t Type; ;
                                                        ^
/home/xx/cub/cub/block/specializations/../../block/../util_type.cuh:545:9: error: ‘__host__’ does not name a type; did you mean ‘__loff_t’?
             __host__ __device__ __forceinline__ CubVector operator+(const CubVector &other) const          \
             ^
/home/xx/cub/cub/block/specializations/../../block/../util_arch.cuh:64:38: error: ‘__host__’ does not name a type; did you mean ‘CUhostFn’?
         #define CUB_RUNTIME_FUNCTION __host__ __device__
                                      ^
/home/xx/cub/cub/device/../iterator/arg_index_input_iterator.cuh:144:25: error: ‘__forceinline__’ does not name a type; did you mean ‘__thrust_forceinline__’?
     __host__ __device__ __forceinline__ ArgIndexInputIterator(
                         ^~~~~~~~~~~~~~~
                         __thrust_forceinline__
/home/xx/cub/cub/device/device_reduce.cuh:148:12: error: ‘cudaError_t’ does not name a type; did you mean ‘cudaError_enum’?
     static cudaError_t Reduce(
            ^~~~~~~~~~~
            cudaError_enum

这是我的源文件:

device.h

#pragma once

#include <cub/cub.cuh>

void scan_on_device();

device.cu

#include "device.h"

void scan_on_device()

  // Declare, allocate, and initialize device pointers for input and output
  int num_items = 7;
  int *d_in;
  int h_in[]  = 8, 6, 7, 5, 3, 0, 9;
  int sz = sizeof(h_in)/sizeof(h_in[0]);
  int *d_out; // e.g., [ , , , , , , ]
  cudaMalloc(&d_in,  sz*sizeof(h_in[0]));
  cudaMalloc(&d_out, sz*sizeof(h_in[0]));
  cudaMemcpy(d_in, h_in, sz*sizeof(h_in[0]), cudaMemcpyHostToDevice);
  printf("\nInput:\n");
  for (int i = 0; i < sz; i++) printf("%d ", h_in[I]);
  // Determine temporary device storage requirements
  void *d_temp_storage = NULL;
  size_t temp_storage_bytes = 0;
  cub::DeviceScan::InclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items);
  // Allocate temporary storage
  cudaMalloc(&d_temp_storage, temp_storage_bytes);
  // Run inclusive prefix sum
  cub::DeviceScan::InclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items);
// d_out s<-- [8, 14, 21, 26, 29, 29, 38]
  cudaMemcpy(h_in, d_out, sz*sizeof(h_in[0]), cudaMemcpyDeviceToHost);
  printf("\nOutput:\n");
  for (int i = 0; i < sz; i++) printf("%d ", h_in[i]);
  printf("\n");

host.cpp

#include "device.h"
#include <cub/cub.cuh>

int main(void)

    scan_on_device();

    return 0;

我尝试分三步编译它们:

nvcc -O2 -c device.cu -I/home/xx/cub
g++  -O2 -c host.cpp  -I/usr/local/cuda/include/ -I/home/xx/cub
g++ -o tester device.o host.o -L/usr/local/cuda/lib64 -lcudart

第一步顺利,但第二步出现上述错误。任何想法表示赞赏。也许我弄乱了一些链接(到 cuda 或 cub)?

【问题讨论】:

device.hhost.cpp 中删除#include &lt;cub/cub.cuh&gt;。仅将其放在device.cu 中。然后你的代码应该可以编译了。 有人应该为未来的访客添加问题的答案..... 【参考方案1】:

cub 头文件库(例如cub.cuh)包含 CUDA C++ 代码。这样的代码不能由像 g++ 这样的普通主机编译器编译。如果你尝试这样做,你会得到编译错误。

但是,您的项目不需要cub.cuh 在您的device.h 头文件中,也不需要cub.cuh 由g++ 编译。 device.h 头文件中唯一需要的是 scan_on_device() 的函数原型。

因此,如果您在函数实现文件device.cu 中包含 cub 头文件,并在项目的其他地方将其删除,您的代码将编译。

【讨论】:

以上是关于如何用 CUB 库编译 C++?的主要内容,如果未能解决你的问题,请参考以下文章

如何用命令行编译c++程序

如何用VS 2008编译出可通用的lib静态库

如何用Visual Studio 2010编译boost1.42库

如何用Java实现条件编译

如何用cmake编译

如何用XCode创建Objective-c和C++的混编工程?