From 4294a1639ed64d96289b0bdc9e95074ffd8c8f43 Mon Sep 17 00:00:00 2001 From: rarbore2 <rarbore2@illinois.edu> Date: Sun, 17 Nov 2024 15:08:41 -0600 Subject: [PATCH] Setup for CI --- .gitlab-ci.yml | 9 ++ Cargo.lock | 65 ++---------- Cargo.toml | 18 ++-- hercules_opt/src/inline.rs | 2 +- hercules_opt/src/pass.rs | 2 +- hercules_samples/dot/Cargo.toml | 5 + hercules_samples/dot/build.rs | 16 ++- hercules_samples/dot/{ => src}/dot.hir | 0 hercules_samples/dot/src/main.rs | 16 +-- hercules_samples/fac/Cargo.toml | 5 + hercules_samples/fac/build.rs | 16 ++- hercules_samples/fac/{ => src}/fac.hir | 0 hercules_samples/fac/src/main.rs | 14 +-- hercules_samples/matmul/Cargo.toml | 5 + hercules_samples/matmul/build.rs | 16 ++- hercules_samples/matmul/src/main.rs | 17 ++-- hercules_samples/matmul/{ => src}/matmul.hir | 0 juno_build/Cargo.toml | 1 + juno_build/src/lib.rs | 100 ++++++++++++++++--- juno_frontend/src/lib.rs | 49 +++++++-- juno_samples/simple3/src/main.rs | 14 ++- 21 files changed, 225 insertions(+), 145 deletions(-) create mode 100644 .gitlab-ci.yml rename hercules_samples/dot/{ => src}/dot.hir (100%) rename hercules_samples/fac/{ => src}/fac.hir (100%) rename hercules_samples/matmul/{ => src}/matmul.hir (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..d8af3a03 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,9 @@ +build-job: + stage: build + script: + - cargo build + +test-job: + stage: test + script: + - cargo test diff --git a/Cargo.lock b/Cargo.lock index 47f8fce9..440cdd3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -369,26 +369,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derive_more" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "dot" version = "0.1.0" @@ -396,7 +376,9 @@ dependencies = [ "async-std", "clap", "hercules_rt", + "juno_build", "rand", + "with_builtin_macros", ] [[package]] @@ -467,7 +449,9 @@ dependencies = [ "async-std", "clap", "hercules_rt", + "juno_build", "rand", + "with_builtin_macros", ] [[package]] @@ -623,20 +607,6 @@ dependencies = [ "ron", ] -[[package]] -name = "hercules_interpreter" -version = "0.1.0" -dependencies = [ - "bitvec", - "clap", - "derive_more", - "hercules_ir", - "hercules_opt", - "itertools", - "ordered-float", - "rand", -] - [[package]] name = "hercules_ir" version = "0.1.0" @@ -686,20 +656,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "hercules_tests" -version = "0.1.0" -dependencies = [ - "bitvec", - "clap", - "hercules_interpreter", - "hercules_ir", - "hercules_opt", - "itertools", - "ordered-float", - "rand", -] - [[package]] name = "hermit-abi" version = "0.4.0" @@ -750,6 +706,7 @@ dependencies = [ name = "juno_build" version = "0.1.0" dependencies = [ + "hercules_ir", "hercules_rt", "juno_frontend", "with_builtin_macros", @@ -772,16 +729,6 @@ dependencies = [ "phf", ] -[[package]] -name = "juno_matmul" -version = "0.1.0" -dependencies = [ - "async-std", - "hercules_rt", - "juno_build", - "with_builtin_macros", -] - [[package]] name = "juno_scheduler" version = "0.0.1" @@ -920,7 +867,9 @@ dependencies = [ "async-std", "clap", "hercules_rt", + "juno_build", "rand", + "with_builtin_macros", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 027e9bf7..8fa3079b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,20 +6,20 @@ members = [ "hercules_opt", "hercules_rt", "hercules_rt_proc", - - "hercules_test/hercules_interpreter", - "hercules_test/hercules_tests", "hercules_tools/hercules_driver", - - "juno_frontend", - "juno_scheduler", - "juno_build", + + #"hercules_test/hercules_interpreter", + #"hercules_test/hercules_tests", "hercules_samples/dot", "hercules_samples/matmul", "hercules_samples/fac", - "juno_samples/matmul", - "juno_samples/simple3", + "juno_frontend", + "juno_scheduler", + "juno_build", + + #"juno_samples/matmul", + "juno_samples/simple3", ] diff --git a/hercules_opt/src/inline.rs b/hercules_opt/src/inline.rs index bd192c39..ecc8027f 100644 --- a/hercules_opt/src/inline.rs +++ b/hercules_opt/src/inline.rs @@ -197,7 +197,7 @@ fn inline_func( // Stich the control use of the original call node's region with // the predecessor control of the inlined function's return. - edit = edit.replace_all_uses(control, called_return_pred)?; + edit = edit.replace_all_uses(control, old_id_to_new_id(called_return_pred))?; // Stitch uses of parameter nodes in the inlined function to the IDs // of arguments provided to the call node. diff --git a/hercules_opt/src/pass.rs b/hercules_opt/src/pass.rs index 81617169..cb56f709 100644 --- a/hercules_opt/src/pass.rs +++ b/hercules_opt/src/pass.rs @@ -676,7 +676,7 @@ impl PassManager { .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() - .unwrap(); + .expect("Error running clang. Is it installed?"); assert!(clang_process.wait().unwrap().success()); println!("{}", output_archive); diff --git a/hercules_samples/dot/Cargo.toml b/hercules_samples/dot/Cargo.toml index ab10aeda..69cd39e3 100644 --- a/hercules_samples/dot/Cargo.toml +++ b/hercules_samples/dot/Cargo.toml @@ -4,8 +4,13 @@ version = "0.1.0" authors = ["Russel Arbore <rarbore2@illinois.edu>"] edition = "2021" +[build-dependencies] +juno_build = { path = "../../juno_build" } + [dependencies] clap = { version = "*", features = ["derive"] } +juno_build = { path = "../../juno_build" } hercules_rt = { path = "../../hercules_rt" } rand = "*" async-std = "*" +with_builtin_macros = "0.1.0" diff --git a/hercules_samples/dot/build.rs b/hercules_samples/dot/build.rs index 47fb55e8..cfa03fd3 100644 --- a/hercules_samples/dot/build.rs +++ b/hercules_samples/dot/build.rs @@ -1,12 +1,10 @@ -use std::env::current_dir; +extern crate juno_build; +use juno_build::JunoCompiler; fn main() { - println!( - "cargo::rustc-link-search=native={}", - current_dir().unwrap().display() - ); - println!("cargo::rustc-link-lib=static=dot"); - - println!("cargo::rerun-if-changed=dot.hman"); - println!("cargo::rerun-if-changed=libdot.a"); + JunoCompiler::new() + .ir_in_src("dot.hir") + .unwrap() + .build() + .unwrap(); } diff --git a/hercules_samples/dot/dot.hir b/hercules_samples/dot/src/dot.hir similarity index 100% rename from hercules_samples/dot/dot.hir rename to hercules_samples/dot/src/dot.hir diff --git a/hercules_samples/dot/src/main.rs b/hercules_samples/dot/src/main.rs index dbf18713..6d4cf380 100644 --- a/hercules_samples/dot/src/main.rs +++ b/hercules_samples/dot/src/main.rs @@ -1,18 +1,20 @@ extern crate async_std; extern crate clap; -extern crate hercules_rt; +extern crate juno_build; -// To compile currently, run from the Hercules project root directory: -// cargo run --bin hercules_driver hercules_samples/dot/dot.hir "Codegen(\"hercules_samples/dot\",\"dot\")" -// Then, you can execute this example with: -// cargo run --bin dot -hercules_rt::use_hman!("hercules_samples/dot/dot.hman"); +juno_build::juno!("dot"); fn main() { async_std::task::block_on(async { let mut a = vec![0.0, 1.0, 0.0, 2.0, 0.0, 3.0, 0.0, 4.0]; let mut b = vec![0.0, 5.0, 0.0, 6.0, 0.0, 7.0, 0.0, 8.0]; let c = unsafe { dot(a.as_mut_ptr(), b.as_mut_ptr(), 8).await }; - println!("{}", c,); + println!("{}", c); + assert_eq!(c, 70.0); }); } + +#[test] +fn dot_test() { + main(); +} diff --git a/hercules_samples/fac/Cargo.toml b/hercules_samples/fac/Cargo.toml index bef11a91..9082a4fc 100644 --- a/hercules_samples/fac/Cargo.toml +++ b/hercules_samples/fac/Cargo.toml @@ -4,8 +4,13 @@ version = "0.1.0" authors = ["Russel Arbore <rarbore2@illinois.edu>"] edition = "2021" +[build-dependencies] +juno_build = { path = "../../juno_build" } + [dependencies] clap = { version = "*", features = ["derive"] } +juno_build = { path = "../../juno_build" } hercules_rt = { path = "../../hercules_rt" } rand = "*" async-std = "*" +with_builtin_macros = "0.1.0" diff --git a/hercules_samples/fac/build.rs b/hercules_samples/fac/build.rs index f43f9fbd..49a60248 100644 --- a/hercules_samples/fac/build.rs +++ b/hercules_samples/fac/build.rs @@ -1,12 +1,10 @@ -use std::env::current_dir; +extern crate juno_build; +use juno_build::JunoCompiler; fn main() { - println!( - "cargo::rustc-link-search=native={}", - current_dir().unwrap().display() - ); - println!("cargo::rustc-link-lib=static=fac"); - - println!("cargo::rerun-if-changed=fac.hman"); - println!("cargo::rerun-if-changed=libfac.a"); + JunoCompiler::new() + .ir_in_src("fac.hir") + .unwrap() + .build() + .unwrap(); } diff --git a/hercules_samples/fac/fac.hir b/hercules_samples/fac/src/fac.hir similarity index 100% rename from hercules_samples/fac/fac.hir rename to hercules_samples/fac/src/fac.hir diff --git a/hercules_samples/fac/src/main.rs b/hercules_samples/fac/src/main.rs index 5e5b4dde..e3a307fc 100644 --- a/hercules_samples/fac/src/main.rs +++ b/hercules_samples/fac/src/main.rs @@ -1,16 +1,18 @@ extern crate async_std; extern crate clap; -extern crate hercules_rt; +extern crate juno_build; -// To compile currently, run from the Hercules project root directory: -// cargo run --bin hercules_driver hercules_samples/fac/fac.hir "Codegen(\"hercules_samples/fac\",\"fac\")" -// Then, you can execute this example with: -// cargo run --bin fac -hercules_rt::use_hman!("hercules_samples/fac/fac.hman"); +juno_build::juno!("fac"); fn main() { async_std::task::block_on(async { let f = unsafe { fac(8).await }; println!("{}", f); + assert_eq!(f, 40320); }); } + +#[test] +fn fac_test() { + main(); +} diff --git a/hercules_samples/matmul/Cargo.toml b/hercules_samples/matmul/Cargo.toml index 744b3f59..9066c153 100644 --- a/hercules_samples/matmul/Cargo.toml +++ b/hercules_samples/matmul/Cargo.toml @@ -4,8 +4,13 @@ version = "0.1.0" authors = ["Russel Arbore <rarbore2@illinois.edu>"] edition = "2021" +[build-dependencies] +juno_build = { path = "../../juno_build" } + [dependencies] clap = { version = "*", features = ["derive"] } +juno_build = { path = "../../juno_build" } hercules_rt = { path = "../../hercules_rt" } rand = "*" async-std = "*" +with_builtin_macros = "0.1.0" diff --git a/hercules_samples/matmul/build.rs b/hercules_samples/matmul/build.rs index aa4cd97f..ec6eb892 100644 --- a/hercules_samples/matmul/build.rs +++ b/hercules_samples/matmul/build.rs @@ -1,12 +1,10 @@ -use std::env::current_dir; +extern crate juno_build; +use juno_build::JunoCompiler; fn main() { - println!( - "cargo::rustc-link-search=native={}", - current_dir().unwrap().display() - ); - println!("cargo::rustc-link-lib=static=matmul"); - - println!("cargo::rerun-if-changed=matmul.hman"); - println!("cargo::rerun-if-changed=libmatmul.a"); + JunoCompiler::new() + .ir_in_src("matmul.hir") + .unwrap() + .build() + .unwrap(); } diff --git a/hercules_samples/matmul/src/main.rs b/hercules_samples/matmul/src/main.rs index ac5e96b2..f3ceba93 100644 --- a/hercules_samples/matmul/src/main.rs +++ b/hercules_samples/matmul/src/main.rs @@ -2,13 +2,9 @@ extern crate async_std; extern crate clap; -extern crate hercules_rt; +extern crate juno_build; -// To compile currently, run from the Hercules project root directory: -// cargo run --bin hercules_driver hercules_samples/matmul/matmul.hir "Codegen(\"hercules_samples/matmul\",\"matmul\")" -// Then, you can execute this example with: -// cargo run --bin matmul -hercules_rt::use_hman!("hercules_samples/matmul/matmul.hman"); +juno_build::juno!("matmul"); fn main() { async_std::task::block_on(async { @@ -19,5 +15,14 @@ fn main() { matmul(a.as_mut_ptr(), b.as_mut_ptr(), c.as_mut_ptr(), 2, 2, 2).await; } println!("[[{}, {}], [{}, {}]]", c[0], c[1], c[2], c[3]); + assert_eq!(c[0], 19.0); + assert_eq!(c[1], 22.0); + assert_eq!(c[2], 43.0); + assert_eq!(c[3], 50.0); }); } + +#[test] +fn matmul_test() { + main(); +} diff --git a/hercules_samples/matmul/matmul.hir b/hercules_samples/matmul/src/matmul.hir similarity index 100% rename from hercules_samples/matmul/matmul.hir rename to hercules_samples/matmul/src/matmul.hir diff --git a/juno_build/Cargo.toml b/juno_build/Cargo.toml index 2e35059e..4f623498 100644 --- a/juno_build/Cargo.toml +++ b/juno_build/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] juno_frontend = { path = "../juno_frontend" } hercules_rt = { path = "../hercules_rt" } +hercules_ir = { path = "../hercules_ir" } with_builtin_macros = "0.1.0" diff --git a/juno_build/src/lib.rs b/juno_build/src/lib.rs index c40d8de1..e01a5187 100644 --- a/juno_build/src/lib.rs +++ b/juno_build/src/lib.rs @@ -1,16 +1,21 @@ +extern crate hercules_ir; extern crate hercules_rt; + use juno_compiler::*; use std::env::{current_dir, var}; use std::fmt::Write; -use std::fs::create_dir_all; +use std::fs::{create_dir_all, read_to_string}; use std::path::{Path, PathBuf}; use with_builtin_macros::with_builtin; // JunoCompiler is used to compile juno files into a library and manifest file appropriately to // import the definitions into a rust project via the juno! macro defined below +// You can also specify a Hercules IR file instead of a Juno file and this will compile that IR +// file (though in that case a schedule is not supported) pub struct JunoCompiler { + ir_src_path: Option<PathBuf>, src_path: Option<PathBuf>, out_path: Option<PathBuf>, verify: JunoVerify, @@ -21,6 +26,7 @@ pub struct JunoCompiler { impl JunoCompiler { pub fn new() -> Self { JunoCompiler { + ir_src_path: None, src_path: None, out_path: None, verify: JunoVerify::None, @@ -32,6 +38,33 @@ impl JunoCompiler { // Sets the name of the Juno file, this file should be contained in the src/ // file of the package that the JunoCompiler is used in the build script of pub fn file_in_src<P>(mut self, file: P) -> Result<Self, String> + where + P: AsRef<Path>, + { + self.src_path = Some(Self::make_src_path(&file)?); + self.ir_src_path = None; + self.out_path = Some(Self::get_out_path(&file)?); + Self::print_cargo_info(file); + + Ok(self) + } + + // Sets the name of the input Hercules IR file which is contained in the src/ directory of the + // package that the JunoCompiler is used in the build script of + pub fn ir_in_src<P>(mut self, file: P) -> Result<Self, String> + where + P: AsRef<Path>, + { + self.ir_src_path = Some(Self::make_src_path(&file)?); + self.src_path = None; + self.out_path = Some(Self::get_out_path(&file)?); + Self::print_cargo_info(file); + + Ok(self) + } + + // Construct the path to a file in the source directory + fn make_src_path<P>(file: P) -> Result<PathBuf, String> where P: AsRef<Path>, { @@ -48,34 +81,45 @@ impl JunoCompiler { }; path.push("src"); path.push(file.as_ref()); - self.src_path = Some(path); - // We also set the output file in this process, under the OUT_DIR cargo provides + Ok(path) + } + + // Construct the path to the output directory, under the OUT_DIR cargo provides + fn get_out_path<P>(file: P) -> Result<PathBuf, String> + where + P: AsRef<Path>, + { let mut out = PathBuf::new(); out.push(var("OUT_DIR").unwrap()); out.push(file.as_ref().parent().unwrap().to_str().unwrap()); let Ok(()) = create_dir_all(&out) else { return Err("Failed to create output directory.".to_string()); }; - self.out_path = Some(out); + Ok(out) + } - // Tell cargo to rerun if the Juno file changes + // Prints information to tell cargo the following + // - Rerun if the source file changes + // - Add the output directory to its linker search + // - Link the compiled library file + // Tell cargo to rerun if the Juno file changes + fn print_cargo_info<P>(src_file: P) + where + P: AsRef<Path>, + { println!( "cargo::rerun-if-changed=src/{}", - file.as_ref().to_str().unwrap() + src_file.as_ref().to_str().unwrap() ); - // Tell cargo to include the output directory in its linker search - // (and to link the resulting library) println!( "cargo::rustc-link-search=native={}", var("OUT_DIR").unwrap() ); println!( "cargo::rustc-link-lib=static={}", - file.as_ref().file_stem().unwrap().to_str().unwrap() + src_file.as_ref().file_stem().unwrap().to_str().unwrap() ); - - Ok(self) } pub fn verify(mut self, enabled: bool) -> Self { @@ -139,7 +183,8 @@ impl JunoCompiler { // Builds the juno file into a libary and a manifest file. pub fn build(self) -> Result<(), String> { let JunoCompiler { - src_path: Some(src_path), + ir_src_path: ir_src_path, + src_path: src_path, out_path: Some(out_path), verify, x_dot, @@ -149,12 +194,35 @@ impl JunoCompiler { return Err("No source file specified.".to_string()); }; - let src_file = src_path.to_str().unwrap().to_string(); let out_dir = out_path.to_str().unwrap().to_string(); - match compile(src_file, verify, x_dot, schedule, out_dir) { - Ok(()) => Ok(()), - Err(errs) => Err(format!("{}", errs)), + if let Some(src_path) = src_path { + let src_file = src_path.to_str().unwrap().to_string(); + + match compile(src_file, verify, x_dot, schedule, out_dir) { + Ok(()) => Ok(()), + Err(errs) => Err(format!("{}", errs)), + } + } else { + let Some(ir_src_path) = ir_src_path else { + return Err("No source file specified.".to_string()); + }; + + let ir_src_file = ir_src_path.to_str().unwrap().to_string(); + let ir_src_path = Path::new(&ir_src_file); + let module_name = String::from(ir_src_path.file_stem().unwrap().to_str().unwrap()); + + let Ok(contents) = read_to_string(&ir_src_path) else { + return Err("Unable to open and read input file.".to_string()); + }; + let Ok(ir_mod) = hercules_ir::parse::parse(&contents) else { + return Err("Unable to parse Hercules IR file.".to_string()); + }; + + match compile_ir(ir_mod, None, verify, x_dot, schedule, out_dir, module_name) { + Ok(()) => Ok(()), + Err(errs) => Err(format!("{}", errs)), + } } } } diff --git a/juno_frontend/src/lib.rs b/juno_frontend/src/lib.rs index 1ac61fe5..cccadbdd 100644 --- a/juno_frontend/src/lib.rs +++ b/juno_frontend/src/lib.rs @@ -14,6 +14,8 @@ extern crate hercules_ir; use std::fmt; use std::path::Path; +use juno_scheduler::FunctionMap; + pub enum JunoVerify { None, JunoOpts, @@ -96,6 +98,26 @@ pub fn compile( }; let (module, func_info) = codegen::codegen_program(prg); + compile_ir( + module, + Some(func_info), + verify, + x_dot, + schedule, + output_dir, + module_name, + ) +} + +pub fn compile_ir( + module: hercules_ir::ir::Module, + func_info: Option<FunctionMap>, + verify: JunoVerify, + x_dot: bool, + schedule: JunoSchedule, + output_dir: String, + module_name: String, +) -> Result<(), ErrorMessage> { let mut pm = match schedule { JunoSchedule::None => hercules_opt::pass::PassManager::new(module), JunoSchedule::DefaultSchedule => { @@ -103,16 +125,24 @@ pub fn compile( pm.make_plans(); pm } - JunoSchedule::Schedule(file) => match juno_scheduler::schedule(&module, func_info, file) { - Ok(plans) => { - let mut pm = hercules_opt::pass::PassManager::new(module); - pm.set_plans(plans); - pm - } - Err(msg) => { - return Err(ErrorMessage::SchedulingError(msg)); + JunoSchedule::Schedule(file) => { + let Some(func_info) = func_info else { + return Err(ErrorMessage::SchedulingError( + "Cannot schedule, no function information provided".to_string(), + )); + }; + + match juno_scheduler::schedule(&module, func_info, file) { + Ok(plans) => { + let mut pm = hercules_opt::pass::PassManager::new(module); + pm.set_plans(plans); + pm + } + Err(msg) => { + return Err(ErrorMessage::SchedulingError(msg)); + } } - }, + } }; if verify.verify() || verify.verify_all() { pm.add_pass(hercules_opt::pass::Pass::Verify); @@ -121,6 +151,7 @@ pub fn compile( if x_dot { pm.add_pass(hercules_opt::pass::Pass::Xdot(true)); } + add_pass!(pm, verify, Inline); add_pass!(pm, verify, CCP); add_pass!(pm, verify, DCE); add_pass!(pm, verify, GVN); diff --git a/juno_samples/simple3/src/main.rs b/juno_samples/simple3/src/main.rs index 441408ee..1eb0173d 100644 --- a/juno_samples/simple3/src/main.rs +++ b/juno_samples/simple3/src/main.rs @@ -1,8 +1,8 @@ #![feature(future_join)] extern crate async_std; -extern crate juno_build; extern crate hercules_rt; +extern crate juno_build; juno_build::juno!("simple3"); @@ -10,9 +10,13 @@ fn main() { async_std::task::block_on(async { let mut a = vec![1, 2, 3, 4, 5, 6, 7, 8]; let mut b = vec![8, 7, 6, 5, 4, 3, 2, 1]; - unsafe { - let c = simple3(a.as_mut_ptr(), b.as_mut_ptr(), 8).await; - println!("{:?}", c); - } + let c = unsafe { simple3(a.as_mut_ptr(), b.as_mut_ptr(), 8).await }; + println!("{:?}", c); + assert_eq!(c.0, 120); }); } + +#[test] +fn simple3_test() { + main(); +} -- GitLab