c++ - 如何用 CUB 库编译 C++?
问题描述
我正在使用 CUB 设备功能,就像这里的示例 ( https://forums.developer.nvidia.com/t/cub-library/37675/2 )。我能够使用 .cu 编译上述示例中的 .cu 源文件nvcc
。
但是,我想知道是否可以CUB
在 .cpp 源文件中调用设备函数并编译 .cpp 源文件(使用nvcc
or g++
)?我知道它是可能的thrust
,因为这里的例子对我有用。
目前我只是将 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
这是我的源文件:
设备.h
#pragma once
#include <cub/cub.cuh>
void scan_on_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");
}
主机.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)?
解决方案
cub 头文件库(例如cub.cuh
)包含 CUDA C++ 代码。这样的代码不能由像 g++ 这样的普通主机编译器编译。如果您尝试这样做,您将收到编译错误。
但是,您的项目不需要cub.cuh
在device.h
头文件中,也不需要cub.cuh
由 g++ 编译。device.h
头文件中唯一需要的是scan_on_device()
.
因此,如果您在函数实现文件中包含 cub 头文件device.cu
,并在项目的其他位置将其删除,您的代码将编译。
推荐阅读
- c++ - 类中的公共数据成员
- java - 无法在 TextView 上设置文本。给出 NullPointerException
- kubernetes - 如何让 My First ingress 在裸机 NodeIP 上运行?
- arrays - 使用反应钩子和受控组件更改获取的列表数组的值
- google-sheets - 如何使用查询根据谷歌表中的某些条件过滤数据
- python - 使用属性装饰器时,类对象同时包含 _和属性
- spring-boot - 如果我们在 K8s 中部署应用程序时使用 Eureka Discovery、Ribbon 等 Spring Cloud,何时使用?
- r - 使用深度网络和 R 中的 MNIST 数据读取手写数字序列 - 第 1 部分
- reactjs - TypeError: cv.Mat 不是构造函数(React & OpenCV.js)
- javascript - 禁用提交按钮,直到所有表单输入在 Rails 中都有值