概述
本示例展示了如何在 x86_64 主机中构建应用程序,目标设备为使用 aarch64 架构的 Jetson 设备。它使用了 cmake-3.5 中首次提供的几个特性。示例应用程序本身会创建一个输入图像,对其应用盒状滤波器,并将结果保存到磁盘。
说明
JetPack 的安装程序已经使用 gcc 设置了交叉编译工具链,但如果由于某些原因它不可用,请使用以下命令手动安装:
apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
现在可以指示 cmake 通过在 samples 目录中调用以下命令来创建交叉编译构建树
cmake . -DCMAKE_TOOLCHAIN_FILE=Toolchain_aarch64_l4t.cmake
文件 Toolchain_aarch64_l4t.cmake
包含在 samples 目录中,并定义了将要使用的交叉编译器以及其他配置。特别是,它还允许 CUDA 应用程序的交叉编译,前提是 CUDA aarch64 交叉编译库已正确安装在主机上。
- 注意
- 此示例也可以编译为目标主机。只需在 cmake 调用期间省略
CMAKE_TOOLCHAIN_FILE
参数即可。
用法是
./vpi_sample_08_cross_aarch64_l4t <后端>
其中
- backend:cpu、cuda 或 pva 之一;它定义了将执行处理的后端。
源代码
为了方便起见,这里提供了也安装在 samples 目录中的代码。
语言
39 #define CHECK_STATUS(STMT) \
42 VPIStatus status = (STMT); \
43 if (status != VPI_SUCCESS) \
45 char buffer[VPI_MAX_STATUS_MESSAGE_LENGTH]; \
46 vpiGetLastStatusMessage(buffer, sizeof(buffer)); \
47 std::ostringstream ss; \
48 ss << vpiStatusGetName(status) << ": " << buffer; \
49 throw std::runtime_error(ss.str()); \
53 int main(
int argc,
char *argv[])
66 throw std::runtime_error(std::string(
"Usage: ") + argv[0] +
" <cpu|pva|cuda>");
69 std::string strBackend = argv[1];
74 if (strBackend ==
"cpu")
78 else if (strBackend ==
"cuda")
82 else if (strBackend ==
"pva")
88 throw std::runtime_error(
"Backend '" + strBackend +
89 "' not recognized, it must be either cpu, cuda or pva.");
95 char imgContents[512][512];
96 for (
int i = 0; i < 512; ++i)
98 for (
int j = 0; j < 512; ++j)
100 imgContents[i][j] = i * 512 + j + i;
108 memset(&imgData, 0,
sizeof(imgData));
140 std::ofstream fd((
"boxfiltered_" + strBackend +
".pgm").c_str());
142 fd <<
"P5\n512 512 255\n";
143 for (
int i = 0; i < 512; ++i)
154 catch (std::exception &e)
156 std::cerr << e.what() << std::endl;
VPIStatus vpiSubmitBoxFilter(VPIStream stream, uint64_t backend, VPIImage input, VPIImage output, int32_t kernelWidth, int32_t kernelHeight, VPIBorderExtension border)
在图像上运行 2D 盒状滤波器。
VPIImageBuffer buffer
存储图像内容。
VPIImagePlanePitchLinear planes[VPI_MAX_PLANE_COUNT]
所有图像平面在 pitch-linear 布局中的数据。
VPIImageBufferPitchLinear pitch
以 pitch-linear 布局存储的图像。
VPIImageFormat format
图像格式。
VPIImageBufferType bufferType
图像缓冲区类型。
int32_t height
此平面的高度(像素)。
int32_t pitchBytes
一行的开头与前一行的开头之间的字节差。
void vpiImageDestroy(VPIImage img)
销毁图像实例。
struct VPIImageImpl * VPIImage
图像的句柄。
VPIStatus vpiImageCreateWrapper(const VPIImageData *data, const VPIImageWrapperParams *params, uint64_t flags, VPIImage *img)
通过包装现有内存块创建图像对象。
VPIStatus vpiImageLockData(VPIImage img, VPILockMode mode, VPIImageBufferType bufType, VPIImageData *data)
获取图像对象的锁并返回图像内容。
VPIStatus vpiImageCreate(int32_t width, int32_t height, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
使用指定的标志创建空的图像实例。
VPIStatus vpiImageUnlock(VPIImage img)
释放图像对象上的锁。
@ VPI_IMAGE_BUFFER_HOST_PITCH_LINEAR
主机可访问,平面采用 pitch-linear 内存布局。
struct VPIStreamImpl * VPIStream
流的句柄。
VPIStatus vpiStreamSync(VPIStream stream)
阻塞调用线程,直到此流队列中所有提交的命令都完成(队列为空)...
void vpiStreamDestroy(VPIStream stream)
销毁流实例并释放所有硬件资源。
VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
创建流实例。
@ VPI_BACKEND_CUDA
CUDA 后端。
@ VPI_BORDER_ZERO
图像外部的所有像素均被视为零。
@ VPI_LOCK_READ
仅锁定内存以进行读取。
这是正在使用的 cmake 工具链文件。
27 set(CMAKE_SYSTEM_NAME Linux)
28 set(CMAKE_SYSTEM_PROCESSOR aarch64)
30 set(target_arch aarch64-linux-gnu)
31 set(CMAKE_LIBRARY_ARCHITECTURE ${target_arch} CACHE STRING "" FORCE)
35 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
36 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
37 set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
38 set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
39 set(CMAKE_FIND_ROOT_PATH "/usr/${target_arch}")
41 # 需要避免执行一些更严格的编译器检查,这些检查在
43 set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
46 find_program(CMAKE_C_COMPILER ${target_arch}-gcc)
47 find_program(CMAKE_CXX_COMPILER ${target_arch}-g++)
48 if(NOT CMAKE_C_COMPILER OR NOT CMAKE_CXX_COMPILER)
49 message(FATAL_ERROR "找不到适用于 ${target_arch} 的合适的 C/C++ 交叉编译器")
52 set(CMAKE_AR ${target_arch}-ar CACHE FILEPATH "" FORCE)
53 set(CMAKE_RANLIB ${target_arch}-ranlib)
54 set(CMAKE_LINKER ${target_arch}-ld)
58 set(CMAKE_EXE_LINKER_FLAGS_INIT -Wl,--allow-shlib-undefined)
61 set(CMAKE_CUDA_FLAGS "-ccbin ${CMAKE_CXX_COMPILER} -Xcompiler -fPIC" CACHE STRING "" FORCE)
最后是随附的 CMakeLists.txt。请注意,它只是一个简单的 CMakeLists.txt。与交叉编译相关的所有内容都在上面的工具链文件中定义。
27 cmake_minimum_required(VERSION 3.5)
29 # 要从 x86 为 aarch64-l4t 目标进行交叉编译,
30 # 请将 -DCMAKE_TOOLCHAIN_FILE=Toolchain_aarch64_l4t.cmake 传递给
33 project(vpi_sample_08_cross_aarch64_l4t)
35 find_package(vpi ${vpi_API_VERSION} REQUIRED)
37 add_executable(${PROJECT_NAME} main.cpp)
38 target_link_libraries(${PROJECT_NAME} vpi)