Skip to content

Commit

Permalink
Merge branch 'main' into python-schema-wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
jetuk committed Jan 13, 2024
2 parents b552662 + 651d7bb commit 8fb9911
Show file tree
Hide file tree
Showing 122 changed files with 5,786 additions and 2,406 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
sudo apt-get update
sudo apt-get install libhdf5-dev ocl-icd-opencl-dev zlib1g-dev
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install Dependencies
Expand All @@ -47,7 +47,7 @@ jobs:
sudo apt-get update
sudo apt-get install libhdf5-dev ocl-icd-opencl-dev liblzma-dev zlib1g-dev
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Build and test
Expand Down
8 changes: 3 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


[workspace]
resolver = "2"
members = [
Expand Down Expand Up @@ -40,11 +38,11 @@ thiserror = "1.0.25"
time = { version = "0.3", features = ["serde", "serde-well-known", "serde-human-readable", "macros"] }
num = "0.4.0"
ndarray = "0.15.3"
polars = { version = "0.35.4", features = ["lazy", "rows", "ndarray"] }
pyo3-polars = "0.9.0"
polars = { version = "0.36.2", features = ["lazy", "rows", "ndarray"] }
pyo3-polars = "0.10.0"
pyo3 = { version = "0.20.0" }
tracing = "0.1"
csv = "1.1"
hdf5 = { version="0.8.1" }
hdf5-sys = { version="0.8.1", features=["static"] }
pywr-v1-schema = { git = "https://github.com/pywr/pywr-schema/", tag="v0.7.0", package = "pywr-schema" }
pywr-v1-schema = { git = "https://github.com/pywr/pywr-schema/", tag="v0.9.0", package = "pywr-schema" }
2 changes: 1 addition & 1 deletion pywr-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pywr-cli"
version = "0.1.0"
version = "2.0.0-dev"
edition = "2021"
rust-version = "1.60"
description = "A generalised water resource allocation model."
Expand Down
95 changes: 66 additions & 29 deletions pywr-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use anyhow::{Context, Result};
use clap::{Parser, Subcommand, ValueEnum};
use pywr_core::model::Model;
#[cfg(feature = "ipm-ocl")]
use pywr_core::solvers::{ClIpmF32Solver, ClIpmF64Solver, ClIpmSolverSettings};
use pywr_core::solvers::{ClpSolver, ClpSolverSettings};
Expand All @@ -9,16 +8,13 @@ use pywr_core::solvers::{HighsSolver, HighsSolverSettings};
#[cfg(feature = "ipm-simd")]
use pywr_core::solvers::{SimdIpmF64Solver, SimdIpmSolverSettings};
use pywr_core::test_utils::make_random_model;
use pywr_core::timestep::Timestepper;
use pywr_core::tracing::setup_tracing;
use pywr_core::PywrError;
use pywr_schema::model::PywrModel;
use pywr_schema::model::{PywrModel, PywrMultiNetworkModel};
use pywr_schema::ConversionError;
use rand::SeedableRng;
use rand_chacha::ChaCha8Rng;
use std::fmt::{Display, Formatter};
use std::path::{Path, PathBuf};
use time::macros::date;

#[derive(Copy, Clone, ValueEnum)]
enum Solver {
Expand Down Expand Up @@ -92,6 +88,25 @@ enum Commands {
#[arg(long, default_value_t = false)]
debug: bool,
},
RunMulti {
/// Path to Pywr model JSON.
model: PathBuf,
/// Solver to use.
#[arg(short, long, default_value_t=Solver::Clp)]
solver: Solver,
#[arg(short, long)]
data_path: Option<PathBuf>,
#[arg(short, long)]
output_path: Option<PathBuf>,
/// Use multiple threads for simulation.
#[arg(short, long, default_value_t = false)]
parallel: bool,
/// The number of threads to use in parallel simulation.
#[arg(short, long, default_value_t = 1)]
threads: usize,
#[arg(long, default_value_t = false)]
debug: bool,
},
RunRandom {
num_systems: usize,
density: usize,
Expand All @@ -117,6 +132,15 @@ fn main() -> Result<()> {
threads,
debug,
} => run(model, solver, data_path.as_deref(), output_path.as_deref(), *debug),
Commands::RunMulti {
model,
solver,
data_path,
output_path,
parallel,
threads,
debug,
} => run_multi(model, solver, data_path.as_deref(), output_path.as_deref(), *debug),
Commands::RunRandom {
num_systems,
density,
Expand Down Expand Up @@ -171,50 +195,63 @@ fn run(path: &Path, solver: &Solver, data_path: Option<&Path>, output_path: Opti
setup_tracing(debug).unwrap();

let data = std::fs::read_to_string(path).unwrap();
let data_path = data_path.or_else(|| path.parent());
let schema_v2: PywrModel = serde_json::from_str(data.as_str()).unwrap();

let (model, timestepper): (Model, Timestepper) = schema_v2.build_model(data_path, output_path).unwrap();
let model = schema_v2.build_model(data_path, output_path).unwrap();

match *solver {
Solver::Clp => model.run::<ClpSolver>(&timestepper, &ClpSolverSettings::default()),
Solver::Clp => model.run::<ClpSolver>(&ClpSolverSettings::default()),
#[cfg(feature = "highs")]
Solver::HIGHS => model.run::<HighsSolver>(&timestepper, &HighsSolverSettings::default()),
Solver::HIGHS => model.run::<HighsSolver>(&HighsSolverSettings::default()),
#[cfg(feature = "ipm-ocl")]
Solver::CLIPMF32 => model.run_multi_scenario::<ClIpmF32Solver>(&timestepper, &ClIpmSolverSettings::default()),
Solver::CLIPMF32 => model.run_multi_scenario::<ClIpmF32Solver>(&ClIpmSolverSettings::default()),
#[cfg(feature = "ipm-ocl")]
Solver::CLIPMF64 => model.run_multi_scenario::<ClIpmF64Solver>(&timestepper, &ClIpmSolverSettings::default()),
Solver::CLIPMF64 => model.run_multi_scenario::<ClIpmF64Solver>(&ClIpmSolverSettings::default()),
#[cfg(feature = "ipm-simd")]
Solver::IpmSimd => {
model.run_multi_scenario::<SimdIpmF64Solver<4>>(&timestepper, &SimdIpmSolverSettings::default())
}
Solver::IpmSimd => model.run_multi_scenario::<SimdIpmF64Solver<4>>(&SimdIpmSolverSettings::default()),
}
.unwrap();
}

fn run_multi(path: &Path, solver: &Solver, data_path: Option<&Path>, output_path: Option<&Path>, debug: bool) {
setup_tracing(debug).unwrap();

let data = std::fs::read_to_string(path).unwrap();
let data_path = data_path.or_else(|| path.parent());

let schema_v2: PywrMultiNetworkModel = serde_json::from_str(data.as_str()).unwrap();

let model = schema_v2.build_model(data_path, output_path).unwrap();

match *solver {
Solver::Clp => model.run::<ClpSolver>(&ClpSolverSettings::default()),
#[cfg(feature = "highs")]
Solver::HIGHS => model.run::<HighsSolver>(&HighsSolverSettings::default()),
#[cfg(feature = "ipm-ocl")]
Solver::CLIPMF32 => model.run_multi_scenario::<ClIpmF32Solver>(&ClIpmSolverSettings::default()),
#[cfg(feature = "ipm-ocl")]
Solver::CLIPMF64 => model.run_multi_scenario::<ClIpmF64Solver>(&ClIpmSolverSettings::default()),
#[cfg(feature = "ipm-simd")]
Solver::IpmSimd => model.run_multi_scenario::<SimdIpmF64Solver<4>>(&SimdIpmSolverSettings::default()),
}
.unwrap();
}

fn run_random(num_systems: usize, density: usize, num_scenarios: usize, solver: &Solver) {
let timestepper = Timestepper::new(date!(2020 - 01 - 01), date!(2020 - 01 - 10), 1);
let mut rng = ChaCha8Rng::seed_from_u64(0);
let model = make_random_model(
num_systems,
density,
timestepper.timesteps().len(),
num_scenarios,
&mut rng,
)
.unwrap();
let model = make_random_model(num_systems, density, num_scenarios, &mut rng).unwrap();

match *solver {
Solver::Clp => model.run::<ClpSolver>(&timestepper, &ClpSolverSettings::default()),
Solver::Clp => model.run::<ClpSolver>(&ClpSolverSettings::default()),
#[cfg(feature = "highs")]
Solver::HIGHS => model.run::<HighsSolver>(&timestepper, &HighsSolverSettings::default()),
Solver::HIGHS => model.run::<HighsSolver>(&HighsSolverSettings::default()),
#[cfg(feature = "ipm-ocl")]
Solver::CLIPMF32 => model.run_multi_scenario::<ClIpmF32Solver>(&timestepper, &ClIpmSolverSettings::default()),
Solver::CLIPMF32 => model.run_multi_scenario::<ClIpmF32Solver>(&ClIpmSolverSettings::default()),
#[cfg(feature = "ipm-ocl")]
Solver::CLIPMF64 => model.run_multi_scenario::<ClIpmF64Solver>(&timestepper, &ClIpmSolverSettings::default()),
Solver::CLIPMF64 => model.run_multi_scenario::<ClIpmF64Solver>(&ClIpmSolverSettings::default()),
#[cfg(feature = "ipm-simd")]
Solver::IpmSimd => {
model.run_multi_scenario::<SimdIpmF64Solver<4>>(&timestepper, &SimdIpmSolverSettings::default())
}
Solver::IpmSimd => model.run_multi_scenario::<SimdIpmF64Solver<4>>(&SimdIpmSolverSettings::default()),
}
.unwrap();
}
1 change: 1 addition & 0 deletions pywr-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tracing = { workspace = true }
tracing-subscriber = { version ="0.3.17", features=["env-filter"] }
highs-sys = { git = "https://github.com/jetuk/highs-sys", branch="fix-build-libz-linking", optional = true }
# highs-sys = { path = "../../highs-sys" }
nalgebra = "0.32.3"

pyo3 = { workspace = true }

Expand Down
Loading

0 comments on commit 8fb9911

Please sign in to comment.