资讯动态

ZLUDA 中的 highs-sys:HiGHS 线性规划求解器的 Rust 绑定——特性开关、构建链与 Highs_call 接口完全指南

发布时间:2026/9/14 10:53:17 来源:尧图企业网站定制
ZLUDA 中的 highs-sysHiGHS 线性规划求解器的 Rust 绑定——特性开关、构建链与 Highs_call 接口完全指南【免费下载链接】ZLUDACUDA on non-NVIDIA GPUs项目地址: https://gitcode.com/GitHub_Trending/zl/ZLUDA本篇技术指南围绕 ZLUDA 仓库中 vendored 的 highs-sys 展开它是一套针对 HiGHS 线性规划Linear Programming求解器的 Rust 系统级绑定。读完后你将掌握如何为该 crate 配置特性开关build/discover/ninja/libz/highs_release、如何在 Linux/macOS/Windows 上备齐编译工具链、build.rs是如何通过 CMake 完成 HiGHS 源码静态构建与链接的以及如何用Highs_call这一简易 C 接口提交并求解一个实际的 LP 问题。一、highs-sys 是什么以及它在 ZLUDA 中的定位highs-sys 是 HiGHS 线性规划求解器的 Rust 绑定上游项目地址为 rust-or/highs-sys本项目将其以子目录形式 vendored 在 ext/highs-sys/。Cargo.toml 表明该 crate 版本为 1.11.0、MIT 许可关键字标签为linear-programming、optimization、math、solver。从仓库结构看highs-sys 在 ZLUDA 中承担双重角色它是 工作区成员根 Cargo.toml 的members列表中显式包含ext/highs-sys它同时是 crates.io 依赖的本地替换根 Cargo.toml 末尾的[patch.crates-io]段将highs-sys指向ext/highs-sys即工作区内任何依赖highs-sys的 crate 都会解析到这份 vendored 源码从而获得可复现、可审计的依赖版本。绑定由两部分构成src/c_bindings.rsbindgen 预生成的 FFI 声明#![allow(non_snake_case)]等 lint 放宽就是为了容纳 C 风格命名其中同时包含Highs_callc_bindings.rs#L1419与参数更完整的Highs_lpCallc_bindings.rs#L118src/lib.rs在include!(c_bindings.rs)之上补充了一组 Rust 风格的常量定义详见第五节。HiGHS 求解器本身的 C 源码以 git 子模块形式放在 ext/HiGHS/。需要注意的是当前 checkout 中ext/HiGHS目录为空说明该子模块尚未初始化。若你从上游克隆 highs-sysREADME 明确要求使用git clone --recursive带上子模块在 ZLUDA 中使用 vendored 副本做默认构建时同样需要保证ext/HiGHS已被正确填充例如通过递归初始化子模块否则build.rs指向的../HiGHS源目录不存在构建会失败。二、两种获取 HiGHS 的方式源码构建 vs 系统发现highs-sys 核心设计是“二选一”要么由 crate 自己编译 HiGHS 并静态链接要么链接系统上已安装好的版本。这对应 Cargo.toml 中两组可选构建依赖cmake对应build特性驱动 HiGHS 源码构建pkg-config对应discover特性探测系统已安装的 HiGHS。特性开关速查表特性默认作用生效前提build开启编译 HiGHS 源码并静态链接需要 C 编译器与 CMakehighs_release开启将 CMake profile 固定为Release与下游项目的 build profile 解耦仅在build开启时有效libz关闭链接 libz使 HiGHS 支持读取mps.gzgzip 压缩的 MPS 文件仅在build开启时有效ninja关闭将 CMake 生成器设为 Ninja仅在build开启时有效discover关闭用 pkg-config 发现并链接已安装的 HiGHS与build同时开启时优先需要 pkg-config 与系统 HiGHSdefault [build, highs_release]意味着开箱即用的行为就是“源码构建 静态链接 Release 档优化”。build.rs 的main()还内置了一个防御性检查如果启用了highs_release、libz、ninja中任意一个却没启用build会直接panic!并提示这些特性将永远不生效——这保证了“特性声明与实际构建行为不一致”的错误在编译期就暴露出来。运行时依赖C 标准库无论采用哪种链接方式HiGHS 在运行时的最低依赖是 C 标准库。你的构建系统和任何部署目标系统都必须安装它Debian/Ubuntusudo apt-get install libstdc6README 指出它通常已经预装macOS安装 Xcode 时自带 libcWindows依赖 MSVC 运行时一般随系统或 VS Build Tools 提供。编译工具链安装源码构建路径若走build特性构建机至少需要一个 C 编译器和 CMake启用额外特性还会引入相应依赖Linux以 Debian 为例sudo apt install g cmakemacOSxcode-select --install # C 编译器 brew install cmake # CMake 经 Homebrew 安装最省事如果启用了libz或ninja特性相应组件也需通过 brew 安装。Windows需要 CMake 与 Clang随 LLVM 发行两者都可以通过 winget 安装winget install -e --id Kitware.CMake winget install -e --id LLVM.LLVM启用 Ninja 特性时还可追加winget install -e --id Ninja-build.Ninja若需要libz即读取mps.gz的能力要么在你的项目中把libz-syscrate 作为依赖引入要么自行装好 libz 并设置ZLIB_ROOT环境变量让构建脚本找到它。仓库还提供了一个一键脚本 install-dependencies.sh按包管理器自动分派apt-get安装libstdc6 cmake、dnf安装libstdc cmake、brew安装cmake其他系统则报错退出。链接已安装版本discover 路径如果不想每次编译 HiGHS可以链接系统里现成的版本在系统上安装 pkg-config在依赖声明中启用discover特性例如highs-sys { features [discover] }且关闭默认的build。discover走的是动态链接因此被部署的系统上同样必须存在该版本的 HiGHS 运行库。上游 README 同时提醒编写时 HiGHS 被各家包管理器收录的情况很少多数场景下仍可能需要从源码自行构建并安装 HiGHS。三、build.rs 深度解析从 CMake 配置到链接指令build.rs 是理解该 crate 构建行为的关键其决策流程为discover()成功则跳过构建否则build()两者皆失败则 panic“Could neither discover nor build HiGHS”。3.1 源码构建build 特性build()函数build.rs#L35-L76基于cmake::Config指向../HiGHS源目录并设置了若干关键 CMake 定义let dst dst .define(FAST_BUILD, ON) // HiGHS 的快速构建模式 .define(BUILD_SHARED_LIBS, OFF) // 强制静态库 .define(CMAKE_MSVC_RUNTIME_LIBRARY, MultiThreaded) // 静态 MSVC 运行时 .define(ZLIB, if cfg!(feature libz) { ON } else { OFF }) .build();配合highs_release特性时的dst.profile(Release)可以看到 ZLUDA 采用的默认组合追求的是不依赖宿主项目的 profile、始终 Release 优化的纯静态HiGHS 库从而避免把libhighs.so/.dll带入产物。构建完成后脚本向 cargo 输出链接指令rustc-link-searchnative.../lib与.../lib64静态库查找路径rustc-link-libstatichighs显式静态链接libz特性开启时追加rustc-link-libz按目标平台链接 C 标准库Apple 目标链dylibcLinux 与 MinGW 目标链dylibstdc这正呼应了第二节“运行时需要 C 标准库”的说明rustc-rerun-if-changed../HiGHS/highs/interfaces/highs_c_api.h当 HiGHS C API 头文件变化时触发重建保证 FFI 声明与求解器版本同步。两个值得注意的工程细节sccache 加速try_use_sccache()检测环境变量SCCACHE_PATH命中后将其设置为 C/C 编译器的 launcherWindows 上还额外处理了 MSVC 调试信息格式与 CMP0141 策略。这对反复重编 HiGHS 大型 C 代码库的场景是实质性提速手段。Ninja 自动探测try_use_ninja()并不机械信任ninja特性而是实际执行ninja --version只有命令存在且返回成功才把 CMake 生成器设为 Ninja——特性声明与工具链可用性在此对齐。3.2 系统发现discover 特性discover()build.rs#L111-L124通过 pkg-config 探测名为highs的包且要求版本不低于 1.5.0atleast_version(1.5.0)。探测成功后会调用 bindgen基于 pkg-config 给出的 include 路径现场生成绑定allowlist_function(^Highs.*)入口头文件是 wrapper.h 这个“trivial wrapper”作用只是让 HiGHS 头文件能从 include 路径中被发现。从源码结构看build路径下generate_bindings是注释掉的build.rs#L53-L54绑定以预生成形式固化在 src/c_bindings.rs 中而discover路径则动态生成。两条路径都锚定同一个^Highs.*函数白名单API 面保持一致。四、Highs_call 接口一次完整的 LP 求解HiGHS 提供一个“简易 C 接口”Highs_call专为求解如下一般 LP 设计Min c^T x subject to L A x U; l x u其中A是 m 行 n 列的约束矩阵稀疏存储为列主序压缩格式。各参数与语义的对应关系如下完整注释见 test_highs_call.rs#L6-L58参数含义numcol/numrow变量个数 n / 约束个数 mnnz矩阵 A 中非零元总数colcost目标系数向量 ccollower/colupper变量下界 l / 上界 urowlower/rowupper约束下界 L / 上界 Uastart/aindex/avalue列主序三元组列起始位置astart[0]必须为 0/ 按列排列的行下标 / 按列排列的非零值colvalue/coldual输出原解 x / 变量 x 的对偶值rowvalue/rowdual输出Ax 值 / 约束的对偶值colbasisstatus/rowbasisstatus输出变量/约束的基本-非基本状态modelstatus输出求解状态码见下表求解最大化问题时只需把 c 取负即可。完整可运行示例以下示例来自上游 README演示求解问题Min f 2x_0 3x_1 s.t. x_1 6 10 x_0 2x_1 14 8 2x_0 x_1 0 x_0 3; 1 x_1其最优解为x_0 2, x_1 4fn main() { let numcol: usize 2; let numrow: usize 3; let nnz: usize 5; // 列成本、变量上下界 let colcost: [f64] [2.0, 3.0]; let collower: [f64] [0.0, 1.0]; let colupper: [f64] [3.0, 1.0e30]; // 1e30 表示“无上界” // 行约束上下界 let rowlower: [f64] [-1.0e30, 10.0, 8.0]; let rowupper: [f64] [6.0, 14.0, 1.0e30]; // 约束矩阵的列主序存储 // 第 0 列: (row1, 1.0), (row2, 2.0) - x_0 系数: 0*x? 即 A [0 1; 1 2; 2 1] let astart: [c_int] [0, 2]; let aindex: [c_int] [1, 2, 0, 1, 2]; let avalue: [f64] [1.0, 2.0, 1.0, 2.0, 1.0]; let colvalue: mut [f64] mut vec![0.; numcol]; let coldual: mut [f64] mut vec![0.; numcol]; let rowvalue: mut [f64] mut vec![0.; numrow]; let rowdual: mut [f64] mut vec![0.; numrow]; let colbasisstatus: mut [c_int] mut vec![0; numcol]; let rowbasisstatus: mut [c_int] mut vec![0; numrow]; let modelstatus: mut c_int mut 0; let status: c_int unsafe { Highs_call( numcol.try_into().unwrap(), numrow.try_into().unwrap(), nnz.try_into().unwrap(), colcost.as_ptr(), collower.as_ptr(), colupper.as_ptr(), rowlower.as_ptr(), rowupper.as_ptr(), astart.as_ptr(), aindex.as_ptr(), avalue.as_ptr(), colvalue.as_mut_ptr(), coldual.as_mut_ptr(), rowvalue.as_mut_ptr(), rowdual.as_mut_ptr(), colbasisstatus.as_mut_ptr(), rowbasisstatus.as_mut_ptr(), modelstatus, ) }; assert_eq!(status, 0); // 最优解 x_0 2, x_1 4 assert_eq!(colvalue, [2., 4.]); }仓库内的集成测试 tests/test_highs_call.rs 用同一问题做了回归验证断言返回状态为STATUS_OK且colvalue [2., 4.]。值得注意的是该测试调用的是参数更完整的Highs_lpCalltest_highs_call.rs#L87-L111比Highs_call多传了三类参数MATRIX_FORMAT_COLUMN_WISE1显式声明列主序lib.rs中还定义了MATRIX_FORMAT_ROW_WISE2可供行主序输入OBJECTIVE_SENSE_MINIMIZE1目标方向OBJECTIVE_SENSE_MAXIMIZE-1对应最大化无需再手工取负 coffset目标函数常数项偏移示例中为0.0。因此选择建议是只有“最小化 列主序”的最朴素场景用Highs_call需要行主序、最大化或目标偏移时改用Highs_lpCall。五、lib.rs 的常量面状态码与格式枚举src/lib.rs 在预生成绑定之上补了一层对 Rust 友好的常量层求解后判断modelstatus时可直接使用这些名称而非裸整数状态码STATUS_OK 0、STATUS_WARNING 1、STATUS_ERROR -1模型状态MODEL_STATUS_*NOTSET(0)、LOAD_ERROR(1)、MODEL_ERROR(2)、PRESOLVE_ERROR(3)、SOLVE_ERROR(4)、POSTSOLVE_ERROR(5)、MODEL_EMPTY(6)、OPTIMAL(7)、INFEASIBLE(8)、UNBOUNDED_OR_INFEASIBLE(9)、UNBOUNDED(10)、OBJECTIVE_BOUND(11)、OBJECTIVE_TARGET(12)、REACHED_TIME_LIMIT(13)、REACHED_ITERATION_LIMIT(14)、UNKNOWN(15)并导出MODEL_STATUS_MIN/MODEL_STATUS_MAX作为遍历边界矩阵格式MATRIX_FORMAT_NONE(0)、MATRIX_FORMAT_COLUMN_WISE(1)、MATRIX_FORMAT_ROW_WISE(2)目标方向OBJECTIVE_SENSE_MINIMIZE(1)、OBJECTIVE_SENSE_MAXIMIZE(-1)。所有类型的整数宽度统一为 HiGHS C API 的HighsInt调用方从usize/i32传入时需像示例那样做try_into()转换。六、适用前提、限制与验证路径结合本仓库的实际内容使用该 crate 时需注意以下前提子模块前提默认build路径要求ext/HiGHS已包含 HiGHS 源码当前 checkout 中该目录为空属于未初始化的子模块上游 highs-sys 仓库要求以--recursive方式克隆以获取子模块。discover 版本下限pkg-config 路径硬性要求 HiGHS ≥ 1.5.0低版本系统包会导致探测失败并回退本 crate 中回退失败即直接报错。动态链接的部署代价discover通常产生动态链接运行目标机必须安装对应 HiGHSbuild路径产出静态库部署面最小但运行机仍需 C 标准库。libz 的读取能力边界libz特性只影响“能否读取mps.gz压缩 MPS 文件”与 LP 求解本身无关不需要该输入格式时可保持关闭以减小依赖面。绑定来源差异build路径使用预生成的 c_bindings.rsdiscover路径按系统头文件现场生成两条路径的函数白名单一致^Highs.*但对新 HiGHS 版本 API 演进的响应时机不同跨版本行为应以rerun-if-changed锚定的highs_c_api.h为准。验证与深入路径回归测试位于 tests/test_highs_call.rs、test_highs_functions.rs绑定入口头文件为 wrapper.h构建逻辑全文见 build.rs上游 README 亦建议以其 tests 目录作为更多用法的参照。【免费下载链接】ZLUDACUDA on non-NVIDIA GPUs项目地址: https://gitcode.com/GitHub_Trending/zl/ZLUDA创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价