Skip to content

Commit 66a79b1

Browse files
committed
add clarabel wasm feature flag
1 parent d4a4942 commit 66a79b1

9 files changed

+68
-33
lines changed

.github/workflows/rust.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ jobs:
3838
curl -LO https://github.com/rust-or/good_lp/releases/download/cplex/cplex.bin
3939
chmod u+x cplex.bin
4040
./cplex.bin -f ./.github/cplex/response.properties
41+
# Install wasm-pack
42+
cargo install wasm-pack
4143
- name: Build with all default solvers (no cplex)
4244
run: cargo build --features all_default_solvers --tests
4345
- name: Run tests with all default solvers (no cplex)
@@ -57,4 +59,8 @@ jobs:
5759
run: cargo test --no-default-features --features cplex-rs
5860
- name: Run tests with Clarabel
5961
run: cargo test --no-default-features --features clarabel
62+
- name: Run tests with Clarabel on WASM
63+
run: wasm-pack test --node --no-default-features --features "clarabel,clarabel-wasm"
64+
- name: Run tests with minilp on WASM
65+
run: wasm-pack test --node --no-default-features --features "minilp"
6066
- run: cargo bench

Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ default = ["coin_cbc", "singlethread-cbc"]
1616
singlethread-cbc = ["coin_cbc?/singlethread-cbc"]
1717
scip = ["russcip"]
1818
all_default_solvers = ["coin_cbc", "minilp", "lpsolve", "highs", "russcip", "lp-solvers", "clarabel"] # cplex-rs is not included because it is incompatible with lpsolve
19+
clarabel-wasm = ["clarabel/wasm"]
1920

2021
[dependencies]
2122
coin_cbc = { version = "0.1", optional = true, default-features = false }
@@ -29,9 +30,14 @@ clarabel = { version = "0.9.0", optional = true, features = [] }
2930
fnv = "1.0.5"
3031

3132
[dev-dependencies]
32-
criterion = "0.5"
3333
float_eq = "1.0"
3434

35+
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
36+
criterion = "0.5"
37+
38+
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
39+
wasm-bindgen-test = "0.3.0"
40+
3541
[[bench]]
3642
name = "benchmark"
3743
harness = false

benches/benchmark.rs

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
1-
use criterion::{black_box, criterion_group, criterion_main, Criterion};
1+
#[cfg(not(target_arch = "wasm32"))]
2+
mod bench {
3+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
24

3-
use good_lp::{default_solver, variable, variables, Expression, Solution, SolverModel};
5+
use good_lp::{default_solver, variable, variables, Expression, Solution, SolverModel};
46

5-
pub fn criterion_benchmark(c: &mut Criterion) {
6-
c.bench_function("sum((2 x_i + 1) for i in [1..100_000])", |b| {
7-
b.iter(|| {
8-
let mut vars = variables!();
9-
let v: Expression = (0..100_000)
10-
.map(|_i| {
11-
let x_i = vars.add_variable();
12-
black_box(2) * black_box(x_i) + black_box(1)
13-
})
14-
.sum();
15-
v
16-
})
17-
});
18-
19-
c.bench_function(
20-
"solving empty problem with 1M variables and reading results",
21-
|b| {
7+
pub fn criterion_benchmark(c: &mut Criterion) {
8+
c.bench_function("sum((2 x_i + 1) for i in [1..100_000])", |b| {
229
b.iter(|| {
2310
let mut vars = variables!();
24-
let vs = vars.add_vector(variable().min(0).name("test"), 1_000_000);
25-
let obj: Expression = vs.iter().sum();
26-
let sol = vars.minimise(&obj).using(default_solver).solve().unwrap();
27-
sol.eval(obj)
11+
let v: Expression = (0..100_000)
12+
.map(|_i| {
13+
let x_i = vars.add_variable();
14+
black_box(2) * black_box(x_i) + black_box(1)
15+
})
16+
.sum();
17+
v
2818
})
29-
},
30-
);
31-
}
19+
});
3220

33-
criterion_group!(benches, criterion_benchmark);
34-
criterion_main!(benches);
21+
c.bench_function(
22+
"solving empty problem with 1M variables and reading results",
23+
|b| {
24+
b.iter(|| {
25+
let mut vars = variables!();
26+
let vs = vars.add_vector(variable().min(0).name("test"), 1_000_000);
27+
let obj: Expression = vs.iter().sum();
28+
let sol = vars.minimise(&obj).using(default_solver).solve().unwrap();
29+
sol.eval(obj)
30+
})
31+
},
32+
);
33+
}
34+
35+
criterion_group!(benches, criterion_benchmark);
36+
criterion_main!(benches);
37+
}

tests/readme_example.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use std::error::Error;
22

33
use good_lp::{constraint, default_solver, variables, Solution, SolverModel};
4+
#[cfg(target_arch = "wasm32")]
5+
use wasm_bindgen_test::*;
46

57
#[test]
8+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
69
fn main() -> Result<(), Box<dyn Error>> {
710
variables! {
811
vars:

tests/resource_allocation_problem.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
1313
use good_lp::variable::ProblemVariables;
1414
use good_lp::{default_solver, variable, variables, Expression, Solution, SolverModel, Variable};
15-
15+
#[cfg(target_arch = "wasm32")]
16+
use wasm_bindgen_test::*;
1617
struct Product {
1718
// amount of fuel producing 1 unit takes
1819
needed_fuel: f64,
@@ -65,6 +66,7 @@ impl ResourceAllocationProblem {
6566
use float_eq::assert_float_eq;
6667

6768
#[test]
69+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
6870
fn resource_allocation() {
6971
let mut pb = ResourceAllocationProblem::new(5., 3.);
7072
let steel = pb.add(Product {
@@ -87,6 +89,7 @@ fn resource_allocation() {
8789
}
8890

8991
#[test]
92+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
9093
fn using_a_vector() {
9194
let products = vec![
9295
Product {

tests/shadow_price.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use good_lp::{
55
solvers::{DualValues, SolutionWithDual},
66
variable, variables, Solution, Solver, SolverModel,
77
};
8-
8+
#[cfg(target_arch = "wasm32")]
9+
use wasm_bindgen_test::*;
910
// Using a generic function here ensures the dual can be retrieved in a generic,
1011
// solver-independent manner.
1112
#[allow(dead_code)]
@@ -75,6 +76,7 @@ where
7576
macro_rules! dual_test {
7677
($([$solver_feature:literal, $solver:expr])*) => {
7778
#[test]
79+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
7880
fn determine_shadow_prices() {
7981
$(
8082
#[cfg(feature = $solver_feature)]
@@ -83,6 +85,7 @@ macro_rules! dual_test {
8385
}
8486

8587
#[test]
88+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
8689
fn furniture_problem() {
8790
$(
8891
#[cfg(feature = $solver_feature)]

tests/solver_scaling.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use float_eq::assert_float_eq;
22
use good_lp::{constraint, default_solver, variable, variables, Expression, Solution, SolverModel};
3-
3+
#[cfg(target_arch = "wasm32")]
4+
use wasm_bindgen_test::*;
45
const BIG_NUM: usize = 1000; // <- Set this higher to test how good_lp and the solvers scale
56

67
#[test]
@@ -21,6 +22,7 @@ fn solve_large_problem() {
2122
}
2223

2324
#[test]
25+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2426
fn add_10_000_constraints() {
2527
let mut vars = variables!();
2628
let v = vars.add_vector(variable(), 10_000);
@@ -31,6 +33,7 @@ fn add_10_000_constraints() {
3133
}
3234

3335
#[test]
36+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
3437
fn sum_binaries() {
3538
// See: https://github.com/rust-or/good_lp/issues/8
3639
let mut vars = variables!();

tests/static_solver.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use good_lp::{constraint, variables, Solution, SolverModel, StaticSolver};
2-
2+
#[cfg(target_arch = "wasm32")]
3+
use wasm_bindgen_test::*;
34
// See: https://github.com/rust-or/good_lp/pull/5
45

56
fn generic_solve_example<S: StaticSolver>(solver: S) -> Result<(), Box<dyn std::error::Error>> {
@@ -19,6 +20,7 @@ fn generic_solve_example<S: StaticSolver>(solver: S) -> Result<(), Box<dyn std::
1920
}
2021

2122
#[test]
23+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2224
fn concrete() {
2325
generic_solve_example(good_lp::default_solver).expect("solve")
2426
}

tests/variables.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use good_lp::{variables, Expression};
2+
#[cfg(target_arch = "wasm32")]
3+
use wasm_bindgen_test::*;
24

35
#[test]
6+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
47
fn complex_expression() {
58
let mut var1 = variables!();
69
let a = var1.add_variable();
@@ -14,6 +17,7 @@ fn complex_expression() {
1417
}
1518

1619
#[test]
20+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1721
fn large_sum() {
1822
let mut var1 = variables!();
1923
let var_vec: Vec<_> = (0..100_000).map(|_i| var1.add_variable()).collect();
@@ -23,6 +27,7 @@ fn large_sum() {
2327
}
2428

2529
#[test]
30+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
2631
fn complete() {
2732
let mut var1 = variables!();
2833
let mut var2 = variables!();
@@ -38,6 +43,7 @@ fn complete() {
3843
}
3944

4045
#[test]
46+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
4147
fn debug_format() {
4248
let mut vars = variables!();
4349
let a = vars.add_variable();

0 commit comments

Comments
 (0)