Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,39 @@ jobs:
run: pytest
working-directory: pumpkin-py

wasm:
name: Build pumpkin-solver (wasm32-unknown-emscripten)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# cache Cargo registry & your target/ dir
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

# install Rust & add the Emscripten target
- uses: dtolnay/rust-toolchain@stable
- run: rustup target add wasm32-unknown-emscripten

# install Emscripten SDK & clang
- run: |
sudo apt-get update
sudo apt-get install -y emscripten clang

# build only pumpkin-solver for wasm
- name: Build pumpkin-solver wasm
run: |
cargo build \
--release \
--target wasm32-unknown-emscripten \
-p pumpkin-solver

docs:
name: Documentation
runs-on: ubuntu-latest
Expand Down
76 changes: 76 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions pumpkin-solver/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pumpkin-solver"
version = "0.2.0"
version = "0.1.4"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The versioning is incorrect when compared to the current main

description = "The Pumpkin combinatorial optimisation solver library."
readme = "../README.md"
authors.workspace = true
Expand All @@ -15,10 +15,9 @@ bitfield = "0.14.0"
enumset = "1.1.2"
fnv = "1.0.3"
rand = { version = "0.8.5", features = [ "small_rng", "alloc" ] }
signal-hook = "0.3.17"
once_cell = "1.19.0"
downcast-rs = "1.2.1"
drcp-format = { version = "0.2.1", path = "../drcp-format" }
drcp-format = { version = "0.2.0", path = "../drcp-format" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here please

convert_case = "0.6.0"
itertools = "0.13.0"
flatzinc = "0.3.21"
Expand All @@ -28,6 +27,12 @@ bitfield-struct = "0.9.2"
num = "0.4.3"
enum-map = "2.7.3"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
signal-hook = "0.3.17"

[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2", features = ["js"] }

[dev-dependencies]
clap = { version = "4.5.17", features = ["derive"] }
env_logger = "0.10.0"
Expand Down
13 changes: 12 additions & 1 deletion pumpkin-solver/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,18 @@ fn add_output_file<P: AsRef<Path>>(
output_stem: &str,
) {
let output_dir = output_dir.as_ref();
if is_msvc {
let target = std::env::var("TARGET").unwrap();
if target.contains("wasm32") {
// Output as a .wasm file when targeting WebAssembly.
let wasm_filename = format!("{output_stem}.wasm");
let output_file = output_dir.join(wasm_filename);
let _ = cmd.arg("-o").arg(output_file);

// Enable exceptions for Emscripten target
if target.contains("emscripten") {
let _ = cmd.arg("-fexceptions");
}
} else if is_msvc {
let exe_name = format!("{output_stem}.exe");

// The path to the object file.
Expand Down
1 change: 1 addition & 0 deletions pumpkin-solver/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pub mod termination {
//! the time budget is exceeded.
pub use crate::engine::termination::combinator::*;
pub use crate::engine::termination::indefinite::*;
#[cfg(not(target_arch = "wasm32"))]
pub use crate::engine::termination::os_signal::*;
pub use crate::engine::termination::time_budget::*;
pub use crate::engine::termination::TerminationCondition;
Expand Down
15 changes: 11 additions & 4 deletions pumpkin-solver/src/bin/pumpkin-solver/flatzinc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ use pumpkin_solver::results::SatisfactionResult;
use pumpkin_solver::results::SolutionReference;
use pumpkin_solver::statistics::StatisticLogger;
use pumpkin_solver::termination::Combinator;
#[cfg(target_arch = "wasm32")]
use pumpkin_solver::termination::Indefinite as OsSignalReplacement;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming here is a bit confusing; Indefinite is fine here

#[cfg(not(target_arch = "wasm32"))]
use pumpkin_solver::termination::OsSignal;
use pumpkin_solver::termination::TerminationCondition;
use pumpkin_solver::termination::TimeBudget;
Expand Down Expand Up @@ -83,10 +86,14 @@ pub(crate) fn solve(
) -> Result<(), FlatZincError> {
let instance = File::open(instance)?;

let mut termination = Combinator::new(
OsSignal::install(),
time_limit.map(TimeBudget::starting_now),
);
#[cfg(not(target_arch = "wasm32"))]
let signal_condition = OsSignal::install();

#[cfg(target_arch = "wasm32")]
let signal_condition = OsSignalReplacement;

let mut termination =
Combinator::new(signal_condition, time_limit.map(TimeBudget::starting_now));

let instance = parse_and_compile(&mut solver, instance, options)?;
let outputs = instance.outputs.clone();
Expand Down
1 change: 1 addition & 0 deletions pumpkin-solver/src/engine/termination/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

pub(crate) mod combinator;
pub(crate) mod indefinite;
#[cfg(not(target_arch = "wasm32"))]
pub(crate) mod os_signal;
pub(crate) mod time_budget;

Expand Down