Skip to content

Commit

Permalink
added compiler executable
Browse files Browse the repository at this point in the history
  • Loading branch information
martinjrobins committed Aug 22, 2023
1 parent 3b6ac89 commit e60e30d
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 4 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]

[[bin]]
name = "diffeq"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand All @@ -18,6 +21,7 @@ itertools = ">=0.10.3"
inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master", features = ["llvm14-0"] }
sundials-sys = { version = ">=0.2.3", features = ["idas"] }
ouroboros = ">=0.17"
clap = { version = "4.3.23", features = ["derive"] }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]

Expand All @@ -34,4 +38,4 @@ debug = true

[profile.release]
opt-level = 3
debug = false
debug = false
5 changes: 5 additions & 0 deletions examples/logistic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
model logistic_growth(r -> NonNegative, k -> NonNegative, y(t), z(t)) {
dot(y) = r * y * (1 - y / k)
y(0) = 1.0
z = 2 * y
}
23 changes: 23 additions & 0 deletions examples/logistic.ds
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
in = [r, k]
r { 1 }
k { 1 }
u_i {
y = 1,
z = 0,
}
dudt_i {
dydt = 0,
dzdt = 0,
}
F_i {
dydt,
0,
}
G_i {
(r * y) * (1 - (y / k)),
(2 * y) - z,
}
out_i {
y,
z,
}
112 changes: 112 additions & 0 deletions src/bin/diffeq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@

use std::{path::Path, ffi::OsStr};

use clap::Parser;
use diffeq::{parser::{parse_ms_string, parse_ds_string}, continuous::ModelInfo, discretise::DiscreteModel, codegen::Compiler};

/// compiles a model in continuous (.cs) or discrete (.ds) format to an object file
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Input filename
input: String,

/// Output filename
#[arg(short, long)]
out: Option<String>,

/// Model to build (only for continuous model files)
#[arg(short, long)]
model: Option<String>,
}

fn main() {
let cli = Args::parse();

let inputfile = Path::new(&cli.input);
let out = if let Some(out) = cli.out {
out.clone()
} else {
"out.o".to_owned()
};
let outfile = Path::new(&out);
let is_discrete = inputfile.extension().unwrap_or(OsStr::new("")).to_str().unwrap() == "ds";
let is_continuous = inputfile.extension().unwrap_or(OsStr::new("")).to_str().unwrap() == "cs";
if !is_discrete && !is_continuous {
panic!("Input file must have extension .ds or .cs");
}
let text = match std::fs::read_to_string(inputfile) {
Ok(text) => {
text
}
Err(e) => {
panic!("{}", e);
}
};
if is_continuous {
let models = match parse_ms_string(text.as_str()) {
Ok(models) => {
models
}
Err(e) => {
panic!("{}", e);
}
};
let model_name = if let Some(model_name) = cli.model {
model_name
} else {
panic!("Model name must be specified for continuous models");
};
let model_info = match ModelInfo::build(model_name.as_str(), &models) {
Ok(model_info) => {
model_info
}
Err(e) => {
panic!("{}", e);
}
};
if model_info.errors.len() > 0 {
for error in model_info.errors {
println!("{}", error.as_error_message(text.as_str()));
}
panic!("Errors in model");
}
let model = DiscreteModel::from(&model_info);
let compiler = match Compiler::from_discrete_model(&model) {
Ok(compiler) => {
compiler
}
Err(e) => {
panic!("{}", e);
}
};
compiler.write_object_file(outfile).unwrap();
} else {
let model = match parse_ds_string(text.as_str()) {
Ok(model) => {
model
}
Err(e) => {
panic!("{}", e);
}
};
let model = match DiscreteModel::build(&cli.input, &model) {
Ok(model) => {
model
}
Err(e) => {
panic!("{}", e.as_error_message(text.as_str()));
}
};
let compiler = match Compiler::from_discrete_model(&model) {
Ok(compiler) => {
compiler
}
Err(e) => {
panic!("{}", e);
}
};
compiler.write_object_file(outfile).unwrap();
};
}

6 changes: 3 additions & 3 deletions src/codegen/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ impl Compiler {
})
}

pub fn write_object_file(&self) -> Result<()> {
pub fn write_object_file(&self, path: &Path) -> Result<()> {
Target::initialize_x86(&InitializationConfig::default());

let opt = OptimizationLevel::Default;
Expand All @@ -242,7 +242,6 @@ impl Compiler {
)
.unwrap();

let path = Path::new("main.o");
self.with_data(|data|
target_machine.write_to_file(data.codegen.module(), FileType::Object, &path).map_err(|e| anyhow::anyhow!("Error writing object file: {:?}", e))
)
Expand Down Expand Up @@ -285,7 +284,8 @@ mod tests {
assert_eq!(model_info.errors.len(), 0);
let discrete_model = DiscreteModel::from(&model_info);
let object = Compiler::from_discrete_model(&discrete_model).unwrap();
object.write_object_file().unwrap();
let path = Path::new("main.o");
object.write_object_file(path).unwrap();
}

macro_rules! tensor_test {
Expand Down

0 comments on commit e60e30d

Please sign in to comment.