#ispc #build-script #cargo-build #simd #bindings-generator #generated-bindings #build-dependencies

构建 ispc_compile

ispc_compile 是 Cargo 构建脚本的构建时依赖,用于编译和链接 ISPC 代码,并生成对生成的库的 Rust 绑定。生成的绑定可以使用 ispc_rt 导入,它还将支持链接到预构建的 ISPC 代码。使用预构建的二进制文件对于使用 ISPC 分发库或工具很有用,同时不需要最终用户拥有 ISPC 编译器。

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构建工具 中排名

Download history 23/week @ 2024-04-22 11/week @ 2024-04-29 4/week @ 2024-05-13 21/week @ 2024-05-20 27/week @ 2024-05-27 26/week @ 2024-06-03 21/week @ 2024-06-10 22/week @ 2024-06-17 20/week @ 2024-06-24 99/week @ 2024-07-01 5/week @ 2024-07-08 15/week @ 2024-07-15 2/week @ 2024-07-22 43/week @ 2024-07-29 17/week @ 2024-08-05

77 每月下载量
6 crates 中使用

MIT 许可证

43KB
702

ispc-rs

Actions Status Latest version Documentation MIT

一个小型库,旨在作为 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_compileispc_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);

一些更完整的示例可以在 examples/ 文件夹中找到。独立的包示例在这里 here

依赖关系

~6–8MB
~148K SLoC