18 个稳定版本
2.0.1 | 2023 年 12 月 16 日 |
---|---|
2.0.0 | 2022 年 11 月 7 日 |
1.1.0 | 2022 年 6 月 29 日 |
1.0.13 | 2022 年 3 月 9 日 |
1.0.5 | 2019 年 2 月 25 日 |
305 在 构建工具 中排名
77 每月下载量
在 6 crates 中使用
43KB
702 行
ispc-rs
一个小型库,旨在作为 Cargo 的构建依赖项使用,以便轻松将 ISPC 代码集成到 Rust 项目中。ispc-rs 分为两个 crate:编译时 crate ispc_compile 和运行时 crate ispc_rt。这种拆分允许库作者避免将不必要的依赖项推送到不计划修改 ISPC 代码的库的最终用户。如果不需要这种分离,还提供了 ispc-rs crate,它将编译时和运行时 crate 打包成一个方便的单个 crate。
文档
Rust 文档可以在 这里 找到,ISPC 文档可以在 这里 找到。
使用 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代码并生成绑定,ISPC编译器和libclang(用于rust-bindgen)必须在您的路径中。如果使用ispc_rt
链接到之前编译的库,则不需要这些。
Windows用户
您需要Visual Studio,并必须使用Rust的MSVC ABI版本,因为ISPC和Clang在Windows上与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生成的库的绑定导入到具有相同名称的模块中。请注意,所有导入的函数都将是不安全的,因为它们是针对您的lib的原始C绑定。
#[macro_use]
extern crate ispc;
// Functions exported from simple will be callable under simple::*
ispc_module!(simple);
使用独立的编译和运行时crate
使用独立包的过程与单个包类似;然而,您将使用单独的 ispc_compile
和 ispc_rt
包,其中前者标记为可选依赖项。这允许最终用户使用该包并利用其 ISPC 代码,而无需在自己的机器上重新构建代码。因此,也建议为多个矢量 ISA 构建您的 ISPC 代码,以便跨 CPU 架构实现可移植性。您还需要为每个目标主机三元组打包编译的 ISPC 库。这可以通过在每个您想支持的用户的目标主机系统上启用 ispc 功能来构建您的包来完成。请注意,即使您没有为其提供二进制的系统,您的包的用户仍然可以通过启用 ispc 功能使用您的包来编译 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/
目录下,以便与包的其他部分一起打包。当使用 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
~148K SLoC