32个版本 (18个稳定版)
2.0.1 | 2023年12月16日 |
---|---|
2.0.0 | 2022年11月7日 |
1.1.0 | 2022年6月29日 |
1.0.13 | 2022年3月12日 |
0.3.0 | 2016年7月15日 |
#115 in 构建实用工具
每月26次下载
105KB
1.5K SLoC
ispc-rs
一个小型库,旨在作为Cargo的构建依赖项使用,以便轻松地将ISPC代码集成到Rust项目中。ispc-rs分为两个crate:编译时crate ispc_compile和运行时crate ispc_rt。这种分离允许库作者避免将不必要的依赖项推送到不计划修改ISPC代码的库的最终用户。如果不需要这种分离,还提供了一个ispc-rs crate,它将编译时和运行时crate捆绑成一个方便的单个crate。
文档
使用ispc-rs
使用ispc-rs,您可以从构建脚本编译您的ISPC代码以生成一个本地库和一个包含对导出ISPC函数的绑定的Rust模块。ispc-rs将输出命令到Cargo以链接本地库,您可以使用提供的宏将Rust绑定导入到代码中,以调用库。以这种方式使用ispc-rs需要在编译crate时提供ISPC编译器和clang。
当编写需要打包和使用ISPC代码的crate或程序,但并不一定要求这些依赖在最终用户系统上时,ispc-rs实际上分为两个crate:编译时crate(ispc_compile
)和运行时crate(ispc_rt
)。ispc_compile
crate用于在构建脚本中编译ISPC代码,生成本地库和Rust绑定。ispc_rt
crate包含轻量级代码,可以包含在构建脚本中,用于查找并链接先前编译的本地库,以及一个宏来导入先前生成的Rust绑定。建议的使用案例是将ispc_compile
作为带有功能门控的可选依赖项。当使用此功能门控构建时,将构建ISPC代码,否则运行时crate将查找并使用现有的库。
报告ispc-rs的问题
请将任何问题或功能请求报告到GitHub问题跟踪器。
编译ISPC代码的要求
ISPC编译器和libclang(用于rust-bindgen)必须在您的路径中可用,才能编译ISPC代码并生成绑定。如果您使用ispc_rt
来链接到先前编译的库,则不需要这些。
Windows用户
您需要Visual Studio,并且必须使用Rust的MSVC ABI版本,因为在Windows上ISPC和Clang与MSVC链接。为了使bindgen能够找到libclang,您需要将libclang.lib
复制到clang.lib
,并将其放置在您的路径中。您还需要设置环境变量LIBCLANG_PATH=<LLVM路径\bin>
,以便bindgen能够成功找到clang。
将ispc-rs作为单个crate使用
要使用ispc-rs作为单个crate,您需要在crate中添加一个构建脚本(build.rs
),告诉Cargo关于它,并将ispc-rs作为构建时和编译时依赖项添加。
# Cargo.toml
[package]
# ...
build = "build.rs"
[dependencies]
ispc = "2.0"
[build-dependencies]
ispc = "2.0"
现在您可以使用ispc
将您的代码编译成静态库
extern crate ispc;
fn main() {
// Compile our ISPC library, this call will exit with EXIT_FAILURE if
// compilation fails.
ispc::compile_library("simple", &["src/simple.ispc"]);
}
运行cargo build
现在应将您的ISPC文件编译成库,并将您的Rust应用程序与之链接。为了提供额外的便利,提供了ispc_module
宏,用于将使用rust-bindgen生成的库绑定导入到具有相同名称的模块中。请注意,导入的所有函数都将是不安全的,因为它们是到您库的原始C绑定。
#[macro_use]
extern crate ispc;
// Functions exported from simple will be callable under simple::*
ispc_module!(simple);
使用独立的编译和运行时crate
使用独立crate的过程与单个crate的过程类似;然而,您将使用单独的ispc_compile
和ispc_rt
crate,其中前者标记为可选依赖项。这将允许最终用户使用crate并利用其ISPC代码,而无需在他们的机器上重新构建代码。因此,还建议为多个向量ISA构建您的ISPC代码,以便跨CPU架构提供可移植性。您还需要为每个宿主目标三元组打包编译的ISPC库。这可以通过在支持您库的用户的目标主机系统上启用ispc功能来构建crate来完成。请注意,在您未提供二进制的系统上使用您的crate的用户仍然可以通过使用带有ispc功能的crate来自行编译ISPC代码。
# Cargo.toml
[package]
# ...
build = "build.rs"
[dependencies]
ispc_rt = "2.0"
[build-dependencies]
ispc_rt = "2.0"
ispc_compile = { "2.0", optional = true }
[features]
ispc = ["ispc_compile"]
在构建脚本中,我们现在可以使用ispc
特性,可选地使用ispc_compile
编译ispc代码,否则我们将使用ispc_rt
链接先前构建的代码。在这里,我们还将输出编译后的ISPC库和绑定到src/目录中。
extern crate ispc_rt;
#[cfg(feature = "ispc")]
extern crate ispc_compile;
#[cfg(feature = "ispc")]
fn link_ispc() {
use ispc_compile::TargetISA;
ispc_compile::Config::new()
.file("src/simple.ispc")
.target_isas(vec![
TargetISA::SSE2i32x4,
TargetISA::SSE4i32x4,
TargetISA::AVX1i32x8,
TargetISA::AVX2i32x8,
TargetISA::AVX512KNLi32x16,
TargetISA::AVX512SKXi32x16])
.out_dir("src/")
.compile("simple");
}
#[cfg(not(feature = "ispc"))]
fn link_ispc() {
ispc_rt::PackagedModule::new("simple")
.lib_path("src/")
.link();
}
fn main() {
link_ispc();
}
运行cargo build --features ispc
现在将构建您的ISPC文件到库中,并为您导出的ISPC函数生成绑定。编译后的库和生成的绑定文件将保存在src/
目录下,以便与crate的其他部分一起打包。当使用cargo build
构建时,将链接之前为宿主系统编译的库。
无论是否使用ispc特性构建,您都可以像以前一样使用ispc_module!
宏将生成的绑定导入到您的Rust代码中
#[macro_use]
extern crate ispc;
// Functions exported from simple will be callable under simple::*
ispc_module!(simple);
依赖关系
~6–8MB
~150K SLoC